[lworld] VerifyError: Bad type on operand stack, limitation in javac for value type constructors
Srikanth
srikanth.adayapalam at oracle.com
Mon Jul 16 13:15:31 UTC 2018
Thanks Paul,
This is a tricky issue indeed, but not a hard limitation.
I have raised: https://bugs.openjdk.java.net/browse/JDK-8207332 for this
problem.
I will tackle the related but simpler problem against
https://bugs.openjdk.java.net/browse/JDK-8207341
first and then get to JDK-8207332.
Thanks!
Srikanth
On Friday 13 July 2018 11:54 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