对于那些不遵循 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 对于全局变量,但正确的选择是将变量声明为 public(如第 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 } }
在下一篇文章中我们将讨论上下文和嵌套句子。
包含项目完整代码和文档的存储库位于此处。
以上是一些错误的解决的详细内容。更多信息请关注PHP中文网其他相关文章!