對於那些不遵循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中文網其他相關文章!