Home  >  Article  >  Backend Development  >  Resolution of some bugs

Resolution of some bugs

王林
王林Original
2024-07-24 14:23:31954browse

Resolução de alguns bugs

For those who are not following POJ (Pascal on the JVM) it is a compiler that transforms a subset from Pascal to JASM (Java Assembly) so that we can use the JVM as an execution environment.

In the last post we implemented support for Pascal's functions.

In this post, are we going to talk about cool things? Not so much lol. This time we're just going to talk about bugs :-)

As we are compiling for the JVM, it is necessary to detail the functioning of various points of this incredible virtual machine. Therefore, at various times I detail the internal functioning of the JVM as well as some of its instructions (opcodes).

Bug regarding parameters passed to the program via the command line

When I implemented the variable declaration, I didn't pay attention to the fact that, in the JVM, the first variable in the main function is the args, an array that contains the arguments passed to the program. So in this PR I implicitly reserve the first position for args.

Bug when dealing with local and global variables

As the test Pascal programs only contained global variables, I had not noticed a serious error in the JASM generation. The moment I created programs that contained global and local variables I realized that something wasn't right lol.

From the Pascal program below:

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

POJ generated the following 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
    }
}

To try to identify the problem, I created a Java program equivalent to the Pascal program above:

public class GlobalVarDeclaration {
    public static int globalVar;

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

When I disassembled the class I got the following assembly:

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

At this point I noticed the declaration "public static globalVar I" (line 2) and the instructions putstatic (line 6) and getstatic (line 9) . What was expected were the astore and istore instructions used by POJ until now. Reading the JVM documentation I realized that POJ was declaring global variables as if they were local variables of a function to the JVM :-D

Anyway, until now POJ was (erroneously) using the opcodes aload/iload/astore/ istore for global variables, but the correct option would be to declare the variables as public (as in line 2) and use getstatic/putstatic.

With this, the code was refactored here so that the symbol table can handle local and global declarations. And here the code was refactored so that the symbol table can generate the correct instructions for local and global variables.

JASM code generation has been changed here to handle the new symbol table as well as clean up local declarations after a function or procedure ends.

With this, from the Pascal program below:

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

POJ now correctly generates the following 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
    }
}

Next steps

In the next post we will talk about contexts and nested sentences.

Complete project code

The repository with the project's complete code and documentation is here.

The above is the detailed content of Resolution of some bugs. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Previous article:Producer/ConsumerNext article:Producer/Consumer