ac lang survey

7
 AspectC++ – A Language Overview c 2005 Olaf Spinczyk <os@aspectc .org> Friedrich-Alex ander Univ ersity Erlangen-Nure mberg Computer Science 4 May 20, 2005 This is an overview about the AspectC++ language, an aspect-oriented extension for C/C+ +, prepa red for the Europ ean AOSD Network of Excel lence . Detai led infor matio n on AspectC++ including manuals and tutorial slides with lots of examples is available from the AspectC++ Project Homepage . The overv iew is based on the documentat ion for AspectC+ + 0.9.3. The languag e is still “work in progress”. Joinpoint Model and Pointcut Language AspectC++ supports static joinpoints as well as dynamic joinpoints. While static join- points are named entities in the static program structure, dynamic joinpoints are events that happen during the program execution. Static Joinpoints The following kinds of C++ program entities are considered as static joinpoints: classes, structs, and unions namespaces all kinds of functions (member, non-member, operator, conversion, etc.) Static joinpoints are described by match expressions. For example, "% ...::foo(...)" is a match expression that describes all functions called foo (in any scope, with any argu ment list, and any result type). More informa tion on match expre ssion s is giv en belo w. Note that not all of thes e static joinpoi nt types are currently supp orted as a target of advice (see section ’Advice for Static Joinpoints’). Dynamic Joinpoints The following kinds of events that might happen during the execution of a program are considered as dynamic joinpoints: function call 1

Upload: idkwhii

Post on 05-Apr-2018

218 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Ac Lang Survey

7/31/2019 Ac Lang Survey

http://slidepdf.com/reader/full/ac-lang-survey 1/7

 AspectC++ – A Language Overview

c2005 Olaf Spinczyk <[email protected]>

Friedrich-Alexander University Erlangen-Nuremberg

Computer Science 4

May 20, 2005

This is an overview about the AspectC++ language, an aspect-oriented extension forC/C++, prepared for the European AOSD Network of Excellence. Detailed information

on AspectC++ including manuals and tutorial slides with lots of examples is available

from the AspectC++ Project Homepage.

The overview is based on the documentation for AspectC++ 0.9.3. The language is

still “work in progress”.

Joinpoint Model and Pointcut Language

AspectC++ supports static joinpoints as well as dynamic joinpoints. While static join-

points are named entities in the static program structure, dynamic joinpoints are events

that happen during the program execution.

Static Joinpoints

The following kinds of C++ program entities are considered as static joinpoints:

• classes, structs, and unions

• namespaces

• all kinds of functions (member, non-member, operator, conversion, etc.)

Static joinpoints are described by match expressions. For example, "% ...::foo(...)"

is a match expression that describes all functions called foo (in any scope, with anyargument list, and any result type). More information on match expressions is given

below. Note that not all of these static joinpoint types are currently supported as a

target of advice (see section ’Advice for Static Joinpoints’).

Dynamic Joinpoints

The following kinds of events that might happen during the execution of a program are

considered as dynamic joinpoints:

• function call

1

Page 2: Ac Lang Survey

7/31/2019 Ac Lang Survey

http://slidepdf.com/reader/full/ac-lang-survey 2/7

AspectC++ Language Overview

• function execution

• object construction

• object destruction

The description of dynamic joinpoints is based upon the description mechanism for

static joinpoints in conjunction with joinpoint type specific pointcut functions. For

example:

• call("% ...::foo(...)")

• execution("float MathFuncs::%(float)")

• construction("SomeClassName")

• destruction("A"||"B")

While "% ...::foo(...)" represents a set of static joinpoints, i.e. all functions called

foo, the expression call("% ...::foo(...)") describes all calls to these functions.

A similar mapping from static to dynamic joinpoints is done by the execution(),

construction(), and destruction() pointcut functions.

Pointcut Functions

Further pointcut functions are used to filter or select joinpoints with specific properties.

Some of them can be evaluated at compile time while others yield conditions that have

to be checked at run time:

• cflow ( pointcut) – captures all joinpoints in the dynamic execution context

of the joinpoints in pointcut .

