1024 Miles ================== http://eli.thegreenplace.net/2011/08/22/how-not-to-set-a-timeout-on-a-computation-in-python/#id5 The Big Loop --------------------------- 基于frame的vm,而不是想象中的结构: VM: init for inst in instructions: run inst FrameVM: init frame for inst in framecode: if inst is newframe: FrameVM inst else: run inst #define STACK_LEVEL() ((int)(stack_pointer - f->f_valuestack)) #define EMPTY() (STACK_LEVEL() == 0) frame 结构中存有当前的堆栈信息 遇到块结束的指令,调用 break 其他指令则调用 continue,没有检查错误,也不用退出block,直接执行下一条指令 堆,栈的概念 状态 Code对象:可执行码,程序本身 Frame对象,stack:程序的执行状态 Frame, Block and Statement ---------------------------------- statement比较好理解,一行基本上就是一个statement。block在statement之上,每个 block可以有多个statement,是语句块。if,while,try,for等带:的keyword, 都表示一个新block的开始。 block是最小的控制转移单位,在block之内statement被顺序执行,条件判断,循环,异常处理等 机制都必须借助与block才能实现。运行时,python也会记录block的层级信息,因为异常处理 时需要用到,查找本block的handler。 函数可以看做是代码重用的最小单位,函数内可以有多个,多层block。函数对应于PyCode Object, 每次调用一个函数时,都会生成一个新的frame,所以说frame实际上负责存储运行状态, 是运行时的函数调用栈。 Python VM 指令集构成 -------------------------- http://docs.python.org/2/library/dis.html#python-bytecode-instructions Python VM指令可以分为以下几大类。 堆栈操作 ~~~~~~~~~~~~~~~ :: POP_TOP ROT_TWO ROT_THREE DUP_TOP ROT_FOUR DUP_TOPX 空操作 ~~~~~~~~~~~~ :: NOP 算术操作 ~~~~~~~~~~~~~ :: UNARY_POSITIVE UNARY_NEGATIVE UNARY_NOT UNARY_CONVERT UNARY_INVERT BINARY_POWER BINARY_MULTIPLY BINARY_DIVIDE BINARY_MODULO BINARY_ADD BINARY_SUBTRACT BINARY_FLOOR_DIVIDE BINARY_TRUE_DIVIDE INPLACE_FLOOR_DIVIDE INPLACE_TRUE_DIVIDE INPLACE_ADD INPLACE_SUBTRACT INPLACE_MULTIPLY INPLACE_DIVIDE INPLACE_MODULO INPLACE_POWER 位操作指令 ^^^^^^^^^^^^^^^ :: BINARY_LSHIFT BINARY_RSHIFT BINARY_AND BINARY_XOR BINARY_OR INPLACE_LSHIFT INPLACE_RSHIFT INPLACE_AND INPLACE_XOR INPLACE_OR 数据类型支持 ~~~~~~~~~~~~~~~~~ List操作 ^^^^^^^^^^^^^^ :: LIST_APPEND SLICE+0 SLICE+1 SLICE+2 SLICE+3 STORE_SLICE+0 STORE_SLICE+1 STORE_SLICE+2 STORE_SLICE+3 DELETE_SLICE+0 DELETE_SLICE+1 DELETE_SLICE+2 DELETE_SLICE+3 BUILD_SLICE BUILD_LIST Tuple指令 ^^^^^^^^^^^^^^ :: BUILD_TUPLE UNPACK_SEQUENCE Dict操作 ^^^^^^^^^^^^ :: STORE_MAP BINARY_SUBSCR STORE_SUBSCR DELETE_SUBSCR BUILD_MAP 控制流指令 ~~~~~~~~~~~~~~~~~ :: BREAK_LOOP POP_BLOCK FOR_ITER COMPARE_OP JUMP_FORWARD JUMP_IF_FALSE JUMP_IF_TRUE JUMP_ABSOLUTE CONTINUE_LOOP SETUP_LOOP 异常处理指令 ^^^^^^^^^^^^^^^^^^ :: RAISE_VARARGS END_FINALLY SETUP_EXCEPT SETUP_FINALLY 变量操作指令 ~~~~~~~~~~~~~~~~~~~~ :: LOAD_LOCALS LOAD_GLOBAL LOAD_FAST STORE_FAST DELETE_FAST LOAD_DEREF STORE_DEREF STORE_NAME DELETE_NAME STORE_GLOBAL DELETE_GLOBAL LOAD_CONST LOAD_NAME 变量的作用域,查找机制在这些LOAD_XXX指令中。 函数调用指令 ~~~~~~~~~~~~~~~~~~~ :: CALL_FUNCTION MAKE_FUNCTION MAKE_CLOSURE LOAD_CLOSURE CALL_FUNCTION_VAR CALL_FUNCTION_KW CALL_FUNCTION_VAR_KW RETURN_VALUE class类操作指令 ~~~~~~~~~~~~~~~~~~~~ :: BUILD_CLASS STORE_ATTR LOAD_ATTR DELETE_ATTR 调用class创建对象,调用对象的方法,实际上都是函数调用。class的初始化,继承,MRO,magic方法等逻辑, 以及Python模块导入逻辑,都没有在指令上体现出来,它们隐藏在指令的背后,用C实现,固化到VM了。 整个python语言,要区分哪些在VM之上,哪些在VM之下。 模块导入指令 ~~~~~~~~~~~~~~~~~~ :: IMPORT_STAR IMPORT_NAME IMPORT_FROM Python特殊语法指令 ~~~~~~~~~~~~~~~~~~~~~~~ :: WITH_CLEANUP # with EXEC_STMT # exec YIELD_VALUE # yield GET_ITER # iter PRINT指令 ~~~~~~~~~~~~~~~~ :: PRINT_EXPR PRINT_ITEM PRINT_NEWLINE PRINT_ITEM_TO PRINT_NEWLINE_TO Other ~~~~~~~~~~~~~ :: STOP_CODE EXTENDED_ARG