Scala Programming Language
  1. Scala Programming Language
  2. SI-5799

Value class and secondary constructor result in VerifyError

    Details

      Description

      Consider this code:

      class Foo(val bar: Double) extends AnyVal {
        def this(s: String) = this(s.toDouble)
      }
      new Foo("")
      

      This results in

      java.lang.VerifyError: (class: , method: <init> signature: ()V) Expecting to find double on stack
      	at .<init>(<console>:7)
      	at .<clinit>(<console>)
      	at $print(<console>)
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.lang.reflect.Method.invoke(Method.java:601)
      	at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:775)
      	at scala.tools.nsc.interpreter.IMain$Request$$anonfun$18.apply(IMain.scala:1037)
      	at scala.tools.nsc.interpreter.Line.scala$tools$nsc$interpreter$Line$$runAndSetState(Line.scala:41)
      	at scala.tools.nsc.interpreter.Line$$anonfun$2.apply$mcV$sp(Line.scala:47)
      	at scala.tools.nsc.io.package$$anon$2.run(package.scala:22)
      	at java.lang.Thread.run(Thread.java:722)
      

        Issue Links

          Activity

          Hide
          Simon Ochsenreither added a comment - - edited
          % javap -classpath . -private -c -l -s Foo
          Compiled from "Foo.scala"
          public final class Foo extends java.lang.Object{
          private final double bar;
            Signature: D
          
          public static boolean extension$equals(double, java.lang.Object);
            Signature: (DLjava/lang/Object;)Z
            Code:
             0:	getstatic	#11; //Field Foo$.MODULE$:LFoo$;
             3:	dload_0
             4:	aload_2
             5:	invokevirtual	#13; //Method Foo$.extension$equals:(DLjava/lang/Object;)Z
             8:	ireturn
          
          
          
          
          public static int extension$hashCode(double);
            Signature: (D)I
            Code:
             0:	getstatic	#11; //Field Foo$.MODULE$:LFoo$;
             3:	dload_0
             4:	invokevirtual	#17; //Method Foo$.extension$hashCode:(D)I
             7:	ireturn
          
          
          
          
          public double bar();
            Signature: ()D
            Code:
             0:	aload_0
             1:	getfield	#25; //Field bar:D
             4:	dreturn
          
            LineNumberTable: 
             line 1: 0
          
          
          
          public int hashCode();
            Signature: ()I
            Code:
             0:	getstatic	#11; //Field Foo$.MODULE$:LFoo$;
             3:	aload_0
             4:	invokevirtual	#29; //Method bar:()D
             7:	invokevirtual	#17; //Method Foo$.extension$hashCode:(D)I
             10:	ireturn
          
            LineNumberTable: 
             line 1: 0
          
          
          
          public boolean equals(java.lang.Object);
            Signature: (Ljava/lang/Object;)Z
            Code:
             0:	getstatic	#11; //Field Foo$.MODULE$:LFoo$;
             3:	aload_0
             4:	invokevirtual	#29; //Method bar:()D
             7:	aload_1
             8:	invokevirtual	#13; //Method Foo$.extension$equals:(DLjava/lang/Object;)Z
             11:	ireturn
          
            LineNumberTable: 
             line 1: 0
          
          
          
          public Foo(double);
            Signature: (D)V
            Code:
             0:	aload_0
             1:	dload_1
             2:	putfield	#25; //Field bar:D
             5:	aload_0
             6:	invokespecial	#38; //Method java/lang/Object."<init>":()V
             9:	return
          
            LineNumberTable: 
             line 1: 0
          
            LocalVariableTable: 
             Start  Length  Slot  Name   Signature
             0      10      0    this       LFoo;
             0      10      1    bar       D
          
          
          public Foo(java.lang.String);
            Signature: (Ljava/lang/String;)V
            Code:
             0:	aload_0
             1:	new	#44; //class scala/collection/immutable/StringOps
             4:	dup
             5:	getstatic	#49; //Field scala/Predef$.MODULE$:Lscala/Predef$;
             8:	aload_1
             9:	invokevirtual	#53; //Method scala/Predef$.augmentString:(Ljava/lang/String;)Ljava/lang/String;
             12:	invokespecial	#55; //Method scala/collection/immutable/StringOps."<init>":(Ljava/lang/String;)V
             15:	invokeinterface	#60,  1; //InterfaceMethod scala/collection/immutable/StringLike.toDouble:()D
             20:	invokespecial	#62; //Method "<init>":(D)V
             23:	return
          
            LineNumberTable: 
             line 2: 0
          
            LocalVariableTable: 
             Start  Length  Slot  Name   Signature
             0      24      0    this       LFoo;
             0      24      1    s       Ljava/lang/String;
          
          
          }
          
          % javap -classpath . -private -c -l -s Foo$
          Compiled from "Foo.scala"
          public final class Foo$ extends java.lang.Object{
          public static final Foo$ MODULE$;
            Signature: LFoo$;
          
          public static {};
            Signature: ()V
            Code:
             0:	new	#9; //class Foo$
             3:	invokespecial	#12; //Method "<init>":()V
             6:	return
          
          
          
          
          public final int extension$hashCode(double);
            Signature: (D)I
            Code:
             0:	dload_1
             1:	invokestatic	#21; //Method scala/runtime/BoxesRunTime.boxToDouble:(D)Ljava/lang/Double;
             4:	invokevirtual	#27; //Method java/lang/Object.hashCode:()I
             7:	ireturn
          
            LineNumberTable: 
             line 1: 4
          
            LocalVariableTable: 
             Start  Length  Slot  Name   Signature
             0      8      0    this       LFoo$;
             0      8      1    $this       D
          
          
          public final boolean extension$equals(double, java.lang.Object);
            Signature: (DLjava/lang/Object;)Z
            Code:
             0:	aload_3
             1:	instanceof	#35; //class Foo
             4:	ifeq	35
             7:	aload_3
             8:	checkcast	#35; //class Foo
             11:	invokevirtual	#39; //Method Foo.bar:()D
             14:	dstore	4
             16:	dload_1
             17:	dload	4
             19:	dcmpl
             20:	ifne	27
             23:	iconst_1
             24:	goto	28
             27:	iconst_0
             28:	ifeq	35
             31:	iconst_1
             32:	goto	36
             35:	iconst_0
             36:	ireturn
          
            LineNumberTable: 
             line 1: 0
          
            LocalVariableTable: 
             Start  Length  Slot  Name   Signature
             0      37      0    this       LFoo$;
             0      37      1    $this       D
          
          
          private Foo$();
            Signature: ()V
            Code:
             0:	aload_0
             1:	invokespecial	#40; //Method java/lang/Object."<init>":()V
             4:	aload_0
             5:	putstatic	#42; //Field MODULE$:LFoo$;
             8:	return
          
            LineNumberTable: 
             line 1: 0
          
          }
          
          Show
          Simon Ochsenreither added a comment - - edited % javap -classpath . -private -c -l -s Foo Compiled from "Foo.scala" public final class Foo extends java.lang.Object{ private final double bar; Signature: D public static boolean extension$equals(double, java.lang.Object); Signature: (DLjava/lang/Object;)Z Code: 0: getstatic #11; //Field Foo$.MODULE$:LFoo$; 3: dload_0 4: aload_2 5: invokevirtual #13; //Method Foo$.extension$equals:(DLjava/lang/Object;)Z 8: ireturn public static int extension$hashCode(double); Signature: (D)I Code: 0: getstatic #11; //Field Foo$.MODULE$:LFoo$; 3: dload_0 4: invokevirtual #17; //Method Foo$.extension$hashCode:(D)I 7: ireturn public double bar(); Signature: ()D Code: 0: aload_0 1: getfield #25; //Field bar:D 4: dreturn LineNumberTable: line 1: 0 public int hashCode(); Signature: ()I Code: 0: getstatic #11; //Field Foo$.MODULE$:LFoo$; 3: aload_0 4: invokevirtual #29; //Method bar:()D 7: invokevirtual #17; //Method Foo$.extension$hashCode:(D)I 10: ireturn LineNumberTable: line 1: 0 public boolean equals(java.lang.Object); Signature: (Ljava/lang/Object;)Z Code: 0: getstatic #11; //Field Foo$.MODULE$:LFoo$; 3: aload_0 4: invokevirtual #29; //Method bar:()D 7: aload_1 8: invokevirtual #13; //Method Foo$.extension$equals:(DLjava/lang/Object;)Z 11: ireturn LineNumberTable: line 1: 0 public Foo(double); Signature: (D)V Code: 0: aload_0 1: dload_1 2: putfield #25; //Field bar:D 5: aload_0 6: invokespecial #38; //Method java/lang/Object."<init>":()V 9: return LineNumberTable: line 1: 0 LocalVariableTable: Start Length Slot Name Signature 0 10 0 this LFoo; 0 10 1 bar D public Foo(java.lang.String); Signature: (Ljava/lang/String;)V Code: 0: aload_0 1: new #44; //class scala/collection/immutable/StringOps 4: dup 5: getstatic #49; //Field scala/Predef$.MODULE$:Lscala/Predef$; 8: aload_1 9: invokevirtual #53; //Method scala/Predef$.augmentString:(Ljava/lang/String;)Ljava/lang/String; 12: invokespecial #55; //Method scala/collection/immutable/StringOps."<init>":(Ljava/lang/String;)V 15: invokeinterface #60, 1; //InterfaceMethod scala/collection/immutable/StringLike.toDouble:()D 20: invokespecial #62; //Method "<init>":(D)V 23: return LineNumberTable: line 2: 0 LocalVariableTable: Start Length Slot Name Signature 0 24 0 this LFoo; 0 24 1 s Ljava/lang/String; } % javap -classpath . -private -c -l -s Foo$ Compiled from "Foo.scala" public final class Foo$ extends java.lang.Object{ public static final Foo$ MODULE$; Signature: LFoo$; public static {}; Signature: ()V Code: 0: new #9; //class Foo$ 3: invokespecial #12; //Method "<init>":()V 6: return public final int extension$hashCode(double); Signature: (D)I Code: 0: dload_1 1: invokestatic #21; //Method scala/runtime/BoxesRunTime.boxToDouble:(D)Ljava/lang/Double; 4: invokevirtual #27; //Method java/lang/Object.hashCode:()I 7: ireturn LineNumberTable: line 1: 4 LocalVariableTable: Start Length Slot Name Signature 0 8 0 this LFoo$; 0 8 1 $this D public final boolean extension$equals(double, java.lang.Object); Signature: (DLjava/lang/Object;)Z Code: 0: aload_3 1: instanceof #35; //class Foo 4: ifeq 35 7: aload_3 8: checkcast #35; //class Foo 11: invokevirtual #39; //Method Foo.bar:()D 14: dstore 4 16: dload_1 17: dload 4 19: dcmpl 20: ifne 27 23: iconst_1 24: goto 28 27: iconst_0 28: ifeq 35 31: iconst_1 32: goto 36 35: iconst_0 36: ireturn LineNumberTable: line 1: 0 LocalVariableTable: Start Length Slot Name Signature 0 37 0 this LFoo$; 0 37 1 $this D private Foo$(); Signature: ()V Code: 0: aload_0 1: invokespecial #40; //Method java/lang/Object."<init>":()V 4: aload_0 5: putstatic #42; //Field MODULE$:LFoo$; 8: return LineNumberTable: line 1: 0 }
          Hide
          Simon Ochsenreither added a comment -

          Not quite sure, but the cause could be that “private Foo$()” does “aload_0”, but is missing the LocalVariableTable.

          Show
          Simon Ochsenreither added a comment - Not quite sure, but the cause could be that “private Foo$()” does “aload_0”, but is missing the LocalVariableTable.
          Hide
          Simon Ochsenreither added a comment -

          Fixed in aad84ecba3.

          Show
          Simon Ochsenreither added a comment - Fixed in aad84ecba3.

            People

            • Assignee:
              Martin Odersky
              Reporter:
              Simon Ochsenreither
            • Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development