阶段任务
在上一阶段中,我们完成了将带标注的 AST 翻译成语义等价的 TAC IR。 这一阶段,我们的目标与上一阶段完全一致,但是 IR 采用 JVM 字节码。
JVM (Java Virtual Machine) 是一种解释执行 JVM 字节码的虚拟机。 它为 Java 而生,实现了 Java 的跨平台运行,这是因为 JVM 屏蔽了与具体操作系统和处理器平台相关的信息,且具有自己完善的硬体架构,如处理器、堆栈、寄存器等,以及相应的指令系统。 虽然 JVM 的运行效率无法与原生相提并论,但是 JIT、Hotspot 等特性也能让 JVM 在工业级应用中拥有不错的性能。 作为一种编程语言的虚拟机,实际上不只专用于 Java 语言,只要生成符合标准的 JVM class 文件,任何语言都可以由 JVM 编译运行。 例如,Scala, Kotlin, Groovy, Closure 等语言都能原生运行在 JVM 上,而 JavaScript, Erlang, Python, Pascal 等语言都有第三方在 JVM 上的实现。 使用 JVM 的好处在于,语言设计者和使用者均可以直接复用 Java 生态中已有的库。
与基于(伪)寄存器的 TAC 不同,JVM 是栈式虚拟机,即大部分指令的操作数都放在栈上。 例如为了求 x + y
,栈式虚拟机会采用如下指令(示意):
即我们先往栈中压入左和右操作数,然后调用 add
指令完成加法的计算: 它会从栈顶弹出两个元素,分别作为右操作数和左操作数,然后执行加法运算,最后将结果压入栈顶。
这一阶段的核心任务是:把带有类型标注的 AST 翻译成语义上等价的 JVM 字节码,并充分利用 JVM 自带的类、数组等简化翻译过程, 以及调用 Java 标准库函数实现 TAC 中的 8 个运行时库函数。 通过这个阶段,希望大家能掌握栈式虚拟机 IR 的翻译方法,并且对于 JVM 中的过程调用约定、面向对象机制、存储布局等内容有所了解。
相关文件
与本阶段相关的文件有:
```text src └── main └── scala └── decaf └── jvm ├── JVMClass.scala JVM Class 文件的包装 ├── JVMGen.scala 代码生成入口 └── Util.scala 辅助函数
Last updated