Thanks very much for that - I'll give it a try!
I guess what Im still a bit confused about is how the original return value
of the method ends up on the stack - as we've just inserted our call right
before the return.
Is it the redirect-branches which sorts everything out - or have I just
missed something fundamental?

-----Original Message-----
From: Doshi, Rutvik [mailto:[EMAIL PROTECTED]
Sent: Thursday, August 19, 2004 6:38 PM
To: BCEL Users List
Cc: [EMAIL PROTECTED]
Subject: RE: Before Return


Hi 

It is fairly easy.. Suppose I've a static method in the class

Public MyClass {

        public static void methodReturnEvent(String className, String
methodName ){

                System.out.println("Method returned : " + className +
"::" + methodName ) ;
        }
}


In my byte instrumentation code I would do the following

        JavaClass clazz = ... my class in wrapped in the JavaClass

        ConstantPoolGen cpGen = new
ConstantPoolGen(clazz.getConstantPool() );

        // add a reference the to static method in the constantpool
        int methodReturn =
cpGen.addMethodRef("MyClass","methodReturnEvent",
                "(Ljava/lang/String;Ljava/lang/String;)V");


        Method[] methods = clazz.getMethods();

        
      for (int i = 0; i < methods.length; i++) {
                        // iterate thru all the methods and instrument
them
                        methods[i] = instrumentReturn(methods[i], cpGen)
;
            
      }


public Method instrumentReturn(Javaclass clazz, Method m,
ConstantPoolGen cpGen, int methodReturn) {

        MethodGen           mg  = new MethodGen(m, clazz.getClassName(),
                                                cpGen);
        // get the instruction list
          InstructionList     il  = mg.getInstructionList();
        InstructionHandle[] ihs = il.getInstructionHandles();

          String methodName = mg.getName()

        
        for (int j = 0; j < ihs.length; j++) {
                // check if the instruction is a return instruction
            if (ihs[j].getInstruction() instanceof ReturnInstruction) {

                          // create instruction set to invoke static
method
                        InstructionList endPoint = new
InstructionList();
                        endPoint.append(new PUSH(cpGen,
clazz.getClassName()));
                        endPoint.append(new PUSH(cpGen, methodName));
                        endPoint.append(new INVOKESTATIC(methodReturn));
                        // insert it before the return instruction
                InstructionHandle ih = il.insert(ihs[j], endPoint);
                il.redirectBranches(ihs[j], ih);
            }
        }

          mg.setMaxStack();

          return mg.getMethod() ;
}




-----Original Message-----
From: Irving, Dave [mailto:[EMAIL PROTECTED] 
Sent: Thursday, August 19, 2004 11:28 AM
To: '[EMAIL PROTECTED]'
Subject: RE: Before Return

Hmmm.... In fact, what I think I'd really like to do is get a try /
finally
around a whole method call.
I know that 'finally' doesn't exist at the byte code level - so I think
I've
still got the problem of inserting instructions before each return (JSRs
I
guess...).
 
I've had some experience with BCEL - I managed to get a mock object
generator implemented using it (still haven't got round to making it
open
source....) - but I've never had to insert instructions before like
this.
Any pointers would be really appreciated!
 
 
-----Original Message-----
From: Irving, Dave 
Sent: Thursday, August 19, 2004 3:28 PM
To: [EMAIL PROTECTED]
Subject: Before Return


Hi,
 
I want to make a call to a static method before each return of a method
of
an existing class - at the moment Im not too fussed about dealing with
exceptions.
I can find the return instructions easy enough and insert my
instructions -
but what Im not sure about is how to "re-setup" everything for the
return
that follows.
Has anyone done this before and have any pointers?
 
Many thanks,
 
Dave


This e-mail and any attachment is for authorised use by the intended
recipient(s) only. It may contain proprietary material, confidential
information and/or be subject to legal privilege. It should not be
copied, disclosed to, retained or used by, any other party. If you are
not an intended recipient then please promptly delete this e-mail and
any attachment and all copies and inform the sender. Thank you.

This e-mail and any attachment is for authorised use by the intended recipient(s) 
only. It may contain proprietary material, confidential information and/or be subject 
to legal privilege. It should not be copied, disclosed to, retained or used by, any 
other party. If you are not an intended recipient then please promptly delete this 
e-mail and any attachment and all copies and inform the sender. Thank you.

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to