首頁 >後端開發 >Golang >一些錯誤的解決

一些錯誤的解決

王林
王林原創
2024-07-24 14:23:311032瀏覽

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