views:

91

answers:

2

Hey everyone,

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

+1  A: 

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.

Tom Hawtin - tackline
+2  A: 

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.

Archie