10000 Added better warning message if you've forgotten to run pull-binary-libs... by jsuereth · Pull Request #15 · scala/scala · GitHub
[go: up one dir, main page]

Skip to content

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

Closed
wants to merge 1 commit into from

Conversation

jsuereth
Copy link
Contributor
@jsuereth jsuereth commented Dec 2, 2011

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

@soc
Copy link
Contributor
soc commented Dec 2, 2011

Thanks! I hit exactly this problem before.

@paulp
Copy link
Contributor
paulp commented Dec 2, 2011

I just had ant run the script. I don't know what happens on windows though.

@paulp paulp closed this Dec 2, 2011
@jsuereth
Copy link
Contributor Author
jsuereth commented Dec 2, 2011

Probably better it issue a warning an then try to run the script.... should I alter this?

@paulp
Copy link
Contributor
paulp commented Dec 2, 2011

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:
[echo] Downloading bootstrap libs. (To do this by hand, run ./pull-binary-libs.sh)
[exec] Obtaining [/scratch/trunk4/docs/examples/plugintemplate/lib/scalatest.jar] from binary repository...
[exec] Downloading from http://typesafe.artifactoryonline.com/typesafe/scala-sha-bootstrap/org/scala-lang/bootstrap/8b6ba65c8146217333f0762087fe2340d572e832/docs/examples/plugintemplate/lib/scalatest.jar
[exec] Obtaining [/scratch/trunk4/lib/ant/ant-contrib.jar] from binary repository...

@phaller phaller mentioned this pull request May 1, 2012
havocp referenced this pull request in havocp/scala May 2, 2012
@phaller phaller mentioned this pull request May 3, 2012
heathermiller pushed a commit to heathermiller/scala that referenced this pull request Oct 11, 2012
scala.reflect.api.Symbols documentation
som-snytt added a commit to som-snytt/scala that referenced this pull request Jul 16, 2013
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
```
retronym referenced this pull request in retronym/scala Apr 23, 2015
```
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
```
lrytz pushed a commit to lrytz/scala that referenced this pull request May 20, 2016
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
}
```
lrytz pushed a commit to lrytz/scala that referenced this pull request May 20, 2016
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] }
```
lrytz pushed a commit to lrytz/scala that referenced this pull request May 25, 2016
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
}
```
lrytz pushed a commit to lrytz/scala that referenced this pull request May 25, 2016
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] }
```
lrytz pushed a commit to lrytz/scala that referenced this pull request Jun 6, 2016
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
}
```
lrytz pushed a commit to lrytz/scala that referenced this pull request Jun 6, 2016
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] }
```
lrytz pushed a commit that referenced this pull request Jun 29, 2016
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
}
```
adriaanm pushed a commit that referenced this pull request Aug 22, 2016
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
OlivierBlanvillain pushed a commit to OlivierBlanvillain/scala that referenced this pull request Jun 27, 2017
Drop unused operations in NameHelper
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
0