目标和架构概述¶
高级目标¶
传统上,语言解释器是用目标平台语言(如 C/Posix、Java 或 C#)编写的。每个实现都提供了应用程序源代码和目标环境之间基本映射。诸如 .NET 框架以及某种程度上的 Java 虚拟机等“全方位”环境的目标之一,是提供标准化和更高级的功能,以支持语言实现者编写语言实现。
PyPy 正在尝试一种更雄心勃勃的方法。我们使用 Python 高级语言的一个子集,称为 RPython 语言,用它编写语言作为简单的解释器,很少引用或依赖于底层细节。RPython 工具链通过插入适当的底层方面,为我们选择的平台生成具体的虚拟机。可以通过选择其他功能和平台配置来定制结果。
我们的目标是为语言实现者提供一个可能的解决方案:为 l * o * p
个解释器编写 l
种动态语言和 p
个平台,并做出 o
个关键的设计决策。PyPy 旨在使独立更改这些变量中的每一个成为可能,从而
l
:我们可以发展或完全替换我们分析的语言;o
:我们可以调整和优化翻译过程,以基于不同的模型和权衡产生特定于平台的代码;p
:我们可以编写新的翻译器后端来针对不同的物理和虚拟平台。
相比之下,标准化的目标环境(例如 .NET)在其关注范围内强制执行 p=1
。这有助于通过提供更高级别的基础来构建,从而使 o
稍微减小一些。尽管如此,我们认为强制使用一个通用环境并非必要。PyPy 的目标是证明这一说法——至少在语言实现方面是如此——展示了一种不依赖于标准化的 l * o * p
问题的方法。
这个目标中最雄心勃勃的部分是 生成即时编译器,而不是只将源解释器翻译成目标平台的解释器。这是语言实现领域中通常被认为非常具有挑战性的一个方面,因为其中涉及的复杂性。
架构¶
RPython 工具链的工作是将 RPython 语言 程序转换为该程序的高效版本,用于各种目标平台之一,通常是比 Python 低得多的级别。
我们采取的方法是通过几个步骤降低源 RPython 程序的抽象级别,从高级别一直降低到目标平台的级别,无论目标平台是什么。目前,我们支持两种主要的 target 平台:假设 C 风格的内存模型,带有结构和指针的平台,以及假设面向对象的模型,带有类、实例和方法的平台(例如,Java 和 .NET 虚拟机就是这样)。
RPython 工具链永远不会看到 RPython 源代码或语法树,而是从定义作为输入给出的函数对象行为的 *代码对象* 开始。可以将其视为将预导入的 RPython 程序“冻结”成适合目标平台的可执行形式。
翻译过程的步骤可以概括如下
- 每个源函数的代码对象由 控制流图构建器 转换为 控制流图。
- 控制流图由 注释器 处理,它执行全程序类型推断,以使用运行时可能采用的类型来注释控制流图的每个变量。
- 注释器提供的信息由 RTyper 用于将控制流图的高级操作转换为更接近目标平台抽象级别的操作。
- 可选地,然后可以应用 各种转换 <optional-transformations>,例如,执行内联等优化,添加诸如无栈式并发等功能,或为 垃圾回收器 插入代码。
- 然后,将图转换为目标平台的源代码并编译成可执行文件。
此过程在 有关 RPython 工具链的文档 和论文 编译动态语言实现 中有更详细的描述。
进一步阅读¶
- RPython 入门:参与 PyPy 源代码的实践指南。
- PyPy 的虚拟机构建方法:一篇提交给 2006 年 OOPSLA 附加的动态语言研讨会的论文。
- 翻译文档:我们翻译过程的详细描述。
- PyPy 中的 JIT 生成,描述了我们如何从解释器生成即时编译器。
- 如何使用 RPython 工具链 来 实现自己的解释器 的教程。