对于那些不遵循 POJ 的人(JVM 上的 Pascal)是一个将 子集 从 Pascal 转换为 JASM 的编译器(Java Assembly),这样我们就可以使用JVM作为执行环境。
在上一篇文章中,我们实现了对 Pascal 的 函数 的支持。
在这篇文章中,我们要讨论一些很酷的事情吗?没那么多哈哈。这次我们只讨论错误:-)
当我们为 JVM 进行编译时,有必要详细说明这个令人难以置信的虚拟机的各个点的功能。因此,我多次详细介绍 JVM 的内部功能及其一些指令(操作码)。
当我实现变量声明时,我没有注意到这样一个事实:在 JVM 中,main 函数中的第一个变量是 args,一个包含传递给程序的参数的数组。因此,在此 PR 中,我隐式为 args.
保留第一个位置由于测试 Pascal 程序仅包含全局变量,因此我没有注意到 JASM 生成中存在严重错误。当我创建包含全局和局部变量的程序时,我意识到有些事情不对,哈哈。
来自下面的 Pascal 程序:
program global_var_declaration; var globalvar : integer; begin globalvar := 123; write (globalvar); end.
POJ 生成了以下 JASM:
// Code generated by POJ 0.1 public class global_var_declaration { public static main([java/lang/String)V { ;; globalvar := 123; bipush 123 istore 1 ;; write (globalvar); getstatic java/lang/System.out java/io/PrintStream iload 1 invokevirtual java/io/PrintStream.print(I)V return } }
为了尝试找出问题,我创建了一个与上面的 Pascal 程序等效的 Java 程序:
public class GlobalVarDeclaration { public static int globalVar; public static void main(String[] args) { globalVar = 123; System.out.println(globalVar); } }
当我反汇编类时,我得到以下程序集:
1: public class GlobalVarDeclaration { 2: public static globalVar I 3: 4: public static main([java/lang/String)V { 5: bipush 123 6: putstatic GlobalVarDeclaration.globalVar I 7: 8: getstatic java/lang/System.out java/io/PrintStream 9: getstatic GlobalVarDeclaration.globalVar I 10: invokevirtual java/io/PrintStream.println(I)V 11: 12: return 13: } 14: }
此时我注意到声明“public static globalVar I”(第2行)和指令putstatic(第6行)和getstatic(第2行) 9) .所期望的是 POJ 到目前为止使用的指令 astore 和 istore。阅读 JVM 文档,我意识到 POJ 声明全局变量就好像它们是 JVM 函数的局部变量一样:-D
无论如何,到目前为止,POJ(错误地)使用操作码 aload/iload/astore/ Istore 用于全局变量,但正确的选项是将变量声明为公共变量(如第 2 行所示)并使用 getstatic/putstatic.
因此,这里对代码进行了重构,以便符号表可以处理本地和全局声明。这里代码被重构,以便符号表可以为局部和全局变量生成正确的指令。
JASM 代码生成已在此处进行更改,以处理新的符号表以及在函数或过程结束后清理本地声明。
这样,从下面的 Pascal 程序中:
program GlobalVarDeclaration; var globalvar : integer; begin globalvar := 123; write (globalvar); end.
POJ 现在可以正确生成以下 JASM:
// Code generated by POJ 0.1 public class global_var_declaration { public static globalvar I public static main([java/lang/String)V { ;; globalvar := 123; bipush 123 putstatic global_var_declaration.globalvar I ;; write (globalvar); getstatic java/lang/System.out java/io/PrintStream getstatic global_var_declaration.globalvar I invokevirtual java/io/PrintStream.print(I)V return } }
在下一篇文章中我们将讨论上下文和嵌套句子。
包含项目完整代码和文档的存储库位于此处。
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3