13916729435 发表于 2017-5-7 07:57:45

[笔记]Python虚拟机对创建基本内置对象的执行过程

同样的,有demo.py代码如下:
i = 1
s = "Python"
d = {"1":1, "2":2}
l =

有test.py代码如下:


import dis
source = open('./demo.py').read()
co = compile(source, './demo.py', 'exec')
dis.dis(co)




输出如下:

1         0 LOAD_CONST               0 (1)
3 STORE_NAME               0 (i)
2         6 LOAD_CONST               1 ('Python')
9 STORE_NAME               1 (s)
3          12 BUILD_MAP                2
15 LOAD_CONST               0 (1)
18 LOAD_CONST               2 ('1')
21 STORE_MAP         
22 LOAD_CONST               3 (2)
25 LOAD_CONST               4 ('2')
28 STORE_MAP         
29 STORE_NAME               2 (d)
4          32 LOAD_CONST               3 (2)
35 LOAD_CONST               5 (3)
38 BUILD_LIST               2
41 STORE_NAME               3 (l)
44 LOAD_CONST               6 (None)
47 RETURN_VALUE




这里需要讨论的就是字典和列表的创建。




对于d = {"1":1, "2":2}这一语句,Python虚拟机首先是执行BUILD_MAP:

      case BUILD_MAP:
x = _PyDict_NewPresized((Py_ssize_t)oparg);
PUSH(x);
if (x != NULL) continue;
break;




接着把键值对压栈,然后执行STORE_MAP:

      case STORE_MAP:
w = TOP();   /* key */
u = SECOND();/* value */
v = THIRD();   /* dict */
STACKADJ(-2);
assert (PyDict_CheckExact(v));
err = PyDict_SetItem(v, w, u);/* v = u */
Py_DECREF(u);
Py_DECREF(w);
if (err == 0) continue;
break;




因为刚才把键值对压栈了,所以现在栈顶是key,第二个是value,第三个是字典对象,栈指针-2,然后把键值对放入字典对象中。

接着再插入一个键值对,然后执行STORE_NAME,把字典对象d放入局部符号表中。




对于l = 这一语句,Python虚拟机先是把两个元素压栈,然后执行BUILD_LIST,携带参数2:

      case BUILD_LIST:
x =PyList_New(oparg);
if (x != NULL) {
for (; --oparg >= 0;) {
w = POP();
PyList_SET_ITEM(x, oparg, w);
}
PUSH(x);
continue;
}
break;




Python虚拟机根据命令参数决定出栈多少个元素放入列表中,最后一样是把列表对象l出栈,放入局部符号表中。
页: [1]
查看完整版本: [笔记]Python虚拟机对创建基本内置对象的执行过程