|  |  |  | 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 |