[lworld] VerifyError: Bad type on operand stack, limitation in javac for value type constructors
Paul Sandoz
paul.sandoz at oracle.com
Fri Jul 13 18:24:00 UTC 2018
Hi,
The program below compiles but fails when executed:
$ java -XX:+EnableValhalla A
Exception in thread "main" java.lang.VerifyError: Bad type on operand stack
Exception Details:
Location:
A$Point.$makeValue$()LA$Point; @12: i2b
Reason:
Type 'A$Point' (current frame, stack[1]) is not assignable to integer
Current Frame:
bci: @12
flags: { }
locals: { 'A$Point' }
stack: { 'A$Point', 'A$Point' }
Bytecode:
0000000: cb00 024b 2a2a 03cc 0004 594b 91cc 0003
0000010: 4b2a b0
at A.main(A.java:31)
The cause is this constructor:
Point() {
x = y = 0; // This is the cause
}
the byte code of which is:
A$Point();
descriptor: ()V
flags: (0x0000)
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 6: 0
If the constructor is updated to the following then things work:
Point() {
x = 0;
y = 0;
}
static A$Point point();
descriptor: ()LA$Point;
flags: (0x0008) ACC_STATIC
Code:
stack=2, locals=0, args_size=0
0: iconst_0
1: iconst_0
2: invokestatic #6 // Method point:(II)LA$Point;
5: areturn
There is a limitation in javac's current approach mapping field assignments to arguments passed to the static factory method.
Paul.
public class A {
static final __ByValue class Point {
final int x;
final int y;
Point() {
x = y = 0; // This is the cause
}
static Point point(int x, int y) {
Point p = __MakeDefault Point();
p = __WithField(p.x, x);
p = __WithField(p.y, y);
return p;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof Point)) return false;
Point op = (Point) o;
return x == op.x && y == op.y;
}
static Point point() {
return point(0, 0);
}
}
public static void main(String[] args) {
Point p = Point.point();
}
}
More information about the valhalla-dev
mailing list