Heim >Backend-Entwicklung >Golang >Behebung einiger Fehler

Behebung einiger Fehler

王林
王林Original
2024-07-24 14:23:311034Durchsuche

Resolução de alguns bugs

Für diejenigen, die POJ (Pascal auf der JVM) nicht befolgen: Es handelt sich um einen Compiler, der eine Teilmenge von Pascal in JASM umwandelt ( Java Assembly), damit wir die JVM als Ausführungsumgebung verwenden können.

Im letzten Beitrag haben wir die Unterstützung für Pascals Funktionen implementiert.

Werden wir in diesem Beitrag über coole Dinge sprechen? Nicht so sehr, lol. Dieses Mal reden wir nur über Bugs :-)

Während wir für die JVM kompilieren, ist es notwendig, die Funktionsweise verschiedener Punkte dieser unglaublichen virtuellen Maschine im Detail zu beschreiben. Daher erläutere ich an verschiedenen Stellen die interne Funktionsweise der JVM sowie einige ihrer Anweisungen (Opcodes).

Fehler bezüglich Parametern, die über die Befehlszeile an das Programm übergeben wurden

Als ich die Variablendeklaration implementiert habe, habe ich nicht darauf geachtet, dass in der JVM die erste Variable in der Hauptfunktion args ist, ein Array, das die an das Programm übergebenen Argumente enthält. Daher reserviere ich in dieser PR implizit die erste Position für args.

Fehler beim Umgang mit lokalen und globalen Variablen

Da die Test-Pascal-Programme nur globale Variablen enthielten, war mir kein schwerwiegender Fehler in der JASM-Generierung aufgefallen. Als ich Programme erstellte, die globale und lokale Variablen enthielten, wurde mir klar, dass etwas nicht stimmte, lol.

Aus dem Pascal-Programm unten:

program global_var_declaration;
var
    globalvar : integer;
begin
    globalvar := 123;
    write (globalvar);
end.

POJ hat den folgenden JASM generiert:

// 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
    }
}

Um das Problem zu identifizieren, habe ich ein Java-Programm erstellt, das dem obigen Pascal-Programm entspricht:

public class GlobalVarDeclaration {
    public static int globalVar;

    public static void main(String[] args) {
        globalVar = 123;
        System.out.println(globalVar);
    }
}

Als ich die Klasse zerlegte, erhielt ich die folgende Baugruppe:

 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: }

An dieser Stelle bemerkte ich die Deklaration „public static globalVar I“ (Zeile 2) und die Anweisungen putstatic (Zeile 6) und getstatic (Zeile 9) . Was erwartet wurde, waren die bisher von POJ verwendeten Anweisungen astore und istore. Beim Lesen der JVM-Dokumentation wurde mir klar, dass POJ globale Variablen so deklarierte, als wären sie lokale Variablen einer Funktion für die JVM :-D

Jedenfalls hat POJ bisher (fälschlicherweise) die Opcodes aload/iload/astore/istore für globale Variablen, aber die richtige Option wäre, die Variablen als öffentlich zu deklarieren (wie in Zeile 2) und getstatic/putstatic. zu verwenden

Damit wurde der Code hier umgestaltet, sodass die Symboltabelle lokale und globale Deklarationen verarbeiten kann. Und hier wurde der Code umgestaltet, damit die Symboltabelle die richtigen Anweisungen für lokale und globale Variablen generieren kann.

Die JASM-Codegenerierung wurde hier geändert, um die neue Symboltabelle zu verarbeiten und lokale Deklarationen nach dem Ende einer Funktion oder Prozedur zu bereinigen.

Damit aus dem Pascal-Programm unten:


program GlobalVarDeclaration;
var
    globalvar : integer;
begin
    globalvar := 123;
    write (globalvar);
end.
POJ generiert jetzt korrekt den folgenden 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
    }
}
Nächste Schritte

Im nächsten Beitrag werden wir über Kontexte und verschachtelte Sätze sprechen.

Vollständiger Projektcode

Das Repository mit dem vollständigen Code und der Dokumentation des Projekts finden Sie hier.

Das obige ist der detaillierte Inhalt vonBehebung einiger Fehler. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Vorheriger Artikel:Produzent/VerbraucherNächster Artikel:Produzent/Verbraucher