Python写的Python解释器(六)

编译自: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上解决了问题。

原文发布于微信公众号 - 鸿的学习笔记(shujuxuexizhilu)

原文发表时间:2018-05-08

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏java达人

方法参数过多怎么办

我们在编程或阅读前人的代码时,经常会看到多个参数的方法,有的甚至达到二十个,看得人眼花缭乱,不便于阅读和维护,而且参数很容易混淆,如两个参数类型同为short型...

3068
来自专栏机器之心

教程 | PyTorch内部机制解析:如何通过PyTorch实现Tensor

选自Github 机器之心编译 参与:朱乾树、黄小天 PyTorch 中的基本单位是张量(Tensor)。本文的主旨是如何在 PyTorch 中实现 Tens...

4305
来自专栏java一日一条

10个惊艳的Swift单行代码

几年前,一篇表述“10个Scala函数式单行代码”的文章非常受欢迎,并且随后立马出现了其他的语言版本,例如Haskell版本,Ruby版本,Groovy版本,C...

972
来自专栏java一日一条

Java 编程要点之 I/O 流详解

字节流处理原始的二进制数据 I/O。输入输出的是8位字节,相关的类为 InputStream 和 OutputStream.

1202
来自专栏Java学习网

Java面试题系列之基础部分(六)——每天学5个问题

Java基础部分学习的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语法,集合的语法,io的语法,虚拟机方面的语法,这些都是最基...

2665
来自专栏咸鱼不闲

fastjson 重复引用和循环引用问题

数据传输使用json格式再方便不过了。 fastjson 由阿里巴巴那伙人使用Java语言编写,号称最快的JSON库 前两天遇到一个问题 后台的数据转化为jso...

3184
来自专栏JavaEdge

Netty 源码深度解析(九) - 编码概述1 抽象类 MessageToByteEncoder2 抽象类 MessageToMessageEncoder一个java对象最后是如何转变成字节流,写到s

编码器实现了ChannelOutboundHandler,并将出站数据从 一种格式转换为另一种格式,和我们方才学习的解码器的功能正好相反。Netty 提供...

3141
来自专栏程序你好

最近我遇到的10个Java面试问题

最近,我参加了一些java的面试。突然,我有了一个想法,我想和大家分享我的经历。我希望我能通过分享我最近几个月遇到的10个Java面试问题来帮助大家。

973
来自专栏锦小年的博客

python学习笔记7.4-内建模块base64

有时候,我们用noepad++或者记事本打开图片或者程序等文件的时候会显示大量的乱码,主要原因是这些文件编码的时候并不是字符串编码的。如果我们想把这些文件正常显...

2279
来自专栏FD的专栏

写出形似QML的C++代码

我的第一个想法(居然?)是做个Embedded-DSL。不过C++又不是Ruby……随便搜了一下,发现了一篇文章,也只是利用了重载运算符和运算符优先级,看上去限...

692

扫码关注云+社区

领取腾讯云代金券