| Generating Code for Methods |
| < Code to pass parameter values > | |
| JSR | proc-name |
| proc-name | LINK | A6,#-<local variable space size> |
| < Code for procedure body > | ||
| UNLK | ||
| RTD | #-param-count | |
class program {
class A {
void m1( ... ) {
print( "hi" );
}
void m2( ... ) {
m1( ... );
}
}
class B extends A {
void m1( ... ) {
print( "bye" );
}
}
void main() {
( new A() ).m2();
( new B() ).m2();
}
}
Note: If you are just dying to do something clever to improve the quality of the code you produce you should observe that it is safe to skip the method table if the class containing the method being invoked has no subclasses or if none of the subclasses override the method.
meth( ... )
in which "meth" is defined in the same class as the method that contains the
invocation, this actually isn't an issue since the active object isn't changed so A5
should remain the same.
expr.meth( ... )
the object produced by "expr" becomes the active object.
meth( ... )
in which meth is defined in a surrounding class definition (i.e. scope rules rule),
you have to follow the chain of static links stored in objects to get "up" to the
object corresponding to the class in which the method was defined.
meth( ... )
you should modify the syntax tree by turning this into a subtree for an
expression of the form
expr.meth( ... )
where "expr" is a chain of refvar nodes that loads the needed values from
the chain of static links.
I said "goofed" in this case because if you try to do this
during code generation instead of during the binding phase you
will discover that you don't have enough information. The level
information in a method's decldesc cannot be used to decide if a method
is non-local (since it might have been inherited). You have to instead use
the level information in binding stack entries (which are no longer accessible
during code generation).
To understand the need to do this better, consider the example in
Figure *:
class program {
void main() {
...
}
class base {
int y;
void m1() { ... y ... }
}
class wrapper {
class outer extends base {
class inner {
void m2() { m1(); }
}
}
}
}
| Generating Code for Methods |