對於那些不遵循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