Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Thanks again to Mike and ruediste for their comments.</p> <p>Mike was right: My problem was that I tried passing a reference as a method call argument right after it was created by NEW but before its constructor has been called. The JVM specification clearly states that such a behavior is forbidden: "The verifier rejects code that uses the new object before it has been initialized [...]" (see <a href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.10.2.4" rel="nofollow">http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.10.2.4</a>)</p> <p>However, the instruction sequence of creating and initializing a new object leaves my desired object on top of the operand stack where it can easily be obtained :)</p> <p>In the end, I blew up my code bit for the INVOKESPECIAL handling:</p> <pre><code>if (opcode == INVOKESPECIAL) { // Invoke constructors and private methods // Ignore initialization of java/lang/Object if (name.equals("&lt;init&gt;") &amp;&amp; owner.equals("java/lang/Object")) { super.visitMethodInsn(opcode, owner, name, desc); return; } if (methodName.equals("&lt;clinit&gt;")) { if (name.equals("&lt;clinit&gt;")) { // call to a static initializer from within a static initializer // there is no object reference! super.visitMethodInsn(opcode, owner, name, desc); } else if (name.equals("&lt;init&gt;")) { // call to a constructor from within a static initializer super.visitMethodInsn(opcode, owner, name, desc); // object reference is initialized and on stack now -&gt; obtain it via DUP } else { // call to a private method from within a static initializer // no this-reference in static initializer! super.visitMethodInsn(opcode, owner, name, desc); } } else if (methodName.equals("&lt;init&gt;")) { if (name.equals("&lt;clinit&gt;")) { // call to a static initializer from within a constructor // there is no object reference! super.visitMethodInsn(opcode, owner, name, desc); } else if (name.equals("&lt;init&gt;")) { // call to a constructor from within a constructor super.visitMethodInsn(opcode, owner, name, desc); // if this constructor call is not an invocation of the super constructor: obtain object reference via DUP } else { // call to a private method from within a constructor // object reference is the this-reference (at local variable 0) super.visitMethodInsn(opcode, owner, name, desc); } } else { if (name.equals("&lt;clinit&gt;")) { // call to a static initializer from within some method // there is no object reference! super.visitMethodInsn(opcode, owner, name, desc); } else if (name.equals("&lt;init&gt;")) { // call to a constructor from within some method super.visitMethodInsn(opcode, owner, name, desc); // obtain object reference via DUP } else { // call to a private method from within some method // if the private method is called within some NON-STATIC method: object reference is the this-reference (at local variable 0) // if the private method is called within some NON-STATIC method: there is no object reference! super.visitMethodInsn(opcode, owner, name, desc); } } } </code></pre> <p>Possibly this helps someone who's trying to do similar stuff :)</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload