![]() | ![]() | ![]() | 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 |