Homework 6
Frames  

powered by FreeFind

Modified: 

Overview

Frames hold the activation record for calling a method. Though the frame is used at runtime, the location of parameters and local variables is performed at compile time. Chapter 6 examined a general approach to frame generation, we will simplify to problem by targeting the JVM.

Homework 3 defined the concrete grammar necessary for SableCC to generate a parser, however an abstract grammar results in a simpler solution for the type checker.

Homework 4 introduced the concrete to abstract grammar transformations of SableCC3 which will be applied to the MiniJava language. The implementation of the interpreter used the the DepthFirstAdapter class to visit nodes of the AST.

Homework 5 combined those ideas with that of a symbol table to implement a type checker based on the complete abstract grammar definition of MiniJava in SableCC3 form and skeleton classes for the necessary Java.

Homework 6 combines these ideas to determine where data is located in the frame (offset) required for each method and update the symbol table with that information. Much of the previous work will be used. The basic idea is build upon that work to add frame location information to the symbol table.

JVM FRAME Construction

Since the target machine is the JVM, the machine specific elements of the compiler should be placed in a separate directory. The organization of the frame is illustrated and described below.

Symbol table printing

The symbol table is a key source of information to the compiler, understanding its contents is critical. The following is a display of the important symbol table data for the MiniJava program at left.

class Factorial {
    public static void main(String [] a) {
        System.out.println(new Fac().ComputeFac(10));
    }
}
 
class Fac {
    int z1;
    int z2;
   
    public int ComputeFac(int num) {
        int num_aux;

        if (num < 1)
            num_aux = 1;
        else
            num_aux = num * (this.ComputeFac(num-1));
        return num_aux;
    }
   
    public int test1 (int x, int y) {
        int q;
        int r;
        return x;
    }
}
Classes
Factorial
    Fields
    Methods
Fac
    Fields
      z1  <class minijava.node.AIntType>
      z2  <class minijava.node.AIntType>
    Methods
      test1  <class minijava.node.AIntType>
        Parameters
          x  1  <class minijava.node.AIntType>   
          y  2  <class minijava.node.AIntType>  
        Variables
          q  3  <class minijava.node.AIntType>  
          r   4  <class minijava.node.AIntType>     
     ComputeFac
        Parameters
           num 1 <class minijava.node.AIntType>
        Variables
           num_aux 2  <class minijava.node.AIntType>

The basic approach begins with the SymbolTable object constructed by BuildSymbolTableVisitor, it contains all the symbol table data; a getSymbolTable() accessor of BuildSymbolTableVisitor returns the SymbolTable object constructed.

Printing the classes, methods, etc. from the symbol table is a mainly a matter of understanding the 4 classes of the SymbolTable package: SymbolTable, Class, Method, Variable. Each has accessor methods (usually named getId(), getParams(), getVars(), etc.) which returns data from the object.

The symbol table organization parallels that of a Java program in that there are multiple classes, each class can have multiple methods; each method multiple parameters and variables; etc. These are returned as an enumeration which can be accessed sequentially. For example, the following iterates through all classes and the globals (fields) of the class:

    public void Print() {
     System.out.println("Classes");
     Enumeration ce = symbolTable.getClasses();
     while(ce.hasMoreElements()) {
        Class c = (Class)ce.nextElement();
        System.out.println(c.getId());
       
        System.out.println("\t"+"Fields");
        Enumeration ge = c.getGlobals();
        while(ge.hasMoreElements()) {
            Variable v = (Variable)ge.nextElement();
            System.out.println("\t"+"\t"+v.id()+"\t<"+v.Type().getClass()+">");
        }
     }
  }

Main.java will need modification to call your printing class.

 

Assignment

  1. Compute frame offsets for the JVM by implementing two packages: FrameVisitor and JVM.
  2. Write a separate package to print the symbol table contents and the frame offsets of each variable.
  3. Type check any 3 provided MiniJava test programs.  

Files

Use HW5 as a starting point, add JVM and FrameVisitor packages.

Getting Started

The HW5 directory contained a BlueJ project that can be used as a starting point for HW6. To execute:

  1. Generate the minijava parser as described above.
  2. Start BlueJ and open the project.
  3. Right click on Main and compile (or Select | Tools | Compile Selected).
  4. Right click on Main and void main(arguments).
  5. Enter the name of a test file as: {"Factorial.java"}

Turn In

  1. Cover sheet with your name, C431, date, and Homework 6.
  2. Print out of FrameVisitor, JVMFrame and the symbol table printer.
  3. Print out of symbol table produced from the 3 tests.