• No results found

5.3 Partial Behavioral Reflection Revisited

5.3.2 The Link

1

*

Figure 5.3: The link in GEPPETTO2

5.3.2 The Link

In our new model, the link is an even more central abstraction than in the original model. The link defines where reification occurs by being set as an annotation on the AST nodes, it defines which meta-object to call and it contains the definition for the exact protocol between the base and the meta-level.

The parameters of the link are contained in attributes that are set when configuring the link prior to installing it in a node. The attributes are set via single message sends to the link object. For convenience, default values are defined for the attributes.

To illustrate this, we show as an example a link that, when installed on a message send node, would replace this send with an invocation of a method#send:to:with:in the meta-object of classSender:

link := GPLink new metaObject: Sender new;

selector: #send:to:with:;

arguments: #(selector receiver arguments);

control: #instead.

Link Attributes

In the following, we provide an overview of all the attributes that can be configured for a link.

Meta-object. Primarily, the link defines which meta-object to use. This can

be any Squeak object. There is no special superclass or any special structure or methods required.

link metaObject: Sender new.

Selector: The selector defines which method to call on the meta-object.

Thus, it is a symbol; the default is#value. When the selector defined requires multiple arguments, these are defined with the#arguments:

attribute.

link selector: #send:to:with:.

Arguments. When calling a method with multiple arguments, we have to specify which arguments to pass to the meta object. The arguments are specified by a literal array containing symbols describing what exactly to pass as arguments. The default is the empty array.

link arguments: #(selector receiver arguments).

We use symbols to specify which information exactly is to be passed to the meta-level. We give a complete list later in the section on reified data.

Control: The control attribute specifies when the call to the meta-object should occur: i.e., before, after or instead of the original operation.

The control is specified using a symbol. Possible values are#before,

#afteror#instead. The default is#before. link control: #instead.

Condition. Optionally we may want to control the link further by spec-ifying a condition. This condition can be any object that returns a boolean value when being sent #value. This means we can use Booleans, as e.g., true valuereturns true. Blocks are the most natu-ral condition. In addition, the user of the framework can provide a special object that implements#valueif needed.

With blocks as conditions, link activation can be easily controlled. As an example, the following link would only be active when tracing would be turned on in the system-wide preferences:

link condition: [Preferences traceEnabled].

The link is active if the block evaluates totrue, that is, when the preference is enabled.

For conditions that depend on reified information only available at runtime from the base object, we provide a way to specify which parameters to pass to the block by using#condition:arguments:. We can pass any reified information to the condition block. The following would restrict a link to one certain object:

link condition: [:object | object == myObject] arguments: #(object).

Meta-object Scope. As in GEPPETTO1, we provide the concept of meta-object scope. This enables us to have different meta meta-objects associated for different base level entities instead of one global meta-object per link. We can configure a link to have meta objects per class, per method, per object or per node.

link metaScope: #object.

When using meta-object scope, we have to create new meta-objects at runtime. Therefore, we specify the meta-object for the link not statically, but using a block of code:

link metaCreator: [MyMeta new].

The system takes care to create new meta-objects as required using this block and it manages the association of meta-object to the entities requested.

Concurrency. Optionally, we can parametrize a link to execute a meta-object in its own thread.

link beConcurrent.

The link calling code is wrapped in a block that is then sent the message#forkto start a new process. We have not fully explored the potential to incorporate concurrency aspects in our MOP. We identify a potential to address these aspects in future work.

Inlining Properties. The last set of attributes that we describe are those related to code generation. They have no semantic meaning; they only change performance properties.

Both the meta-object and the condition can be either inlined in the bytecode or accessed via an indirection over the link. Either of those options has performance properties that can be beneficial depending on runtime usage. The default behavior is to inline both condition and meta-object.

When we change the meta-object or the condition of existing, installed links at runtime, all affected methods need to be recompiled. There-fore, if we plan to change the meta-object at runtime frequently, we can configure the link to be non-inlining. The unfortunate side-effect of that is a slight decrease in link-call performance, as any call to the meta-object (or the evaluation of the condition) is indirected via the link.

link inlineMeta: false.

link inlineCondition: false.

The decision not to inline should only be taken when it is sure that changes happen so frequently that recompiling would have a larger effect on performance than the indirection. An interesting property of our fully dynamic model is that we can switch the inlining behavior at runtime. There is no need to decide this up-front or have a link fixed to one behavior over its entire lifetime.

Access to Reified Data

We support various kinds of reified base level information that can be passed to the meta-level. Examples are the arguments passed to the method that is called on the meta-object. Table 5.1 shows all reifications available in the standard system. All these are defined using a plugin based architecture and can be thus extended by any user of the framework (see Section 5.5.2).

Many of the reifications are already mentioned in Chapter 3 such as the receiver and arguments of a message send. We have added some that open up interesting possibilities:

Link. We can request the link to be passed to the meta-object. In this way we can for example deactivate links from the meta-level or reflect in general on links.

Node. The node that the link is installed on. This allows the meta-object to reason about or even to annotate or modify the structure of a method.

Later in this chapter we see an example how this provides an easy way to implement a tracing tool for dynamic analysis.

Continuation. Sometimes, we want to abort the execution of the meta-level and return to the base. We can request a continuation to be created and passed to the meta-object. The continuation is an object that, when sent#valuewill continue execution of the base level code. The continuation is a true continuation. We based our implementation on the realization of continuations in Seaside, a continuation-based

Operation Reified Data Description All Nodes #context current stack-frame

#object the object

#class the class of the object

#control before, after or instead

#link the link itself

#node the node that the link is installed on

#continuation a continuation object

#process the current thread executing Message Send/ #arguments arguments as an array Method Evaluation #argX Xthargument

#sender sender object

#senderSelector sender selector

#receiver receiver object

#selector selector of method

#operation operation as object

#result returned result (after only) Block #arguments arguments as an array

#argX Xthargument

#result returned result (after only) Temp/InstVar Read #varname name of variable

#offset offset of variable

#value value of variable

#operation operation as object Assignment #varname name of variable

#offset offset of variable

#value value of variable

#operation operation as object

#newvalue new value (write only) Table 5.1: Supported reified data.

web-framework [51, 12]. We can, for example, store the continuation object in the meta-object before we return normally to the base level.

Later we can use the stored continuation to return from the meta-level again as many times as we like.

We specify the information to be passed to the meta-level with literal symbols which results in far more concise code then the dedicatedParameter class used in Chapter 3.

Links are not created to be specific to a certain kind of node. This is im-portant to provide the possibility of crosscutting not only class boundaries but even operations: we want one link to be installable on both message-sends and assignments, for example. But not all nodes support the same

reified data. For example, only message sends have a receiver. We therefore check at the time that the link is set as an annotation on a node if the link is compatible with the node.