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

Olaf Spinczyk Olaf.Spinczyk at informatik.uni-erlangen.de
Sat Nov 12 13:29:23 CET 2005


Hi,

AspectC++ supports advice for the construction and destruction of 
objects with the pointcut functions "construction" and "destruction". 
"construction" advice can be understood as advice for the execution of 
the constructor *after* the base classes and attributes listed in the 
base class init list have been initialized.

- Olaf

Dimple wrote:
>Hi Olaf,
>Does new version of AspectC++ support replacing of Constructors or
>Destructors using aspect?
>class Parent1;
>class Parent2;
>I want to use Parent2 class in place of Parent1. is this supported?
>
>Thanks,
>Dimple
>
>
>
>-----Original Message-----
>From: Olaf Spinczyk [mailto:Olaf.Spinczyk at informatik.uni-erlangen.de] 
>Sent: Friday, November 11, 2005 8:53 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,
>
>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
>>    
>
>
>
>_______________________________________________
>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