Fwd: java.lang.VerifyError: Bad type on operand stack

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Wed Jan 7 11:25:44 UTC 2015


I consulted with the inference Gods (they seem to be lurking in Valhalla 
from time to time) and it would seem that this is actually the correct 
behavior.
The problem is that the constructor is considered perfectly applicable 
during the 'strict' applicability step, which only uses subtyping - 
therefore the only allowed inference result there is 'int' - and the 
target type seems to contradict there. It is possible that we will relax 
this a bit moving forward by introducing some ad hoc rules, but the 
status quo seems to be expressive enough, while avoiding being 
unnecessarily messy.

At the same time, the Gods pointed out that inference should only be 
allowed to do boxing/unboxing tricks when an inference constraints of 
the kind

alpha :> int

has been derived from a compatibility check (i.e. because we want to 
pass an 'int' where 'alpha' is expected). These tricks should not be 
allowed in the general case - example:

<any T> T[] clone(T[] arg) { return arg; }

int[] arr1 = clone(new int[3]); //ok
Integer[] arr2 = clone(new int[3]); //fail

Here, the array subtyping rules essentially mean that no boxing can 
occurr, so the only choice for T is 'int' in the second case, which, 
again, is incompatible with the target.

The compiler gets some of this right and some other things only happen 
to be right 'by accident' - I'm working on a patch that will clean this 
up a bit.

Maurizio

On 06/01/15 16:27, Sven Reimers wrote:
> @Maurizio: sorry forgot the mailing list...
>
>
> ---------- Forwarded message ----------
> From: Sven Reimers <sven.reimers at gmail.com>
> Date: Tue, Jan 6, 2015 at 5:20 PM
> Subject: Re: java.lang.VerifyError: Bad type on operand stack
> To: Maurizio Cimadamore <maurizio.cimadamore at oracle.com>
>
>
> Follow-Up:
>
> I tried a few different things and got into this:
>
> Point3D<Integer> integerPoint = new Point3D<>(1,2,3);
>
> compiles only if
>
> public static class Point3D<T> {... }
>
> not for
>
> public static class Point3D<any T> {... }
>
> ErrorMessage from the compiler is:
>
> incompatible types: cannot infer type arguments for Point3D<>
>        Point3D<Integer> integerPoint = new Point3D<>(1,2,3);
>                                                   ^
>      reason: cannot infer type-variable(s) T
>        (argument mismatch; int cannot be converted to Integer)
>    where T is a type-variable:
>      T extends <any> declared in class Point3D
>
> Is this intentional (not sure I found this stated in the draft)?
>
> Thanks
>
> Sven
>
>
> On Tue, Jan 6, 2015 at 4:10 PM, Maurizio Cimadamore <
> maurizio.cimadamore at oracle.com> wrote:
>
>> Whoops :-)
>>
>> Thanks for the report
>>
>> Maurizio
>>
>>
>> On 06/01/15 15:13, Sven Reimers wrote:
>>
>>> Hi,
>>>
>>> as suggested by Brian I tried to get some sample code written and running
>>> on top of valhalla.
>>>
>>> First problem I encountered was that a missing diamond <> on the right
>>> hand
>>> side (my bad - seems I am really relying on my IDE) was just a warning
>>> that
>>> I was using a raw type.
>>>
>>> Running my example I got this:
>>>
>>> Specializing Valhalla$Point3D${0=I}; searching for Valhalla$Point3D.class
>>> (not found)
>>> Specializing Valhalla$Point3D${0=I}; searching for Valhalla$Point3D.class
>>> (found)
>>> Error: A JNI error has occurred, please check your installation and try
>>> again
>>> Exception in thread "main" java.lang.VerifyError: Bad type on operand
>>> stack
>>> Exception Details:
>>>     Location:
>>>       Valhalla.main([Ljava/lang/String;)V @36: invokevirtual
>>>     Reason:
>>>       Type 'Valhalla$Point3D' (current frame, stack[2]) is not assignable
>>> to
>>> 'Valhalla$Point3D${0=I}'
>>>     Current Frame:
>>>       bci: @36
>>>       flags: { }
>>>       locals: { '[Ljava/lang/String;', 'Valhalla$Point3D' }
>>>       stack: { 'java/io/PrintStream', 'java/lang/StringBuilder',
>>> 'Valhalla$Point3D' }
>>>     Bytecode:
>>>       0000000: bb00 0259 04b8 0003 05b8 0003 06b8 0003
>>>       0000010: b700 044c b200 05bb 0006 59b7 0007 1208
>>>       0000020: b600 092b b600 0ab6 000b b600 0cb6 000d
>>>       0000030: b1
>>>
>>> at java.lang.Class.getDeclaredMethods0(Native Method)
>>> at java.lang.Class.privateGetDeclaredMethods(Class.java:2704)
>>> at java.lang.Class.privateGetMethodRecursive(Class.java:3049)
>>> at java.lang.Class.getMethod0(Class.java:3019)
>>> at java.lang.Class.getMethod(Class.java:1787)
>>> at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:568)
>>> at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:535)
>>>
>>> Example Code (see the missing <> just after Point3D...):
>>>
>>> public class Valhalla {
>>>
>>>
>>>      public static void main (String[] args) {
>>>
>>>         Point3D<int> intPoint = new Point3D(1,2,3);
>>>
>>>         System.out.println("X: " + intPoint.getX());
>>>
>>>      }
>>>
>>>      public static class Point3D<any T> {
>>>    private T x;
>>> private T y;
>>>           private T z;
>>>
>>>           public Point3D(T x, T y, T z) {
>>> this.x = x;
>>>                   this.y = y;
>>>                   this.z = z;
>>> }
>>>
>>>           public T getX() {
>>>      return x;
>>> }
>>>
>>>           public T getY() {
>>>      return y;
>>> }
>>>
>>>           public T getZ() {
>>>      return z;
>>> }
>>>
>>>      }
>>>
>>> }
>>>
>>> Hope to provide more feedback once I got more code running.
>>>
>>> Thanks for the impressive work so far.
>>>
>>> -Sven
>>>
>>>
>



More information about the valhalla-dev mailing list