鹦鹉虚拟机/鹦鹉内部
鹦鹉开发项目是一个大型且复杂的项目,具有多个方面。以下是有关鹦鹉构建流程的一些关键点的概述。此处的一些要点以前没有讨论过,但我们将在本章或后面的章节中介绍它们
- 构建环境使用 Configure.pl 程序配置。该程序是用 Perl 5 编写的,就像 Parrot 的许多构建工具一样。Configure.pl 确定系统上的选项,包括您使用的编译器、使用的 Make 程序(如果有)、所需的特定于平台的库等等。
- PMC 是用类似 C 的脚本编写的,该脚本使用 PMC 编译器编译成 C 代码。PMC 编译器将为所有 PMC 生成 C 代码和相关头文件,并将 PMC 注册到 Parrot PMC 表中。
- 操作码是用类似 C 的脚本编写的,该脚本编译成 C,就像 PMC 一样。操作码文件的语法在某些方面类似于用于 PMC 的语法,但在许多方面也有所不同。Ops 文件在编译成机器代码之前被转换成 C。
- 本机调用接口 (NCI) 函数签名必须在使用 NCI 编译器编译之前被转换成 C 函数
- 实时操作必须被转换成 C 代码,以便编译成本机代码。
- PASM 和 PIR 的解析器是用 Lex/Bison 编写的。这些需要被编译成 C 文件,以便进行编译。
- 常量字符串转换器将 CONST_STRING 声明在编译时转换成字符串常量。这在执行时节省了很多时间。
- Makefile 通过编译所有 PMC、编译所有 C 文件、构建可执行文件和库等等来自动化构建过程。
在本章中,我们将概述鹦鹉虚拟机的一些组件,后面的章节将讨论各种鹦鹉子系统,包括我们上面描述的许多过程。本节中的章节都将讨论鹦鹉黑客和开发。如果您对帮助开发鹦鹉不感兴趣,可以跳过这些章节。
以下是 Parrot 仓库的一般结构,就源代码而言
有两个用于 PIR 的解析器。第一个是 IMCC,目前正在使用,但效率低下,另一个是 PIRC,效率更高,但尚未稳定。长期计划是在 Parrot 1.0 版本发布时,让 PIRC 成为主要的 PIR 解析器。
IMCC 和 PIRC 都是用 C 语言编写的,解析器是用 Lex 和 Yacc 编写的。
PIRC 和 IMCC 充当两个其他 Parrot 组件的前端:字节码编译器和解释器。
字节码编译器是 Parrot 的一部分,负责将输入符号(以 PASM 或 PIR 的形式)转换成 Parrot 字节码。这个字节码一旦编译,就可以在 Parrot 上快速高效地运行。
另一个相关的 Parrot 组件是字节码优化器,它负责对 Parrot 字节码进行低级优化。
虽然字节码编译器从 PIRC 或 IMCC 获取输入符号并将它们转换成字节码以供存储和以后执行,但解释器使用这些符号直接执行程序。这意味着没有编译的中间步骤,并且脚本可以在没有编译的情况下快速执行。
I/O 子系统控制对控制台、文件和操作系统的读写操作。许多功能是在特殊的 PMC 中执行的。
正则表达式引擎用于为 Parrot 程序提供快速的正则表达式。这个引擎的功能最明显地体现在 PGE 中,但也存在于其他地方。Perl 6 正则表达式(这个引擎基于该表达式)与 Perl 5 正则表达式及其变体有很大的不同。
内存管理子系统旨在为 Parrot 和在 Parrot 之上运行的程序分配和组织内存。垃圾收集器检测到分配的内存不再使用,并将该内存返回到池中以供以后分配。
Parrot 不仅仅是一个可执行程序,它也是一个可链接的库,称为 libparrot。 libparrot 可以链接到其他程序,并且可以在该程序内部调用 Parrot 解释器对象。创建了一个完整的嵌入 API,允许 libparrot 与其他程序通信。
Parrot 可以通过使用动态库来扩展,例如 linux .so
文件或 Windows .dll
文件。这些扩展必须以安全和受控的方式与 Parrot 交互。为此,编写了扩展 API,以便为扩展提供与 Parrot 内核通信的通道。
接下来的几章将重点介绍 Parrot 的各个组件。我们将讨论每个组件的软件体系结构和操作。正如我们已经看到的那样,Parrot 本身是用 C 编程语言编写的,尽管各个组件(例如操作码、PMC 和其他功能)是用特殊的领域特定语言编写的,然后被翻译成 C 代码。一些更高级的功能,例如 PCT 也是用 PASM 和 PIR 编写的。PIR 的解析器是用 Lex 和 Yacc 的组合编写的。
Parrot 编程通常需要对 C 编程语言有很好的了解,但也需要对 Perl 5 有很好的理解。这是因为 Perl 5 用于编写所有控制 Parrot 构建过程的开发工具。