http://eli.thegreenplace.net/2011/08/22/how-not-to-set-a-timeout-on-a-computation-in-python/#id5
基于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:程序的执行状态
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实际上负责存储运行状态, 是运行时的函数调用栈。
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_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
BUILD_TUPLE UNPACK_SEQUENCE
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
BUILD_CLASS STORE_ATTR LOAD_ATTR DELETE_ATTR
调用class创建对象,调用对象的方法,实际上都是函数调用。class的初始化,继承,MRO,magic方法等逻辑, 以及Python模块导入逻辑,都没有在指令上体现出来,它们隐藏在指令的背后,用C实现,固化到VM了。
整个python语言,要区分哪些在VM之上,哪些在VM之下。
IMPORT_STAR IMPORT_NAME IMPORT_FROM
WITH_CLEANUP # with EXEC_STMT # exec YIELD_VALUE # yield GET_ITER # iter
PRINT_EXPR PRINT_ITEM PRINT_NEWLINE PRINT_ITEM_TO PRINT_NEWLINE_TO
STOP_CODE EXTENDED_ARG