首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python写的Python解释器(六)

Python写的Python解释器(六)

作者头像
哒呵呵
发布2018-08-06 11:31:45
4990
发布2018-08-06 11:31:45
举报
文章被收录于专栏:鸿的学习笔记鸿的学习笔记

编译自:http://www.aosabook.org/en/500L/a-python-interpreter-written-in-python.html 作者:Taavi Burns 翻译:鸿 如有翻译问题或建议,请公众号留言

Frames

目前可以确认Python虚拟机是一个堆栈机器。它通过指令来控制执行顺序,推入和弹出堆栈的值。在上面的例子中,最后一条指令是RETURN_VALUE,它对应于代码中的return语句。但指令返回到哪里呢?

要回答这个问题,必须增加一层结构:frame。frame是有关代码信息和上下文的集合。随着Python代码的执行,frame会随时创建和销毁。每个函数调用都会有一个对应的frame,所以每个frame都有一个与之关联的代码对象时,代码对象可以有多个frame。如果有一个递归调用自己10次的函数,就会有11个frame(每个递归级别拥有一个,另外一个是用于你的module)。通常,Python程序中的每个域都有一个frame。例如,module,函数调用和类定义都会有一个frame。 frame位于call stack上(call stack和平常的堆栈一样)。解释器在执行字节码时操作的堆栈被称为data stack。还有第三个堆栈,称为block stack。block用于特定的控制流,例如循环和异常处理。call stack中的每个frame都有自己的data stack和block stack。

>>> def bar(y):
...     z = y + 3     # <--- (3) ... and the interpreter is here.
...     return z
...
>>> def foo():
...     a = 1
...     b = 2
...     return a + bar(b) # <--- (2) ... which is returning a call to bar ...
...
>>> foo()             # <--- (1) We're in the middle of a call to foo ...
3

此时,解释器正处于函数调用的中间。调用堆栈有三个frame:一个用于模块级别,一个用于函数foo,另一个用于bar。一旦bar返回,与其关联的frame就会弹出call stack并被丢弃。字节码RETURN_VALUE会告诉解释器需要在frame之间传递一个值。这时它会将推出call stack顶层的frame的data stack的顶层值。再将整个frame从call stack中弹出并传递出去。最后,将这个值压入下一个frame的data stack中。

Byterun刚开始时在整个虚拟机上只有一个data stack,而不是在每个frame上都有一个data stack。直到遇上了生成器。最后,通过仔细阅读CPython源码,意识到了错误,之后将data stacke移动到每个frame上解决了问题。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-05-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 鸿的学习笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档