首页 > 代码库 > 《python源码剖析》笔记 python虚拟机中的一般表达式

《python源码剖析》笔记 python虚拟机中的一般表达式

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie


1.字节码指令
LOAD_CONST:从consts表中读取序号为i的元素并压入到运行时栈中
STORE_NAME:改变local名字空间。从符号表names取序号为i的元素作为变量名,
取运行时栈的栈顶元素作为变量值,完成从变量名到变量值的映射关系的创建。
BUILD_MAP:创建一个空的PyDictObject对象,并压入运行时栈
DUP_TOP:将栈顶元素的引用计数增加1,并将它再次压入栈中
ROT_TWO:将栈顶的两个元素进行对调
LOAD_NAME:符号搜索,并将该元素压入运行时栈


Python在执行完一段Code Block后, 一定要返回一些值,所以在Code Block对应的字节码
后都有LOAD_CONST,RETURN_VALUE两个指令。


2.简单内建对象的创建
字节码指令对符号或常量的操作最终都将反映到运行时栈和local名字空间
co_consts 常量表, co_names 符号表

i = 1
#LOAD_CONST 0
#STORE_NAME 0
s = "Python"
#LOAD_CONST 1
#STORE_NAME	1
d = {}
#BUILD_MAP 0
#STORE_NAME 2
l = []
#BUILD_LIST 0
#STORE_NAME 3
#LOAD_CONST 2
#RETURN_VALUE none

3.复杂内建对象的创建

#以(LOAD_CONST,ROT_TWO,LOAD_CONST,STORE_SUBSCR)4字节码为一组,重复不断地将元素插入到PyDictObject对象中去。
d = {"1":1, "2":2} 
# BUILD_MAP 0 
# DUP_TOP 
# LOAD_CONST 2  (1) 
# LOAD_CONST 0  (1) 
# ROT_THREE 
# STORE_SUBSCR 
# DUP_TOP 
# LOAD_CONST 3  (2) 
# LOAD_CONST 4  (2) 
# ROT_THREE 
# STORE_SUBSCR 
# STORE_NAME 2  (d)


l = [1, 2] 
# LOAD_CONST 0  (1) 
# LOAD_CONST 4  (2) 
# BUILD_LIST 2 
# STORE_NAME 3  (1) 

4.其他一般表达式


符号搜索
b = a
#LOAD_NAME 0 (a)
#STORE_NAME 1 (b)

//LOAD_NAME  LGB规则
//获得变量名
w = GETITEM(names, oparg);
//[1]:在local名字空间中查找变量名对应的变量值
v = f->f_locals;
x = PyDict_GetItem(v, w)
Py_XINCREF(x);
if (x == NULL) {
	//[2]:在global名字空间中查找变量名对应的变量值
	x = PyDict_GetItem(f->f_globals, w);
	if (x == NULL) {
		//[3]:在builtin名字空间中查找变量名对应的变量值
		x = PyDict_GetItem(f->f_builtins, w);
		if (x == NULL) {
			//[4]:查找变量名失败,抛出异常
			format_exc_check_arg(
				PyExc_NameError,
				NAME_ERROR_MSG, w);
			break;
		}
	}
	Py_INCREF(x);
}
PUSH(x);

数值运算
Python为PyIntObject对象和 PyStringObject对象准备了快速通道。如果
你的程序中涉及了大量的浮点运算,可以修改 BINARY_ADD中的代码,为浮点
运算建立快速通道。
c = a + b 
# LOAD_NAME 0  (a) 
# LOAD_NAME 1  (b) 
# BINARY_ADD 
# STORE_NAME 2  (c) 
//BINARY_ADD
	w = POP();
	v = TOP();
	if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) {
		//[1]:PyIntObject对象相加的快速通道
		register long a, b, i;
		a = PyInt_AS_LONG(v);
		b = PyInt_AS_LONG(w);
		//[2]:如果加法运算溢出,转向慢速通道
		i = (long)((unsigned long)a + b);
		if ((i^a) < 0 && (i^b) < 0)
			goto slow_add;
		x = PyInt_FromLong(i);
	}
	//[3]:PyStringObjecgt对象相加的快速通道
	else if (PyString_CheckExact(v) &&
			 PyString_CheckExact(w)) {
		x = string_concatenate(v, w, f, next_instr);
		/* string_concatenate consumed the ref to v */
		goto skip_decref_vx;
	}
	//[4]:一般对象相加的慢速通道
	else {
slow_add:
		x = PyNumber_Add(v, w);
	}
	Py_DECREF(v);
skip_decref_vx:
	Py_DECREF(w);
	SET_TOP(x);
	break;


信息输出

print c 
# LOAD_NAME 2  (c) 
# PRINT_ITEM 
# PRINT_NEWLINE