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 uni开发者_运维技巧nitialized reference but I can't pass it as parameter? I would appreciate any help. Thank you
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.
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.
精彩评论