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

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, 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