字节码和对象
我正在开发一个字节码检测项目。目前,在处理对象时,验证器大多数时候都会抛出错误。因此,我想弄清楚有关对象规则的事情(我阅读了 JVMS,但找不到我正在寻找的答案):
我正在检测新指令:
原始字节码
NEW <MyClass>
DUP
INVOKESPECIAL <MyClass.<init>>
检测后的
NEW <MyClass>
DUP
INVOKESTATIC <Profiler.handleNEW>
DUP
INVOKESPECIAL <MyClass.<init>>
请注意,我添加了对 Profiler 的调用。 handleNEW() 它将对象引用(新创建的对象)作为参数。
上面的代码会抛出一个VerificationError。如果我不添加 INVOKESTATIC(仅留下 DUP),则不会。那么我违反了什么规则呢?我可以复制未初始化的引用,但无法将其作为参数传递?我将不胜感激任何帮助。谢谢
I am working on a bytecode instrumentation project. Currently when handling objects, the verifier throws an error most of the time. So I would like to get things clear concerning rules with objects (I read the JVMS but couldn't find the answer I was looking for):
I am instrumenting the NEW instruction:
original bytecode
NEW <MyClass>
DUP
INVOKESPECIAL <MyClass.<init>>
after instrumentation
NEW <MyClass>
DUP
INVOKESTATIC <Profiler.handleNEW>
DUP
INVOKESPECIAL <MyClass.<init>>
Note that I added a call to Profiler.handleNEW() which takes as argument an object reference (the newly created object).
The piece of code above throws a VerificationError. While if I don't add the INVOKESTATIC (leaving only the DUP), it doesn't. So what is the rule that I'm violating? I can duplicate an uninitialized reference but I can't pass it as parameter? I would appreciate any help. Thank you
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
JVM 验证程序将构造函数尚未被调用的对象视为具有称为“未初始化”的特殊编译时类型。
因此,从验证者的角度来看,您将错误类型的对象作为第一个参数传递给
Profiler.handleNEW()
,因为“未初始化”不被视为 Object 的子类(因此说话)。JVM 规范中关于如何定义“未初始化”的相关部分是 此处。
The JVM verifier treats an object whose constructor has yet to be called as if it had a special compile-time type called "uninitialized".
So what's happening from the verifier's point of view is that you are passing the wrong type of object as the first parameter to
Profiler.handleNEW()
, because "uninitialized" is not considered a subclass of Object (so to speak).The relevant part of the JVM spec regarding how "uninitialized" is defined is here.
在调用 java.lang.Object 构造函数之前(从技术上讲,它可能正常退出),引用的类型是“未初始化”的。因此,在调用构造函数之前,您不能对引用执行太多操作。在相关对象的构造函数中也是如此。
Until the
java.lang.Object
constructor is called (technically it is probably normally exited), the type of the reference is "uninitialised". So you can't do much with the reference before calling a constructor on it. This is also true in the constructors of the object in question.