• base( pointcut) and derived ( pointcut) – yield classes based on queries

in the class hierarchy

• within( pointcut) – filters joinpoints depending on their lexical scope

• that(type pattern), target(type pattern), result(type pattern),

and args(type pattern) – filters joinpoints depending on the current object

type, the target object type in a call, and the result and arguments types of a

dynamic joinpoint.

• &&, ||, ! – intersection, union, and exclusion of joinpoints in pointcuts

Instead of the type pattern it is also possible to pass the name of a context variable to

which context information from the joinpoint shall be bound. In this case the type of 

the context variable is used for the type matching.

c2005 Olaf Spinczyk 2

Page 3: Ac Lang Survey

7/31/2019 Ac Lang Survey

http://slidepdf.com/reader/full/ac-lang-survey 3/7

AspectC++ Language Overview

Match Mechanism Capabilities

The match mechanism provides % and ... as wildcard symbols. Thereby the following

features are supported:

• pattern based name matching, e.g. "%X%" matches all names that contain an up-percase X

• flexible scope matching, e.g. "Foo::...::Bar" matches Bar in the scope Foo or

any of its nested scopes

• flexible matching of function argument type lists, e.g. "% foo(...,int)" matches

foo with an int as its last argument type

• matching template argument lists, e.g. "C<T,...>" matches an instance of the

class template C with a first template argument type T

• type patterns, e.g. "const % *" matches all pointer types that reference objects

of a constant type

Named Pointcuts

Pointcut expressions can be given a name. The definition of a named pointcut can be

placed in any aspect, class, or namespace. The mechanism can be used for dynamic as

well as static joinpoints. For example:

class O S t re a m {

// ...

 pointcut m a n i pu l a t o r_ t y p es ( ) = " h e x " | | " oc t " | | " b in " | | " e n dl " ;

};

In the context of an aspect, named pointcuts can also be defined as virtual or pure

virtual, which allows refinement/definition in a derived aspect (see example at the end

of this overview).

Advice Model and Language

Advice for Static Joinpoints

The only kind of advice for static joinpoints that is currently supported by AspectC++

is the introduction. By using this kind of advice the aspect code is able to add newelements to classes, structures, or unions. Everything that is syntactically permitted in

the body of a C++ class can be introduced by advice:

• attribute introduction, e.g. advice "AClass" : int _introduced_attribute;

• type introduction, e.g. advice "AClass" : typedef int INT;

• member function introduction, e.g. advice "AClass" : void f();

• nested type introduction, e.g. advice "AClass" : class Inner { ... };

• constructor introduction, e.g. advice "AClass" : AspectName(int, double);

c2005 Olaf Spinczyk 3

Page 4: Ac Lang Survey

7/31/2019 Ac Lang Survey

http://slidepdf.com/reader/full/ac-lang-survey 4/7

AspectC++ Language Overview

• destructor introduction, e.g. advice "AClass" : ~AspectName() { ... }

• base class introduction, e.g. advice "AClass" : baseclass(ANewBaseclass);

The syntax advice <target- pointcut> : <introduction> supports the intro-

duction of an element into an arbitrary set of target classes with a single advice.

Advice for Dynamic Joinpoints

Advice for dynamic joinpoints is used to affect the flow of control, when the joinpoint

is reached. The following kinds of advice are supported:

• before advice

• after advice

• around advice

These advice types can orthogonally be combined with all dynamic joinpoint types.

Advice for dynamic joinpoints is defined with the following syntax:

advice <target-pointcut> : ( before|after|around) (<arguments>) {

<advice-body >

}

While the before and after advice bodies are executed before or after the event de-

scribed by <target-pointcut>, an around advice body is executed instead of theevent.

Advice Language and Joinpoint API

The advice body is implemented in standard C++. Additionally, the joinpoint API 

can be used to access (read and write) context information (e.g. function argument

and result values) as well as static type information about the current joinpoint. To

access the joinpoint API the object JoinPoint *tjp can be used, which is implicitly

available in advice code. Advice that uses the static type information provided by the

 joinpoint API is called generic advice. This concept is the key for generic, type-safe,

