summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2007-07-12 15:01:25 +0000
committerIulian Dragos <jaguarul@gmail.com>2007-07-12 15:01:25 +0000
commit6d2449f066e1146f4dd6305dc96a096d98830d53 (patch)
treec24bfabdbb013590be0d96e975daf608680babf1 /src
parent8b78ce001230be826d9cda61f4d5973ffe007f0b (diff)
downloadscala-6d2449f066e1146f4dd6305dc96a096d98830d53.tar.gz
scala-6d2449f066e1146f4dd6305dc96a096d98830d53.tar.bz2
scala-6d2449f066e1146f4dd6305dc96a096d98830d53.zip
Fixed bug #1205 to optimize even more tail calls.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala9
-rw-r--r--src/compiler/scala/tools/nsc/transform/TailCalls.scala8
2 files changed, 9 insertions, 8 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index 33d8739333..d79310ec93 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -47,9 +47,6 @@ abstract class GenICode extends SubComponent {
val Comparator_equals = definitions.getMember(definitions.getModule("scala.runtime.Comparator"),
nme.equals_)
- /** Tree transformer that makes fresh label defs. */
- val duplicator = new DuplicateLabels
-
///////////////////////////////////////////////////////////
override def run: Unit = {
@@ -558,7 +555,7 @@ abstract class GenICode extends SubComponent {
ctx1
}) :: handlers;
- val duppedFinalizer = duplicator(ctx, finalizer)
+ val duppedFinalizer = (new DuplicateLabels(ctx.labels.keySet))(ctx, finalizer)
if (settings.debug.value)
log("Duplicated finalizer: " + duppedFinalizer)
ctx.Try(
@@ -1666,7 +1663,7 @@ abstract class GenICode extends SubComponent {
* All LabelDefs are entered into the context label map, since it makes no sense
* to delay it any more: they will be used at some point.
*/
- class DuplicateLabels extends Transformer {
+ class DuplicateLabels(boundLabels: collection.Set[Symbol]) extends Transformer {
val labels: Map[Symbol, Symbol] = new HashMap
var method: Symbol = _
var ctx: Context = _
@@ -1679,7 +1676,7 @@ abstract class GenICode extends SubComponent {
override def transform(t: Tree): Tree = {
t match {
- case t @ Apply(fun, args) if t.symbol.isLabel =>
+ case t @ Apply(fun, args) if (t.symbol.isLabel && !boundLabels(t.symbol)) =>
if (!labels.isDefinedAt(t.symbol)) {
val oldLabel = t.symbol
val sym = method.newLabel(oldLabel.pos, unit.fresh.newName(oldLabel.name.toString))
diff --git a/src/compiler/scala/tools/nsc/transform/TailCalls.scala b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
index 605cf3f3fc..142ae140fd 100644
--- a/src/compiler/scala/tools/nsc/transform/TailCalls.scala
+++ b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
@@ -227,8 +227,12 @@ abstract class TailCalls extends Transform
case Return(expr) => super.transform(tree)
case Try(block, catches, finalizer) =>
- if (finalizer == EmptyTree) super.transform(tree)
- else tree
+ if (finalizer == EmptyTree)
+ super.transform(tree)
+ else
+ copy.Try(tree, transform(block, mkContext(ctx, false)), // recursive calls are not in tail position if there is non-empty finally clause
+ transformTrees(catches, ctx).asInstanceOf[List[CaseDef]],
+ transform(finalizer, ctx))
case Throw(expr) => super.transform(tree)
case New(tpt) => super.transform(tree)