-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Added better warning message if you've forgotten to run pull-binary-libs... #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…ibs.sh after initial checkout.
Thanks! I hit exactly this problem before. |
I just had ant run the script. I don't know what happens on windows though. |
Probably better it issue a warning an then try to run the script.... should I alter this? |
Well, it does echo a message. I thought it would be a warning but it just says "info". I guess echo level="warn" was a bad guess. init.starr: |
scala.reflect.api.Symbols documentation
The REPL :java -app command is a convenience to locate the body of DelayedInit code. Now it will look for new style delayedEndpoints on the class before it falls back to showing the apply method of the delayedInit$body closure. ``` apm@mara:~/tmp$ skala Welcome to Scala version 2.11.0-20130711-153246-eb1c3137f5 (OpenJDK 64-Bit Server VM, Java 1.7.0_21). Type in expressions to have them evaluated. Type :help for more information. scala> :javap -pv -app delayed.C public final void delayedEndpoint$delayed$C$1(); flags: ACC_PUBLIC, ACC_FINAL Code: stack=2, locals=1, args_size=1 0: getstatic scala#29 // Field scala/Predef$.MODULE$:Lscala/Predef$; 3: ldc scala#31 // String this is the initialization code of C 5: invokevirtual scala#35 // Method scala/Predef$.println:(Ljava/lang/Object;)V 8: return LocalVariableTable: Start Length Slot Name Signature 0 9 0 this Ldelayed/C; LineNumberTable: line 11: 0 scala> :q apm@mara:~/tmp$ rm delayed/*.class apm@mara:~/tmp$ scalac delayed.scala apm@mara:~/tmp$ skala Welcome to Scala version 2.11.0-20130711-153246-eb1c3137f5 (OpenJDK 64-Bit Server VM, Java 1.7.0_21). Type in expressions to have them evaluated. Type :help for more information. scala> :javap -pv -app delayed.C public final java.lang.Object apply(); flags: ACC_PUBLIC, ACC_FINAL Code: stack=2, locals=1, args_size=1 0: getstatic scala#13 // Field scala/Predef$.MODULE$:Lscala/Predef$; 3: ldc scala#15 // String this is the initialization code of C 5: invokevirtual scala#19 // Method scala/Predef$.println:(Ljava/lang/Object;)V 8: getstatic scala#25 // Field scala/runtime/BoxedUnit.UNIT:Lscala/runtime/BoxedUnit; 11: areturn LocalVariableTable: Start Length Slot Name Signature 0 12 0 this Ldelayed/C$delayedInit$body; LineNumberTable: line 11: 0 line 10: 8 ```
``` cat sandbox/test.scala && qscalac -target:jvm-1.8 -Ybackend:GenASM sandbox/test.scala && (for c in 'T' 'T$' 'C'; do javap -c -classpath . $c; done) | cat -v; qscala Test trait T { def t(s: String) = 42 val v = 42 } class C extends T object Test { def main(args: Array[String]): Unit = { println(new C().t("")) } } Compiled from "test.scala" public interface T { public abstract void T$_setter_$v_$eq(int); public int t(java.lang.String); Code: 0: bipush 42 2: ireturn public abstract int v(); } Error: class not found: T$ Compiled from "test.scala" public class C implements T { public int v(); Code: 0: aload_0 1: getfield #15 // Field v:I 4: ireturn public void T$_setter_$v_$eq(int); Code: 0: aload_0 1: iload_1 2: putfield #15 // Field v:I 5: return public C(); Code: 0: aload_0 1: invokespecial #24 // Method java/lang/Object."<init>":()V 4: aload_0 5: invokestatic #30 // Method T$class.$init$:(LT;)V 8: return } 42 topic/indylambda-emit-indy /code/scala2 cat sandbox/test.scala && qscalac -target:jvm-1.8 -Ybackend:GenBCode sandbox/test.scala && (for c in 'T' 'T$' 'C'; do javap -c -classpath . $c; done) | cat -v; qscala Test trait T { def t(s: String) = 42 val v = 42 } class C extends T object Test { def main(args: Array[String]): Unit = { println(new C().t("")) } } Compiled from "test.scala" public interface T { public abstract void T$_setter_$v_$eq(int); public int t(java.lang.String); Code: 0: bipush 42 2: ireturn public abstract int v(); } Error: class not found: T$ Compiled from "test.scala" public class C implements T { public int v(); Code: 0: aload_0 1: getfield #15 // Field v:I 4: ireturn public void T$_setter_$v_$eq(int); Code: 0: aload_0 1: iload_1 2: putfield #15 // Field v:I 5: return public C(); Code: 0: aload_0 1: invokespecial #24 // Method java/lang/Object."<init>":()V 4: aload_0 5: invokestatic #30 // Method T$class.$init$:(LT;)V 8: return } 42 ```
This corrects an error in the change to the trait encoding in scala#5003: getters in traits should have empty bodies and be emitted as abstract. ``` % ~/scala/2.12.0-M4/bin/scalac sandbox/test.scala && javap -c T Compiled from "test.scala" public interface T { public abstract void T$_setter_$x_$eq(int); public int x(); Code: 0: aload_0 1: invokeinterface scala#15, 1 // InterfaceMethod x:()I 6: ireturn public int y(); Code: 0: aload_0 1: invokeinterface scala#20, 1 // InterfaceMethod y:()I 6: ireturn public void y_$eq(int); Code: 0: aload_0 1: iload_1 2: invokeinterface scala#24, 2 // InterfaceMethod y_$eq:(I)V 7: return public void $init$(); Code: 0: aload_0 1: bipush 42 3: invokeinterface scala#29, 2 // InterfaceMethod T$_setter_$x_$eq:(I)V 8: aload_0 9: bipush 24 11: invokeinterface scala#24, 2 // InterfaceMethod y_$eq:(I)V 16: return } % qscalac sandbox/test.scala && javap -c T Compiled from "test.scala" public interface T { public abstract void T$_setter_$x_$eq(int); public abstract int x(); public abstract int y(); public abstract void y_$eq(int); public static void $init$(T); Code: 0: aload_0 1: bipush 42 3: invokeinterface scala#21, 2 // InterfaceMethod T$_setter_$x_$eq:(I)V 8: aload_0 9: bipush 24 11: invokeinterface scala#23, 2 // InterfaceMethod y_$eq:(I)V 16: return public void $init$(); Code: 0: aload_0 1: invokestatic scala#27 // Method $init$:(LT;)V 4: return } ```
And use this as the target of the default methods or statically resolved super or $init calls. The call-site change is predicated on `-Yuse-trait-statics` as a stepping stone for experimentation / bootstrapping. I have performed this transformation in the backend, rather than trying to reflect this in the view from Scala symbols + ASTs. Once we commit to this change, we can remove the `lateInterfaces` bookkeeping from the backend, as we no long will need to add ancestor interfaces as direct parents to allow use of invokespecial for super calls. ``` > ;scalac sandbox/test.scala ; scala Test [info] Running scala.tools.nsc.MainGenericRunner -usejavacp Test T C [success] Total time: 2 s, completed 04/05/2016 11:07:13 AM > eval "javap -classpath . -c -private C".!! [info] ans: String = Compiled from "test.scala" [info] public class C implements T { [info] public C(); [info] Code: [info] 0: aload_0 [info] 1: invokespecial scala#14 // Method java/lang/Object."<init>":()V [info] 4: aload_0 [info] 5: invokespecial scala#17 // Method T.$init$:()V [info] 8: getstatic scala#23 // Field scala/Predef$.MODULE$:Lscala/Predef$; [info] 11: ldc scala#24 // String C [info] 13: invokevirtual scala#28 // Method scala/Predef$.println:(Ljava/lang/Object;)V [info] 16: aload_0 [info] 17: invokespecial scala#32 // Method T.foo:()I [info] 20: pop [info] 21: return [info] } > ;scalac -Yuse-trait-statics sandbox/test.scala ; scala Test [info] Running scala.tools.nsc.MainGenericRunner -usejavacp Test T C [success] Total time: 2 s, completed 04/05/2016 11:07:39 AM > eval "javap -classpath . -c -private C".!! [info] ans: String = Compiled from "test.scala" [info] public class C implements T { [info] public C(); [info] Code: [info] 0: aload_0 [info] 1: invokespecial scala#14 // Method java/lang/Object."<init>":()V [info] 4: aload_0 [info] 5: invokestatic scala#18 // Method T.$init$:(LT;)V [info] 8: getstatic scala#24 // Field scala/Predef$.MODULE$:Lscala/Predef$; [info] 11: ldc scala#25 // String C [info] 13: invokevirtual scala#29 // Method scala/Predef$.println:(Ljava/lang/Object;)V [info] 16: aload_0 [info] 17: invokestatic scala#33 // Method T.foo:(LT;)I [info] 20: pop [info] 21: return [info] } > eval "javap -classpath . -c -private T".!! [info] ans: String = Compiled from "test.scala" [info] public interface T { [info] public static int foo(T); [info] Code: [info] 0: iconst_0 [info] 1: ireturn [info] [info] public int foo(); [info] Code: [info] 0: aload_0 [info] 1: invokestatic scala#15 // Method foo:(LT;)I [info] 4: ireturn [info] [info] public static void $init$(T); [info] Code: [info] 0: getstatic scala#24 // Field scala/Predef$.MODULE$:Lscala/Predef$; [info] 3: ldc scala#25 // String T [info] 5: invokevirtual scala#29 // Method scala/Predef$.println:(Ljava/lang/Object;)V [info] 8: return [info] [info] public void $init$(); [info] Code: [info] 0: aload_0 [info] 1: invokestatic scala#32 // Method $init$:(LT;)V [info] 4: return [info] } ```
This corrects an error in the change to the trait encoding in scala#5003: getters in traits should have empty bodies and be emitted as abstract. ``` % ~/scala/2.12.0-M4/bin/scalac sandbox/test.scala && javap -c T Compiled from "test.scala" public interface T { public abstract void T$_setter_$x_$eq(int); public int x(); Code: 0: aload_0 1: invokeinterface scala#15, 1 // InterfaceMethod x:()I 6: ireturn public int y(); Code: 0: aload_0 1: invokeinterface scala#20, 1 // InterfaceMethod y:()I 6: ireturn public void y_$eq(int); Code: 0: aload_0 1: iload_1 2: invokeinterface scala#24, 2 // InterfaceMethod y_$eq:(I)V 7: return public void $init$(); Code: 0: aload_0 1: bipush 42 3: invokeinterface scala#29, 2 // InterfaceMethod T$_setter_$x_$eq:(I)V 8: aload_0 9: bipush 24 11: invokeinterface scala#24, 2 // InterfaceMethod y_$eq:(I)V 16: return } % qscalac sandbox/test.scala && javap -c T Compiled from "test.scala" public interface T { public abstract void T$_setter_$x_$eq(int); public abstract int x(); public abstract int y(); public abstract void y_$eq(int); public static void $init$(T); Code: 0: aload_0 1: bipush 42 3: invokeinterface scala#21, 2 // InterfaceMethod T$_setter_$x_$eq:(I)V 8: aload_0 9: bipush 24 11: invokeinterface scala#23, 2 // InterfaceMethod y_$eq:(I)V 16: return public void $init$(); Code: 0: aload_0 1: invokestatic scala#27 // Method $init$:(LT;)V 4: return } ```
And use this as the target of the default methods or statically resolved super or $init calls. The call-site change is predicated on `-Yuse-trait-statics` as a stepping stone for experimentation / bootstrapping. I have performed this transformation in the backend, rather than trying to reflect this in the view from Scala symbols + ASTs. Once we commit to this change, we can remove the `lateInterfaces` bookkeeping from the backend, as we no long will need to add ancestor interfaces as direct parents to allow use of invokespecial for super calls. ``` > ;scalac sandbox/test.scala ; scala Test [info] Running scala.tools.nsc.MainGenericRunner -usejavacp Test T C [success] Total time: 2 s, completed 04/05/2016 11:07:13 AM > eval "javap -classpath . -c -private C".!! [info] ans: String = Compiled from "test.scala" [info] public class C implements T { [info] public C(); [info] Code: [info] 0: aload_0 [info] 1: invokespecial scala#14 // Method java/lang/Object."<init>":()V [info] 4: aload_0 [info] 5: invokespecial scala#17 // Method T.$init$:()V [info] 8: getstatic scala#23 // Field scala/Predef$.MODULE$:Lscala/Predef$; [info] 11: ldc scala#24 // String C [info] 13: invokevirtual scala#28 // Method scala/Predef$.println:(Ljava/lang/Object;)V [info] 16: aload_0 [info] 17: invokespecial scala#32 // Method T.foo:()I [info] 20: pop [info] 21: return [info] } > ;scalac -Yuse-trait-statics sandbox/test.scala ; scala Test [info] Running scala.tools.nsc.MainGenericRunner -usejavacp Test T C [success] Total time: 2 s, completed 04/05/2016 11:07:39 AM > eval "javap -classpath . -c -private C".!! [info] ans: String = Compiled from "test.scala" [info] public class C implements T { [info] public C(); [info] Code: [info] 0: aload_0 [info] 1: invokespecial scala#14 // Method java/lang/Object."<init>":()V [info] 4: aload_0 [info] 5: invokestatic scala#18 // Method T.$init$:(LT;)V [info] 8: getstatic scala#24 // Field scala/Predef$.MODULE$:Lscala/Predef$; [info] 11: ldc scala#25 // String C [info] 13: invokevirtual scala#29 // Method scala/Predef$.println:(Ljava/lang/Object;)V [info] 16: aload_0 [info] 17: invokestatic scala#33 // Method T.foo:(LT;)I [info] 20: pop [info] 21: return [info] } > eval "javap -classpath . -c -private T".!! [info] ans: String = Compiled from "test.scala" [info] public interface T { [info] public static int foo(T); [info] Code: [info] 0: iconst_0 [info] 1: ireturn [info] [info] public int foo(); [info] Code: [info] 0: aload_0 [info] 1: invokestatic scala#15 // Method foo:(LT;)I [info] 4: ireturn [info] [info] public static void $init$(T); [info] Code: [info] 0: getstatic scala#24 // Field scala/Predef$.MODULE$:Lscala/Predef$; [info] 3: ldc scala#25 // String T [info] 5: invokevirtual scala#29 // Method scala/Predef$.println:(Ljava/lang/Object;)V [info] 8: return [info] [info] public void $init$(); [info] Code: [info] 0: aload_0 [info] 1: invokestatic scala#32 // Method $init$:(LT;)V [info] 4: return [info] } ```
This corrects an error in the change to the trait encoding in scala#5003: getters in traits should have empty bodies and be emitted as abstract. ``` % ~/scala/2.12.0-M4/bin/scalac sandbox/test.scala && javap -c T Compiled from "test.scala" public interface T { public abstract void T$_setter_$x_$eq(int); public int x(); Code: 0: aload_0 1: invokeinterface scala#15, 1 // InterfaceMethod x:()I 6: ireturn public int y(); Code: 0: aload_0 1: invokeinterface scala#20, 1 // InterfaceMethod y:()I 6: ireturn public void y_$eq(int); Code: 0: aload_0 1: iload_1 2: invokeinterface scala#24, 2 // InterfaceMethod y_$eq:(I)V 7: return public void $init$(); Code: 0: aload_0 1: bipush 42 3: invokeinterface scala#29, 2 // InterfaceMethod T$_setter_$x_$eq:(I)V 8: aload_0 9: bipush 24 11: invokeinterface scala#24, 2 // InterfaceMethod y_$eq:(I)V 16: return } % qscalac sandbox/test.scala && javap -c T Compiled from "test.scala" public interface T { public abstract void T$_setter_$x_$eq(int); public abstract int x(); public abstract int y(); public abstract void y_$eq(int); public static void $init$(T); Code: 0: aload_0 1: bipush 42 3: invokeinterface scala#21, 2 // InterfaceMethod T$_setter_$x_$eq:(I)V 8: aload_0 9: bipush 24 11: invokeinterface scala#23, 2 // InterfaceMethod y_$eq:(I)V 16: return public void $init$(); Code: 0: aload_0 1: invokestatic scala#27 // Method $init$:(LT;)V 4: return } ```
And use this as the target of the default methods or statically resolved super or $init calls. The call-site change is predicated on `-Yuse-trait-statics` as a stepping stone for experimentation / bootstrapping. I have performed this transformation in the backend, rather than trying to reflect this in the view from Scala symbols + ASTs. ``` > ;scalac sandbox/test.scala ; scala Test [info] Running scala.tools.nsc.MainGenericRunner -usejavacp Test T C [success] Total time: 2 s, completed 04/05/2016 11:07:13 AM > eval "javap -classpath . -c -private C".!! [info] ans: String = Compiled from "test.scala" [info] public class C implements T { [info] public C(); [info] Code: [info] 0: aload_0 [info] 1: invokespecial scala#14 // Method java/lang/Object."<init>":()V [info] 4: aload_0 [info] 5: invokespecial scala#17 // Method T.$init$:()V [info] 8: getstatic scala#23 // Field scala/Predef$.MODULE$:Lscala/Predef$; [info] 11: ldc scala#24 // String C [info] 13: invokevirtual scala#28 // Method scala/Predef$.println:(Ljava/lang/Object;)V [info] 16: aload_0 [info] 17: invokespecial scala#32 // Method T.foo:()I [info] 20: pop [info] 21: return [info] } > ;scalac -Yuse-trait-statics sandbox/test.scala ; scala Test [info] Running scala.tools.nsc.MainGenericRunner -usejavacp Test T C [success] Total time: 2 s, completed 04/05/2016 11:07:39 AM > eval "javap -classpath . -c -private C".!! [info] ans: String = Compiled from "test.scala" [info] public class C implements T { [info] public C(); [info] Code: [info] 0: aload_0 [info] 1: invokespecial scala#14 // Method java/lang/Object."<init>":()V [info] 4: aload_0 [info] 5: invokestatic scala#18 // Method T.$init$:(LT;)V [info] 8: getstatic scala#24 // Field scala/Predef$.MODULE$:Lscala/Predef$; [info] 11: ldc scala#25 // String C [info] 13: invokevirtual scala#29 // Method scala/Predef$.println:(Ljava/lang/Object;)V [info] 16: aload_0 [info] 17: invokestatic scala#33 // Method T.foo:(LT;)I [info] 20: pop [info] 21: return [info] } > eval "javap -classpath . -c -private T".!! [info] ans: String = Compiled from "test.scala" [info] public interface T { [info] public static int foo(T); [info] Code: [info] 0: iconst_0 [info] 1: ireturn [info] [info] public int foo(); [info] Code: [info] 0: aload_0 [info] 1: invokestatic scala#15 // Method foo:(LT;)I [info] 4: ireturn [info] [info] public static void $init$(T); [info] Code: [info] 0: getstatic scala#24 // Field scala/Predef$.MODULE$:Lscala/Predef$; [info] 3: ldc scala#25 // String T [info] 5: invokevirtual scala#29 // Method scala/Predef$.println:(Ljava/lang/Object;)V [info] 8: return [info] [info] } ```
This corrects an error in the change to the trait encoding in #5003: getters in traits should have empty bodies and be emitted as abstract. ``` % ~/scala/2.12.0-M4/bin/scalac sandbox/test.scala && javap -c T Compiled from "test.scala" public interface T { public abstract void T$_setter_$x_$eq(int); public int x(); Code: 0: aload_0 1: invokeinterface #15, 1 // InterfaceMethod x:()I 6: ireturn public int y(); Code: 0: aload_0 1: invokeinterface #20, 1 // InterfaceMethod y:()I 6: ireturn public void y_$eq(int); Code: 0: aload_0 1: iload_1 2: invokeinterface #24, 2 // InterfaceMethod y_$eq:(I)V 7: return public void $init$(); Code: 0: aload_0 1: bipush 42 3: invokeinterface #29, 2 // InterfaceMethod T$_setter_$x_$eq:(I)V 8: aload_0 9: bipush 24 11: invokeinterface #24, 2 // InterfaceMethod y_$eq:(I)V 16: return } % qscalac sandbox/test.scala && javap -c T Compiled from "test.scala" public interface T { public abstract void T$_setter_$x_$eq(int); public abstract int x(); public abstract int y(); public abstract void y_$eq(int); public static void $init$(T); Code: 0: aload_0 1: bipush 42 3: invokeinterface #21, 2 // InterfaceMethod T$_setter_$x_$eq:(I)V 8: aload_0 9: bipush 24 11: invokeinterface #23, 2 // InterfaceMethod y_$eq:(I)V 16: return public void $init$(); Code: 0: aload_0 1: invokestatic #27 // Method $init$:(LT;)V 4: return } ```
Top level modules in Scala currently desugar as: ``` class C; object O extends C { toString } ``` ``` public final class O$ extends C { public static final O$ MODULE$; public static {}; Code: 0: new #2 // class O$ 3: invokespecial #12 // Method "<init>":()V 6: return private O$(); Code: 0: aload_0 1: invokespecial #13 // Method C."<init>":()V 4: aload_0 5: putstatic #15 // Field MODULE$:LO$; 8: aload_0 9: invokevirtual #21 // Method java/lang/Object.toString:()Ljava/lang/String; 12: pop 13: return } ``` The static initalizer `<clinit>` calls the constructor `<init>`, which invokes superclass constructor, assigns `MODULE$= this`, and then runs the remainder of the object's constructor (`toString` in the example above.) It turns out that this relies on a bug in the JVM's verifier: assignment to a static final must occur lexically within the <clinit>, not from within `<init>` (even if the latter is happens to be called by the former). I'd like to move the assignment to <clinit> but that would change behaviour of "benign" cyclic references between modules. Example: ``` package p1; class CC { def foo = O.bar}; object O {new CC().foo; def bar = println(1)}; // Exiting paste mode, now interpreting. scala> p1.O 1 ``` This relies on the way that we assign MODULE$ field after the super class constructors are finished, but before the rest of the module constructor is called. Instead, this commit removes the ACC_FINAL bit from the field. It actually wasn't behaving as final at all, precisely the issue that the stricter verifier now alerts us to. ``` scala> :paste -raw // Entering paste mode (ctrl-D to finish) package p1; object O // Exiting paste mode, now interpreting. scala> val O1 = p1.O O1: p1.O.type = p1.O$@ee7d9f1 scala> scala.reflect.ensureAccessible(p1.O.getClass.getDeclaredConstructor()).newInstance() res0: p1.O.type = p1.O$@64cee07 scala> O1 eq p1.O res1: Boolean = false ``` We will still achieve safe publication of the assignment to other threads by virtue of the fact that `<clinit>` is executed within the scope of an initlization lock, as specified by: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.5 Fixes scala/scala-dev#SD-194
Drop unused operations in NameHelper
Fixes the issue where someone checks out the scala repository fresh and ANT just issues a big old ugly error message rather than telling you that you have to run the pull-binary-deps.sh script.
Review by @SoundRabbit or @paulp