diff options
author | Tiark Rompf <tiark.rompf@epfl.ch> | 2010-03-29 09:55:44 +0000 |
---|---|---|
committer | Tiark Rompf <tiark.rompf@epfl.ch> | 2010-03-29 09:55:44 +0000 |
commit | f500aeb1fda09b3d0c142da1307694ab4dacc883 (patch) | |
tree | cbcc5857c4222fe11e5eb8bb81379d45069c9bbe /src/continuations/plugin | |
parent | 59da69b707e2e79fbaad4aae7fc347ca1b66a34b (diff) | |
download | scala-f500aeb1fda09b3d0c142da1307694ab4dacc883.tar.gz scala-f500aeb1fda09b3d0c142da1307694ab4dacc883.tar.bz2 scala-f500aeb1fda09b3d0c142da1307694ab4dacc883.zip |
closes 2864.
Diffstat (limited to 'src/continuations/plugin')
4 files changed, 70 insertions, 25 deletions
diff --git a/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala b/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala index 500f102790..3b99eb2008 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala @@ -401,6 +401,11 @@ abstract class CPSAnnotationChecker extends CPSUtils { transChildrenInOrder(tree, tpe, qual::(transArgList(fun, args).flatten), Nil) + case TypeApply(fun @ Select(qual, name), args) if (fun.tpe ne null) && !fun.tpe.isErroneous => + vprintln("[checker] checking select apply " + tree + "/" + tpe) + + transChildrenInOrder(tree, tpe, List(qual, fun), Nil) + case Apply(fun, args) if (fun.tpe ne null) && !fun.tpe.isErroneous => vprintln("[checker] checking unknown apply " + tree + "/" + tpe) @@ -418,8 +423,28 @@ abstract class CPSAnnotationChecker extends CPSUtils { vprintln("[checker] checking select " + tree + "/" + tpe) // FIXME: put it back in?? (problem with test cases select.scala and Test2.scala) - // transChildrenInOrder(tree, tpe, List(qual)) - tpe + // transChildrenInOrder(tree, tpe, List(qual), Nil) + + //TODO: cleanup + + // seem to be only a problem if qual is of type OverloadedType + + if (!tpe.isInstanceOf[OverloadedType] && !tpe.isInstanceOf[MethodType] && !tpe.isInstanceOf[PolyType]) { + transChildrenInOrder(tree, tpe, List(qual), Nil) + } else { + if (qual.tpe.hasAnnotation(MarkerCPSTypes)) { + // If it's a method without parameters, just apply it. normally done in adapt, but + // we have to do it here so we don't lose the cps information + tpe match { + case PolyType(List(), restpe) => + //println("yep: " + restpe + "," + restpe.getClass) + transChildrenInOrder(tree, restpe, List(qual), Nil) + case _ => + tpe + } + } else + tpe + } case If(cond, thenp, elsep) => transChildrenInOrder(tree, tpe, List(cond), List(thenp, elsep)) diff --git a/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala b/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala index 566f175183..57cba6e829 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala @@ -11,7 +11,7 @@ trait CPSUtils { var cpsEnabled = false val verbose: Boolean = System.getProperty("cpsVerbose", "false") == "true" - @inline def vprintln(x: =>Any): Unit = if (verbose) println(x) + @inline final def vprintln(x: =>Any): Unit = if (verbose) println(x) lazy val MarkerCPSSym = definitions.getClass("scala.util.continuations.cpsSym") diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala index 5bad9e960c..92ec00be66 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala @@ -192,8 +192,8 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with .setInfo(ldef.symbol.info) .setFlag(Flags.SYNTHETIC) - val subst = new TreeSymSubstituter(List(ldef.symbol), List(sym)) - val rhsVal = transExpr(subst(rhs), None, getAnswerTypeAnn(tree.tpe)) + new TreeSymSubstituter(List(ldef.symbol), List(sym)).traverse(rhs) + val rhsVal = transExpr(rhs, None, getAnswerTypeAnn(tree.tpe)) val stm1 = localTyper.typed(DefDef(sym, rhsVal)) val expr = localTyper.typed(Apply(Ident(sym), List())) diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala index 3c35149636..15adfa7d82 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala @@ -84,6 +84,9 @@ abstract class SelectiveCPSTransform extends PluginComponent with log("found shift: " + tree) atPos(tree.pos) { val funR = gen.mkAttributedRef(MethShiftR) // TODO: correct? + //gen.mkAttributedSelect(gen.mkAttributedSelect(gen.mkAttributedSelect(gen.mkAttributedIdent(ScalaPackage), + //ScalaPackage.tpe.member("util")), ScalaPackage.tpe.member("util").tpe.member("continuations")), MethShiftR) + //gen.mkAttributedRef(ModCPS.tpe, MethShiftR) // TODO: correct? log(funR.tpe) Apply( TypeApply(funR, targs).setType(appliedType(funR.tpe, targs.map((t:Tree) => t.tpe))), @@ -183,21 +186,32 @@ abstract class SelectiveCPSTransform extends PluginComponent with case expr => (Nil, expr) } - val expr2 = if (catches.nonEmpty) { - val pos = catches.head.pos - val arg = currentOwner.newValueParameter(pos, "$ex").setInfo(ThrowableClass.tpe) - val catches2 = catches1 map (duplicateTree(_).asInstanceOf[CaseDef]) - val rhs = Match(Ident(arg), catches2) - val fun = Function(List(ValDef(arg)), rhs) - val expr2 = localTyper.typed(atPos(pos) { Apply(Select(expr1, expr1.tpe.member("flatMapCatch")), List(fun)) }) + val targettp = transformCPSType(tree.tpe) - arg.owner = fun.symbol +// val expr2 = if (catches.nonEmpty) { + val pos = catches.head.pos + val argSym = currentOwner.newValueParameter(pos, "$ex").setInfo(ThrowableClass.tpe) + val rhs = Match(Ident(argSym), catches1) + val fun = Function(List(ValDef(argSym)), rhs) + val funSym = currentOwner.newValueParameter(pos, "$catches").setInfo(appliedType(PartialFunctionClass.tpe, List(ThrowableClass.tpe, targettp))) + val funDef = localTyper.typed(atPos(pos) { ValDef(funSym, fun) }) + val expr2 = localTyper.typed(atPos(pos) { Apply(Select(expr1, expr1.tpe.member("flatMapCatch")), List(Ident(funSym))) }) + + argSym.owner = fun.symbol val chown = new ChangeOwnerTraverser(currentOwner, fun.symbol) chown.traverse(rhs) - expr2 - } else - expr1 + val exSym = currentOwner.newValueParameter(pos, "$ex").setInfo(ThrowableClass.tpe) + val catch2 = { localTyper.typedCases(tree, List( + CaseDef(Bind(exSym, Typed(Ident("_"), TypeTree(ThrowableClass.tpe))), + Apply(Select(Ident(funSym), "isDefinedAt"), List(Ident(exSym))), + Apply(Ident(funSym), List(Ident(exSym)))) + ), ThrowableClass.tpe, targettp) } + + //typedCases(tree, catches, ThrowableClass.tpe, pt) + + localTyper.typed(Block(List(funDef), treeCopy.Try(tree, treeCopy.Block(block1, stms, expr2), catch2, finalizer1))) + /* disabled for now - see notes above @@ -215,9 +229,6 @@ abstract class SelectiveCPSTransform extends PluginComponent with } else expr2 */ - - - treeCopy.Try(tree, treeCopy.Block(block1, stms, expr2), catches1, finalizer1) } else { treeCopy.Try(tree, block1, catches1, finalizer1) } @@ -249,7 +260,9 @@ abstract class SelectiveCPSTransform extends PluginComponent with log("found marked ValDef "+name+" of type " + vd.symbol.tpe) val tpe = vd.symbol.tpe - val rhs1 = transform(rhs) + val rhs1 = atOwner(vd.symbol) { transform(rhs) } + + new ChangeOwnerTraverser(vd.symbol, currentOwner).traverse(rhs1) // TODO: don't traverse twice log("valdef symbol " + vd.symbol + " has type " + tpe) log("right hand side " + rhs1 + " has type " + rhs1.tpe) @@ -257,8 +270,10 @@ abstract class SelectiveCPSTransform extends PluginComponent with log("currentOwner: " + currentOwner) log("currentMethod: " + currentMethod) - val (bodyStms, bodyExpr) = transBlock(rest, expr) + // FIXME: result will later be traversed again by TreeSymSubstituter and + // ChangeOwnerTraverser => exp. running time. + // Should be changed to fuse traversals into one. val specialCaseTrivial = bodyExpr match { case Apply(fun, args) => @@ -291,6 +306,8 @@ abstract class SelectiveCPSTransform extends PluginComponent with arg.owner = fun.symbol new ChangeOwnerTraverser(currentOwner, fun.symbol).traverse(body) + // see note about multiple traversals above + log("fun.symbol: "+fun.symbol) log("fun.symbol.owner: "+fun.symbol.owner) log("arg.owner: "+arg.owner) @@ -314,6 +331,8 @@ abstract class SelectiveCPSTransform extends PluginComponent with }) } + def mkBlock(stms: List[Tree], expr: Tree) = if (stms.nonEmpty) Block(stms, expr) else expr + try { if (specialCaseTrivial) { log("will optimize possible tail call: " + bodyExpr) @@ -332,9 +351,9 @@ abstract class SelectiveCPSTransform extends PluginComponent with val argSym = currentOwner.newValue(vd.symbol.name).setInfo(tpe) val argDef = localTyper.typed(ValDef(argSym, Select(ctxRef, ctxRef.tpe.member("getTrivialValue")))) val switchExpr = localTyper.typed(atPos(vd.symbol.pos) { - val body2 = duplicateTree(Block(bodyStms, bodyExpr)) // dup before typing! + val body2 = duplicateTree(mkBlock(bodyStms, bodyExpr)) // dup before typing! If(Select(ctxRef, ctxSym.tpe.member("isTrivial")), - applyTrivial(argSym, Block(argDef::bodyStms, bodyExpr)), + applyTrivial(argSym, mkBlock(argDef::bodyStms, bodyExpr)), applyCombinatorFun(ctxRef, body2)) }) (List(ctxDef), switchExpr) @@ -342,7 +361,7 @@ abstract class SelectiveCPSTransform extends PluginComponent with // ctx.flatMap { <lhs> => ... } // or // ctx.map { <lhs> => ... } - (Nil, applyCombinatorFun(rhs1, Block(bodyStms, bodyExpr))) + (Nil, applyCombinatorFun(rhs1, mkBlock(bodyStms, bodyExpr))) } } catch { case ex:TypeError => @@ -351,8 +370,9 @@ abstract class SelectiveCPSTransform extends PluginComponent with } case _ => + val stm1 = transform(stm) val (a, b) = transBlock(rest, expr) - (transform(stm)::a, b) + (stm1::a, b) } } } |