开发,设计,生活

编程语言

  • 2014-09-14 15:36:58 2014-09-20 14:48:32[U] 编程语言

    什么是字节码

    1. python解释器在执行python脚本文件时,对文件中的python源代码进行编译,编译的结果就是byte code(字节码)
    2. python虚拟机执行编译好的字节码,完成程序的运行
    3. python会为导入的模块创建字节码文件


    字节码文件的创建过程

    1. 当a.py依赖b.py时,如在a.py中import b
    2. python先检查是否有b.pyc文件(字节码文件),如果有,并且修改时间比b.py晚,就直接调用b.pyc
    3. 否则编译b.py生成b.pyc,然后加载新生成的字节码文件


    字节码对象

    1. 每个py文件会包含许多代码块(Code Block)
    2. 每个代码块(Code Block)会编译创建一个字节码对象(PyCodeObject)
    3. PyCodeObject 对象本身是嵌套的,根据代码块的结构嵌套
    4. 子 PyCodeObject 对象保存在父对象的 co_consts 变量中


    代码块 Code Block

    # 整个文件是一个代码块 1
    
    # 代码块 2
    class TestA(object):
        pass
    
    # 代码块 3
    class TestB(object):
        pass
    
    # 代码块 4
    def show():
        print 'show ...'
    
    a = TestA()
    show()
    


    字节码对象的结构

    /* 字节码对象 */
    typedef struct {
        PyObject_HEAD
        int co_argcount;        /* Code Block 参数个数 */
        int co_nlocals;     /* 局部变量个数 */
        int co_stacksize;       /* 栈空间 */
        int co_flags;       /* CO_..., see below */
        PyObject *co_code;      /* 字节码指令序列 */
        PyObject *co_consts;    /* 常量列表(子代码块也在这里) */
        PyObject *co_names;     /* 字符串符号列表 */
        PyObject *co_varnames;  /* 局部变量名 */
        PyObject *co_freevars;  /* 闭包所需要的变量 */
        PyObject *co_cellvars;      /* 嵌套函数所引用的局部变量名 */
        /* The rest doesn't count for hash/cmp */
        PyObject *co_filename;  /* py文件路径 */
        PyObject *co_name;      /* Code block 的函数名或类名 */
        int co_firstlineno;     /* Code block 起始行 */
        PyObject *co_lnotab;    /* 字节码指令与源代码的对应关系 */
        void *co_zombieframe;     /* for optimization only (see frameobject.c) */
        PyObject *co_weakreflist;   /* to support weakrefs to code objects */
    } PyCodeObject;
    


    字节码文件的内部实现

    字节码对象序列化到硬盘的结果,就是字节码文件。这个过程是一个递归写入的过程。

    static void w_object(PyObject *v, WFILE *p)
    {
        Py_ssize_t i, n;
        p->depth++;
    
        /* ... */
        else if (PyCode_Check(v)) {
            PyCodeObject *co = (PyCodeObject *)v;
            w_byte(TYPE_CODE, p);
            w_long(co->co_argcount, p);
            w_long(co->co_nlocals, p);
            w_long(co->co_stacksize, p);
            w_long(co->co_flags, p);
            w_object(co->co_code, p);
            w_object(co->co_consts, p);
            w_object(co->co_names, p);
            w_object(co->co_varnames, p);
            w_object(co->co_freevars, p);
            w_object(co->co_cellvars, p);
            w_object(co->co_filename, p);
            w_object(co->co_name, p);
            w_long(co->co_firstlineno, p);
            w_object(co->co_lnotab, p);
        }
        /* ... */
    }
    


    反序列化执行字节码文件

    字节码文件在反序列化时创建字节码对象的结构,虚拟机在执行的时候根据字节码对象执行程序功能。