[aspectc-user] context of a cflow pointcut?
daniel.lohmann at informatik.uni-erlangen.de
Mon Feb 19 14:27:21 CET 2007
Panu Bloigu wrote:
> Hello Daniel,
> thanks for taking the time to answer this. Could you please explain why
> the caller it self does not exist? Clearly there is an instance of B
> from which A::target() is called, isn't there?
Not that I am aware of...
To clarify this a bit: The "instance context" returned by that() is the
value (and type) of the this pointer at the calling position.
Actually, your code contains two calls to A::target();
1) A::target() is called from main(), which obviously has no object
instance context. This explains the error line:
test.acc:126: error: ‘void*’ is not a pointer-to-object type
This may be confusing, as the call is clearly not in the cflow of
B::wrapper(). However, it can be explained with the actual process of
pointcut evaluation. More on the background below.
> I'm inserting the call to
> the code of B::wrapper() with the execution pointcut, so I can't
> understand why there wouldn't be a pointer to an instance of B within
2) A::target() is called from within the execution advice of aspect
Test. The AspectC++ join-point model currently does not support
join-points from within code advice bodies. Hence the call in the
execution advice body is not considered as a potential join-point.
However, even if AspectC++ would consider it as a join-point, the code
would probably not yield the expected result. First, during the advice
execution we are before/after/around the execution of B::wrapper(),
thus not yet in the cflow of B::wrapper(). Second, the instance context
(this pointer) in an advice body is the aspect instance (of type Test),
hence there is no B at this calling position either.
Some more background with respect to 1)
You are matching with the pointcut:
call("void A::target()") && cflow(execution("void B::wrapper()"))
This pointcut does (semantically) not match 1), as the call from within
main() is not in the control flow of B::wrapper(). However, as the
cflow part of the pointcut expression is evaluated at runtime, advice
code has nevertheless to be generated (instantiated) for 1). (In theory
some module might invoke main() from within the cflow of B::wrapper.)
In the advice instance, the expression tjp->that() yields a void* to
indicate that there is no object instance.
While this is a principle problem of the ac++ code generation, you can
easily prevent such problems. Use the that() pointcut function for
further discrimination of join-points to those where a B instance is
advice call("void A::target()") && cflow(execution("void B::wrapper()"))
&& that(b) : before( B* b)
b->id(); // use context variable
tjp->that->id(); // use joinpoint API
Hope that helps
More information about the aspectc-user