Our language for method bodies is ``as small as possible, but no smaller.'' This allows us to focus on the essence of the new construct. An expression is either the empty expression, a variable reference, a self reference, a context reference, or a method invocation within a context.
We assume a set Identifier of variable identifiers, and a set MethodName of
method names. We will use to range over Expression,
to range
over Identifier, and
to range over MethodName.
The semantics that will be given below uses the semantic domains in Figure 20.
Figure 20: Summary of naming and typing conventions
We assume a set OID of object identifiers and a set ClassName of class names.
The function maps an object (represented by an object identifier) to
its class. A special object identifier
is used to refer to the
null object. A special class
is used to refer to a null class,
with
.
An object store defines the relations among a set of objects
by mapping an object identifier and a variable identifier
to a target object identifier. For example, if object
references
object
through the identifier
, then
.
We represent structure and behavior in separate models. Class structure is
represented in a class graph such as that given in Figure 8.
Class behavior is represented in a static method map which is a
mapping from method signatures to implementations. A method signature simply
consists of a class name and a method name. A method implementation is an
expression generated by the grammar in Figure 19. Since we
focus on context attachment to calls, we make the simplifying assumption that
all methods are class-stored.
Figure 21: Example class definitions
Figure 21 contains class definitions for the Equipment, CompositeEquipment, and InventoryVisitor classes. The structural part of the class definitions is represented by the class graph in Figure 8. The behavioral part of the class definitions is represented in the static method map in Figure 22 (shown as a set of tuples). Since we assume empty default before and after methods are defined for each class, we will not explicitly show them in the example code and method maps.
Figure 23: Context method map defined by InventoryVisitor class
A class definition, in addition to data members and methods, may contain
method updates which are defined in a separate static method map, called
the context method map. We use the term to refer to
the context method map containing the method updates defined by context class
. In Figure 21, the InventoryVisitor class
defines an implementation of the before method of the
Equipment class. The context method map
in
Figure 23 reflects this method update (shown as a tuple). We assume
the context method map
defined for the null class
is empty, thus it does not define any method updates.
An element of ContextMethodMapCollection defines a mapping from context
classes to context method maps
.
It is not necessary to explicitly represent the context relation between
classes in the structural model, rather it is easily inferred from the
behavioral model based on the relations between a method signature and its
implementations. For example, we can infer that InventoryVisitor is
context-related to Equipment, since the method map
defines an implementation for the before
method of the Equipment class.
When an expression containing a method invocation is encountered during program execution, the current implementation of the method must be computed. Context attachment may dynamically alter the implementation for a given method signature. Thus, the current implementation defined for the signature is computed and subsequently executed within the scope of both the base object (the object receiving the message) as well as the context object (the object defining the current implementation). A dynamic method map defines a mapping from a method signature to an implementation and object identifier pair (the context object defining the implementation).
A dynamic method map is initialized from the default method implementations
given in the static method map, with the context-object-identifier entries
initialized to . Thus, the initial dynamic method implementations
are defined by the static class definitions.
Context attachment during program execution may alter the dynamic method map.
When a context object is attached to a method invocation, the dynamic
method map is first altered based on the method updates defined in the static
method map
, before performing the actual method call.
The function
takes a dynamic method map, a static method map, and a
context object as input, and returns the modified dynamic method map. The
static method map passed into the function is that which contains the
method updates defined by the class of the context object
, namely
.
Method map flattening is the process of pushing method implementations down the inheritance hierarchy to avoid a search at run-time. In the following semantics, we assume all maps are the results of such flattening.