The semantics of method selection are defined as if each invocation of a function bundle selects the method to invoke at run-time through a complex procedure. This defines the required behavior, but the contemplated implementation is more optimized than that.
Method selection can be done at compile-time, at link-time, or at run-time.
Compile-time method selection is possible when the most specific method applicable to the actual parameter types known at compile-time is sealed or dominant. Those modifiers guarantee that the actual method selected at run-time will be the same or equivalent. This opens the door to inlining the method. Note that class slot readers and writers can be inlined this way when the instance class is known at compile-time. If not inlined, the method can be called directly at run-time.
Link-time method selection is possible when the most specific method applicable to actual parameter types known at compile-time is more specific than any other method in the function bundle. Therefore this method will be invoked. The linker can connect caller directly to callee.
Run-time method selection is required when neither compile-time nor link-time method selection is possible. The caller is linked to a dispatcher program that chooses from among the methods of the function bundle that are applicable to actual parameter types known at compile-time. This might be fewer than all the function's methods. The dispatcher code might be generated on the fly by the linker.
When the compiler generates code for a function call that is not inlined, it generates code to place the actual parameters in registers or stack locations and generates a description for the linker of the actual parameter types and locations. The compiler can recognize keywords that are apparently named formal parameter selectors and represent them in the linker description rather than generating code to place them in registers.
If the locations chosen by the compiler exactly match the locations where the method selected by the linker expects its actual parameters, the call can jump directly to the code of that method. Otherwise the call must jump to an adaptor program that moves the actual parameters to the right locations, supplies default values in the right locations for formal parameters that have no corresponding actual parameters, and jumps to the code of the method. Adaptor code might be generated on the fly by the linker. Adaptor code can also be generated as part of the target method; for example, it is convenient for the compiler to generate an adaptor to supply the default value for an optional parameter that simply puts the default into the appropriate register and drops through to the code used when the optional parameter is present.
It is possible to put an adaptor in front of or behind a dispatcher.
If dynamic addition of methods to existing function bundles is allowed, and the method selected at compile-time or link-time is not sealed or dominant, there must be a mechanism that can break that link and redo link-time method selection. This is done by indirecting through a function cell that contains the address of the method, dispatcher, or adaptor code to be called. Each function bundle owns a set of function cells. Each function cell is for a specific set of compile-time actual parameter types and locations.
Previous page Table of Contents Next page