=== ./T.java
public class T extends a.A {
public static void main(String[] args) {
new T().f(42);
}
public void f(int x) {
Runnable r;
r = () -> {
System.err.println(x);
new I();
};
// r = () -> new I();
}
}
=== ./a/A.java
package a;
public class A {
public class I {}
}
===
```
$ javac -fullversion
javac full version "24-ea+6-619"
$ javac a/A.java T.java
$ java T
...
Caused by: java.lang.VerifyError: Bad local variable type
Exception Details:
Location:
T.lambda$f$0(I)V @11: aload_0
Reason:
Type integer (current frame, locals[0]) is not assignable to reference type
Current Frame:
bci: @11
flags: { }
locals: { integer }
stack: { uninitialized 7, uninitialized 7 }
Bytecode:
0000000: b200 121a b600 18bb 001d 592a b700 1f57
0000010: b1
```
If the line with `r = () -> new I();` is uncommented, javac crashes:
```
javac a/A.java T.java
...
java.lang.NullPointerException: Cannot read field "sym" because "this.lvar[0]" is null
at jdk.compiler/com.sun.tools.javac.jvm.Code.emitop0(Code.java:572)
at jdk.compiler/com.sun.tools.javac.jvm.Items$SelfItem.load(Items.java:369)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.genArgs(Gen.java:884)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.visitNewClass(Gen.java:2041)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCNewClass.accept(JCTree.java:1912)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.genExpr(Gen.java:859)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.visitExec(Gen.java:1802)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCExpressionStatement.accept(JCTree.java:1644)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.genDef(Gen.java:588)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.genStat(Gen.java:623)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.genStat(Gen.java:609)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.genStats(Gen.java:660)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.internalVisitBlock(Gen.java:1121)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.visitBlock(Gen.java:1085)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:1133)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.genDef(Gen.java:588)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.genStat(Gen.java:623)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.genMethod(Gen.java:949)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.visitMethodDef(Gen.java:912)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:957)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.genDef(Gen.java:588)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.genClass(Gen.java:2494)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.genCode(JavaCompiler.java:770)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.generate(JavaCompiler.java:1702)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.generate(JavaCompiler.java:1670)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:977)
at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:319)
at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:178)
at jdk.compiler/com.sun.tools.javac.Main.compile(Main.java:66)
at jdk.compiler/com.sun.tools.javac.Main.main(Main.java:52)
```
The code for the lambda is change from
```
private void lambda$f$0(int);
Code:
0: getstatic #18 // Field java/lang/System.err:Ljava/io/PrintStream;
3: iload_1
4: invokevirtual #24 // Method java/io/PrintStream.println:(I)V
7: new #29 // class a/A$I
10: dup
11: aload_0
12: invokespecial #31 // Method a/A$I."<init>":(La/A;)V
15: pop
16: return
```
to
```
private static void lambda$f$0(int);
Code:
0: getstatic #18 // Field java/lang/System.err:Ljava/io/PrintStream;
3: iload_0
4: invokevirtual #24 // Method java/io/PrintStream.println:(I)V
7: new #29 // class a/A$I
10: dup
11: aload_0
12: invokespecial #31 // Method a/A$I."<init>":(La/A;)V
15: pop
16: return
```
Note that the lambda is become static and failing to implicitly capture the enclosing instance, and then it is trying to pass aload_0 to the inner class constructor, which is the captured int parameter.
public class T extends a.A {
public static void main(String[] args) {
new T().f(42);
}
public void f(int x) {
Runnable r;
r = () -> {
System.err.println(x);
new I();
};
// r = () -> new I();
}
}
=== ./a/A.java
package a;
public class A {
public class I {}
}
===
```
$ javac -fullversion
javac full version "24-ea+6-619"
$ javac a/A.java T.java
$ java T
...
Caused by: java.lang.VerifyError: Bad local variable type
Exception Details:
Location:
T.lambda$f$0(I)V @11: aload_0
Reason:
Type integer (current frame, locals[0]) is not assignable to reference type
Current Frame:
bci: @11
flags: { }
locals: { integer }
stack: { uninitialized 7, uninitialized 7 }
Bytecode:
0000000: b200 121a b600 18bb 001d 592a b700 1f57
0000010: b1
```
If the line with `r = () -> new I();` is uncommented, javac crashes:
```
javac a/A.java T.java
...
java.lang.NullPointerException: Cannot read field "sym" because "this.lvar[0]" is null
at jdk.compiler/com.sun.tools.javac.jvm.Code.emitop0(Code.java:572)
at jdk.compiler/com.sun.tools.javac.jvm.Items$SelfItem.load(Items.java:369)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.genArgs(Gen.java:884)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.visitNewClass(Gen.java:2041)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCNewClass.accept(JCTree.java:1912)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.genExpr(Gen.java:859)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.visitExec(Gen.java:1802)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCExpressionStatement.accept(JCTree.java:1644)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.genDef(Gen.java:588)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.genStat(Gen.java:623)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.genStat(Gen.java:609)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.genStats(Gen.java:660)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.internalVisitBlock(Gen.java:1121)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.visitBlock(Gen.java:1085)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:1133)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.genDef(Gen.java:588)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.genStat(Gen.java:623)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.genMethod(Gen.java:949)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.visitMethodDef(Gen.java:912)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:957)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.genDef(Gen.java:588)
at jdk.compiler/com.sun.tools.javac.jvm.Gen.genClass(Gen.java:2494)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.genCode(JavaCompiler.java:770)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.generate(JavaCompiler.java:1702)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.generate(JavaCompiler.java:1670)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:977)
at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:319)
at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:178)
at jdk.compiler/com.sun.tools.javac.Main.compile(Main.java:66)
at jdk.compiler/com.sun.tools.javac.Main.main(Main.java:52)
```
The code for the lambda is change from
```
private void lambda$f$0(int);
Code:
0: getstatic #18 // Field java/lang/System.err:Ljava/io/PrintStream;
3: iload_1
4: invokevirtual #24 // Method java/io/PrintStream.println:(I)V
7: new #29 // class a/A$I
10: dup
11: aload_0
12: invokespecial #31 // Method a/A$I."<init>":(La/A;)V
15: pop
16: return
```
to
```
private static void lambda$f$0(int);
Code:
0: getstatic #18 // Field java/lang/System.err:Ljava/io/PrintStream;
3: iload_0
4: invokevirtual #24 // Method java/io/PrintStream.println:(I)V
7: new #29 // class a/A$I
10: dup
11: aload_0
12: invokespecial #31 // Method a/A$I."<init>":(La/A;)V
15: pop
16: return
```
Note that the lambda is become static and failing to implicitly capture the enclosing instance, and then it is trying to pass aload_0 to the inner class constructor, which is the captured int parameter.
- relates to
-
JDK-8334037 Local class creation in lambda in pre-construction context crashes javac
-
- Resolved
-
- links to
-
Commit(master) openjdk/jdk/939fe000
-
Review(master) openjdk/jdk/20259