Skip to content

Latest commit

 

History

History
265 lines (208 loc) · 4.71 KB

1024.rst

File metadata and controls

265 lines (208 loc) · 4.71 KB

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