《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

《python源码剖析》笔记 python虚拟机中的一般表达式,布布扣,bubuko.com

时间: 2024-12-28 10:31:25

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

Python源码剖析笔记3-Python执行原理初探

Python源码剖析笔记3-Python执行原理初探 本文简书地址:http://www.jianshu.com/p/03af86845c95 之前写了几篇源码剖析笔记,然而慢慢觉得没有从一个宏观的角度理解python执行原理的话,从底向上分析未免太容易让人疑惑,不如先从宏观上对python执行原理有了一个基本了解,再慢慢探究细节,这样也许会好很多.这也是最近这么久没有更新了笔记了,一直在看源码剖析书籍和源码,希望能够从一个宏观层面理清python执行原理.人说读书从薄读厚,再从厚读薄方是理解了

Python源码剖析笔记0 ——C语言基础

python源码剖析笔记0--C语言基础回顾 要分析python源码,C语言的基础不能少,特别是指针和结构体等知识.这篇文章先回顾C语言基础,方便后续代码的阅读. 1 关于ELF文件 linux中的C编译得到的目标文件和可执行文件都是ELF格式的,可执行文件中以segment来划分,目标文件中,我们是以section划分.一个segment包含一个或多个section,通过readelf命令可以看到完整的section和segment信息.看一个栗子: char pear[40]; static

python源码剖析笔记1——Python对象初见

python源码剖析笔记1--Python对象初见 工作整两年了,用python最多,然而对于python内部机制不一定都清楚,每天沉醉于增删改查的简单逻辑编写,实在耗神.很多东西不用就忘记了,比如C语言,正好,python源码用C写的,分析python源码的同时又能温故C语言基础,实在是件很好的事情.另外,还有陈儒大神的<python源码剖析>做指引,分析也不至于没头没脑.期望在一个月的业余时间,能有所小成,以此为记. 1 python中的对象 python中,一切东西都是对象,在c语言实现

Python源码剖析笔记4-内建数据类型

Python源码剖析笔记4-内建数据类型 Python内建数据类型包括整数对象PyIntObject,字符串对象PyStringObject,列表对象PyListObject以及字典对象PyDictObject等.整数对象之前已经分析过了,这一篇文章准备分析下余下几个对象,这次在<python源码剖析>中已经写的很详细的部分就不赘述了,主要是总结一些之前看书时疑惑的地方. 1 整数对象-PyIntObject 参见 python整数对象. 2 字符串对象-PyStringObject 2.1

Python源码剖析笔记2-Python整数对象

Python源码剖析笔记2-Python整数对象 本文简书地址: http://www.jianshu.com/p/0136ed90cd46 千里之行始于足下,从简单的类别开始分析,由浅入深也不至于自己丧失信心.先来看看Python整数对象,也就是python中的PyIntObject对象,对应的类型对象是PyInt_Type. 1 Python整数对象概览 为了性能考虑,python中对小整数有专门的缓存池,这样就不需要每次使用小整数对象时去用malloc分配内存以及free释放内存.pyth

Python源码剖析笔记6-函数机制

Python的函数机制是很重要的部分,很多时候用python写脚本,就是几个函数简单解决问题,不需要像java那样必须弄个class什么的. 本文简书地址:http://www.jianshu.com/p/d00108741a18 1 函数对象PyFunctionObject PyFunctionObject对象的定义如下: typedef struct { PyObject_HEAD PyObject *func_code; /* A code object */ PyObject *func

Python源码剖析笔记5-模块机制

本文简书地址: http://www.jianshu.com/p/14586ec50ab6 python中经常用到模块,比如import xxx,from xxx import yyy这样子,里面的机制也是需要好好探究一下的,这次主要从黑盒角度来探测模块机制,源码分析点到为止,详尽的源码分析见陈儒大神的<python源码剖析>第14章. 1 如何导入模块 首先来看一个导入模块的例子.创建一个文件夹demo5,文件夹中有如下几个文件. [email protected] ~/demo5 $ ls

《python源码剖析》笔记 python虚拟机中的函数机制

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 1.Python虚拟机在执行函数调用时会动态地创建新的 PyFrameObject对象, 这些PyFrameObject对象之间会形成PyFrameObject对象链,模拟x86平台上运行时栈 2.PyFuctionObject对象 typedef struct { PyObject_HEAD PyObject *func_code: //对应函数编译后的PyCodeObject对象 Py

《python源码剖析》笔记 Python虚拟机框架

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 1. Python虚拟机会从编译得到的PyCodeObject对象中依次读入每一条字节码指令, 并在当前的上下文环境中执行这条字节码指令. Python虚拟机实际上是在模拟操作中执行文件的过程 PyCodeObject对象中包含了字节码指令以及程序的所有静态信息,但没有包含 程序运行时的动态信息--执行环境(PyFrameObject) 2.Python源码中的PyFrameObject