and  efficient advice in AspectC++. The static type information from the joinpoint

API can even be used to instantiate template metaprograms, which is a technique for joinpoint specific code generation at compile time.

The joinpoint API is also used to proceed the execution from within around advice

(tjp->proceed()). Alternatively, tjp->action() may be called to retrieve and store the

 proceed context  as an AC::Action object. Later, action.trigger() may be called to

proceed the intercepted flow of control.

Catching and changing exceptions can be done by standard C++ features in around

advice (try, catch, throw).

c2005 Olaf Spinczyk 4

Page 5: Ac Lang Survey

7/31/2019 Ac Lang Survey

http://slidepdf.com/reader/full/ac-lang-survey 5/7

AspectC++ Language Overview

Example

The following advice is generic advice, because its implementation can deal with mul-

tiple overloaded C::foo(...) implementations that have different result types:

advice execution( " % C : : fo o ( .. . ) " ) : around () {

c o ut < < " e x e c ut i n g " < < J o i n Po i n t : : s i gn a t u re ( )

< < " on " < < * tjp- > t ha t () < < e nd l ;

tjp- > p r o ce e d ( ) ;

c ou t < < " th e r es ul t w as " < < *tjp- > r es u lt ( ) < < e nd l ;

}

Aspect Module Model

The following example code shows an aspect Logging defined in AspectC++:

aspect L o g gi n g {

o s t re a m * _ o u t ; // ordinary attributes

 public:

void b i nd _ st r ea m ( o st r ea m * o ) { _ ou t = o ; } // member function

 pointcut virtual l o g g e d_ c l a ss e s ( ) = 0 ; // pure virtual pointcut

// some advice

advice execution( " % . . . : :% ( . . . ) " ) & & within( l o g g e d _c l a s se s ( ) ) :

before () {

* _ ou t < < " e x ec u ti n g " < < J o in P oi n t :: s i gn a tu r e ( ) < < e nd l ;

}

};

Aspects are the language element that is used to group all the definitions that are needed

to implement a crosscutting concern. An aspect definition is allowed to contain mem-

ber functions, attributes, nested classes, named pointcuts, etc. as ordinary classes.

Additionally, aspects normally contain advice definitions.

Aspects that contain pure virtual member functions or pure virtual pointcuts are called

abstract aspects. These aspects only affect the system if a (concrete) aspect is derived,

which defines an implementation for the pure virtual functions and the pure virtual

pointcuts. Abstract aspects are the AspectC++ mechanism to implement reusable as-

pect code.

Aspect inheritance is slighly restricted. Aspects can inherit from ordinary classes and

abstract aspects but not from concrete aspects. Derived aspects can redefine virtualpointcuts and virtual functions defined by base aspects.

Aspect Instantiation Model

By default, aspects are singletons, i.e. there is one global instance automatically created

for each non-abstract aspect in the program. However, by defining the aspectof() static

member function of an aspect the user can implement arbitrary instantiation schemes,

such as per-target , per-thread , or per-joinpoint . For each dynamic joinpoint that is

affected by the aspect the aspectof() function has to return the right aspect instance

c2005 Olaf Spinczyk 5

Page 6: Ac Lang Survey

7/31/2019 Ac Lang Survey

http://slidepdf.com/reader/full/ac-lang-survey 6/7

AspectC++ Language Overview

on which the advice bodies are invoked. The instances themselfs are usually created

with the introduction mechanism. The aspectof() function has access to the joinpointAPI in order to find the right aspect instance for the current joinpoint. Here is an

example:

aspect I n s t a n c e P e r T a r g e t A s p e c t {

 pointcut t a r g et _ c l a ss ( ) = " T a r g e tN a m e " ;

// an attribute of the aspect (stored per target)

int _ c a l l s ;

// aspect instance created by introduction:

advice t a r g et _ c l as s ( ) : I n s t a nc e P e r Ta r g e t As p e c t _ i n s ta n c e ;

// definition of the instantiation scheme in aspectof():

static I n s t a nc e P e r Ta r g e t As p e c t * a s p e c to f ( ) {

return tjp- > t a r g e t ( ) - > _ i n s t a n c e ;

}// the advice

advice call( " % . . . : :% ( . . . ) " ) & & t a r ge t ( t a r g e t_ c l a ss ( ) ) : before () {

 _c al ls ++ ;

}

// attribute initialization in the aspect constructor 

I n s t a nc e P e r Ta r g e t As p e c t ( ) : _ c a ll s ( 0 ) { }

};

