Java ASM visitMethodInsn参数?

时间:2017-07-30 05:16:34

标签: java stack java-bytecode-asm visitor invocation

我试图通过阅读文档和查看示例代码来了解Java的ObjectWeb ASM库(框架?)是如何工作的。我正在慢慢理解它背后的想法,但我发现了一些我不理解的示例代码,所以我希望有人可以向我解释。

代码采用mv,一个从ClassWriter的visitMethod方法获得的MethodVisitor,并开始像这样操作方法:

    mv.visitCode();
    String methodSignature = "(L" + worldClass + ";IIIL" + blockClass + ";)V";

    Label l0 = new Label();
    mv.visitLabel(l0);
    mv.visitLineNumber(81, l0);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitVarInsn(ILOAD, 2);
    mv.visitVarInsn(ILOAD, 3);
    mv.visitVarInsn(ILOAD, 4);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKESTATIC, "com/olafski/fastleafdecay/FldHandler", "handleLeafDecay", methodSignature);

当然还有更多内容,但这是我不理解的部分。从方法签名中可以看出,它需要5个参数:一个World类,三个整数和一个Block类(是的,签名字符串中的那些变量确实为这些类保存了正确的FQN)。然而,在访问新方法调用之前,只有四个参数被压入堆栈(加上对this的引用)。那么它从哪里获得第五个参数?

1 个答案:

答案 0 :(得分:0)

有五个参数:

因为handleLeafDecay是静态方法(INVOKESTATIC操作数用于调用它),所以在方法调用之前不会在堆栈上推送对this的引用。但是,this的引用用作第五个参数。

因此生成的字节码将等同于此代码:

public void generatedMethod(World wolrd, int i1, int i2, int i3, Block block) {
    FldHandler.handleLeafDecay(wolrd, i1, i2, i3, this);
    // ...
}

这意味着此方法位于Block类或其衍生物内。此外,block参数未使用。