[aspectc-user] Defining an Aspect Instantiation Model with ac++1.0

Olaf Spinczyk Olaf.Spinczyk at informatik.uni-erlangen.de
Fri Nov 11 15:52:41 CET 2005


Hi Dimple,

in the listing I've sent to you only the function Child1::xa1 prints 
"void Child1::xa1()\n". It is NOT the aspect. Therefore, I am pretty 
sure that everything works as expected. Here is the code fragment:

 > class Child1:public Parent_Impl {
 > public:
 >    Child1();
 >    ~Child1();
 >    void xa1();
 >    void a2();
 >    void a3();
 >
 > };
 >
 >
 > Child1::Child1():Parent_Impl()
 > {
 > }
 >
 > Child1::~Child1()
 > {
 > }
 >
 > void Child1::xa1()  { printf("void Child1::xa1()\n"); }
 > void Child1::a2() { printf("child1   a2\n"); }
 > void Child1::a3() { printf("void Child1::a3()\n"); }

BTW, it makes no sense to call tjp->proceed(), because this will perform 
the original *virtual* function call.

Best regards,

Olaf


Dimple wrote:
> Hi,
> Using this aspect 
> 
> aspect ChildInsteadOfParent {
>    advice call ("% Parent_Impl::a1()") : around () {
>      printf("redirecting call of %s to ", JoinPoint::signature());
>      ((Child1*)tjp->target ())->xa1 ();
>    }
>    advice call ("% Parent_Impl::a3()") : around () {
>      printf("redirecting call of %s to ", JoinPoint::signature());
>      ((Child1*)tjp->target ())->Child1::a3 ();
>    }
> };
> 
> The output is:
> 
> redirecting call of void Parent_Impl::a1() to void Child1::xa1()
> child1   a2
> redirecting call of void Parent_Impl::a3() to void Child1::a3()
> 
> it printing "redirecting call to child class and method" but it is not
> printing message that I have put in child method means it is not proceeding
> in Child1::xa1 method. 
> It should have print 
> child1 xa1 also
> 
> Means output should have been like this:
> 
> 1)redirecting call of void Parent_Impl::a1() to void Child1::xa1()
> 2)child1   xa1
> 3)child1   a2
> 4)redirecting call of void Parent_Impl::a3() to void Child1::a3()
> 5)child1   a3
> 
> Line 1,2 becoz of first advice 
> Line 3 Normal call no changes
> Line 4,5 becoz of second advice
> 
> Actually if I call tjp->proceed() in advice it calls parent method.
> And I tried doing tjp->target()->proceed() it is giving me some error :(.
> 
> 
> 
> -----Original Message-----
> From: Olaf Spinczyk [mailto:Olaf.Spinczyk at informatik.uni-erlangen.de] 
> Sent: Friday, November 11, 2005 2:33 AM
> To: dkaul at isis.vanderbilt.edu
> Cc: aspectc-user at aspectc.org
> Subject: Re: [aspectc-user] Defining an Aspect Instantiation Model with
> ac++1.0
> 
> Hi Dimple,
> 
> now I got it. You want to avoid the virtual function call if you know 
> the exact object type at compile time. This reminds me very much of my 
> work on "open components" some years ago. If you need some related work:
> 
> Andreas Gal, Wolfgang Schröder-Preikschat, Olaf Spinczyk, "Open 
> Components", Proceedings of the First OOPSLA Workshop on Language 
> Mechanisms for Programming Software Components, Tampa, Florida, 15th 
> Oktober 2001.
> 
> Now back to your problem: Your goal is to redirect a call to a virtual 
> function, i.e. a function that is defined in Parent_Impl, to another 
> function, which is defined in Child1. This can be achieved with the 
> following advice:
> 
>    advice call ("% Parent_Impl::a1()") : around () {
>      printf("redirecting call of %s to ", JoinPoint::signature());
>      ((Child1*)tjp->target ())->xa1 ();
>    }
> 
> The virtual function call to a1 will be completely replaced by the 
> non-virtual call to xa1. Here I used the name xa1 in Child1 instead of 
> a1 to make sure that the function is not virtual. A function with the 
> same name would also be virtual, because it overrides a virtual function 
> with the same name and argument types.
> 
> If you want the function in Child1 to have the same name, you can use a 
> scope operator. By this means a virtual function call mechanism is also 
> disabled. However, if there was another class derived from Child1 that 
> overrides the function again, this final specialization wouldn't be 
> called. Here is the advice:
> 
>    advice call ("% Parent_Impl::a3()") : around () {
>      printf("redirecting call of %s to ", JoinPoint::signature());
>      ((Child1*)tjp->target ())->Child1::a3 ();
>    }
> 
> Your next question will probably be: Is there any generic way to 
> redirect *all* calls to virtual functions of Parent_Impl to a function 
> with the same name in Child1? This is not possible with AspectC++ at the 
> moment.
> 
> Here is the complete listing:
> 
> #include <stdio.h>
> 
> class Parent_Impl {
> public:
>    Parent_Impl();
>    ~Parent_Impl();
>    virtual void a1();
>    virtual void a2();
>    virtual void a3();
> };
> 
> class Child:public Parent_Impl {
> public:
>    Child();
>    ~Child();
>    void a1();
>    void a2();
>    void a3();
> 
> };
> 
> Parent_Impl::Parent_Impl()
> {
> }
> 
> Parent_Impl::~Parent_Impl()
> {
> }
> 
> void Parent_Impl::a1()
> {
>   printf("parent a1\n");
> 
> }
> 
> void Parent_Impl::a2()
> {
>   printf("parent a2\n");
> }
> 
> void Parent_Impl::a3()
> {
>   printf("parent a3\n");
> }
> redirecting call of void Parent_Impl::a1() to void Child1::xa1()
> child1   a2
> redirecting call of void Parent_Impl::a3() to void Child1::a3()
> 
> Child::Child():Parent_Impl()
> {
> }
> 
> Child::~Child()
> {
> }
> 
> 
> void Child::a1()
> {
>      printf("child a1\n");
> }
> 
> void Child::a2()
> {
>      printf("child a2\n");
> }
> 
> void Child::a3()
> {
>      printf("child a3\n");
> }
> 
> class Child1:public Parent_Impl {
> public:
>    Child1();
>    ~Child1();
>    void xa1();
>    void a2();
>    void a3();
> 
> };
> 
> 
> Child1::Child1():Parent_Impl()
> {
> }
> 
> Child1::~Child1()
> {
> }
> 
> void Child1::xa1()  { printf("void Child1::xa1()\n"); }
> void Child1::a2() { printf("child1   a2\n"); }
> void Child1::a3() { printf("void Child1::a3()\n"); }
> 
> int main ()
> {
>    Parent_Impl *r_impl = new Child1();
>    r_impl->a1();
>    r_impl->a2();
>    r_impl->a3();
>    return 0;
> }
> 
> aspect ChildInsteadOfParent {
>    advice call ("% Parent_Impl::a1()") : around () {
>      printf("redirecting call of %s to ", JoinPoint::signature());
>      ((Child1*)tjp->target ())->xa1 ();
>    }
>    advice call ("% Parent_Impl::a3()") : around () {
>      printf("redirecting call of %s to ", JoinPoint::signature());
>      ((Child1*)tjp->target ())->Child1::a3 ();
>    }
> };
> 
> The output is:
> 
> redirecting call of void Parent_Impl::a1() to void Child1::xa1()
> child1   a2
> redirecting call of void Parent_Impl::a3() to void Child1::a3()
> 
> What do you think about this solution?
> 
> - Olaf
> 
> 
> Dimple wrote:
>>Hi,
>>
>>There are different classes like "Child" and "Child1" with various
>>functionalities.
>>To work transparently across all frameworks, an abstract base class called
>>"Parent_Impl" has been added that delegates to concreter subclasses via
>>virtual method calls.
>>
>>I want to specialize my framework with a concrete subclass (i.e., a
> subclass
>>with no virtual methods) and thus eliminate the generality by using a
>>particular child instance directly.
>>For example I know child class Child1 is to be used, I want to define that
>>in my aspect and thus bypass parent.
>>
>>Hope I have made things little clearer :)
>>
>>Thanks,
>>Dimple 
>>
>>
>>-----Original Message-----
>>From: Olaf Spinczyk [mailto:Olaf.Spinczyk at informatik.uni-erlangen.de] 
>>Sent: Thursday, November 10, 2005 11:29 AM
>>To: dkaul at isis.vanderbilt.edu
>>Cc: aspectc-user at aspectc.org
>>Subject: Re: [aspectc-user] Defining an Aspect Instantiation Model with
>>ac++1.0
>>
>>Hi,
>>
>>sorry for the late answer.
>>
>>I have to say that I don't understand what you want to achieve. 
>>Redirecting the execution of parent functions to child functions sounds 
>>like the normal late binding mechanism with virtual functions. Do you 
>>want to achieve the same without having to declare the functions as 
>>'virtual'?
>>
>>Please describe your goal a bit more precise.
>>
>>- Olaf
>>
>>
>>Dimple wrote:
>>>Hi Olaf,
>>>I have read your AspectC++ 2005 tutorial slides and 
>>>I have been trying to implement aspects for the attached example program.
>>>Based on your example code 
>>>aspect AlwaysDoThirdBeforeSecond {
>>>  advice execution("void C1::second()") : before () {
>>>    tjp->that ()->third ();
>>>  }
>>>};
>>>I tried all different types advices.
>>>However, in this scenario I wanted to call child class instead of parent
>>>class. I am not sure if this is possible in AspectC++.
>>>I also tried using Ordering of aspects and using around for parent but
>>that
>>>is also not working.
>>>
>>>Plz see enclosed example code.
>>>Thanks,
>>>Dimple
>>>
>>>
>>>-----Original Message-----
>>>From: Olaf Spinczyk [mailto:Olaf.Spinczyk at informatik.uni-erlangen.de] 
>>>Sent: Friday, November 04, 2005 2:26 AM
>>>To: dkaul at isis.vanderbilt.edu
>>>Subject: Re: [aspectc-user] Defining an Aspect Instantiation Model with
>>>ac++1.0
>>>
>>>Hi,
>>>
>>>you could use the following aspect:
>>>
>>>aspect DoThirdBeforeSecondInMain {
>>>  advice call("void C1::second()") && within("int main()") : before () {
>>>    tjp->target ()->third ();
>>>  }
>>>};
>>>
>>>It matches all calls to second that are located within main.
>>>
>>>If you *always* want third to be executed before second, you could also
>>use:
>>>aspect AlwaysDoThirdBeforeSecond {
>>>  advice execution("void C1::second()") : before () {
>>>    tjp->that ()->third ();
>>>  }
>>>};
>>>
>>>This one call third before every execution of second.
>>>
>>>I hope this helps. Did you already read out AOSD 2005 tutorial slides? 
>>>They contain a step-by-step introduction into the pointcut language.
>>>
>>>Olaf
>>>
>>>PS: You've sent your mail to (CC:) "aspectc-user-bounces at aspectc.org". 
>>>This is probably not what you wanted. The mailing list is 
>>>aspectc-user at aspectc.org.
>>>
>>>
>>>Dimple wrote:
>>>>Hi Olaf,
>>>>I was trying out one example code
>>>>
>>>>#include <stdio.h>
>>>>
>>>>// ------------------------------- normal C++
> ----------------------------
>>>>class C1 {
>>>>public:
>>>>void first()  { printf("First\n"); }
>>>>void second() { printf("Second\n"); }
>>>>void third() { printf("Third\n"); }
>>>>};
>>>>
>>>>int main () {
>>>>C1 c1;
>>>>
>>>>c1.first();
>>>>
>>>>
> printf("**************************************************************\n\n")
>>>>;
>>>>c1.second();
>>>>}
>>>>
>>>>
>>>>I wanted to figure out how I can do this in aspectc++
>>>>What I want is I want to run c1.first() normally, then I want to call
>>>>c1.third() before c1.second(). 
>>>>Means to say that I want to insert c1.third() method between c1.first()
>>>and
>>>>c1.second().
>>>>I checked all the examples given in aspectC++ but could not figure out
> how
>>>>to do it.
>>>>
>>>>Thanks in advance,
>>>>Dimple
>>>>
>>>>
>>>>
>>>>-----Original Message-----
>>>>From: aspectc-user-bounces at aspectc.org
>>>>[mailto:aspectc-user-bounces at aspectc.org] On Behalf Of Olaf Spinczyk
>>>>Sent: Wednesday, November 02, 2005 9:41 AM
>>>>To: Sergio Queiroz
>>>>Cc: aspectc-user at aspectc.org
>>>>Subject: Re: [aspectc-user] Defining an Aspect Instantiation Model with
>>>>ac++1.0
>>>>
>>>>Hi,
>>>>
>>>>the bug has number 267 in bugzilla and I've just fixed it.
>>>>
>>>>Thanks again for reporting this problem!
>>>>
>>>>Olaf
>>>>
>>>>
>>>>Olaf Spinczyk wrote:
>>>>>Hi Sergio,
>>>>>
>>>>>I tried to compile your example and got the following error message:
>>>>>
>>>>><ac>: In member function `void 
>>>>>TJP__ZN6DCache16page_replacementEv_0::proceed()
>>>>>':
>>>>><ac>:26: error: `_that' undeclared (first use this function)
>>>>>
>>>>>Did you mean this problem? It seems to be a code generation bug :-(. The
> 
>>>>>member _that is referenced but not generated.
>>>>>
>>>>>As a workaround (until 1.0pre2) you can add the following line to your 
>>>>>execution/around advice:
>>>>>
>>>>>if (0) tjp->proceed()
>>>>>
>>>>>After adding this line I was able to compile your example.
>>>>>
>>>>>-Olaf
>>>>>
>>>>>
>>>>>Sergio Queiroz wrote:
>>>>>>Hi!
>>>>>>
>>>>>>I downloaded the new AspectC++ version and I was trying to compile 
>>>>>>some code
>>>>>>that worked pretty nice with version 0.92.
>>>>>>
>>>>>>The problem is that ac++ 1.0 could not compile my examples :(
>>>>>>
>>>>>>I tried to reduce the source code and I am sending my files, some
>>problem
>>>>>>occurred during parsing. I am using linux.
>>>>>>
>>>>>>This is the output of the command "g++ -v":
>>>>>>
>>>>>>Reading specs from /usr/lib/gcc-lib/i486-linux/3.3.5/specs
>>>>>>Configured with: ../src/configure -v
>>>>>>--enable-languages=c,c++,java,f77,pascal,objc,ada,treelang
> --prefix=/usr
>>>>>>--mandir=/usr/share/man --infodir=/usr/share/info
>>>>>>--with-gxx-include-dir=/usr/include/c++/3.3 --enable-shared 
>>>>>>--with-system-zlib
>>>>>>--enable-nls --without-included-gettext --enable-__cxa_atexit
>>>>>>--enable-clocale=gnu --enable-debug --enable-java-gc=boehm
>>>>>>--enable-java-awt=xlib --enable-objc-gc i486-linux
>>>>>>Thread model: posix
>>>>>>gcc version 3.3.5 (Debian 1:3.3.5-8)
>>>>>>
>>>>>>
>>>>>>
>>>>>>Sérgio
>>>>>>
>>>>>>
>>>>>>
>>>>>>-----------------------------------------------------------------------
> -
>>>>>>#include "DCache.h"
>>>>>>
>>>>>>void DCache::doit()
>>>>>>{
>>>>>> total_cycles++;
>>>>>> 
>>>>>>}
>>>>>>
>>>>>>void DCache::reset()
>>>>>>{        total_cycles = 0;
>>>>>>}
>>>>>>
>>>>>>
>>>>>>int DCache::page_replacement()
>>>>>>{
>>>>>> return 0;
>>>>>>}
>>>>>>
>>>>>>
>>>>>>
>>>>>>-----------------------------------------------------------------------
> -
>>>>>>#ifndef DCACHE_H
>>>>>>#define DCACHE_H
>>>>>>
>>>>>>#include "systemc.h"
>>>>>>#include <iostream.h>
>>>>>>
>>>>>>SC_MODULE (DCache)
>>>>>>{
>>>>>>sc_in<bool> clock;
>>>>>>   void doit();
>>>>>>void reset();
>>>>>>int page_replacement();
>>>>>>   float total_cycles;
>>>>>>       SC_CTOR(DCache)
>>>>>>  {
>>>>>>      reset();
>>>>>>               SC_METHOD(doit);
>>>>>>      sensitive_pos << clock;
>>>>>>  }
>>>>>>};
>>>>>>
>>>>>>#endif
>>>>>>
>>>>>>
>>>>>>-----------------------------------------------------------------------
> -
>>>>>>#include "DCache.h"
>>>>>>
>>>>>>int
>>>>>>sc_main (int argc, char **argv) {
>>>>>> sc_signal <bool> clock;
>>>>>> 
>>>>>> DCache dcache ("dcache");
>>>>>> dcache.clock (clock);
>>>>>> 
>>>>>> int i = 0;
>>>>>>
>>>>>> sc_initialize ();
>>>>>> 
>>>>>> while (i++ < 10) {
>>>>>>     clock.write (0);
>>>>>>
>>>>>>     cout << dcache.page_replacement () << endl;
>>>>>>    
>>>>>>     clock.write (1);
>>>>>> }
>>>>>> 
>>>>>> return 0;
>>>>>>}
>>>>>>
>>>>>>
>>>>>>-----------------------------------------------------------------------
> -
>>>>>>_______________________________________________
>>>>>>aspectc-user mailing list
>>>>>>aspectc-user at aspectc.org
>>>>>>http://www.aspectc.org/mailman/listinfo/aspectc-user
>>>>>_______________________________________________
>>>>>aspectc-user mailing list
>>>>>aspectc-user at aspectc.org
>>>>>http://www.aspectc.org/mailman/listinfo/aspectc-user
>>>>_______________________________________________
>>>>aspectc-user mailing list
>>>>aspectc-user at aspectc.org
>>>>http://www.aspectc.org/mailman/listinfo/aspectc-user
>>>>
>>>>
>>>------------------------------------------------------------------------
>>>
>>>#include <stdio.h>
>>>aspect ChildInsteadOfParent 
>>>{
>>>
>>> pointcut Parent_Methods () = "% Parent_Impl::%(...)";
>>> pointcut Child_Methods () = "% Child::%(...)";
>>>
>>>//advice call(Parent_Methods()) || call (Child_Methods()):around() //
>>Nothing is displayed
>>>//advice call (Parent_Methods()) :before()
>>> //advice execution (Parent_Methods ()) && target (Child_Methods
>>()):around()
>>> advice execution (Parent_Methods ()):around()
>>> {
>>>   printf("Signature is  %s\n", JoinPoint::signature());
>>>   tjp->proceed();
>>>   //printf("Result is  %s\n", tjp->result());
>>> }
>>>};
>>>
>>>
>>>class Parent_Impl {
>>>public:
>>> Parent_Impl();
>>> ~Parent_Impl();
>>> virtual void a1(); 
>>> virtual void a2(); 
>>> virtual void a3(); 
>>>};
>>>
>>>class Child:public Parent_Impl {
>>>public:
>>> Child();
>>> ~Child();
>>> void a1();
>>> void a2();
>>> void a3();
>>>
>>>};
>>>
>>>Parent_Impl::Parent_Impl()
>>>{
>>>}
>>>
>>>Parent_Impl::~Parent_Impl()
>>>{
>>>}
>>>
>>>void Parent_Impl::a1()
>>>{
>>>printf("parent a1\n");
>>>
>>>}
>>>
>>>void Parent_Impl::a2()
>>>{
>>>printf("parent a2\n");
>>>}
>>>
>>>void Parent_Impl::a3()
>>>{
>>>printf("parent a3\n");
>>>}
>>>
>>>Child::Child():Parent_Impl()
>>>{
>>>}
>>>
>>>Child::~Child()
>>>{
>>>}
>>>
>>>
>>>void Child::a1() 
>>>{ 
>>>   printf("child a1\n");
>>>}
>>>
>>>void Child::a2()
>>>{ 
>>>   printf("child a2\n");
>>>}
>>>
>>>void Child::a3()
>>>{ 
>>>   printf("child a3\n");
>>>}
>>>
>>>class Child1:public Parent_Impl {
>>>public:
>>> Child1();
>>> ~Child1();
>>> void a1();
>>> void a2();
>>> void a3();
>>>
>>>};
>>>
>>>
>>>Child1::Child1():Parent_Impl()
>>>{
>>>}
>>>
>>>Child1::~Child1()
>>>{
>>>}
>>>
>>>void Child1::a1()  { printf("child1   a1\n"); }
>>>void Child1::a2() { printf("child1   a2\n"); }
>>>void Child1::a3() { printf("child1   a3\n"); }
>>>
>>>int main () 
>>>{
>>> //Parent_Impl *r_impl = new Child1();
>>> Parent_Impl *r_impl= new Parent_Impl();
>>> r_impl->a1();
>>> r_impl->a2();
>>> r_impl->a3();
>>>	 
>>> return 0;
>>>}
>>
> 
> 
> 
> _______________________________________________
> aspectc-user mailing list
> aspectc-user at aspectc.org
> http://www.aspectc.org/mailman/listinfo/aspectc-user




More information about the aspectc-user mailing list