„Wenn ein Arbeiter seine Arbeit gut machen will, muss er zuerst seine Werkzeuge schärfen.“ – Konfuzius, „Die Gespräche des Konfuzius. Lu Linggong“
Titelseite > Programmierung > Behebung einiger Fehler

Behebung einiger Fehler

Veröffentlicht am 19.08.2024
Durchsuche:483

Resolução de alguns bugs

Für diejenigen, die POJ nicht verfolgen (Pascal auf der JVM) ist ein Compiler, der eine Teilmenge von Pascal nach 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 die erste Position implizit für Argumente.

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 Klasse zerlegt habe, habe ich die folgende Assembly erhalten:

 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 fielen mir die Deklaration „public static globalVar I“ (Zeile 2) und die Anweisungen putstatic (Zeile 6) und getstatic (Zeile) auf 9) . Was erwartet wurde, waren die bisher von POJ verwendeten Anweisungen astore und istore. Als ich die JVM-Dokumentation las, wurde mir klar, dass POJ globale Variablen so deklarierte, als wären sie lokale Variablen einer Funktion für die JVM :-D

Jedenfalls hat das POJ bisher (fälschlicherweise) die Opcodes aload/iload/astore/ Istore verwendet 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.

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

Freigabeerklärung Dieser Artikel ist abgedruckt unter: https://dev.to/alexgarzao/resolucao-de-alguns-bugs-3a1i?1 Bei Verstößen wenden Sie sich bitte an [email protected], um ihn zu löschen
Neuestes Tutorial Mehr>

Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.

Copyright© 2022 湘ICP备2022001581号-3