Re: [Jastadd] [bug report] enclosing class's field access within an anonymous class
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