《python源码剖析》笔记 python虚拟机中的一般表达式
2014-06-17 17:09
525 查看
本文为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 符号表
3.复杂内建对象的创建
4.其他一般表达式
符号搜索
数值运算
Python为PyIntObject对象和 PyStringObject对象准备了快速通道。如果
你的程序中涉及了大量的浮点运算,可以修改 BINARY_ADD中的代码,为浮点
运算建立快速通道。
信息输出
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
相关文章推荐
- (Python学习9)Python虚拟机中的一般表达式
- 《python源码剖析》笔记 python虚拟机中的函数机制
- (Python学习9)Python虚拟机中的一般表达式
- 《python源码剖析》笔记 Python虚拟机框架
- 《python源代码分析》笔记 pythonVM一般表达式
- python学习笔记之语言、调试、语法、变量、表达式
- 学习python笔记——表达式
- python学习笔记---数字和表达式
- python 学习笔记 表达式(9)
- 【笔记】模电—lesson 37 负反馈放大电路增益的一般表达式 (hust)
- Python 学习笔记之运算符与表达式
- python的正则表达式学习笔记
- 深入Python3 (Dive Into Python3)笔记5--正则表达式
- Python下的正则表达式原理和优化笔记
- python 系统学习笔记(十五)---正则表达式
- [Python]第六课笔记--正则表达式
- Python源码剖析[19] —— 执行引擎之一般表达式(2)
- Python 正则表达式之 补充学习笔记
- Python学习笔记(3):运算符与表达式
- [笔记]Python虚拟机的运行时基本知识