OW2 Consortium
Search OW2 Mail Archive: 

Advanced Search - Powered by Google


Mail Archive Home | asm List | November 2008 Index

<--  Date Index  --> <--  Thread Index    

[asm] Re: pattern for wrapping methods


Hi Walter,

I didn't know whether I understand your problem correctly, but
I'm not sure whether you need to forward every instruction to
both method visitors.

I would suggest to build the strategy adapter using the follow-
ing pattern. But I'm not sure if this really fits your needs.

public class StrategyAdapter extends ClassAdapter {

  public MethodVisitor visitMethod(int access, String name,
      String desc, String sign, String[] excepts) {
     // FIXME: select wrapper ...
     this.createWrapperX(access, name, desc, sign, excepts);
     ...
     return super.visitMethod(access, "_" + name, desc, sign,
       excepts);
  }

  public void createWrapperX(int access, String name, String desc,
      String sign, String[] excepts) {
     MethodVisitor mv = this.cv.visitMethod(access, name, desc,
       sign, excepts);
     if (mv != null) {
        mv.visitCode();
        ... other changes ...
        mv.visitVarInsn(ALOAD, 0);
        Type[] args = Type.getArgumentTypes(desc);
        for (int index = 0; index < args.length; index++) {
          // FIXME: load local variables!
          mv.visitVarInsn(xLOAD, index);
        }
        mv.visitMethodInsn(ACC_PRIVATE, "_" + name, desc, sign,
          excepts);
        ... other changes ...
        // FIXME: change return type!
        mv.visitInsn(RETURN);
        mv.visitMaxs(args.length ..., args.length ...);
        mv.visitEnd();
      }
    }
  }
}

If necessary it is also possible to chain multiple wrapping
calls or modify the wrapping call according to your needs.

Best regards,

Tronje

Walter Harley wrote:
> Looking for a good design pattern for the following problem.  I have some
> classes whose methods I need to modify according to a series of specific
> strategies - for instance, "rename the original method and call it inside a
> read lock."  
> 
> So, I have some class adapters, and each adapter has a static table of
> method identifier to modification strategy.  When visitMethod() is called on
> the adapter, it looks up the method in the table, and applies the
> modification strategy.  I'm trying to figure out what kind of object this
> "modification strategy" is - for example, is it a MethodVisitor?  (I don't
> think so.)
> 
> The issue is that the modification may require creating a new method in the
> class, and renaming the original method, and generating contents for both of
> those classes based on the original contents.  So I might want to call the
> class adapter's super.visitMethod() more than once.  From inside the
> strategy object, I don't know how to call the class adapter's delegate.
> 
> One way to do it would be to have my class adapters all implement an
> interface like this:
> 
>     public interface IDelegatingClassVisitor {
>       MethodVisitor delegateVisitMethod(...);
>     }
> 
> And generally the adapter's implementation would look like:
> 
>     MethodVisitor delegateVisitMethod(...) {
>       super.visitMethod(...); 
>     }
> 
> Then I could have:
> 
>     public interface MethodModificationStrategy {
>       MethodVisitor visitMethod(IDelegatingClassVisitor cv, ...);
>     }
> 
> And I could implement strategy classes with code like this:
> 
>     /** rename original to inner and call it */
>     public SimpleWrapperStrategy implements MethodModificationStrategy {
>       public MethodVisitor visitMethod(IDelegatingClassVisitor cv, ...) {
>         MethodVisitor mvWrapper = cv.visitMethod(...);
>         // visit mv with code of wrapper method
> 
>         MethodVisitor mvInner = cv.visitMethod(innerMethodName, ...);
>         return mvInner;
>       }
>     }
> 
> Or to get really fancy, code like this:
> 
>     /** make two identical methods */
>     public MethodDuplicatorStrategy implements MethodModificationStrategy {
>       public MethodVisitor visitMethod(IDelegatingClassVisitor cv, ...) {
>         final MethodVisitor mvOriginal = cv.visitMethod(...);
>         final MethodVisitor mvDup = cv.visitMethod(duplicateMethodName,
> ...);
>         return new MethodVisitor() {
>           visitFooInsn() {
>             mvOriginal.visitFooInsn();
>             mvDup.visitFooInsn();
>           }
>           // and so forth for the whole MV interface
>         }
>       }
>     }
> 
> The thing I don't like about this is that IDelegatingClassVisitor seems like
> a kind of weird thing to have to add to my class adapters.  Also, usually to
> generate the code I need a lot of additional information like the name of
> the type being modified, its outer type, and so  forth; and so I have to
> suck that across the IDelegatingClassVisitor interface too, either via
> additional methods or as additional parameters to visitMethod.
> 
> Is there a cleaner way to do this?  It must be a really common task, I
> think.
> 


-- 
      Tronje Krop <tronje.krop@xxxxxxxxxxxxxxxxxxx>
         - Multimedia Communications Lab (KOM) -
                 Div. Mobile Networking
 Dept. of Electrical Engineering & Information Technology
                Dept. of Computer Science
           Darmstadt University of Technology

      Phone +49-6151-16-7055, Fax +49-6151-16-6152
  Merkstrasse 25 (S3/06-344), 64283 Darmstadt, Germany
             http://www.kom.tu-darmstadt.de

    Encrypted eMail welcome! GPG/PGP-Key: 0x9AD43A05
   68E5 A3D3 75A0 B096 AC75  62D5 8EEE 3D18 9AD4 3A05

  No responsibility is taken for the correctness of the
 previous information. Please delete if you receive this
                   mail unintentional.


<--  Date Index  --> <--  Thread Index    

Reply via email to:

Powered by MHonArc.

Copyright © 2006-2007, OW2 Consortium | contact | webmaster.