added ${version.suffix}

git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@10404 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
michelou 2007-03-20 10:13:38 +00:00
parent 86c192938d
commit 5b827456ad
2 changed files with 77 additions and 61 deletions

View File

@ -248,6 +248,7 @@ BUILD SUPPORT MACROS
<include name="**/*.xml"/> <include name="**/*.xml"/>
<include name="**/*.js"/> <include name="**/*.js"/>
<include name="**/*.css"/> <include name="**/*.css"/>
<include name="**/*.png"/>
</fileset> </fileset>
</copy> </copy>
<copy todir="@{build.dir}/lib/compiler"> <copy todir="@{build.dir}/lib/compiler">
@ -256,6 +257,7 @@ BUILD SUPPORT MACROS
<include name="**/*.xml"/> <include name="**/*.xml"/>
<include name="**/*.js"/> <include name="**/*.js"/>
<include name="**/*.css"/> <include name="**/*.css"/>
<include name="**/*.png"/>
</fileset> </fileset>
</copy> </copy>
</sequential> </sequential>
@ -890,7 +892,7 @@ GENERATES A DISTRIBUTION
</propertyfile> </propertyfile>
<property file="${number.file}"/> <property file="${number.file}"/>
<property name="version.number" <property name="version.number"
value="${version.major}.${version.minor}.${version.patch}"/> value="${version.major}.${version.minor}.${version.patch}${version.suffix}"/>
<runtarget target="pack"/> <runtarget target="pack"/>
</target> </target>
@ -901,7 +903,7 @@ GENERATES A DISTRIBUTION
</propertyfile> </propertyfile>
<property file="${number.file}"/> <property file="${number.file}"/>
<property name="version.number" <property name="version.number"
value="${version.major}.${version.minor}.${version.patch}"/> value="${version.major}.${version.minor}.${version.patch}${version.suffix}"/>
<runtarget target="pack"/> <runtarget target="pack"/>
</target> </target>

View File

