python虚拟机自带吗_Python虚拟机

1、PyFrameObject

Python在真正执行的时候并不是面对的PyCodeObject对象,而是PyFrameObject对象,它包含静态的PyCodeObject和执行环境。

typedef struct _frame {

PyObject_VAR_HEAD

struct _frame *f_back;/* previous frame, or NULL */ 执行环境上一个栈帧

PyCodeObject *f_code;/* code segment */ PyCodeObject对象

PyObject *f_builtins;/* builtin symbol table (PyDictObject) */builtin名字空间

PyObject *f_globals;/* global symbol table (PyDictObject) */global名字空间

PyObject *f_locals;/* local symbol table (any mapping) */local名字空间

PyObject **f_valuestack;/* points after the last local */运行时栈的栈底位置

/* Next free slot in f_valuestack. Frame creation sets to f_valuestack.

Frame evaluation usually NULLs it, but a frame that yields sets it

to the current stack top. */

PyObject **f_stacktop; 栈顶位置

PyObject *f_trace;/* Trace function */

/* If an exception is raised in this frame, the next three are used to

* record the exception info (if any) originally in the thread state. See

* comments before set_exc_info() -- it's not obvious.

* Invariant: if _type is NULL, then so are _value and _traceback.

* Desired invariant: all three are NULL, or all three are non-NULL. That

* one isn't currently true, but "should be".

*/

PyObject *f_exc_type, *f_exc_value, *f_exc_traceback;

PyThreadState *f_tstate;

int f_lasti;/* Last instruction if called */ 上一条字节码指令在f_code中的偏移位置

/* Call PyFrame_GetLineNumber() instead of reading this field

directly. As of 2.3 f_lineno is only valid when tracing is

active (i.e. when f_trace is set). At other times we use

PyCode_Addr2Line to calculate the line from the current

bytecode index. */

int f_lineno;/* Current line number */ 当前字节码对应的源代码行数。

int f_iblock;/* index in f_blockstack */

PyTryBlock f_blockstack[CO_MAXBLOCKS]; /* for try and loop blocks */ try和loop的最大内嵌数目20个。

PyObject *f_localsplus[1];/* locals+stack, dynamically sized */ 动态内存,维护(局部变量+cell对象集合+free对象集合+运行时栈)所需要的空间。

} PyFrameObject;

Python提供了获取当前栈帧的接口:sys._getframe()

2、执行流程。

PyObject *

PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)

{

...

co = f->f_code; # PyCodeObject

names = co->co_names;

consts = co->co_consts;

fastlocals = f->f_localsplus;

freevars = f->f_localsplus + co->co_nlocals;

first_instr = (unsigned char*) PyString_AS_STRING(co->co_code); PyStringObject类型的对象,字节码指令序列的开始

next_instr = first_instr + f->f_lasti + 1; 下一条待执行的字节码指令的位置。

stack_pointer = f->f_stacktop;

assert(stack_pointer != NULL);

f->f_stacktop = NULL; /* remains NULL unless yield suspends frame */

...

why = WHY_NOT; 返回标志。

for (;;) {

opcode = NEXTOP();

switch (opcode) {

}

}

}

/* Status code for main loop (reason for stack unwind) */

enum why_code {

WHY_NOT = 0x0001, /* No error */ 正常退出

WHY_EXCEPTION = 0x0002, /* Exception occurred */ 异常

WHY_RERAISE = 0x0004, /* Exception re-raised by 'finally' */ raise

WHY_RETURN = 0x0008, /* 'return' statement */ return返回

WHY_BREAK = 0x0010, /* 'break' statement */ break中断

WHY_CONTINUE = 0x0020, /* 'continue' statement */continue中断

WHY_YIELD = 0x0040 /* 'yield' operator */ yield中断

};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值