This section explains how messages can be dispatched, i.e. how the implementation of a method can be invoked, given the message.
A method is translated by the compiler to a C function with essentially the same arguments as the method, with two mandatory additions and some additions depending on the return type of the method. For the method
(boolean, Any) next
defined for the
instance tom.Enumerator, the C function
implementing this is
tom_byte i_tom_Enumerator__or__next (tom_object self, selector cmd, tom_object *ret1)
As can be seen, the first element of the tuple return type is the type
returned by the implementation C function. Such a function always has
two `implicit' first arguments:
self being the object receiving
the message, and
cmd being the message sent. Following these two
are the `normal' arguments to the method, which are none in this case.
Finally, any of the remaining return values are to be returned in the
pointer arguments supplied after the normal arguments. In the example,
a pointer for returning the second tuple element is provided.
A message is dispatched by invoking the method implementation for the
(self, cmd) pair. The lookup of the implementation,
i.e. the pointer to the C function, can be done in three different ways:
trt_lookupwith the receiver and the selector to be invoked (i.e. the values to be passed for
trt_lookupreturns a function pointer to the method implementation. Invoke that function with the arguments.
trt_lookupfunction. This is a rather unwise way of invoking a method as it considerably increases code size.
trt_sendto dispatch a message, the function
trt_sendis invoked with all the arguments to be passed to the method implementation.
trt_sendwill perform the lookup and jump directly to the implementation.
These different dispatching mechanisms can be selected by an option to otmc. They are described here for explanatory purposes; never implement any of these directly in your C code; the next section explains how to do that portably.
Sending is the preferred way of dispatching messages, though possibly
not present on all TOM implementations as it involves an assembly
language routine. Also note that there are dependencies of the
applicability of some dispatching mechanisms. For example, it is
impossible to use sending on dynamically loaded code on
machines. This is not a TOM feature but due to the interspace stubs
needed by the hpux shared library interspace calls, added to the fact
that a callee stores the return program counter in the stack frame of
When doing profiling on a TOM program, all code should really use the
lookup way of dispatching instead of sending to dispatch. Otherwise,
all methods will be reported to only invoke
trt_send will be reported as the culprit which invoked every
method and thus effectively void the use of the call graph.
Go to the first, previous, next, last section, table of contents.