我开发与ASM的检测引擎,我需要拦截的方法,其中接收阵列类型的参数调用。为此,我实施了MethodVisitor
,并在其visitMethodInsn
中检查desc
参数是否指定了数组类型的任何参数。如果目标方法没有数组类型的参数,那么我无关并且插入原始方法调用:super.visitMethodInsn(opcode, owner, name, desc);
如何避免的VerifyError:“希望找到堆栈未初始化对象”的对象已经初始化
另一方面,如果目标方法具有数组类型的参数,那么我必须执行一个针对其论点的具体行动。我获得访问每个参数的最简单的解决方案是调用一个中介方法,具有与目标方法相同的描述符,并且在此介体中,我可以轻松访问其参数(与传递给目标方法的参数相对应)。
然而,当目标方法是一个实例的构造(<init>
)出现一个问题。
NEW XXX
DUP
INVOKESPECIAL XXXX.<init>()
根据我上面的解释,我移动INVOKESPECIAL
呼叫到调解方法和新创建的对象是该中介的第一个参数的方法:在Java的new XXX()
如下被翻译成字节码。然而,验证者为这个介体产生一个错误,报告介体的第一个参数(它将成为目标方法的第一个参数 - <init>
)不是一个“单元化对象”。更确切地说,我得到了错误:Exception in thread "main" java.lang.VerifyError: Expecting to find unitialized object on stack”
。
一旦我用两种不同的方法分割字节码NEW
和INVOKESPECIAL
,验证者声称传递给INVOKESPECIAL
的参数已经被初始化。
任何建议来解决这个问题呢? (请不要回答我避免介体并直接访问堆栈中的参数,因为复制并替换占用堆栈中任意位置的参数并非易事)。
“mediator”方法是什么意思? – vijay
想象一下,在某些时候,我的工具引擎正在拦截目标方法的调用:'obj.foo(x)'。因此,在这一点上,我将这个调用替换为:'obj.foo(x)',by:'mediator $ foo(obj,x)' - 在这种情况下,调解器$ foo是调用方类中的一个新的静态方法。因此,'mediator $ foo(obj,x)'完成它需要的东西,然后调用目标:'obj.foo(x)'。 –
是静态还是实例方法的中介方法? – vijay