目标和架构概述¶
本文档概述了 PyPy 的目标和架构。如果您有兴趣使用 PyPy或对其进行黑客攻击,请查看我们的入门部分。
高级目标¶
我们开发翻译框架的主要动机是提供一个功能齐全、可定制、快速且高度兼容的 Python 实现,在各种平台上运行和交互,并允许快速引入新的高级语言功能。
这个 Python 实现是用 RPython 编写的,它是一个相对简单的解释器,在某些方面比 CPython(Python 的 C 语言参考实现)更容易理解。我们正在利用其高级性和灵活性,以传统方法需要对源代码进行广泛更改的方式快速尝试功能或实现技术。例如,PyPy 的 Python 解释器可以选择提供延迟计算的对象——这是一个小的扩展,需要对 CPython 进行全局更改。另一个例子是垃圾收集技术:将 CPython 更改为使用不基于引用计数的垃圾收集器将是一项重大工作,而在 PyPy 中,它是一个局限于翻译框架的问题,与解释器源代码完全正交。
PyPy Python 解释器¶
PyPy 的Python 解释器是用 RPython 编写的,并实现了完整的 Python 语言。这个解释器非常接近地模拟了 CPython 的行为。它包含以下关键组件
字节码编译器是预处理阶段,通过一系列灵活的传递(标记器、词法分析器、解析器、抽象语法树构建器、字节码生成器)生成紧凑的字节码格式。字节码评估器解释这个字节码。它通过将所有实际的用户对象操作委托给对象空间来完成大部分工作。后者可以被认为是内置类型的库。它定义了用户对象的实现,如整数和列表,以及它们之间的操作,如加法或真值测试。
字节码评估器和对象空间之间的这种划分提供了很大的灵活性。可以插入不同的对象空间来获得 Python 对象的不同或增强的行为。
层¶
RPython¶
RPython 是我们用来编写解释器的语言。并非整个 PyPy 项目都是用 RPython 编写的,只有在翻译过程中被编译的部分才使用 RPython。有趣的是,RPython 没有解析器,它从实时 Python 对象编译而来,这使得在导入时进行各种元编程成为可能。简而言之,Python 是 RPython 的元编程语言。
RPython 标准库位于 rlib
子目录中。
请参阅 RPython 入门 以了解更多信息,或参阅 RPython 示例 以了解如何在不编写解释器的情况下使用 RPython。
翻译¶
翻译工具链 - 这是负责将 RPython 翻译成流程图,然后翻译成 C 的部分。在 架构 文档中对此进行了更多介绍。
它位于 rpython
目录中:flowspace
、annotator
和 rtyper
。
PyPy 解释器¶
它位于 pypy
目录中。 pypy/interpreter
是用 RPython 编写的 Python 标准解释器。它使用 RPython 的事实一开始并不明显。内置模块是用 pypy/module/*
编写的。CPython 用 C 实现的一些模块是用纯 Python 编写的;它们位于顶层 lib_pypy
目录中。Python 的标准库(对 PyPy 做了一些修改)位于 lib-python
中。
JIT 编译器¶
即时编译器 (JIT):我们有一个跟踪 JIT,它跟踪用 RPython 编写的解释器,而不是它解释的用户程序。因此,它适用于任何解释器,即任何语言。但要使其正常工作并非易事:它需要少量精确的“提示”,并且可能需要对解释器进行一些小的重构。JIT 本身也包含几个几乎独立的部分:位于 rpython/jit/metainterp
中的跟踪器本身,位于 rpython/jit/metainterp/optimizer
中的优化器,它优化残余操作列表,以及位于 rpython/jit/backend/<machine-name>
中的后端,它将其转换为机器代码。编写新的后端是进入项目的一种传统方式。
垃圾收集器¶
垃圾收集器 (GC):如果您习惯了 CPython 的 C 代码,您可能会注意到,RPython 代码中没有 Py_INCREF/Py_DECREF
等效项。 RPython 中的垃圾收集 是在翻译过程中插入的。此外,这不是引用计数;它是一个真正的 GC,用更多 RPython 代码编写。我们目前最好的一个位于 rpython/memory/gc/incminimark.py
中。