首页 >后端开发 >Golang >一些错误的解决

一些错误的解决

王林
王林原创
2024-07-24 14:23:311031浏览

Resolução de alguns bugs

对于那些不遵循 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 迄今为止使用的 astoreistore 指令。阅读 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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn