[lworld] VerifyError: Bad type on operand stack, limitation in javac for value type constructors (original) (raw)

Harold David Seigel harold.seigel at oracle.com
Fri Jul 13 18:47:23 UTC 2018


Hi Paul,

For a withfield instruction, do you expect the verifier to push the type of the field on its stack or the type of the valuetype containing the field.  Currently, it pushes the valuetype on the stack.

This is a JVM Spec issue.

Harold

On 7/13/2018 2:24 PM, Paul Sandoz wrote:

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, argssize=1 0: aload0 1: invokespecial #1 // Method java/lang/Object."":()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) ACCSTATIC Code: stack=2, locals=0, argssize=0 0: iconst0 1: iconst0 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