From e3bb9bfa5cdaa4ef293713a7bebb189f73732e6d Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sun, 28 Jun 2009 19:36:31 +0000 Subject: DSL refinement continues apace. good-sized whacks on Erasure. --- src/compiler/scala/tools/nsc/ast/TreeDSL.scala | 5 +- .../scala/tools/nsc/transform/Erasure.scala | 149 +++++++-------------- .../scala/tools/nsc/transform/LazyVals.scala | 29 ++-- src/compiler/scala/tools/nsc/transform/Mixin.scala | 8 +- 4 files changed, 70 insertions(+), 121 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala index 884e54a21d..7e5e133345 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala @@ -139,7 +139,10 @@ trait TreeDSL { val arg = if (msg == null) Nil else List(msg.TOSTRING) Throw(New(TypeTree(sym.tpe), List(arg))) } - def NEW(tpe: Tree, args: Tree*) = New(tpe, List(args.toList)) + def NEW(tpe: Tree, args: Tree*) = New(tpe, List(args.toList)) + def NEW(sym: Symbol, args: Tree*) = + if (args.isEmpty) New(TypeTree(sym.tpe)) + else New(TypeTree(sym.tpe), List(args.toList)) def VAL(sym: Symbol) = new ValStart(sym) def DEF(sym: Symbol) = new DefStart(sym) diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index 188bab5810..8ed3aaef88 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -13,7 +13,8 @@ import scala.tools.nsc.util.Position import symtab._ import Flags._ -abstract class Erasure extends AddInterfaces with typechecker.Analyzer { +abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.TreeDSL +{ import global._ // the global environment import definitions._ // standard classes and methods // @S: XXX: why is this here? earsure is a typer, if you comment this @@ -21,6 +22,9 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { lazy val typerXXX = this.typer import typerXXX.{typed} // methods to type trees + import CODE._ + def typedPos(pos: Position)(tree: Tree) = typed { atPos(pos)(tree) } + val phaseName: String = "erasure" def newTransformer(unit: CompilationUnit): Transformer = @@ -371,20 +375,15 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { val rhs1 = box(rhs) treeCopy.LabelDef(tree, name, params, rhs1) setType rhs1.tpe case _ => - typed { - atPos(tree.pos) { - val sym = tree.tpe.typeSymbol; - if (sym == UnitClass) { - if (treeInfo.isPureExpr(tree)) gen.mkAttributedRef(BoxedUnit_UNIT) - else Block(List(tree), gen.mkAttributedRef(BoxedUnit_UNIT)) - } else if (sym == ArrayClass) { - boxArray(tree) - } else { - Apply(gen.mkAttributedRef(boxMethod(tree.tpe.typeSymbol)), List(tree)). - setPos(tree.pos) setType ObjectClass.tpe - } - } - } + typedPos(tree.pos)(tree.tpe.typeSymbol match { + case UnitClass => + if (treeInfo isPureExpr tree) REF(BoxedUnit_UNIT) + else BLOCK(tree, REF(BoxedUnit_UNIT)) + case ArrayClass => + boxArray(tree) + case x => + (REF(boxMethod(x)) APPLY tree) setPos (tree.pos) setType (ObjectClass.tpe) + }) } /** generate ScalaRuntime.boxArray(tree) */ @@ -393,11 +392,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { val rhs1 = boxArray(rhs) treeCopy.LabelDef(tree, name, params, rhs1) setType rhs1.tpe case _ => - typed { - atPos(tree.pos) { - gen.mkRuntimeCall(nme.boxArray, List(tree)) - } - } + typedPos(tree.pos) { gen.mkRuntimeCall(nme.boxArray, List(tree)) } } /** Unbox tree of boxed type to expected type pt. @@ -411,23 +406,16 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { val rhs1 = unbox(rhs, pt) treeCopy.LabelDef(tree, name, params, rhs1) setType rhs1.tpe case _ => - typed { - atPos(tree.pos) { - if (pt.typeSymbol == UnitClass) { - if (treeInfo.isPureExpr(tree)) Literal(()) - else Block(List(tree), Literal(())) - } - else if (pt.typeSymbol == ArrayClass) { - val tree1 = adaptToType(tree, BoxedArrayClass.tpe) - gen.mkRuntimeCall(nme.arrayValue, List(tree1, Literal(pt.typeArgs.head))) - } - else { - atPos(tree.pos) { - Apply(gen.mkAttributedRef(unboxMethod(pt.typeSymbol)), List(tree)) setType pt - } - } - } - } + typedPos(tree.pos)(pt.typeSymbol match { + case UnitClass => + if (treeInfo isPureExpr tree) UNIT + else BLOCK(tree, UNIT) + case ArrayClass => + val tree1 = adaptToType(tree, BoxedArrayClass.tpe) + gen.mkRuntimeCall(nme.arrayValue, List(tree1, Literal(pt.typeArgs.head))) + case _ => + (REF(unboxMethod(pt.typeSymbol)) APPLY tree) setType pt + }) } /**

@@ -451,61 +439,25 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { */ private def cast(tree: Tree, pt: Type): Tree = { assert(pt eq pt.normalize) + def asPt(t: Tree) = t AS_ATTR pt + def once(within: (() => Tree) => Tree) = + typedPos(tree.pos)(gen.evalOnce(tree, context.owner, context.unit)(within andThen asPt)) if (tree.tpe.typeSymbol == ObjectClass) { - if (pt.typeSymbol == ArrayClass) - typed { - atPos(tree.pos) { - gen.evalOnce(tree, context.owner, context.unit) { x => - gen.mkAttributedCast( - If( - Apply( - TypeApply( - Select(x(), Object_isInstanceOf), - List(TypeTree(BoxedArrayClass.tpe))), - List()), - unbox(gen.mkAttributedCast(x(), BoxedArrayClass.tpe), pt), - x()), - pt) - } - } - } - else if (pt.typeSymbol isNonBottomSubClass BoxedArrayClass) - typed { - atPos(tree.pos) { - gen.evalOnce(tree, context.owner, context.unit) { x => - gen.mkAttributedCast( - If( - Apply( - TypeApply( - Select(x(), Object_isInstanceOf), - List(TypeTree(BoxedArrayClass.tpe))), - List()), - x(), - boxArray(x())), - pt) - } - } - } - else if (isSeqClass(pt.typeSymbol)) - typed { - atPos(tree.pos) { - gen.evalOnce(tree, context.owner, context.unit) { x => - gen.mkAttributedCast( - If( - Apply( - TypeApply( - Select(x(), Object_isInstanceOf), - List(TypeTree(pt))), - List()), - x(), - boxArray(x())), - pt) - } - } - } - else gen.mkAttributedCast(tree, pt) - } else gen.mkAttributedCast(tree, pt) + if (pt.typeSymbol == ArrayClass) once (x => + (IF (x() IS_OBJ BoxedArrayClass.tpe) + THEN (unbox(x() AS_ATTR BoxedArrayClass.tpe, pt)) + ELSE (x()) + ) + ) + else if (pt.typeSymbol isNonBottomSubClass BoxedArrayClass) once (x => + (IF (x() IS_OBJ BoxedArrayClass.tpe) THEN (x()) ELSE boxArray(x())) + ) + else if (isSeqClass(pt.typeSymbol)) once (x => + (IF (x() IS_OBJ pt) THEN (x()) ELSE (boxArray(x()))) + ) + else asPt(tree) + } else asPt(tree) } /** Is symbol a member of unboxed arrays (which will be expanded directly @@ -514,9 +466,10 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { * @param sym .. * @return true if .. */ - private def isUnboxedArrayMember(sym: Symbol) = - sym.name == nme.apply || sym.name == nme.length || sym.name == nme.update || - sym.owner == ObjectClass + private def isUnboxedArrayMember(sym: Symbol) = sym.name match { + case nme.apply | nme.length | nme.update => true + case _ => sym.owner == ObjectClass + } private def isUnboxedValueMember(sym: Symbol) = sym != NoSymbol && isValueClass(sym.owner) @@ -606,12 +559,10 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { tree match { case Apply(Select(New(tpt), name), args) if (tpt.tpe.typeSymbol == BoxedArrayClass) => assert(name == nme.CONSTRUCTOR); - val translated = - if (args.length >= 2) { - Select(gen.mkAttributedRef(ArrayModule), nme.withDims) - } else { - Select(New(TypeTree(BoxedAnyArrayClass.tpe)), name) - } + val translated: Tree = + if (args.length >= 2) REF(ArrayModule) DOT nme.withDims + else NEW(BoxedAnyArrayClass) DOT name + atPos(tree.pos) { Typed(Apply(translated, args), tpt) } diff --git a/src/compiler/scala/tools/nsc/transform/LazyVals.scala b/src/compiler/scala/tools/nsc/transform/LazyVals.scala index 21370c3176..e8db58c2bc 100644 --- a/src/compiler/scala/tools/nsc/transform/LazyVals.scala +++ b/src/compiler/scala/tools/nsc/transform/LazyVals.scala @@ -9,6 +9,7 @@ abstract class LazyVals extends Transform with ast.TreeDSL { import global._ // the global environment import definitions._ // standard classes and methods import typer.{typed, atOwner} // methods to type trees + import CODE._ val phaseName: String = "lazyvals" @@ -20,8 +21,7 @@ abstract class LazyVals extends Transform with ast.TreeDSL { /** The phase defined by this transform */ class Phase(prev: scala.tools.nsc.Phase) extends StdPhase(prev) { - def apply(unit: global.CompilationUnit): Unit = - newTransformer(unit).transformUnit(unit); + def apply(unit: global.CompilationUnit): Unit = newTransformer(unit) transformUnit unit } /** @@ -92,7 +92,7 @@ abstract class LazyVals extends Transform with ast.TreeDSL { case _ => Block(stats, tree) } - val bmps = bitmaps(methSym) map { b => ValDef(b, Literal(Constant(0))) } + val bmps = bitmaps(methSym) map (ValDef(_, ZERO)) if (bmps.isEmpty) rhs else rhs match { case Block(assign, l @ LabelDef(name, params, rhs1)) if (name.toString.equals("_" + methSym.name) @@ -104,8 +104,6 @@ abstract class LazyVals extends Transform with ast.TreeDSL { } } - import CODE._ - /** return a 'lazified' version of rhs. Rhs should conform to the * following schema: * { @@ -135,21 +133,20 @@ abstract class LazyVals extends Transform with ast.TreeDSL { * } */ private def mkLazyDef(meth: Symbol, tree: Tree, offset: Int): Tree = { - val bitmapSym = getBitmapFor(meth, offset) - val mask = Literal(Constant(1 << (offset % FLAGS_PER_WORD))) + val bitmapSym = getBitmapFor(meth, offset) + val mask = LIT(1 << (offset % FLAGS_PER_WORD)) + def mkBlock(stmt: Tree) = BLOCK(stmt, mkSetFlag(bitmapSym, mask), UNIT) val (block, res) = tree match { - case Block(List(assignment), res) => - (Block(List(assignment, mkSetFlag(bitmapSym, mask)), Literal(Constant(()))), res) - case rhs => - assert(meth.tpe.finalResultType.typeSymbol == definitions.UnitClass) - (Block(List(rhs, mkSetFlag(bitmapSym, mask)), Literal(Constant(()))), Literal(())) + case Block(List(assignment), res) => (mkBlock(assignment), res) + case rhs => (mkBlock(rhs), UNIT) } + assert(res != UNIT || meth.tpe.finalResultType.typeSymbol == UnitClass) - val result = atPos(tree.pos) { - IF ((Ident(bitmapSym) INT_& mask) INT_== ZERO) THEN block ENDIF - } - typed(Block(List(result), res)) + atPos(tree.pos)(typed { + def body = { IF ((Ident(bitmapSym) INT_& mask) INT_== ZERO) THEN block ENDIF } + BLOCK(body, res) + }) } private def mkSetFlag(bmp: Symbol, mask: Tree): Tree = diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index 56bcd34cd2..bcab93b461 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -459,14 +459,14 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { /** Create a static reference to given symbol sym of the * form M.sym where M is the symbol's implementation module. */ - private def staticRef(sym: Symbol) = { + private def staticRef(sym: Symbol): Tree = { sym.owner.info //todo: needed? sym.owner.owner.info //todo: needed? if (sym.owner.sourceModule == NoSymbol) { assert(false, "" + sym + " in " + sym.owner + " in " + sym.owner.owner + " " + sym.owner.owner.info.decls.toList)//debug } - Select(gen.mkAttributedRef(sym.owner.sourceModule), sym) + REF(sym.owner.sourceModule) DOT sym } /** Add all new definitions to a non-trait class @@ -542,9 +542,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { def completeSuperAccessor(stat: Tree) = stat match { case DefDef(mods, name, tparams, List(vparams), tpt, EmptyTree) if (stat.symbol hasFlag SUPERACCESSOR) => - val rhs0 = - Apply(Select(Super(clazz, nme.EMPTY.toTypeName), stat.symbol.alias), - vparams map (vparam => Ident(vparam.symbol))) + val rhs0 = (Super(clazz, nme.EMPTY.toTypeName) DOT stat.symbol.alias)(vparams map (v => Ident(v.symbol)): _*) val rhs1 = localTyper.typed(atPos(stat.pos)(rhs0), stat.symbol.tpe.resultType) val rhs2 = atPhase(currentRun.mixinPhase)(transform(rhs1)) if (settings.debug.value) -- cgit v1.2.3