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

Dimple dkaul at isis.vanderbilt.edu
Fri Nov 11 15:39:51 CET 2005


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;
>>}
> 
> 






More information about the aspectc-user mailing list