当前位置:   article > 正文

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

loadconst

本文为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 符号表

  1. i = 1
  2. #LOAD_CONST 0
  3. #STORE_NAME 0
  4. s = "Python"
  5. #LOAD_CONST 1
  6. #STORE_NAME 1
  7. d = {}
  8. #BUILD_MAP 0
  9. #STORE_NAME 2
  10. l = []
  11. #BUILD_LIST 0
  12. #STORE_NAME 3
  13. #LOAD_CONST 2
  14. #RETURN_VALUE none

3.复杂内建对象的创建

  1. #以(LOAD_CONST,ROT_TWO,LOAD_CONST,STORE_SUBSCR)4字节码为一组,重复不断地将元素插入到PyDictObject对象中去。
  2. d = {"1":1, "2":2}
  3. # BUILD_MAP 0
  4. # DUP_TOP
  5. # LOAD_CONST 2 (1)
  6. # LOAD_CONST 0 (1)
  7. # ROT_THREE
  8. # STORE_SUBSCR
  9. # DUP_TOP
  10. # LOAD_CONST 3 (2)
  11. # LOAD_CONST 4 (2)
  12. # ROT_THREE
  13. # STORE_SUBSCR
  14. # STORE_NAME 2 (d)
  15. l = [1, 2]
  16. # LOAD_CONST 0 (1)
  17. # LOAD_CONST 4 (2)
  18. # BUILD_LIST 2
  19. # STORE_NAME 3 (1)

4.其他一般表达式


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

  1. //LOAD_NAME LGB规则
  2. //获得变量名
  3. w = GETITEM(names, oparg);
  4. //[1]:在local名字空间中查找变量名对应的变量值
  5. v = f->f_locals;
  6. x = PyDict_GetItem(v, w)
  7. Py_XINCREF(x);
  8. if (x == NULL) {
  9. //[2]:在global名字空间中查找变量名对应的变量值
  10. x = PyDict_GetItem(f->f_globals, w);
  11. if (x == NULL) {
  12. //[3]:在builtin名字空间中查找变量名对应的变量值
  13. x = PyDict_GetItem(f->f_builtins, w);
  14. if (x == NULL) {
  15. //[4]:查找变量名失败,抛出异常
  16. format_exc_check_arg(
  17. PyExc_NameError,
  18. NAME_ERROR_MSG, w);
  19. break;
  20. }
  21. }
  22. Py_INCREF(x);
  23. }
  24. PUSH(x);

数值运算
Python为PyIntObject对象和 PyStringObject对象准备了快速通道。如果
你的程序中涉及了大量的浮点运算,可以修改 BINARY_ADD中的代码,为浮点
运算建立快速通道。
  1. c = a + b
  2. # LOAD_NAME 0 (a)
  3. # LOAD_NAME 1 (b)
  4. # BINARY_ADD
  5. # STORE_NAME 2 (c)
  1. //BINARY_ADD
  2. w = POP();
  3. v = TOP();
  4. if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) {
  5. //[1]:PyIntObject对象相加的快速通道
  6. register long a, b, i;
  7. a = PyInt_AS_LONG(v);
  8. b = PyInt_AS_LONG(w);
  9. //[2]:如果加法运算溢出,转向慢速通道
  10. i = (long)((unsigned long)a + b);
  11. if ((i^a) < 0 && (i^b) < 0)
  12. goto slow_add;
  13. x = PyInt_FromLong(i);
  14. }
  15. //[3]:PyStringObjecgt对象相加的快速通道
  16. else if (PyString_CheckExact(v) &&
  17. PyString_CheckExact(w)) {
  18. x = string_concatenate(v, w, f, next_instr);
  19. /* string_concatenate consumed the ref to v */
  20. goto skip_decref_vx;
  21. }
  22. //[4]:一般对象相加的慢速通道
  23. else {
  24. slow_add:
  25. x = PyNumber_Add(v, w);
  26. }
  27. Py_DECREF(v);
  28. skip_decref_vx:
  29. Py_DECREF(w);
  30. SET_TOP(x);
  31. break;


信息输出

  1. print c
  2. # LOAD_NAME 2 (c)
  3. # PRINT_ITEM
  4. # PRINT_NEWLINE

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/199034
推荐阅读
相关标签
  

闽ICP备14008679号