zoukankan      html  css  js  c++  java
  • 《python源代码分析》笔记 pythonVM一般表达式

    本文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

    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    直接拿来用 九个超实用的PHP代码片段(二)
    微信开发值得推荐的开源项目
    PHP文件下载原理
    简化PHP开发的10个工具
    CI Weekly #1 | 这份周刊,带你了解 CI/CD 、DevOps、自动化测试
    fir.im Weekly
    fir.im Weekly
    fir.im Weekly
    用 flow.ci 让 Hexo 持续部署
    fir.im Weekly
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4603661.html
Copyright © 2011-2022 走看看