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:
parent
86c192938d
commit
5b827456ad
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue