You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
SD-194 Tweak module initialization to comply with JVM spec
Dmitry learned that we've been relying on a bug in the
verifier that will be fixed in JDK 9 under the new
classfile format.
Assignment to a static final must occur lexically
within the <clinit>. We were performing this assignment
from the constructor of the module class.
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
```
We currently assign the MODULE$ field after the super class constructors are finished,
but before the rest of the module constructor is called.
```
private p1.O$();
Code:
0: aload_0
1: invokespecial #30 // Method java/lang/Object."<init>":()V
4: aload_0
5: putstatic #32 // Field MODULE$:Lp1/O$;
8: new #34 // class p1/CC
11: dup
12: invokespecial #35 // Method p1/CC."<init>":()V
15: invokevirtual #38 // Method p1/CC.foo:()V
18: return
```
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
```
Fixes scala/scala-dev#SD-194
0 commit comments