[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