9.2. CHARACTERISTICS OF TRACE-BASED ASPECTSTrace-based aspects have two main characteristics. First, aspects are defined over sequences of observable execution states. Second, weaving is more naturally performed on executions rather than program code. The weaver can be seen as a monitor interleaving the execution of the base program and execution of inserts.[1]
9.2.1. Observable Execution TraceThe base program execution is modeled by a sequence of observable execution states (a.k.a. join points). This trace can be formally defined on the basis of small-step semantics [16] of the programming language. Each join point is an abstraction of the execution state. Join points may denote not only syntactic information (e.g., instructions) but also semantic information (e.g., dynamic values). For example, when the user Bob logs in, the function login() is called in the base program with "Bob" as a parameter. This join point of the execution can be represented by the term login("Bob"). 9.2.2. Aspect LanguageThe basic form of an aspect is a rule of the form C C is a crosscut and I is an insert. The insert I is executed whenever the crosscut C matches the current join point. Basic aspects can be combined using operators (sequence, repetition, choice, etc.) to form stateful aspects.
isLogin addLog( In order to build stateful aspects, basic aspects can be combined using control operators. Using a C-like syntax, we can define an aspect that logs all sessions as follows: while(true){ isLogin addLog( This definition applies the basic security aspect again and again. Control operators allow us to define sophisticated aspects on execution traces. For instance, the following aspect tracks sequences of sessions (login followed by logout). In general, several aspects addressing different issues (e.g., debugging and profiling) can be composed (using a parallel operator ||) and woven together. The weaver takes a parallel composition of n aspects A1 ||...|| An and tries to apply each of them (in no specific order) at each join point of the execution trace. Conceptually, the weaver is an execution monitor that selects the current basic aspects of A1,..., An and tries to apply them at each join point. When a crosscut matches the current join point, the corresponding insert is executed. After all basic aspects have been considered, the base program execution is resumed and proceeds until the next join point. When a basic aspect of a stateful aspect Ai has been applied and its insert executed, the state of Ai evolves. The control structure of Ai (e.g., repetition or sequence) specifies which basic aspect must be considered next. For instance, the previous security aspect remains in its initial state until a login occurs. After the aspect has matched a login event, it waits to match a logout event before returning to its initial state. In the remainder of this chapter, we instantiate this framework to form a variety of different definitions of crosscuts, inserts, and stateful aspects. We thereby obtain different aspect languages and enable reasoning about aspect-oriented programs, both manually and, using static analysis techniques, automatically. |