@ -1,12 +1,12 @@
/* NSC -- new scala compiler /* NSC -- new scala compiler
* Copyright 2005 LAMP/EPFL * Copyright 2005-2007 LAMP/EPFL
* @author Iulian Dragos * @author Iulian Dragos
*/ */
// $Id$ // $Id$
package scala.tools.nsc.transform; package scala.tools.nsc.transform
import scala.tools.nsc.symtab.Flags; import scala.tools.nsc.symtab.Flags
/** Perform tail recursive call elimination. /** Perform tail recursive call elimination.
* *
@ -46,36 +46,42 @@ abstract class TailCalls extends Transform
* @version 1.1 * @version 1.1
* *
* What it does: * What it does:
* * <p>
* Finds method calls in tail-position and replaces them with jumps. * Finds method calls in tail-position and replaces them with jumps.
* A call is in a tail-position if it is the last instruction to be * A call is in a tail-position if it is the last instruction to be
* executed in the body of a method. This is done by recursing over * executed in the body of a method. This is done by recursing over
* the trees that may contain calls in tail-position (trees that can't * the trees that may contain calls in tail-position (trees that can't
* contain such calls are not transformed). However, they are not that * contain such calls are not transformed). However, they are not that
* many. * many.
* * </p>
* Self-recursive calls in tail-position are replaced by jumps to a * <p>
* label at the beginning of the method. As the JVM provides no way to * Self-recursive calls in tail-position are replaced by jumps to a
* jump from a method to another one, non-recursive calls in * label at the beginning of the method. As the JVM provides no way to
* tail-position are not optimized. * jump from a method to another one, non-recursive calls in
* * tail-position are not optimized.
* A method call is self-recursive if it calls the current method on * </p>
* the current instance and the method is final (otherwise, it could * <p>
* be a call to an overridden method in a subclass). Furthermore, If * A method call is self-recursive if it calls the current method on
* the method has type parameters, the call must contain these * the current instance and the method is final (otherwise, it could
* parameters as type arguments. * be a call to an overridden method in a subclass). Furthermore, If
* * the method has type parameters, the call must contain these
* This phase has been moved before pattern matching to catch more * parameters as type arguments.
* of the common cases of tail recursive functions. This means that * </p>
* more cases should be taken into account (like nested function, and * <p>
* pattern cases). * This phase has been moved before pattern matching to catch more
* * of the common cases of tail recursive functions. This means that
* If a method contains self-recursive calls, a label is added to at * more cases should be taken into account (like nested function, and
* the beginning of its body and the calls are replaced by jumps to * pattern cases).
* that label. * </p>
* * <p>
* Assumes: Uncurry has been run already, and no multiple parameter * If a method contains self-recursive calls, a label is added to at
* lists exit. * the beginning of its body and the calls are replaced by jumps to
* that label.
* </p>
* <p>
* Assumes: <code>Uncurry</code> has been run already, and no multiple
* parameter lists exit.
* </p>
*/ */
class TailCallElimination(unit: CompilationUnit) extends Transformer { class TailCallElimination(unit: CompilationUnit) extends Transformer {
@ -129,10 +135,10 @@ abstract class TailCalls extends Transform
/** Rewrite this tree to contain no tail recursive calls */ /** Rewrite this tree to contain no tail recursive calls */
def transform(tree: Tree, nctx: Context): Tree = { def transform(tree: Tree, nctx: Context): Tree = {
val oldCtx = ctx; val oldCtx = ctx
ctx = nctx; ctx = nctx
val t = transform(tree); val t = transform(tree)
this.ctx = oldCtx; this.ctx = oldCtx
t t
} }
@ -161,7 +167,7 @@ abstract class TailCalls extends Transform
var newRHS = transform(rhs, newCtx); var newRHS = transform(rhs, newCtx);
if (newCtx.accessed) { if (newCtx.accessed) {
log("Rewrote def " + newCtx.currentMethod); log("Rewrote def " + newCtx.currentMethod)
newRHS = newRHS =
typed(atPos(tree.pos)( typed(atPos(tree.pos)(
@ -174,12 +180,14 @@ abstract class TailCalls extends Transform
} else { } else {
copy.DefDef(tree, mods, name, tparams, vparams, tpt, transform(rhs, newCtx)) copy.DefDef(tree, mods, name, tparams, vparams, tpt, transform(rhs, newCtx))
} }
log("Leaving DefDef: " + name); log("Leaving DefDef: " + name)
t1; t1
case EmptyTree => tree case EmptyTree => tree
case PackageDef(name, stats) => super.transform(tree) case PackageDef(name, stats) =>
super.transform(tree)
case ClassDef(_, name, _, _, _) => case ClassDef(_, name, _, _, _) =>
log("Entering class " + name) log("Entering class " + name)
val res = super.transform(tree) val res = super.transform(tree)
@ -191,7 +199,8 @@ abstract class TailCalls extends Transform
case AliasTypeDef(mods, name, tparams, rhs) => tree // (eliminated by erasure) case AliasTypeDef(mods, name, tparams, rhs) => tree // (eliminated by erasure)
case LabelDef(name, params, rhs) => super.transform(tree) case LabelDef(name, params, rhs) => super.transform(tree)
case Template(parents, body) => super.transform(tree) case Template(parents, body) =>
super.transform(tree)
case Block(stats, expr) => case Block(stats, expr) =>
copy.Block(tree, copy.Block(tree,
@ -203,18 +212,20 @@ abstract class TailCalls extends Transform
case Sequence(_) | Alternative(_) | case Sequence(_) | Alternative(_) |
Star(_) | Bind(_, _) => Star(_) | Bind(_, _) =>
throw new RuntimeException("We should've never gotten inside a pattern"); throw new RuntimeException("We should've never gotten inside a pattern")
case Function(vparams, body) => case Function(vparams, body) =>
tree tree
//throw new RuntimeException("Anonymous function should not exist at this point. at: " + unit.position(tree.pos)); //throw new RuntimeException("Anonymous function should not exist at this point. at: " + unit.position(tree.pos));
case Assign(lhs, rhs) => super.transform(tree); case Assign(lhs, rhs) =>
super.transform(tree)
case If(cond, thenp, elsep) => case If(cond, thenp, elsep) =>
copy.If(tree, cond, transform(thenp), transform(elsep)); copy.If(tree, cond, transform(thenp), transform(elsep))
case Match(selector, cases) => //super.transform(tree); case Match(selector, cases) => //super.transform(tree);
copy.Match(tree, transform(selector, mkContext(ctx, false)), transformTrees(cases).asInstanceOf[List[CaseDef]]); copy.Match(tree, transform(selector, mkContext(ctx, false)), transformTrees(cases).asInstanceOf[List[CaseDef]])
case Return(expr) => super.transform(tree) case Return(expr) => super.transform(tree)
case Try(block, catches, finalizer) => case Try(block, catches, finalizer) =>
@ -232,21 +243,21 @@ abstract class TailCalls extends Transform
isRecursiveCall(fun)) isRecursiveCall(fun))
rewriteTailCall(fun, transformTrees(vargs, mkContext(ctx, false))) rewriteTailCall(fun, transformTrees(vargs, mkContext(ctx, false)))
else else
copy.Apply(tree, tapply, transformTrees(vargs, mkContext(ctx, false))); copy.Apply(tree, tapply, transformTrees(vargs, mkContext(ctx, false)))
case TypeApply(fun, args) => case TypeApply(fun, args) =>
super.transform(tree) super.transform(tree)
case Apply(fun, args) if fun.symbol == definitions.Boolean_or => case Apply(fun, args) if fun.symbol == definitions.Boolean_or =>
copy.Apply(tree, fun, transformTrees(args)); copy.Apply(tree, fun, transformTrees(args))
case Apply(fun, args) => case Apply(fun, args) =>
if (ctx.currentMethod.isFinal && if (ctx.currentMethod.isFinal &&
ctx.tailPos && ctx.tailPos &&
isRecursiveCall(fun)) isRecursiveCall(fun))
rewriteTailCall(fun, transformTrees(args, mkContext(ctx, false))); rewriteTailCall(fun, transformTrees(args, mkContext(ctx, false)))
else else
copy.Apply(tree, fun, transformTrees(args, mkContext(ctx, false))); copy.Apply(tree, fun, transformTrees(args, mkContext(ctx, false)))
case Super(qual, mix) => case Super(qual, mix) =>
tree tree
@ -270,10 +281,10 @@ abstract class TailCalls extends Transform
private def rewriteTailCall(fun: Tree, args: List[Tree]): Tree = { private def rewriteTailCall(fun: Tree, args: List[Tree]): Tree = {
log("Rewriting tail recursive method call at: " + log("Rewriting tail recursive method call at: " +
unit.position(fun.pos)); unit.position(fun.pos))
ctx.accessed = true; ctx.accessed = true
typed(atPos(fun.pos)( typed(atPos(fun.pos)(
Apply(Ident(ctx.label), args))); Apply(Ident(ctx.label), args)))
} }
private def isSameTypes(ts1: List[Symbol], ts2: List[Symbol]): Boolean = { private def isSameTypes(ts1: List[Symbol], ts2: List[Symbol]): Boolean = {
@ -283,10 +294,13 @@ abstract class TailCalls extends Transform
List.forall2(ts1, ts2)(isSameType) List.forall2(ts1, ts2)(isSameType)
} }
/** Return true if the fun tree refers to the same method as the one /** Returns <code>true</code> if the fun tree refers to the same method as
* saved in ctx. If it is a method call, we check that it is applied to * the one saved in <code>ctx</code>. If it is a method call, we check
* "this" * that it is applied to <code>this</code>.
*/ *
* @param fun ...
* @return <code>true</code> ...
*/
private def isRecursiveCall(fun: Tree): Boolean = private def isRecursiveCall(fun: Tree): Boolean =
if (fun.symbol eq ctx.currentMethod) if (fun.symbol eq ctx.currentMethod)
fun match { fun match {
@ -298,8 +312,8 @@ abstract class TailCalls extends Transform
case Ident(_) => true case Ident(_) => true
case _ => false case _ => false
} }
else else
false; false
} }
} }