-
Notifications
You must be signed in to change notification settings - Fork 29
document usage #21
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
Comments
SethTisue
pushed a commit
to SethTisue/scala-parallel-collections
that referenced
this issue
Apr 25, 2017
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 scala#2 // class O$ 3: invokespecial scala#12 // Method "<init>":()V 6: return private O$(); Code: 0: aload_0 1: invokespecial scala#13 // Method C."<init>":()V 4: aload_0 5: putstatic scala#15 // Field MODULE$:LO$; 8: aload_0 9: invokevirtual scala#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
SethTisue
added a commit
to SethTisue/scala-parallel-collections
that referenced
this issue
Apr 25, 2017
and bump version in build.sbt, now that 0.1.2 is released fixes scala#21
Merged
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
what version of Scala to use (and what resolver to add to get it), what dependency to add to your build to use the module, how to test your Scala version properly so 2.11/2.12/2.13 cross-building still works (#22), what import you need to get the needed conversions (
import scala.collection.parallel.CollectionConverters._
)...this is a now task, not a someday task, since we are starting to have library maintainers actually use this (Scala.js is the first guinea pig)
The text was updated successfully, but these errors were encountered: