Python解释器实现:code类型
目录

Python中,每一个命名空间/作用域/code block对应一个PyCodeObject对象。 命名空间可以是一个class、function或module。 PyCodeObject包含以下内容:

/* Bytecode object */
typedef struct {
PyObject_HEAD
int co_argcount;            /* #arguments, except *args */ // 位置参数个数
int co_nlocals;             /* #local variables */         // 局部变量个数(包括位置参数)
int co_stacksize;           /* #entries needed for evaluation stack */  // 栈空间大小
int co_flags;               /* CO_..., see below */
PyObject *co_code;          /* instruction opcodes */      // 字节码指令序列,PyStringObject类型
PyObject *co_consts;        /* list (constants used) */    // 常量,PyTupleObject类型
PyObject *co_names;         /* list of strings (names used) */          // 符号,PyTupleObject类型
PyObject *co_varnames;      /* tuple of strings (local variable names) */  // 局部变量名, 集合?
PyObject *co_freevars;      /* tuple of strings (free variable names) */   // 闭包支持
PyObject *co_cellvars;      /* tuple of strings (cell variable names) */   // 内部嵌套函数引用的局部变量名集合

/* The rest doesn't count for hash/cmp */
PyObject *co_filename;      /* string (where it was loaded from) */        // .py文件名
PyObject *co_name;          /* string (name, for reference) */             // 名字(类名、函数名、模块名)
int co_firstlineno;         /* first source line number */                 // 所在.py文件中的起始行
PyObject *co_lnotab;        /* string (encoding addr<->lineno mapping) See
Objects/lnotab_notes.txt for details. */    // 字节码所在.py文件中对应的行号

void *co_zombieframe;     /* for optimization only (see frameobject.c) */
PyObject *co_weakreflist;   /* to support weakrefs to code objects */
} PyCodeObject;

.pyc包含以下内容:

  • magic number
  • create timestamp
  • PyCodeObject对象的二进制序列化形式

Python支持以下类型的序列化和反序列化:

//marshal.c
#define TYPE_NULL               '0'
#define TYPE_NONE               'N'
#define TYPE_FALSE              'F'
#define TYPE_TRUE               'T'
#define TYPE_STOPITER           'S'
#define TYPE_ELLIPSIS           '.'
#define TYPE_INT                'i'
#define TYPE_INT64              'I'
#define TYPE_FLOAT              'f'
#define TYPE_BINARY_FLOAT       'g'
#define TYPE_COMPLEX            'x'
#define TYPE_BINARY_COMPLEX     'y'
#define TYPE_LONG               'l'
#define TYPE_STRING             's'
#define TYPE_INTERNED           't'
#define TYPE_STRINGREF          'R'
#define TYPE_TUPLE              '('
#define TYPE_LIST               '['
#define TYPE_DICT               '{'
#define TYPE_CODE               'c'
#define TYPE_UNICODE            'u'
#define TYPE_UNKNOWN            '?'
#define TYPE_SET                '<'
#define TYPE_FROZENSET          '>'

对于支持的类型,Python已经知道他们的数据结构了,所以首先写入每种类型的标示符, 然后直接遍历所有字段,递归调用对应序列化函数,最终调用w_byte()写入到文件中即可。

对于PyCodeObject的递归包含,子Code Block是包含在父Code Block的co_consts字段中。

  • TODO: 反编译工具

发表评论