当前位置:  编程技术>综合
本页文章导读:
    ▪python获取变量的数据类型      有时候我们需要知道variable的数据类型,在python中有内置函数type可以获取variable的数据类型 1. 在console输入如下code: id = 1 type(id) 输出:<type 'int'> 2. 在console输入如下code: id = 1L type(id) .........
    ▪探索Lua5.2内部实现:虚拟机指令(5)Arithmetic       原文 name args desc OP_ADD A B C R(A) := RK(B) + RK(C) OP_SUB A B C R(A) := RK(B) - RK(C) OP_MUL A B C R(A) := RK(B) * RK(C) OP_DIV A B C R(A) := RK(B) / RK(C) OP_MOD A B C R(A) := RK(B) % RK(C) OP_POW A B C R(A) := RK(B) ^ RK(.........
    ▪探索Lua5.2内部实现:虚拟机指令(4) Table      原文 name args desc OP_NEWTABLE A B C R(A) := {} (size = B,C) NEWTABLE在寄存器A处创建一个table对象。B和C分别用来存储这个table数组部分和hash部分的初始大小。初始大小是在编译期计算出来并生成.........

[1]python获取变量的数据类型
    来源: 互联网  发布时间: 2013-11-10

有时候我们需要知道variable的数据类型,在python中有内置函数type可以获取variable的数据类型

1. 在console输入如下code:

id = 1

type(id)

输出:<type 'int'>


2. 在console输入如下code:

id = 1L

type(id)

输出:<type 'long'>


3. 在console输入如下code:

id = 1.0

type(id)

输出:<type 'float'>





作者:perfumekristy 发表于2013-1-11 18:15:00 原文链接
阅读:0 评论:0 查看评论

    
[2]探索Lua5.2内部实现:虚拟机指令(5)Arithmetic
    来源: 互联网  发布时间: 2013-11-10

原文

name args desc OP_ADD A B C R(A) := RK(B) + RK(C) OP_SUB A B C R(A) := RK(B) - RK(C) OP_MUL A B C R(A) := RK(B) * RK(C) OP_DIV A B C R(A) := RK(B) / RK(C) OP_MOD A B C R(A) := RK(B) % RK(C) OP_POW A B C R(A) := RK(B) ^ RK(C)

上表中的指令都是与lua本身的二元操作符一一对应的标准3地址指令。B和C两个操作数计算的结果存入A中。

local a = 1;
a = a + 1;
a = a - 1;
a = a * 1;
a = a / 1;
a = a % 1;
a = a ^ 1;
main <test.lua:0,0> (8 instructions at 0x80048eb0)
0+ params, 2 slots, 1 upvalue, 1 local, 1 constant, 0 functions
	1	[1]	LOADK    	0 -1	; 1
	2	[2]	ADD      	0 0 -1	; - 1
	3	[3]	SUB      	0 0 -1	; - 1
	4	[4]	MUL      	0 0 -1	; - 1
	5	[5]	DIV      	0 0 -1	; - 1
	6	[6]	MOD      	0 0 -1
	7	[7]	POW      	0 0 -1	; - 1
	8	[7]	RETURN   	0 1
constants (1) for 0x80048eb0:
	1	1
locals (1) for 0x80048eb0:
	0	a	2	9
upvalues (1) for 0x80048eb0:
	0	_ENV	1	0  

可以看到,生成的指令没有多余的操作,每个指令都对应一个完整的二元计算操作。

name args desc OP_UNM A B R(A) := -R(B) OP_NOT A B A B R(A) := not R(B)

上表中指令对应'-'和'not'一元操作符,表示将B取反或not后放入A中。

local a = 1;
local b = not a;
local c = -a;
	1	[1]	LOADK    	0 -1	; 1
	2	[2]	NOT      	1 0
	3	[3]	UNM      	2 0
	4	[3]	RETURN   	0 1 

在编译和指令生成阶段,lua还支持所有一元和二元操作符表达式的常量表达式折叠”(const expression folding)优化。也就是如果计算操作数如果都是数字常量,可以在编译期计算出结果,就直接使用这个结果值,而不用生成计算指令。

local a = 1 + 1;
local b = not 1;
	1	[1]	LOADK    	0 -1	; 2
	2	[2]	LOADBOOL 	1 0 0
	3	[2]	RETURN   	0 1
从生成的结果可以看到1+1并没有生成对应的OP_ADD,而是直接把结果2赋值给了a。并且也没有为not 1生成OP_NOT指令,而是直接将false赋值给了b。

name args desc OP_LEN A B R(A) := length of R(B)

LEN直接对应'#'操作符,返回B对象的长度,并保存到A中。

local a = #"foo";
	1	[1]	LOADK    	0 -1	; "foo"
	2	[1]	LEN      	0 0
	3	[1]	RETURN   	0 1 

name args desc OP_CONCAT A B C R(A) := R(B).. ... ..R(C)

CONCAT将B和C指定范围内的字符串按顺序传接到一起,将结果存入到A。

local a = "foo1".."foo2".."foo3";
	1	[1]	LOADK    	0 -1	; "foo1"
	2	[1]	LOADK    	1 -2	; "foo2"
	3	[1]	LOADK    	2 -3	; "foo3"
	4	[1]	CONCAT   	0 0 2
	5	[1]	RETURN   	0 1 


作者:yuanlin2008 发表于2013-1-11 18:14:27 原文链接
阅读:7 评论:0 查看评论

    
[3]探索Lua5.2内部实现:虚拟机指令(4) Table
    来源: 互联网  发布时间: 2013-11-10

原文

name args desc OP_NEWTABLE A B C R(A) := {} (size = B,C)

NEWTABLE在寄存器A处创建一个table对象。B和C分别用来存储这个table数组部分和hash部分的初始大小。初始大小是在编译期计算出来并生成到这个指令中的,目的是使接下来对table的初始化填充不会造成rehash而影响效率。B和C使用“floating point byte”的方法来表示成(eeeeexxx)的二进制形式,其实际值为(1xxx) * 2^(eeeee-1)。

local a = {};

	1	[1]	NEWTABLE 	0 0 0
	2	[1]	RETURN   	0 1 

上面代码生成一个空的table,放入local变量a,B和C参数都为0。


name args desc OP_SETLIST A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B

SETLIST用来配合NEWTABLE,初始化表的数组部分使用的。A为保存待设置表的寄存器,SETLIST要将A下面紧接着的寄存器列表(1--B)中的值逐个设置给表的数组部分。

当表需要初始化数组元素数量比较小的情况下,例如:

local a = {1,1,1};
	1	[1]	NEWTABLE 	0 3 0
	2	[1]	LOADK    	1 -1	; 1
	3	[1]	LOADK    	2 -1	; 1
	4	[1]	LOADK    	3 -1	; 1
	5	[1]	SETLIST  	0 3 1	; 1
	6	[1]	RETURN   	0 1
constants (1) for 0x80048eb0:
	1	1 
第1行先用NEWTABLE构建一个具有3个数组元素的表,让到寄存器0中;然后使用3个LOADK向下面3个寄存器装入常量1;最后使用SETLIST设置表的1~3为寄存器1~寄存器3。

如果需要创建一个很大的表,其中包含很多的数组元素,使用如上方法就会遇到一个问题。将这些指按顺序放到寄存器时,会超出寄存器的范围。解决的办法就是按照一个固定大小,将这些数组元素分批进行设置。在Lua中,每批的数量由lopcodes.h中的LFIELDS_PER_FLUSH定义,数量为50。所以,大数量的设置会按照50个一批,先将值设置到表下面的寄存器,然后设置给对应的表项。C代表的就是这一次调用SETLIST设置的是第几批。回到上面的例子,因为只有3个表项,所以1批就搞定了,C的值为1。

下面是一个大表的设置:

local a = 
{
	1,2,3,4,5,6,7,8,9,0,
	1,2,3,4,5,6,7,8,9,0,
	1,2,3,4,5,6,7,8,9,0,
	1,2,3,4,5,6,7,8,9,0,
	1,2,3,4,5,6,7,8,9,0,
	1,2,3
};
	1	[1]	NEWTABLE 	0 30 0
	2	[3]	LOADK    	1 -1	; 1
	3	[3]	LOADK    	2 -2	; 2 
...
	50	[7]	LOADK    	49 -9	; 9
	51	[7]	LOADK    	50 -10	; 0
	52	[7]	SETLIST  	0 50 1	; 1
	53	[8]	LOADK    	1 -1	; 1
	54	[8]	LOADK    	2 -2	; 2
	55	[9]	LOADK    	3 -3	; 3
	56	[9]	SETLIST  	0 3 2	; 2
	57	[9]	RETURN   	0 1
constants (10) for 0x80048eb0:
	1	1
	2	2
	3	3
	4	4
	5	5
	6	6
	7	7
	8	8
	9	9
	10	0 
可以看到,这个表的初始化使用了两个SETLIST指令。第一个处理前50个,C为1,设置id从(C-1)*50 + 1开始,也就是1。第二个处理余下的3个,C为2,设置的id从(C-1)*50 + 1开始,也就是51。

如果数据非常大,导致需要的批次超出了C的表示范围,那么C会被设置成0,然后在SETLIST指令后面生成一个EXTRAARG指令,并用其Ax来存储批次。这与前面说到的LOADKX的处理方法一样,都是为处理超大数据服务的。

如果使用核能产生多个返回值的表达式(... 和 函数调用)初始化数组项,如果这个初始化不是表构造的最后一项,那么只有第一个返回值会被设置到数组项;如果是最后一项,那么SETLIST中的B会被设置为0,表示从A+1到当前栈顶都用来设置。

SETLIST只负责初始化表的数组部分,对于hash部分,还是通过SETTABLE来初始化。

name args desc OP_GETTABLE A B C R(A) := R(B)[RK(C)] OP_SETTABLE A B C R(A)[RK(B)] := RK(C)

GETTABLE使用C表示的key,将寄存器B中的表项值获取到寄存器A中。SETTABLE设置寄存器A的表的B项为C代表的值。

local a = {};
a.x = 1;
local b = a.x;
	1	[1]	NEWTABLE 	0 0 0
	2	[2]	SETTABLE 	0 -1 -2	; "x" 1
	3	[3]	GETTABLE 	1 0 -1	; "x"
	4	[3]	RETURN   	0 1 



作者:yuanlin2008 发表于2013-1-11 18:13:36 原文链接
阅读:8 评论:0 查看评论

    
最新技术文章:
▪error while loading shared libraries的解決方法    ▪版本控制的极佳实践    ▪安装多个jdk,多个tomcat版本的冲突问题
▪简单选择排序算法    ▪国外 Android资源大集合 和个人学习android收藏    ▪.NET MVC 给loading数据加 ajax 等待loading效果
▪http代理工作原理(3)    ▪关注细节-TWaver Android    ▪Spring怎样把Bean实例暴露出来?
▪java写入excel2007的操作    ▪http代理工作原理(1)    ▪浅谈三层架构
▪http代理工作原理(2)    ▪解析三层架构……如何分层?    ▪linux PS命令
▪secureMRT Linux命令汉字出现乱码    ▪把C++类成员方法直接作为线程回调函数    ▪weak-and算法原理演示(wand)
▪53个要点提高PHP编程效率    ▪linux僵尸进程    ▪java 序列化到mysql数据库中
▪利用ndk编译ffmpeg    ▪活用CSS巧妙解决超长文本内容显示问题    ▪通过DBMS_RANDOM得到随机
▪CodeSmith 使用教程(8): CodeTemplate对象    ▪android4.0 进程回收机制    ▪仿天猫首页-产品分类
▪从Samples中入门IOS开发(四)------ 基于socket的...    ▪工作趣事 之 重装服务器后的网站不能正常访...    ▪java序列化学习笔记
▪Office 2010下VBA Addressof的应用    ▪一起来学ASP.NET Ajax(二)之初识ASP.NET Ajax    ▪更改CentOS yum 源为163的源
▪ORACLE 常用表达式    ▪记录一下,AS3反射功能的实现方法    ▪u盘文件系统问题
▪java设计模式-观察者模式初探    ▪MANIFEST.MF格式总结    ▪Android 4.2 Wifi Display核心分析 (一)
▪Perl 正则表达式 记忆方法    ▪.NET MVC 给loading数据加 ajax 等待laoding效果    ▪java 类之访问权限
▪extjs在myeclipse提示    ▪xml不提示问题    ▪Android应用程序运行的性能设计
▪sharepoint 2010 自定义列表启用版本记录控制 如...    ▪解决UIScrollView截获touch事件的一个极其简单有...    ▪Chain of Responsibility -- 责任链模式
▪运行skyeye缺少libbfd-2.18.50.0.2.20071001.so问题    ▪sharepoint 2010 使用sharepoint脚本STSNavigate方法实...    ▪让javascript显原型!
▪kohana基本安装配置    ▪MVVM开发模式实例解析    ▪sharepoint 2010 设置pdf文件在浏览器中访问
▪spring+hibernate+事务    ▪MyEclipse中文乱码,编码格式设置,文件编码格...    ▪struts+spring+hibernate用jquery实现数据分页异步加...
▪windows平台c++开发"麻烦"总结    ▪Android Wifi几点    ▪Myeclipse中JDBC连接池的配置
▪优化后的冒泡排序算法    ▪elasticsearch RESTful搜索引擎-(java jest 使用[入门])...    ▪MyEclipse下安装SVN插件SubEclipse的方法
▪100个windows平台C++开发错误之七编程    ▪串口转以太网模块WIZ140SR/WIZ145SR 数据手册(版...    ▪初识XML(三)Schema
▪Deep Copy VS Shallow Copy    ▪iphone游戏开发之cocos2d (七) 自定义精灵类,实...    ▪100个windows平台C++开发错误之八编程
▪C++程序的内存布局    ▪将不确定变为确定系列~Linq的批量操作靠的住...    ▪DIV始终保持在浏览器中央,兼容各浏览器版本
▪Activity生命周期管理之三——Stopping或者Restarti...    ▪《C语言参悟之旅》-读书笔记(八)    ▪C++函数参数小结
▪android Content Provider详解九    ▪简单的图片无缝滚动效果    ▪required artifact is missing.
▪c++编程风格----读书笔记(1)    ▪codeforces round 160    ▪【Visual C++】游戏开发笔记四十 浅墨DirectX教程...
▪【D3D11游戏编程】学习笔记十八:模板缓冲区...    ▪codeforces 70D 动态凸包    ▪c++编程风格----读书笔记(2)
▪Android窗口管理服务WindowManagerService计算Activity...    ▪keytool 错误: java.io.FileNotFoundException: MyAndroidKey....    ▪《HTTP权威指南》读书笔记---缓存
▪markdown    ▪[设计模式]总结    ▪网站用户行为分析在用户市场领域的应用
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3