4

我一直在尝试使用 ASM 框架在我感兴趣的位置注入字节码,到目前为止我一直很成功。目前我正在尝试注入代码,它基本上创建了一个类的新实例/对象,经过阅读后我发现这个可以使用 INVOKESPECIAL 来实现(我希望我对 INVOKESPECIAL “私有方法和构造函数的 INVOKESPECIAL”的理解是正确的)。

下面是我用来创建实例的代码片段

visitor.visitLdcInsn(System.currentTimeMillis());
visitor.visitLdcInsn(System.currentTimeMillis());
visitor.visitLdcInsn(_type);
visitor.visitVarInsn(ALOAD, metanamevarindex);

eventObject = newLocal(Type.getType("com/vish/RequestTrackerEvent"));

visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, "com/vish/RequestTrackerEvent", "<init>",
                            "(JJLjava/lang/String;Ljava/lang/String;)V");

visitor.visitVarInsn(ASTORE, eventObject);

类的构造函数接受 4 个参数(long、long、String、String)但是每当我这样做时,我都会得到一个如下所示的异常

java.lang.VerifyError: JVMVRFY036 stack underflow;
    at java.lang.J9VMInternals.verifyImpl(Native Method)
    at java.lang.J9VMInternals.verify(J9VMInternals.java:72)
    at java.lang.J9VMInternals.verify(J9VMInternals.java:70)
    at java.lang.J9VMInternals.initialize(J9VMInternals.java:134)

谁能帮助我了解我对 INVOKESPECIAL 的使用/理解是否正确,如果正确,那么我在哪里做错了?

谢谢

4

2 回答 2

2

我不记得 newLocal() 的确切作用,但我知道该方法不会将 NEW 指令插入字节码。它只是在一些 ASM 内部局部变量处理机制中保留空间。

尝试使用类似的东西

visitor.visitTypeInst(Opcodes.NEW, "com/vish/RequestTrackerEvent");

祝你好运

于 2013-09-05T13:09:48.813 回答
1

ASM FAQ 中已经回答了“如何使用 ASM 生成 {some Java code}”之类的问题:

如果您想知道如何生成同步块、try catch 块、finally 语句或任何其他 Java 构造,请将您想要生成的 Java 代码写在一个临时类中,用 javac 编译它,然后使用 ASMifier获取将生成此类的 ASM 代码(请参阅“ 10.如何获取现有类的字节码? ”)。

您可以走得更远,如本文所述,比较转换前后 ASMifier 的输出。

于 2013-09-05T19:16:14.607 回答