Skip to content

Commit

Permalink
Merge pull request #9181 from dotty-staging/fix-1441b
Browse files Browse the repository at this point in the history
Fix #1441: init MODULE$ in <clinit>
  • Loading branch information
liufengyun committed Aug 7, 2020
2 parents b8825a2 + 745d53c commit d5bdea8
Show file tree
Hide file tree
Showing 19 changed files with 329 additions and 114 deletions.
21 changes: 14 additions & 7 deletions .github/workflows/ci.yaml
Expand Up @@ -15,6 +15,9 @@ jobs:
container: lampepfl/dotty:2020-04-24

steps:
- name: Set JDK 11 as default
run: echo "::add-path::/usr/lib/jvm/java-11-openjdk-amd64/bin"

- name: Checkout cleanup script
uses: actions/checkout@v2

Expand Down Expand Up @@ -55,6 +58,9 @@ jobs:
container: lampepfl/dotty:2020-04-24

steps:
- name: Set JDK 11 as default
run: echo "::add-path::/usr/lib/jvm/java-11-openjdk-amd64/bin"

- name: Checkout cleanup script
uses: actions/checkout@v2

Expand Down Expand Up @@ -174,7 +180,7 @@ jobs:
- name: Test
run: ./project/scripts/sbt sbt-dotty/scripted

test_java11:
test_java8:
runs-on: self-hosted
container: lampepfl/dotty:2020-04-24
if: (
Expand All @@ -184,6 +190,9 @@ jobs:
github.event_name == 'schedule'

steps:
- name: Set JDK 8 as default
run: echo "::add-path::/usr/lib/jvm/java-1.8.0-openjdk-amd64/bin"

- name: Checkout cleanup script
uses: actions/checkout@v2

Expand Down Expand Up @@ -215,14 +224,12 @@ jobs:
restore-keys: ${{ runner.os }}-general-

- name: Test
run: |
export PATH="/usr/lib/jvm/java-11-openjdk-amd64/bin:$PATH"
./project/scripts/sbt ";compile ;test"
run: ./project/scripts/sbt ";compile ;test"

publish_nightly:
runs-on: self-hosted
container: lampepfl/dotty:2020-04-24
needs: [test, test_bootstrapped, community_build, test_sbt, test_java11]
needs: [test, test_bootstrapped, community_build, test_sbt, test_java8]
if: github.event_name == 'schedule'
env:
NIGHTLYBUILD: yes
Expand Down Expand Up @@ -323,7 +330,7 @@ jobs:
publish_release:
runs-on: self-hosted
container: lampepfl/dotty:2020-04-24
needs: [test, test_bootstrapped, community_build, test_sbt, test_java11]
needs: [test, test_bootstrapped, community_build, test_sbt, test_java8]
if: github.event_name == 'push' &&
startsWith(github.event.ref, 'refs/tags/') &&
!startsWith(github.event.ref, 'refs/tags/sbt-dotty-')
Expand Down Expand Up @@ -475,7 +482,7 @@ jobs:
publish_sbt_release:
runs-on: self-hosted
container: lampepfl/dotty:2020-04-24
needs: [test, test_bootstrapped, community_build, test_sbt, test_java11]
needs: [test, test_bootstrapped, community_build, test_sbt, test_java8]
if: github.event_name == 'push' &&
startsWith(github.event.ref, 'refs/tags/sbt-dotty-')

Expand Down
33 changes: 11 additions & 22 deletions compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala
Expand Up @@ -364,9 +364,13 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
}
else {
mnode.visitVarInsn(asm.Opcodes.ALOAD, 0)
generatedType =
if (tree.symbol == defn.ArrayClass) ObjectReference
else classBTypeFromSymbol(claszSymbol)
// When compiling Array.scala, the constructor invokes `Array.this.super.<init>`. The expectedType
// is `[Object` (computed by typeToBType, the type of This(Array) is `Array[T]`). If we would set
// the generatedType to `Array` below, the call to adapt at the end would fail. The situation is
// similar for primitives (`I` vs `Int`).
if (tree.symbol != defn.ArrayClass && !tree.symbol.isPrimitiveValueClass) {
generatedType = classBTypeFromSymbol(claszSymbol)
}
}

case DesugaredSelect(Ident(nme.EMPTY_PACKAGE), module) =>
Expand Down Expand Up @@ -710,33 +714,18 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
if (t.symbol ne defn.Object_synchronized) genTypeApply(t)
else genSynchronized(app, expectedType)

case Apply(fun @ DesugaredSelect(Super(_, _), _), args) =>
def initModule(): Unit = {
// we initialize the MODULE$ field immediately after the super ctor
if (!isModuleInitialized &&
jMethodName == INSTANCE_CONSTRUCTOR_NAME &&
fun.symbol.javaSimpleName == INSTANCE_CONSTRUCTOR_NAME &&
claszSymbol.isStaticModuleClass) {
isModuleInitialized = true
mnode.visitVarInsn(asm.Opcodes.ALOAD, 0)
mnode.visitFieldInsn(
asm.Opcodes.PUTSTATIC,
thisName,
str.MODULE_INSTANCE_FIELD,
"L" + thisName + ";"
)
}
}
case Apply(fun @ DesugaredSelect(Super(superQual, _), _), args) =>
// 'super' call: Note: since constructors are supposed to
// return an instance of what they construct, we have to take
// special care. On JVM they are 'void', and Scala forbids (syntactically)
// to call super constructors explicitly and/or use their 'returned' value.
// therefore, we can ignore this fact, and generate code that leaves nothing
// on the stack (contrary to what the type in the AST says).
mnode.visitVarInsn(asm.Opcodes.ALOAD, 0)

// scala/bug#10290: qual can be `this.$outer()` (not just `this`), so we call genLoad (not just ALOAD_0)
genLoad(superQual)
genLoadArguments(args, paramTKs(app))
generatedType = genCallMethod(fun.symbol, InvokeStyle.Super, app.span)
initModule()

// 'new' constructor call: Note: since constructors are
// thought to return an instance of what they construct,
Expand Down
1 change: 1 addition & 0 deletions compiler/src/dotty/tools/backend/jvm/BCodeIdiomatic.scala
Expand Up @@ -29,6 +29,7 @@ trait BCodeIdiomatic {
case "jvm-1.6" => asm.Opcodes.V1_6
case "jvm-1.7" => asm.Opcodes.V1_7
case "jvm-1.8" => asm.Opcodes.V1_8
case "jvm-9" => asm.Opcodes.V9
}

lazy val majorVersion: Int = (classfileVersion & 0xFF)
Expand Down

0 comments on commit d5bdea8

Please sign in to comment.