I am using ASM and want to rewrite something like:
someMethod().targetMethod(args...)
to:
someMethod().injectedMethod(arg).targetMethod(args...)
The trouble is that I don't know what the method before is, I only know the target method (so finding someMethod()
and injecting after that isn't an option).
I also have many versions of the target method, with different sets of parameters I want this to work with.
Using ASM I can easily find the target method invocation, but unfortunately the operand stack at that point is:
[ argN, ..., arg1, instance, ... ]
And while I can work out how far down the instance will be, there's no bytecode I can inject that will read it. I know you can do it for up to 4 parameters using tricks with dup commands, but I need a general solution.
I could add a bunch of local variables and copy everything off the stack, dup the instance pointed and put everything back on, but that's a runtime inefficiency I really don't want.
What I think would work is if I could track which instruction(s) were responsible for putting the instance pointer on the stack, and then I could inject my method invocation there rather than at the target method invocation. However I have had no luck in finding anything to help me do this.
I know that things like AspectJ allow for this, but have to do this for a lot of classes as they load and AspectJ is just too slow.
Can anyone point me at analysis tools built on top of ASM that might let me do this or can anyone think of a better approach for injecting one method call before another?