0

I have a method which returns a value that is generated in another method similar to this:

public static FileChannel open()
{
    return provider.newObject();
}

So the bytecode of the method roughly looks like this:

INVOKEVIRTUAL org/test/Helper.process ()Lorg/test/MyObject;
ARETURN

I have a Java Agent which uses ASM to do bytecode-transformation when the JVM starts up.

Now I would like to inject code which access the returned MyObject without doing too much changes to the invoke itself, i.e. ideally I would just add some bytecode instructions before the ARETURN.

Which ASM/bytecode construct allows me to access the object that is returned here?

centic
  • 15,565
  • 9
  • 68
  • 125

2 Answers2

3

For something simple, you can just put a DUP instruction in there followed by the desired use. If you need to inject more complex code, you should store it in a register (it doesn't really matter which since it won't be used after your code except in the exceedingly unlikely event that areturn throws an exception and there's an exception handler for it in the method).

So if you're using register 0 it would go like astore_0 (your code) aload_0 areturn.

Antimony
  • 37,781
  • 10
  • 100
  • 107
1

If you want to only have access to return statement IMO easier will be to use AdviceAdapter

It has onMethodExit(int opcode) method, which can be overridden in following manner :

public void onMethodExit(int opcode) {
    if( opcode != ARETURN ) {
           return;
    } 
//put yout code here
}

Also I recommended to read http://download.forge.objectweb.org/asm/asm4-guide.pdf .

Grzesuav
  • 459
  • 2
  • 10
  • Thanks, that's a good advice, unfortunately my plumbing is already existing, so I am not able to use AdviceAdapter easily. – centic Apr 02 '15 at 06:56
  • You can try to make a chain of visitors instead of just one, or you can use a Tree API, where you have direct access to list of instructions. – Grzesuav Apr 02 '15 at 06:59