在每次呼叫特定方法之前使用ASM注入字节码
如何重写类(最好使用ASM),以使setupspecial()
调用是在每个调用special> special(int)
之前引入调用的?
public class Application {
public void f() {
System.out.println("A");
// setupSpecial(); ← to be added
special(1);
System.out.println("B");
// setupSpecial(); ← to be added
special(2);
System.out.println("C");
// setupSpecial(); ← to be added
special(3);
}
}
请注意,special()
和setupspecial()
不是application
的成员。
我可以将classVisitor
+methodVisitor
组合和截然呼叫通过覆盖> vistmethodinsn(opccodes.invokevirtual,com),“ com” /acme/magic“,“ special”,“()v”,false),尽管这将为时已晚,因为类型整数的方法已经通过visitintinsn(opcodes.bipush,int)
。我需要一种方法来说“现在我看到了special()
!滚动回电,打开魔术并再次继续进行的调用。”
How can I rewrite a class (preferably using asm) such that a setupSpecial()
invocation is introduced before every single call to special(int)
?
public class Application {
public void f() {
System.out.println("A");
// setupSpecial(); ← to be added
special(1);
System.out.println("B");
// setupSpecial(); ← to be added
special(2);
System.out.println("C");
// setupSpecial(); ← to be added
special(3);
}
}
Note that both special()
and setupSpecial()
are not members of Application
.
I can pass a ClassVisitor
+MethodVisitor
combination and intercept calls to special(int)
via overriding visitMethodInsn(Opcodes.INVOKEVIRTUAL, "com/acme/Magic", "special", "()V", false)
, though this will be too late since the method argument of type integer is already passed via visitIntInsn(Opcodes.BIPUSH, int)
. I need a way to say "Now I see the call to special()
! Roll this call back, turn magic on, and proceed again."
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
JVM具有基于堆栈的体系结构,因此您无需担心
special(int)
调用的参数。如果您只需准备setupspecial()
呼叫special(int)
呼叫: /code>要静态,但没关系),您将获得与以下类似的字节码:
如您所见,
special(int)
呼叫的参数在堆栈上按setupspecial()
,这是不寻常的。但是,一旦setupSpecial()
完成,它仍然将位于堆栈的顶部,因此,只要setupSpecial()
不返回任何值,一切就可以正常工作。如果是这样,您需要添加
pop/pop2
opcode将其从堆栈中删除。The JVM has a stack-based architecture, so you don't need to worry about the parameters to the
special(int)
call. If you simply prepend thesetupSpecial()
call to thespecial(int)
call using:(I assume both
special
andsetupSpecial
to be static, but it does not matter), you'll obtain bytecode similar to this:As you can see, the parameter to the
special(int)
call is pushed on the stack before the call tosetupSpecial()
, which is unusual. However it will still be at the top of the stack oncesetupSpecial()
has finished, so everything will work just fine as long assetupSpecial()
does not return any value.If it does, you'll need to add a
pop/pop2
opcode to remove it from the stack.