This assignment concerns the generation of Java bytecode from the
transformed and analyzed Java code. It consists of the two phases
Resources and Codegeneration. You must hand
in two files resources.ml and
codegeneration.ml that extend the skeleton.
When all phases up to and including the code generation have been completed, you will be able to run your compiler on its own, without having to rely on the online tester.
Instruction module. The type
Instruction.instruction has a constructor representing
each specific instruction and is named with an I followed
by the assembly opcode name. The functions defined in the
Instruction module are used by the stack
limits calculator, the peephole optimizer and the code emitter.
The constructor of an instruction class takes a number of parameters
corresponding to the parameters of the instruction. These will always
have one of the following types (class names are implicitly in the
dovs.instructions package):
int: An integer parameter, representing a
local variable index or array dimensionality.int32: A 32-bit integer parameter, representing an
integer constant.label: A label or a reference to a label.condition: A data type representing the
possible conditions in a conditional jump.signature: The signature of a type or a field.method_signature: The signature of a method.Iif represents any conditional jump that
compares a single value against zero or null.Iifcmp represents any conditional jump that
compares two values against each other.Ildc_int represents any instruction that
pushes an integer constant onto the stack.Ildc_string represents an ldc
instruction whose argument is a string.Ilabel represents a label, i.e. a place in
the code that other instructions can jump to. It does not
correspond to a JVM instruction.Instruction.instruction type. This set
is more than sufficient to implement the whole Joos 2 language.
Resources phase is responsible for calculating the
local variable index for each local variable. The pass also
calculates the signatures of types, fields and methods.
TAst.LocalDecl node in the program, assign a local
variable index to the variable and bind it with the
RAst.LocalDecl constructor. The skeleton already contains
code to do this which is correct but suboptimal.
Codegeneration phase builds instruction lists for the
bodies of all methods and constructors.
<clinit> taking no arguments and throwing no
exceptions. This method should contain the code for initializing all
static fields. Final static fields whose initializers are
compile-time constants should be initialized before other static
fields. Whether or not an expression is a compile-time constant can
be checked (after the constant folding phase has been run) using the
is_constant function.method_body and
constructor_body record labels.Code for initializing non-static fields should be executed immediately after the super constructor call of every constructor that calls a super constructor.
The Joos 0 compiler implements implicit string
concatenation using the String.concat method. However,
javac implements a series of implicit string
concatenation operations as StringBuffer.append calls on
the same StringBuffer object. The first strategy uses
quadratic execution time in the number of consecutive string
concatenation operations, while the latter only uses linear time.
String.concat,StringBuffer.append.
public int m(int a, int b) {
if (a < b) {
return 42;
}
return 123;
}