diff options
author | Burak Emir <emir@epfl.ch> | 2005-12-01 09:21:01 +0000 |
---|---|---|
committer | Burak Emir <emir@epfl.ch> | 2005-12-01 09:21:01 +0000 |
commit | d0b1b0f44ef8ff6b679fbff2b820d444eef136cf (patch) | |
tree | 5ef2b8b7b3fc4b49860874ef070bf088cd6cab91 /sources | |
parent | 2ff070d8797d53a93ae6bd1151f3da8edc8b63ad (diff) | |
download | scala-d0b1b0f44ef8ff6b679fbff2b820d444eef136cf.tar.gz scala-d0b1b0f44ef8ff6b679fbff2b820d444eef136cf.tar.bz2 scala-d0b1b0f44ef8ff6b679fbff2b820d444eef136cf.zip |
use forward jumps to avoid use of result = _
Diffstat (limited to 'sources')
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]) = { |