summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBurak Emir <emir@epfl.ch>2005-12-01 09:21:01 +0000
committerBurak Emir <emir@epfl.ch>2005-12-01 09:21:01 +0000
commitd0b1b0f44ef8ff6b679fbff2b820d444eef136cf (patch)
tree5ef2b8b7b3fc4b49860874ef070bf088cd6cab91
parent2ff070d8797d53a93ae6bd1151f3da8edc8b63ad (diff)
downloadscala-d0b1b0f44ef8ff6b679fbff2b820d444eef136cf.tar.gz
scala-d0b1b0f44ef8ff6b679fbff2b820d444eef136cf.tar.bz2
scala-d0b1b0f44ef8ff6b679fbff2b820d444eef136cf.zip
use forward jumps to avoid use of result = _
-rw-r--r--sources/scala/tools/nsc/backend/icode/GenICode.scala2
-rw-r--r--sources/scala/tools/nsc/matching/AlgebraicMatchers.scala13
-rw-r--r--sources/scala/tools/nsc/matching/CodeFactory.scala6
-rw-r--r--sources/scala/tools/nsc/matching/PatternMatchers.scala37
-rwxr-xr-xsources/scala/tools/nsc/transform/LambdaLift.scala8
5 files changed, 44 insertions, 22 deletions
diff --git a/sources/scala/tools/nsc/backend/icode/GenICode.scala b/sources/scala/tools/nsc/backend/icode/GenICode.scala
index 5339443800..bca00a6187 100644
--- a/sources/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/sources/scala/tools/nsc/backend/icode/GenICode.scala
@@ -1108,7 +1108,7 @@ abstract class GenICode extends SubComponent {
case LabelDef(name, params, rhs) =>
ctx.labels += tree.symbol -> (new Label(tree.symbol) setParams(params map (.symbol)));
ctx.method.addLocals(params map (p => new Local(p.symbol, toTypeKind(p.symbol.info))));
- //super.traverse(rhs);
+ super.traverse(rhs);
case _ => super.traverse(tree);
}
diff --git a/sources/scala/tools/nsc/matching/AlgebraicMatchers.scala b/sources/scala/tools/nsc/matching/AlgebraicMatchers.scala
index 729b39e6ee..4137b128eb 100644
--- a/sources/scala/tools/nsc/matching/AlgebraicMatchers.scala
+++ b/sources/scala/tools/nsc/matching/AlgebraicMatchers.scala
@@ -68,14 +68,19 @@ trait AlgebraicMatchers : TransMatcher {
//////////// generator methods
override def toTree(): Tree = {
+
+ this.exit = currentOwner.newLabel(root.pos, "exitA")
+ .setInfo(new MethodType(List(resultType), resultType));
+
+ val result = exit.newValueParameter(root.pos, "resultA").setInfo( resultType );
+
Block(
List (
- ValDef(root.symbol, _m.selector),
- ValDef(resultVar, EmptyTree)
+ ValDef(root.symbol, _m.selector)
),
If( super.toTree(root.and),
- Ident(resultVar ),
- ThrowMatchError( _m.pos, resultVar.tpe ))
+ LabelDef(exit, List(result), Ident(result)),
+ ThrowMatchError( _m.pos, resultType ))
);
}
diff --git a/sources/scala/tools/nsc/matching/CodeFactory.scala b/sources/scala/tools/nsc/matching/CodeFactory.scala
index 0b8ecab71a..f9f745e1e1 100644
--- a/sources/scala/tools/nsc/matching/CodeFactory.scala
+++ b/sources/scala/tools/nsc/matching/CodeFactory.scala
@@ -115,7 +115,10 @@ import scala.tools.nsc.util.Position;
}
}
- /*protected*/ def Or(left: Tree, right: Tree): Tree = left match {
+ /*protected*/ def Or(left: Tree, right: Tree): Tree = {
+ left match {
+ case If(cond: Tree, thenp: Tree, Literal(Constant(false))) => // little opt, frequent special case
+ If(cond, thenp, right)
case Literal(Constant(value: Boolean))=>
if(value) left else right;
case _ =>
@@ -125,6 +128,7 @@ import scala.tools.nsc.util.Position;
case _ =>
Apply(Select(left, definitions.Boolean_or), List(right));
}
+ }
}
// used by Equals
diff --git a/sources/scala/tools/nsc/matching/PatternMatchers.scala b/sources/scala/tools/nsc/matching/PatternMatchers.scala
index f5732e9f92..9c3e7793ad 100644
--- a/sources/scala/tools/nsc/matching/PatternMatchers.scala
+++ b/sources/scala/tools/nsc/matching/PatternMatchers.scala
@@ -37,7 +37,7 @@ trait PatternMatchers: (TransMatcher with PatternNodes) extends AnyRef with Patt
/** the symbol of the result variable
*/
- protected var resultVar: Symbol = _;
+// protected var resultVar: Symbol = _;
def defs = definitions;
/** init method, also needed in subclass AlgebraicMatcher
@@ -68,9 +68,6 @@ trait PatternMatchers: (TransMatcher with PatternNodes) extends AnyRef with Patt
this.root.and = pHeader(selector.pos,
selector.tpe.widen,
Ident(root.symbol).setType(root.tpe));
- this.resultVar = owner.newVariable(Position.NOPOS, // Flags.MUTABLE,
- //"result").setType( resultType );
- "result").setInfo( resultType );
//Console.println("resultType = "+resultType);
this.owner = owner;
this.selector = selector;
@@ -666,7 +663,7 @@ trait PatternMatchers: (TransMatcher with PatternNodes) extends AnyRef with Patt
//print();
val ncases = numCases(root.and);
- val matchError = ThrowMatchError(selector.pos, resultVar.tpe);
+ val matchError = ThrowMatchError(selector.pos, resultType);
// without a case, we return a match error if there is no default case
if (ncases == 0)
return defaultBody(root.and, matchError);
@@ -727,20 +724,28 @@ trait PatternMatchers: (TransMatcher with PatternNodes) extends AnyRef with Patt
n = n + 1;
mappings = mappings.next;
}
- return Switch(selector, tags, bodies, defaultBody1, resultVar.tpe);
+ return Switch(selector, tags, bodies, defaultBody1, resultType);
*/
nCases = CaseDef(Ident(nme.WILDCARD), defaultBody1) :: nCases;
return Match(selector, nCases)
}
+
+ var exit:Symbol = null;
+ /** simple optimization: if the last pattern is `case _' (no guards), we won't generate the ThrowMatchError
+ */
def generalSwitchToTree(): Tree = {
- val ts = List(
- ValDef(root.symbol, selector),
- ValDef(resultVar, EmptyTree /* DefaultValue */));
+ this.exit = currentOwner.newLabel(root.pos, "exit")
+ .setInfo(new MethodType(List(resultType), resultType));
+ //Console.println("resultType:"+resultType.toString());
+ val result = exit.newValueParameter(root.pos, "result").setInfo( resultType );
+
+ //Console.println("generalSwitchToTree: "+root.or);
+ val ts = List(ValDef(root.symbol, selector));
val res = If(toTree(root.and),
- Ident(resultVar),
- ThrowMatchError(selector.pos, resultVar.tpe /* ,
- Ident(root.symbol) */));
+ LabelDef(exit, List(result), Ident(result)),
+ ThrowMatchError(selector.pos, resultType // , Ident(root.symbol)
+ ));
return Block(ts, res);
}
@@ -798,9 +803,13 @@ trait PatternMatchers: (TransMatcher with PatternNodes) extends AnyRef with Patt
var i = guard.length - 1; while(i >= 0) {
val ts:Seq[Tree] = bound(i).asInstanceOf[Array[Tree]];
var res0: Tree =
+ //Block(
+ // List(Assign(Ident(resultVar), body(i))),
+ // Literal(Constant(true)));
Block(
- List(Assign(Ident(resultVar), body(i))),
- Literal(Constant(true)));
+ List(Apply(Ident(exit), List(body(i)))),
+ Literal(Constant(true))
+ ); // forward jump
if (guard(i) != EmptyTree)
res0 = And(guard(i), res0);
res = Or(Block(ts.toList, res0), res);
diff --git a/sources/scala/tools/nsc/transform/LambdaLift.scala b/sources/scala/tools/nsc/transform/LambdaLift.scala
index 21a0870bd0..49330e728e 100755
--- a/sources/scala/tools/nsc/transform/LambdaLift.scala
+++ b/sources/scala/tools/nsc/transform/LambdaLift.scala
@@ -224,8 +224,12 @@ abstract class LambdaLift extends InfoTransform {
}
private def proxyRef(sym: Symbol) = {
- val psym = proxy(sym);
- if (psym.isLocal) gen.Ident(psym) else memberRef(psym)
+ if (sym.owner.isLabel) //
+ gen.Ident(sym) // bq: account for the fact that LambdaLift does not know how to handle references to LabelDef parameters.
+ else { //
+ val psym = proxy(sym);
+ if (psym.isLocal) gen.Ident(psym) else memberRef(psym)
+ }
}
private def addFreeArgs(pos: int, sym: Symbol, args: List[Tree]) = {