Re: [Jastadd] [bug report] enclosing class's field access within an anonymous class

From: Na, Hyunik <hina_at_kaist.ac.kr>
Date: Wed, 6 Jun 2012 13:38:59 +0900

Basically, however, I think supporting such field accesses is incorrect
under the Java language specification,

because the anonymous class has no immediately enclosing instance in this
case (note that the anonymous class appears in a static context),

and hence the instance of F is not the second lexically enclosing instance
of the anonymous class instance

(see JLS2 8.1.2 and 15.9.2 for the definition of n-th lexically enclosing
instance).

 

But, the instance of F is available at the point of the anonymous class
instantiation unlike the instance of D,

and JastAddJ and javac seem to do their best to support such field accesses

in spite of the insufficient specification about accessing fields of
enclosing instances.

 

- Hyunik

 

 

From: jastadd-bounces_at_cs.lth.se [mailto:jastadd-bounces_at_cs.lth.se] On Behalf
Of Na, Hyunik
Sent: Wednesday, June 06, 2012 12:55 PM
To: jastadd_at_cs.lth.se
Subject: [Jastadd] [bug report] enclosing class's field access within an
anonymous class

 

Hello JastAddJ developers,

 

Compiling the following program using JastAddJ JavaCompiler (rev. 9267)
produces class files for Test, C, E, etc.

 

-=-=-= Test.java

 

class C {

  void added() { }

}

 

class E {

  E( C c ) {

    c.added();

  }

}

 

class F {

  int f = 3;

  class D extends E {

    int d = 3;

    D() {

      //super( new C() { void added() { System.out.println( "d = " + d ); }
} ); // error

      super( new C() { void added() { System.out.println( "f = " + f ); } }
);

    }

  }

}

 

public class Test {

  public static void main( String [] args ) {

    new F().new D();

  }

}

-=-=-=

 

But, running the program results in java.lang.VerifyError:

 

-=-=-=

hina_at_ns:~/myWork/test$ java Test

Exception in thread "main" java.lang.VerifyError: (class: F$D$1, method:
added signature: ()V) Accessing value from uninitialized register 1

        at F$D.<init>(Test.java:32)

        at Test.main(Test.java:39)

-=-=-=

 

Suggested fix is to add the following line:

 

           eq TypeDecl.getChild().inExplicitConstructorInvocation() = false;
// ***

 

or something else to make "Acc_f.inExplicitConstructorInvocation()" false,
where Acc_f is an ASTNode corresponding to the above f access.

(In current JastAddJ, it is true, which is probably not intended.),

and to modify a line in Access.emitThis() defiend in CreateBCode.jrag in
Java1.4Backend.

 

-=-=-=

public void Access.emitThis(CodeGeneration gen, TypeDecl targetDecl) {

    if(targetDecl == hostType())

      gen.emit(Bytecode.ALOAD_0);

    else {

      TypeDecl enclosing = hostType();

      if(inExplicitConstructorInvocation()) {

        gen.emit(Bytecode.ALOAD_1); // !!!

        enclosing = enclosing.enclosing();

      }

      else {

        gen.emit(Bytecode.ALOAD_0); // $$$

      }

      while(enclosing != targetDecl) {

        String classname = enclosing.constantPoolName();

        //enclosing = enclosing.enclosingType(); // modified
to the following line

        enclosing = enclosing.enclosing();

        String desc = enclosing.typeDescriptor();

        int index = gen.constantPool().addFieldref(classname, "this$0",
desc);

        gen.emit(Bytecode.GETFIELD, 0).add2(index);

      }

    }

  }

-=-=-=

 

Without the above *** line, the execution wrongly goes to the above !!!
instead of correct $$$

(the first problem related to this bug).

And "enclosing.enclosingType()" (D in this case) should be
"enclosing.enclosing()" (F, a correct enclosing type in this case)

(the second problem related to this bug).

 

 

Cheers,

- Hyunik

 

 
Received on Wed Jun 06 2012 - 06:39:14 CEST

This archive was generated by hypermail 2.3.0 : Wed Apr 16 2014 - 17:19:06 CEST