"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > Resolución de algunos errores.

Resolución de algunos errores.

Publicado el 2024-08-19
Navegar:540

Resolução de alguns bugs

Para aquellos que no siguen POJ (Pascal en la JVM) es un compilador que transforma un subconjunto de Pascal a JASM (Java Assembly) para que podamos usar la JVM como entorno de ejecución.

En la última publicación implementamos soporte para las funciones de Pascal.

En esta publicación, ¿vamos a hablar de cosas interesantes? No tanto jajaja. Esta vez solo vamos a hablar de errores :-)

Como estamos compilando para la JVM, es necesario detallar el funcionamiento de varios puntos de esta increíble máquina virtual. Por ello, en diversos momentos detallo el funcionamiento interno de la JVM así como algunas de sus instrucciones (opcodes).

Error relacionado con los parámetros pasados ​​al programa a través de la línea de comando

Cuando implementé la declaración de variables no presté atención al hecho de que, en la JVM, la primera variable en la función principal es args, una matriz que contiene los argumentos pasados ​​al programa. Entonces, en este PR reservo la primera posición implícitamente para args.

Error al tratar con variables locales y globales.

Como los programas Pascal de prueba contenían solo variables globales, no había notado un error grave en la generación JASM. En el momento en que creé programas que contenían variables globales y locales me di cuenta de que algo no estaba bien jajaja.

Del siguiente programa Pascal:

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

POJ generó el siguiente 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
    }
}

Para intentar identificar el problema, creé un programa Java equivalente al programa Pascal anterior:

public class GlobalVarDeclaration {
    public static int globalVar;

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

Cuando desarmé la clase obtuve el siguiente ensamblaje:

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

En este punto noté la declaración "public static globalVar I" (línea 2) y las instrucciones putstatic (línea 6) y getstatic (línea 9). Lo que se esperaba eran las instrucciones astore y istore utilizadas por POJ hasta ahora. Al leer la documentación de JVM me di cuenta de que POJ estaba declarando variables globales como si fueran variables locales de una función para la JVM :-D

De todos modos, hasta ahora el POJ estaba usando (erróneamente) los opcodes aload/iload/astore/ Istore para variables globales, pero la opción correcta sería declarar las variables como públicas (como en la línea 2) y usar getstatic/putstatic.

Como resultado, el código fue refactorizado aquí para que la tabla de símbolos pueda manejar declaraciones locales y globales. Y aquí el código fue refactorizado para que la tabla de símbolos pueda generar las instrucciones correctas para las variables locales y globales.

La generación de código JASM se ha cambiado aquí para manejar la nueva tabla de símbolos, así como para limpiar las declaraciones locales después de que finaliza una función o procedimiento.

Con esto, del programa Pascal a continuación:

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

POJ ahora genera correctamente el siguiente 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
    }
}

Próximos pasos

En el próximo post hablaremos sobre contextos y oraciones anidadas.

Código completo del proyecto

El repositorio con el código completo y la documentación del proyecto está aquí.

Declaración de liberación Este artículo se reproduce en: https://dev.to/alexgarzao/resolucao-de-alguns-bugs-3a1i?1 Si hay alguna infracción, comuníquese con [email protected] para eliminarla.
Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3