Java Reference
In-Depth Information
publicNarrowReference(Typetarget){
this.target=target;
}
publicvoidcodegen(CLEmitteroutput){
output.addReferenceInstruction(CHECKCAST,
target.jvmName());
}
}
The compiler creates a NarrowReference instance for each cast of this kind, tailored to the
type it is casting to.
The codegen() method is used in the next code generation phase. We address code
generation in the next chapter.
4.5.7 Java's Denite Assignment Rule
In full Java, every variable (whether it be a local variable or a field) must be definitely
assigned before it is accessed in a computation. That is, it must appear on the left-hand
side of the = operator before it is accessed. The definite assignment rule, as it applies to
Java, is described fully in Chapter 16 of the Java Language Specification [Gosling et al.,
2005]. We do not have this rule in j--, so we need not enforce it in our compiler.
Enforcing the definite assignment rule requires data flow analysis, which determines
where in the program variables are defined (assigned values), where in the program the
variables' values are used, and so where in the program those values are valid (from assign-
ment to last use).
We discuss data flow analysis in Chapters 6 and 7; our JVM-to-MIPS translator performs
data-flow analysis as part of computing live intervals for register allocation.
4.6 Visitor Pattern and the AST Traversal Mechanism
One might ask, \Why does the compiler not use the visitor pattern for traversing the AST
in pre-analysis, analysis, and code generation?"
The visitor pattern is one of the design patterns introduced by Erich Gamma et al.
[Gamma, 1995]. The visitor pattern serves two purposes:
1. It separates the tree traversal function from the action taken at each node. A separate
mechanism, which can be shared by tree-printing, pre-analysis, analysis, and code
generation, traverses the tree.
2. It gathers all of the actions for each phase together into one module (or method).
Thus, all of the tree-printing code is together, all of the pre-analysis code is together,
all of the analysis code is together, and all of the code generation code is together.
The idea is that it separates traversal from actions taken at the nodes (a separation of
concerns) and it makes it simpler to add new actions. For example, to add an optimization
phase one need simply write a single method, rather than having to write an optimize()
method for each node type.
Such an organization would be useful if we were planning to add new actions. But we
 
Search WWH ::




Custom Search