gpt4 book ai didi

java - 如何避免验证错误: “Expecting to find unitialized object on stack” for objects already initialized

转载 作者:行者123 更新时间:2023-12-01 15:03:58 25 4
gpt4 key购买 nike

我正在使用 ASM 开发一个仪表引擎,我需要拦截接收数组类型参数的方法的调用。为此,我实现了 MethodVisitor并在其visitMethodInsn中我检查是否 desc参数指定数组类型的任意参数。如果目标方法没有数组类型的参数,那么我什么也不做,我插入原始方法调用:super.visitMethodInsn(opcode, owner, name, desc);

另一方面,如果目标方法具有数组类型的参数,那么我必须对其参数执行特定操作。我访问每个参数的最简单的解决方案是调用一个中介方法,使用与目标方法相同的描述符,并且在这个中介中我可以轻松访问它的参数(对应于传递给目标方法的参数)。

但是,当目标方法是实例构造函数 ( <init> ) 时,就会出现问题。在 Java 中 new XXX()转换为字节码如下:

  NEW XXX 
DUP
INVOKESPECIAL XXXX.<init>()

根据我上面解释的方法,我正在移动 INVOKESPECIAL调用中介方法,新实例化的对象是该中介的第一个参数。然而,验证者会为此中介者引发错误,报告中介者的第一个参数(这将是目标方法的第一个参数 - <init> )不是“统一对象”。更准确地说,我收到错误:Exception in thread "main" java.lang.VerifyError: Expecting to find unitialized object on stack” .

一旦我分割了字节码 NEWINVOKESPECIAL在两种不同的方法中,验证者声称参数传递给 INVOKESPECIAL已经初始化了。

有什么建议可以解决这个问题吗? (请不要回答我以避免中介并直接访问堆栈中的参数,因为复制和替换占据堆栈中任意位置的参数并不简单。)

最佳答案

validator 拒绝您的代码是正确的(请参阅 JVM 规范)。无法绕过字节码 validator 。

一种解决方法是在构造函数调用时内联中介代码。您仍然可以在调用构造函数之前或之后以方法调用的形式调用中介器的一部分,但构造函数调用必须与 new 指令位于同一方法中。

另一种方法是为每个正在实例化的类创建特殊的中介器,因此中介器本身会调用 new 指令以及构造函数调用。

您还可以查看现有的 AOP 库是否可以正确完成所需的工作。

关于java - 如何避免验证错误: “Expecting to find unitialized object on stack” for objects already initialized,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13234997/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com