Rumah > Artikel > pembangunan bahagian belakang > Penyelesaian beberapa pepijat
Bagi mereka yang tidak mengikuti POJ (Pascal pada JVM) ia adalah pengkompil yang mengubah subset daripada Pascal kepada JASM ( Java Assembly) supaya kita boleh menggunakan JVM sebagai persekitaran pelaksanaan.
Dalam siaran lepas kami melaksanakan sokongan untuk fungsi Pascal.
Dalam siaran ini, adakah kita akan bercakap tentang perkara yang menarik? Tidak begitu banyak lol. Kali ini kita hanya akan bercakap tentang pepijat :-)
Ketika kami sedang menyusun untuk JVM, adalah perlu untuk memperincikan fungsi pelbagai titik mesin maya yang luar biasa ini. Oleh itu, pada pelbagai masa saya memperincikan fungsi dalaman JVM serta beberapa arahannya (opcodes).
Apabila saya melaksanakan pengisytiharan pembolehubah, saya tidak memberi perhatian kepada fakta bahawa, dalam JVM, pembolehubah pertama dalam fungsi utama ialah args, tatasusunan yang mengandungi argumen yang dihantar kepada program. Jadi dalam PR ini secara tersirat saya menyimpan kedudukan pertama untuk args.
Memandangkan program ujian Pascal hanya mengandungi pembolehubah global, saya tidak menyedari ralat serius dalam generasi JASM. Sebaik sahaja saya mencipta program yang mengandungi pembolehubah global dan tempatan, saya menyedari bahawa ada sesuatu yang tidak betul.
Daripada program Pascal di bawah:
program global_var_declaration; var globalvar : integer; begin globalvar := 123; write (globalvar); end.
POJ menjana JASM berikut:
// 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 } }
Untuk cuba mengenal pasti masalah, saya mencipta program Java yang setara dengan program Pascal di atas:
public class GlobalVarDeclaration { public static int globalVar; public static void main(String[] args) { globalVar = 123; System.out.println(globalVar); } }
Apabila saya membuka kelas saya mendapat pemasangan berikut:
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: }
Pada ketika ini saya perhatikan pengisytiharan "public static globalVar I" (baris 2) dan arahan putstatic (baris 6) dan getstatic (baris 9) . Apa yang dijangkakan ialah arahan astore dan istore yang digunakan oleh POJ sehingga sekarang. Membaca dokumentasi JVM saya menyedari bahawa POJ mengisytiharkan pembolehubah global seolah-olah ia adalah pembolehubah tempatan fungsi kepada JVM :-D
Apa pun, sehingga kini POJ (tersalah) menggunakan opcode muat/iload/astore/ istore untuk pembolehubah global, tetapi pilihan yang betul ialah mengisytiharkan pembolehubah sebagai awam (seperti dalam baris 2) dan menggunakan getstatic/putstatic.
Dengan ini, kod telah difaktorkan semula di sini supaya jadual simbol boleh mengendalikan pengisytiharan tempatan dan global. Dan di sini kod telah difaktorkan semula supaya jadual simbol boleh menjana arahan yang betul untuk pembolehubah tempatan dan global.
Penjanaan kod JASM telah ditukar di sini untuk mengendalikan jadual simbol baharu serta membersihkan pengisytiharan tempatan selepas fungsi atau prosedur tamat.
Dengan ini, daripada program Pascal di bawah:
program GlobalVarDeclaration; var globalvar : integer; begin globalvar := 123; write (globalvar); end.
POJ kini menjana JASM berikut dengan betul:
// 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 } }
Dalam siaran seterusnya kita akan bercakap tentang konteks dan ayat bersarang.
Repositori dengan kod dan dokumentasi lengkap projek ada di sini.
Atas ialah kandungan terperinci Penyelesaian beberapa pepijat. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!