summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-01-29 18:47:01 +0100
committerJason Zaugg <jzaugg@gmail.com>2013-01-29 18:56:07 +0100
commit0679da5440869d170df8a485db03532f9f49e04f (patch)
treeeb0f80eb80606335abf35fa8216377469dad2d96 /src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
parenteff78b852e8b866badf9b9738f896c2a31c05474 (diff)
downloadscala-0679da5440869d170df8a485db03532f9f49e04f.tar.gz
scala-0679da5440869d170df8a485db03532f9f49e04f.tar.bz2
scala-0679da5440869d170df8a485db03532f9f49e04f.zip
[backport] SI-6301 / SI-6572 specialization regressions
Squashed commit of the following: commit a3680be29ccd5314c5d027d473b37940eaecd530 Author: Paul Phillips <paulp@improving.org> Date: Fri Aug 31 10:20:16 2012 -0700 Actual fix for SI-6301, specialized crasher. This means the workaround in the previous commit is no longer reached, but it should remain where it is as a much needed layer of robustness/useful error reporting. Conflicts: src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala src/compiler/scala/tools/nsc/typechecker/Duplicators.scala commit f4c45ae204ce3ff3c16b19cab266d0b6515b6e0f Author: Paul Phillips <paulp@improving.org> Date: Fri Aug 31 10:49:24 2012 -0700 Rewrite of GenICode adapt. Started for debuggability, stayed for clarify/performance. Conflicts: src/compiler/scala/tools/nsc/backend/icode/GenICode.scala commit 74842f72a0af485e5def796f777f7003f969d75b Author: Paul Phillips <paulp@improving.org> Date: Fri Aug 31 08:45:34 2012 -0700 Workaround for SI-6301, @specialize crasher. SpecializeTypes is generating symbols with overloaded types which then proceed to crash in CleanUp or GenICode. Until I or someone works out why that is, take a look in case the overload is easily disambiguated by the argument list arity, in which case warn and proceed.
Diffstat (limited to 'src/compiler/scala/tools/nsc/backend/icode/GenICode.scala')
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala60
1 files changed, 22 insertions, 38 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index fd2b11898c..44d7a1929b 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -1164,34 +1164,28 @@ abstract class GenICode extends SubComponent {
resCtx
}
- private def adapt(from: TypeKind, to: TypeKind, ctx: Context, pos: Position): Unit = {
- if (!(from <:< to) && !(from == NullReference && to == NothingReference)) {
- to match {
- case UNIT =>
- ctx.bb.emit(DROP(from), pos)
- debuglog("Dropped an " + from);
-
- case _ =>
- debugassert(from != UNIT, "Can't convert from UNIT to " + to + " at: " + pos)
- assert(!from.isReferenceType && !to.isReferenceType,
- "type error: can't convert from " + from + " to " + to +" in unit " + unit.source + " at " + pos)
-
- ctx.bb.emit(CALL_PRIMITIVE(Conversion(from, to)), pos)
- }
- } else if (from == NothingReference) {
- ctx.bb.emit(THROW(ThrowableClass))
- ctx.bb.enterIgnoreMode
- } else if (from == NullReference) {
- ctx.bb.emit(DROP(from))
- ctx.bb.emit(CONSTANT(Constant(null)))
+ private def adapt(from: TypeKind, to: TypeKind, ctx: Context, pos: Position) {
+ // An awful lot of bugs explode here - let's leave ourselves more clues.
+ // A typical example is an overloaded type assigned after typer.
+ log(s"GenICode#adapt($from, $to, $ctx, $pos)")
+
+ val conforms = (from <:< to) || (from == NullReference && to == NothingReference)
+ def coerce(from: TypeKind, to: TypeKind) = ctx.bb.emit(CALL_PRIMITIVE(Conversion(from, to)), pos)
+ def checkAssertions() {
+ def msg = s"Can't convert from $from to $to in unit ${unit.source} at $pos"
+ debugassert(from != UNIT, msg)
+ assert(!from.isReferenceType && !to.isReferenceType, msg)
}
- else if (from == ThrowableReference && !(ThrowableClass.tpe <:< to.toType)) {
- log("Inserted check-cast on throwable to " + to + " at " + pos)
- ctx.bb.emit(CHECK_CAST(to))
+ if (conforms) from match {
+ case NothingReference => ctx.bb.emit(THROW(ThrowableClass)) ; ctx.bb.enterIgnoreMode
+ case NullReference => ctx.bb.emit(Seq(DROP(from), CONSTANT(Constant(null))))
+ case ThrowableReference if !(ThrowableClass.tpe <:< to.toType) => ctx.bb.emit(CHECK_CAST(to)) // downcast throwables
+ case BYTE | SHORT | CHAR | INT if to == LONG => coerce(INT, LONG) // widen subrange types
+ case _ => ()
}
- else (from, to) match {
- case (BYTE, LONG) | (SHORT, LONG) | (CHAR, LONG) | (INT, LONG) => ctx.bb.emit(CALL_PRIMITIVE(Conversion(INT, LONG)))
- case _ => ()
+ else to match {
+ case UNIT => ctx.bb.emit(DROP(from), pos) // value discarding
+ case _ => checkAssertions() ; coerce(from, to) // other primitive coercions
}
}
@@ -1907,18 +1901,8 @@ abstract class GenICode extends SubComponent {
var handlerCount = 0
- override def toString(): String = {
- val buf = new StringBuilder()
- buf.append("\tpackage: ").append(packg).append('\n')
- buf.append("\tclazz: ").append(clazz).append('\n')
- buf.append("\tmethod: ").append(method).append('\n')
- buf.append("\tbb: ").append(bb).append('\n')
- buf.append("\tlabels: ").append(labels).append('\n')
- buf.append("\texception handlers: ").append(handlers).append('\n')
- buf.append("\tcleanups: ").append(cleanups).append('\n')
- buf.append("\tscope: ").append(scope).append('\n')
- buf.toString()
- }
+ override def toString =
+ s"package $packg { class $clazz { def $method { bb=$bb } } }"
def loadException(ctx: Context, exh: ExceptionHandler, pos: Position) = {
debuglog("Emitting LOAD_EXCEPTION for class: " + exh.loadExceptionClass)