Penyelesaian beberapa pepijat

王林
Lepaskan: 2024-07-24 14:23:31
asal
1028 orang telah melayarinya

Resolução de alguns bugs

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).

Pepijat mengenai parameter yang dihantar kepada program melalui baris arahan

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.

Pepijat apabila berurusan dengan pembolehubah tempatan dan global

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.
Salin selepas log masuk

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
    }
}
Salin selepas log masuk

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);
    }
}
Salin selepas log masuk

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: }
Salin selepas log masuk

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.
Salin selepas log masuk

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
    }
}
Salin selepas log masuk

Langkah seterusnya

Dalam siaran seterusnya kita akan bercakap tentang konteks dan ayat bersarang.

Kod projek lengkap

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!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan