目标和架构概述

高级目标

传统上,语言解释器是用目标平台语言(如 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 工具链的文档 和论文 编译动态语言实现 中有更详细的描述。

进一步阅读