Aspect Composition Model

In AspectC++ any number of aspects can be used in the same application. Aspect com-position is currently restricted to inheritance from abstract aspects. Concrete aspects

cannot be used for the implementation of new aspects.

Aspect interactions can be handled by the developer on a per joinpoint basis with or-

der advice, e.g. advice execution("void f%(...)") : order("Me", !"Me") gives

the aspect Me the highest precedence at all joinpoint described by the pointcut expres-

sion. Order advice can be given by any aspect for any aspect, thus can be separated

from the affected aspects. Aspect names in order advice declarations are match expres-

sions and may contain wildcards, e.g. order("kernel::%", !"kernel::%") gives every

aspect declared in the namespace kernel precedence over all other aspects. Besides this

partial order in the precedence of aspects, the precedence of advice within one aspect

is determined according to its position in the aspect definition. As long as it does not

conflict with order advice AspectC++ aims to give aspects the same precedence at all

 joinpoints.

Aspect Weaving Model

The only implementation of AspectC++ is based on static source to source transforma-

tion. Nevertheless, the language could also be used for dynamic weavers if some really

hard technical challenges like runtime introductions were solved.

c2005 Olaf Spinczyk 6

Page 7: Ac Lang Survey

7/31/2019 Ac Lang Survey

http://slidepdf.com/reader/full/ac-lang-survey 7/7

AspectC++ Language Overview

Example

A reusable observer pattern implementation in AspectC++:

aspect O b s e rv e r P a tt e r n {

// Data structures to manage subjects and observers

.. .

 public:

// Interfaces for each role

struct I S u bj e c t { } ;

struct I O b s er v e r {

virtual void u p da t e ( IS u bj e ct * ) = 0 ;

};

// To be defined by the concrete derived aspect

 pointcut virtual o b se r ve r s ( ) = 0 ;

 pointcut virtual s u bj e ct s ( ) = 0 ;

// subjectChange() matches all non-const methods by default

 pointcut virtual s u b j e ct C h a n ge ( ) =

execution( " % . . .: : %( . .. ) " & & ! " % . . .: : %( . .. ) c on s t ")

&& within( s u b j e c t s ( ) ) ;

// Add new baseclass to each subject/observer class

// and insert code to inform observers

advice o b s e rv e r s ( ) : baseclass( I O b s e r v e r ) ;

advice s u b je c t s ( ) : baseclass( I S u b j e c t ) ;

advice s u b j ec t C h an g e ( ) : after () {

I S u bj e c t * s u b je c t = tjp- > t h a t ( ) ;

u p d a t e O b s e r v e r s ( s u b j e c t ) ;}

// Operations to add, remove and notify observers

void u p d a te O b s e rv e r s ( I S u b je c t * s u b ) { . . . }

void a d dO b se r ve r ( I Su b je c t * s ub , I O bs e rv e r * o b ) { . . . }

void r e mO b se r ve r ( I Su b je c t * s ub , I O bs e rv e r * o b ) { . . . }

};

Concrete aspect, which applies the pattern:

#include " O b s e r v e r P a t t e r n . a h "

#include " C l o c k T i m e r . h "

aspect C l o c kO b s e rv e r : public O b s e rv e r P a tt e r n {// define the pointcuts

 pointcut s ub je ct s () = " C lo ck Ti me r ";

 pointcut o b s e rv e r s ( ) = " D i g it a l C lo c k " | | " A n a lo g C l oc k " ;

 public:

advice o b s e rv e r s ( ) :

void u p d at e ( O b s e rv e r P a tt e r n : : I S ub j e c t * s u b ) {

D r a w ( ) ;

}

};

c2005 Olaf Spinczyk 7