summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2014-01-16 12:58:14 -0800
committerAdriaan Moors <adriaan.moors@typesafe.com>2014-01-16 12:58:14 -0800
commitfe408de32ba84a46bba026a17fe3b9311404e5c5 (patch)
treedfc0f80885caef907a8b1578174be6813161e93d /src/compiler
parentb2963960820734e27d334738cfff5b5354536ec5 (diff)
parentf9cbcbdaf81800b98a6774ca1e1dffcf2875fe4e (diff)
downloadscala-fe408de32ba84a46bba026a17fe3b9311404e5c5.tar.gz
scala-fe408de32ba84a46bba026a17fe3b9311404e5c5.tar.bz2
scala-fe408de32ba84a46bba026a17fe3b9311404e5c5.zip
Merge pull request #3278 from magarciaEPFL/backendish48
improvements to GenBCode
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala13
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeGlue.scala8
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala10
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeSyncAndTry.scala4
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeTypes.scala31
7 files changed, 50 insertions, 19 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
index 4f9f4c9e31..c8845344e9 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
@@ -88,7 +88,9 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
def genThrow(expr: Tree): BType = {
val thrownKind = tpeTK(expr)
- assert(exemplars.get(thrownKind).isSubtypeOf(ThrowableReference))
+ // `throw null` is valid although scala.Null (as defined in src/libray-aux) isn't a subtype of Throwable.
+ // Similarly for scala.Nothing (again, as defined in src/libray-aux).
+ assert(thrownKind.isNullType || thrownKind.isNothingType || exemplars.get(thrownKind).isSubtypeOf(ThrowableReference))
genLoad(expr, thrownKind)
lineNumber(expr)
emit(asm.Opcodes.ATHROW) // ICode enters here into enterIgnoreMode, we'll rely instead on DCE at ClassNode level.
@@ -824,7 +826,6 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
/* Generate code that loads args into label parameters. */
def genLoadLabelArguments(args: List[Tree], lblDef: LabelDef, gotoPos: Position) {
- assert(args forall { a => !a.hasSymbolField || a.hasSymbolWhich( s => !s.isLabel) }, s"SI-6089 at: $gotoPos") // SI-6089
val aps = {
val params: List[Symbol] = lblDef.params.map(_.symbol)
@@ -857,12 +858,11 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
}
def genLoadModule(tree: Tree): BType = {
- // Working around SI-5604. Rather than failing the compile when we see a package here, check if there's a package object.
val module = (
if (!tree.symbol.isPackageClass) tree.symbol
else tree.symbol.info.member(nme.PACKAGE) match {
- case NoSymbol => abort(s"Cannot use package as value: $tree") ; NoSymbol
- case s => devWarning("Bug: found package class where package object expected. Converting.") ; s.moduleClass
+ case NoSymbol => abort(s"SI-5604: Cannot use package as value: $tree")
+ case s => abort(s"SI-5604: found package class where package object expected: $tree")
}
)
lineNumber(tree)
@@ -871,7 +871,8 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
}
def genLoadModule(module: Symbol) {
- if (claszSymbol == module.moduleClass && jMethodName != "readResolve") {
+ def inStaticMethod = methSymbol != null && methSymbol.isStaticMember
+ if (claszSymbol == module.moduleClass && jMethodName != "readResolve" && !inStaticMethod) {
mnode.visitVarInsn(asm.Opcodes.ALOAD, 0)
} else {
val mbt = symInfoTK(module)
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeGlue.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeGlue.scala
index 9dcf263f4f..cc3265c5f9 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeGlue.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeGlue.scala
@@ -661,6 +661,14 @@ abstract class BCodeGlue extends SubComponent {
val CT_NOTHING = brefType("scala/Nothing") // TODO needed?
val CT_NULL = brefType("scala/Null") // TODO needed?
+ val srBooleanRef = brefType("scala/runtime/BooleanRef")
+ val srByteRef = brefType("scala/runtime/ByteRef")
+ val srCharRef = brefType("scala/runtime/CharRef")
+ val srIntRef = brefType("scala/runtime/IntRef")
+ val srLongRef = brefType("scala/runtime/LongRef")
+ val srFloatRef = brefType("scala/runtime/FloatRef")
+ val srDoubleRef = brefType("scala/runtime/DoubleRef")
+
/* Map from type kinds to the Java reference types.
* Useful when pushing class literals onto the operand stack (ldc instruction taking a class literal).
* @see Predef.classOf
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
index 64ed094a47..6b1bb5b220 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
@@ -440,13 +440,11 @@ abstract class BCodeHelpers extends BCodeTypes with BytecodeWriters {
if (sym0 == definitions.NullClass) return RT_NULL;
if (sym0 == definitions.NothingClass) return RT_NOTHING;
- // Working around SI-5604. Rather than failing the compile when we see
- // a package here, check if there's a package object.
val sym = (
if (!sym0.isPackageClass) sym0
else sym0.info.member(nme.PACKAGE) match {
- case NoSymbol => abort(s"Cannot use package as value: ${sym0.fullName}")
- case s => devWarning("Bug: found package class where package object expected. Converting.") ; s.moduleClass
+ case NoSymbol => abort(s"SI-5604: Cannot use package as value: ${sym0.fullName}")
+ case s => abort(s"SI-5604: found package class where package object expected: $s")
}
)
@@ -561,7 +559,9 @@ abstract class BCodeHelpers extends BCodeTypes with BytecodeWriters {
memberCTK
}
- exemplar(csym) // side effect city
+
+ exemplar(csym).directMemberClasses = result
+
result
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala
index 529295389c..c3492b79a9 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala
@@ -46,6 +46,7 @@ abstract class BCodeIdiomatic extends BCodeGlue {
val ObjectReference = brefType("java/lang/Object")
val AnyRefReference = ObjectReference
+ val objArrayReference = arrayOf(ObjectReference)
val JAVA_LANG_OBJECT = ObjectReference
val JAVA_LANG_STRING = brefType("java/lang/String")
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala
index c921d11d00..360ce58ecc 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala
@@ -460,7 +460,7 @@ abstract class BCodeSkelBuilder extends BCodeHelpers {
}
def lineNumber(tree: Tree) {
if (!emitLines || !tree.pos.isDefined) return;
- val nr = tree.pos.line
+ val nr = tree.pos.finalPosition.line
if (nr != lastEmittedLineNr) {
lastEmittedLineNr = nr
lastInsn match {
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeSyncAndTry.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeSyncAndTry.scala
index 27bcbb82d4..9ddb7a3ce8 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeSyncAndTry.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeSyncAndTry.scala
@@ -386,10 +386,6 @@ abstract class BCodeSyncAndTry extends BCodeBodyBuilder {
/* Does this tree have a try-catch block? */
def mayCleanStack(tree: Tree): Boolean = tree exists { t => t.isInstanceOf[Try] }
- abstract class Cleanup(val value: AnyRef) { }
- case class MonitorRelease(v: Symbol) extends Cleanup(v) { }
- case class Finalizer(f: Tree) extends Cleanup (f) { }
-
trait EHClause
case class NamelessEH(typeToDrop: BType, caseBody: Tree) extends EHClause
case class BoundEH (patSymbol: Symbol, caseBody: Tree) extends EHClause
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeTypes.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeTypes.scala
index dd2d63ad17..1eca69936a 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeTypes.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeTypes.scala
@@ -24,11 +24,15 @@ abstract class BCodeTypes extends BCodeIdiomatic {
// when compiling the Scala library, some assertions don't hold (e.g., scala.Boolean has null superClass although it's not an interface)
val isCompilingStdLib = !(settings.sourcepath.isDefault)
+ val srBoxedUnit = brefType("scala/runtime/BoxedUnit")
+
// special names
var StringReference : BType = null
var ThrowableReference : BType = null
var jlCloneableReference : BType = null // java/lang/Cloneable
+ var jlNPEReference : BType = null // java/lang/NullPointerException
var jioSerializableReference : BType = null // java/io/Serializable
+ var scalaSerializableReference : BType = null // scala/Serializable
var classCastExceptionReference : BType = null // java/lang/ClassCastException
/* A map from scala primitive type-symbols to BTypes */
@@ -52,6 +56,8 @@ abstract class BCodeTypes extends BCodeIdiomatic {
/* The Object => String overload. */
var String_valueOf: Symbol = null
+ var ArrayInterfaces: Set[Tracked] = null
+
// scala.FunctionX and scala.runtim.AbstractFunctionX
val FunctionReference = new Array[Tracked](definitions.MaxFunctionArity + 1)
val AbstractFunctionReference = new Array[Tracked](definitions.MaxFunctionArity + 1)
@@ -128,15 +134,17 @@ abstract class BCodeTypes extends BCodeIdiomatic {
)
}
- exemplar(JavaCloneableClass).c
- exemplar(JavaSerializableClass).c
- exemplar(SerializableClass).c
+ exemplar(JavaCloneableClass)
+ exemplar(JavaSerializableClass)
+ exemplar(SerializableClass)
StringReference = exemplar(StringClass).c
StringBuilderReference = exemplar(StringBuilderClass).c
ThrowableReference = exemplar(ThrowableClass).c
jlCloneableReference = exemplar(JavaCloneableClass).c
+ jlNPEReference = exemplar(NullPointerExceptionClass).c
jioSerializableReference = exemplar(JavaSerializableClass).c
+ scalaSerializableReference = exemplar(SerializableClass).c
classCastExceptionReference = exemplar(ClassCastExceptionClass).c
/*
@@ -203,6 +211,23 @@ abstract class BCodeTypes extends BCodeIdiomatic {
* All methods of this class can-multi-thread
*/
case class Tracked(c: BType, flags: Int, sc: Tracked, ifaces: Array[Tracked], innersChain: Array[InnerClassEntry]) {
+
+ // not a case-field because we initialize it only for JVM classes we emit.
+ private var _directMemberClasses: List[BType] = null
+
+ def directMemberClasses: List[BType] = {
+ assert(_directMemberClasses != null, s"getter directMemberClasses() invoked too early for $c")
+ _directMemberClasses
+ }
+
+ def directMemberClasses_=(bs: List[BType]) {
+ if (_directMemberClasses != null) {
+ // TODO we enter here when both mirror class and plain class are emitted for the same ModuleClassSymbol.
+ assert(_directMemberClasses == bs.sortBy(_.off))
+ }
+ _directMemberClasses = bs.sortBy(_.off)
+ }
+
/* `isCompilingStdLib` saves the day when compiling:
* (1) scala.Nothing (the test `c.isNonSpecial` fails for it)
* (2) scala.Boolean (it has null superClass and is not an interface)