summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2013-05-10 10:21:04 -0700
committerPaul Phillips <paulp@improving.org>2013-05-10 10:21:04 -0700
commitb38fae08a25545ba37a97c11aea0bf9971e9ca42 (patch)
tree41828f40e7c674479ab8d841375dc0ea1eb2d3fe
parent4de985c463e51538aa1fd27e5c33ce625b020179 (diff)
parentfb5eb8d562c55e1456033dd98c62c8ff01796846 (diff)
downloadscala-b38fae08a25545ba37a97c11aea0bf9971e9ca42.tar.gz
scala-b38fae08a25545ba37a97c11aea0bf9971e9ca42.tar.bz2
scala-b38fae08a25545ba37a97c11aea0bf9971e9ca42.zip
Merge pull request #2462 from magarciaEPFL/backendish9
SI-6863 root cause fixed using factory of scala.runtime.*Ref
-rw-r--r--src/compiler/scala/tools/nsc/transform/LambdaLift.scala76
-rw-r--r--src/library/scala/runtime/BooleanRef.java3
-rw-r--r--src/library/scala/runtime/ByteRef.java3
-rw-r--r--src/library/scala/runtime/CharRef.java3
-rw-r--r--src/library/scala/runtime/DoubleRef.java3
-rw-r--r--src/library/scala/runtime/FloatRef.java3
-rw-r--r--src/library/scala/runtime/IntRef.java3
-rw-r--r--src/library/scala/runtime/LongRef.java3
-rw-r--r--src/library/scala/runtime/ObjectRef.java3
-rw-r--r--src/library/scala/runtime/ShortRef.java3
-rwxr-xr-xsrc/library/scala/runtime/VolatileBooleanRef.java3
-rwxr-xr-xsrc/library/scala/runtime/VolatileByteRef.java3
-rwxr-xr-xsrc/library/scala/runtime/VolatileCharRef.java3
-rwxr-xr-xsrc/library/scala/runtime/VolatileDoubleRef.java3
-rwxr-xr-xsrc/library/scala/runtime/VolatileFloatRef.java3
-rwxr-xr-xsrc/library/scala/runtime/VolatileIntRef.java3
-rwxr-xr-xsrc/library/scala/runtime/VolatileLongRef.java3
-rwxr-xr-xsrc/library/scala/runtime/VolatileObjectRef.java3
-rwxr-xr-xsrc/library/scala/runtime/VolatileShortRef.java3
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala2
-rw-r--r--test/files/run/t6028.check4
21 files changed, 86 insertions, 50 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
index 6ff8792a45..868bbb1e42 100644
--- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
+++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
@@ -32,6 +32,21 @@ abstract class LambdaLift extends InfoTransform {
}
}
+ /** scala.runtime.*Ref classes */
+ private lazy val allRefClasses: Set[Symbol] = {
+ refClass.values.toSet ++ volatileRefClass.values.toSet ++ Set(VolatileObjectRefClass, ObjectRefClass)
+ }
+
+ /** Each scala.runtime.*Ref class has a static method `create(value)` that simply instantiates the Ref to carry that value. */
+ private lazy val refCreateMethod: Map[Symbol, Symbol] = {
+ mapFrom(allRefClasses.toList)(x => getMemberMethod(x.companionModule, nme.create))
+ }
+
+ /** Quite frequently a *Ref is initialized with its zero (e.g., null, 0.toByte, etc.) Method `zero()` of *Ref class encapsulates that pattern. */
+ private lazy val refZeroMethod: Map[Symbol, Symbol] = {
+ mapFrom(allRefClasses.toList)(x => getMemberMethod(x.companionModule, nme.zero))
+ }
+
def transformInfo(sym: Symbol, tp: Type): Type =
if (sym.isCapturedVariable) capturedVariableType(sym, tpe = lifted(tp), erasedTypes = true)
else lifted(tp)
@@ -444,56 +459,21 @@ abstract class LambdaLift extends InfoTransform {
case ValDef(mods, name, tpt, rhs) =>
if (sym.isCapturedVariable) {
val tpt1 = TypeTree(sym.tpe) setPos tpt.pos
- /* Creating a constructor argument if one isn't present. */
- val constructorArg = rhs match {
- case EmptyTree =>
- sym.tpe.typeSymbol.primaryConstructor.info.paramTypes match {
- case List(tp) => gen.mkZero(tp)
- case _ =>
- debugwarn("Couldn't determine how to properly construct " + sym)
- rhs
- }
- case arg => arg
+
+ val refTypeSym = sym.tpe.typeSymbol
+
+ val factoryCall = typer.typedPos(rhs.pos) {
+ rhs match {
+ case EmptyTree =>
+ val zeroMSym = refZeroMethod(refTypeSym)
+ gen.mkMethodCall(zeroMSym, Nil)
+ case arg =>
+ val createMSym = refCreateMethod(refTypeSym)
+ gen.mkMethodCall(createMSym, arg :: Nil)
+ }
}
- /* Wrap expr argument in new *Ref(..) constructor. But try/catch
- * is a problem because a throw will clear the stack and post catch
- * we would expect the partially-constructed object to be on the stack
- * for the call to init. So we recursively
- * search for "leaf" result expressions where we know its safe
- * to put the new *Ref(..) constructor or, if all else fails, transform
- * an expr to { val temp=expr; new *Ref(temp) }.
- * The reason we narrowly look for try/catch in captured var definitions
- * is because other try/catch expression have already been lifted
- * see SI-6863
- */
- def refConstr(expr: Tree): Tree = typer.typedPos(expr.pos)(expr match {
- // very simple expressions can be wrapped in a new *Ref(expr) because they can't have
- // a try/catch in final expression position.
- case Ident(_) | Apply(_, _) | Literal(_) | New(_) | Select(_, _) | Throw(_) | Assign(_, _) | ValDef(_, _, _, _) | Return(_) | EmptyTree =>
- New(sym.tpe, expr)
- case Try(block, catches, finalizer) =>
- Try(refConstr(block), catches map refConstrCase, finalizer)
- case Block(stats, expr) =>
- Block(stats, refConstr(expr))
- case If(cond, trueBranch, falseBranch) =>
- If(cond, refConstr(trueBranch), refConstr(falseBranch))
- case Match(selector, cases) =>
- Match(selector, cases map refConstrCase)
- // if we can't figure out what else to do, turn expr into {val temp1 = expr; new *Ref(temp1)} to avoid
- // any possibility of try/catch in the *Ref constructor. This should be a safe tranformation as a default
- // though it potentially wastes a variable slot. In particular this case handles LabelDefs.
- case _ =>
- debuglog("assigning expr to temp: " + (expr.pos))
- val tempSym = currentOwner.newValue(unit.freshTermName("temp"), expr.pos) setInfo expr.tpe
- val tempDef = ValDef(tempSym, expr) setPos expr.pos
- val tempRef = Ident(tempSym) setPos expr.pos
- Block(tempDef, New(sym.tpe, tempRef))
- })
- def refConstrCase(cdef: CaseDef): CaseDef =
- CaseDef(cdef.pat, cdef.guard, refConstr(cdef.body))
-
- treeCopy.ValDef(tree, mods, name, tpt1, refConstr(constructorArg))
+ treeCopy.ValDef(tree, mods, name, tpt1, factoryCall)
} else tree
case Return(Block(stats, value)) =>
Block(stats, treeCopy.Return(tree, value)) setType tree.tpe setPos tree.pos
diff --git a/src/library/scala/runtime/BooleanRef.java b/src/library/scala/runtime/BooleanRef.java
index 889db31e2a..92e8055351 100644
--- a/src/library/scala/runtime/BooleanRef.java
+++ b/src/library/scala/runtime/BooleanRef.java
@@ -17,4 +17,7 @@ public class BooleanRef implements java.io.Serializable {
public boolean elem;
public BooleanRef(boolean elem) { this.elem = elem; }
public String toString() { return String.valueOf(elem); }
+
+ public static BooleanRef create(boolean e) { return new BooleanRef(e); }
+ public static BooleanRef zero() { return new BooleanRef(false); }
}
diff --git a/src/library/scala/runtime/ByteRef.java b/src/library/scala/runtime/ByteRef.java
index cc10611e26..27d3259db3 100644
--- a/src/library/scala/runtime/ByteRef.java
+++ b/src/library/scala/runtime/ByteRef.java
@@ -17,4 +17,7 @@ public class ByteRef implements java.io.Serializable {
public byte elem;
public ByteRef(byte elem) { this.elem = elem; }
public String toString() { return java.lang.Byte.toString(elem); }
+
+ public static ByteRef create(byte e) { return new ByteRef(e); }
+ public static ByteRef zero() { return new ByteRef((byte)0); }
}
diff --git a/src/library/scala/runtime/CharRef.java b/src/library/scala/runtime/CharRef.java
index 03d3337b3d..31956f5b55 100644
--- a/src/library/scala/runtime/CharRef.java
+++ b/src/library/scala/runtime/CharRef.java
@@ -17,4 +17,7 @@ public class CharRef implements java.io.Serializable {
public char elem;
public CharRef(char elem) { this.elem = elem; }
public String toString() { return java.lang.Character.toString(elem); }
+
+ public static CharRef create(char e) { return new CharRef(e); }
+ public static CharRef zero() { return new CharRef((char)0); }
}
diff --git a/src/library/scala/runtime/DoubleRef.java b/src/library/scala/runtime/DoubleRef.java
index 317198ee48..0c7d9156d6 100644
--- a/src/library/scala/runtime/DoubleRef.java
+++ b/src/library/scala/runtime/DoubleRef.java
@@ -17,4 +17,7 @@ public class DoubleRef implements java.io.Serializable {
public double elem;
public DoubleRef(double elem) { this.elem = elem; }
public String toString() { return java.lang.Double.toString(elem); }
+
+ public static DoubleRef create(double e) { return new DoubleRef(e); }
+ public static DoubleRef zero() { return new DoubleRef(0); }
}
diff --git a/src/library/scala/runtime/FloatRef.java b/src/library/scala/runtime/FloatRef.java
index e26b89be60..f0e1d5f8f3 100644
--- a/src/library/scala/runtime/FloatRef.java
+++ b/src/library/scala/runtime/FloatRef.java
@@ -17,4 +17,7 @@ public class FloatRef implements java.io.Serializable {
public float elem;
public FloatRef(float elem) { this.elem = elem; }
public String toString() { return java.lang.Float.toString(elem); }
+
+ public static FloatRef create(float e) { return new FloatRef(e); }
+ public static FloatRef zero() { return new FloatRef(0); }
}
diff --git a/src/library/scala/runtime/IntRef.java b/src/library/scala/runtime/IntRef.java
index edb6fafe94..adcf474aae 100644
--- a/src/library/scala/runtime/IntRef.java
+++ b/src/library/scala/runtime/IntRef.java
@@ -17,4 +17,7 @@ public class IntRef implements java.io.Serializable {
public int elem;
public IntRef(int elem) { this.elem = elem; }
public String toString() { return java.lang.Integer.toString(elem); }
+
+ public static IntRef create(int e) { return new IntRef(e); }
+ public static IntRef zero() { return new IntRef(0); }
}
diff --git a/src/library/scala/runtime/LongRef.java b/src/library/scala/runtime/LongRef.java
index 12004b5bb5..51426ab8f6 100644
--- a/src/library/scala/runtime/LongRef.java
+++ b/src/library/scala/runtime/LongRef.java
@@ -17,4 +17,7 @@ public class LongRef implements java.io.Serializable {
public long elem;
public LongRef(long elem) { this.elem = elem; }
public String toString() { return java.lang.Long.toString(elem); }
+
+ public static LongRef create(long e) { return new LongRef(e); }
+ public static LongRef zero() { return new LongRef(0); }
}
diff --git a/src/library/scala/runtime/ObjectRef.java b/src/library/scala/runtime/ObjectRef.java
index c8298b8b21..c553c780a8 100644
--- a/src/library/scala/runtime/ObjectRef.java
+++ b/src/library/scala/runtime/ObjectRef.java
@@ -17,4 +17,7 @@ public class ObjectRef<T> implements java.io.Serializable {
public T elem;
public ObjectRef(T elem) { this.elem = elem; }
public String toString() { return String.valueOf(elem); }
+
+ public static <U> ObjectRef create(U e) { return new ObjectRef(e); }
+ public static ObjectRef zero() { return new ObjectRef(null); }
}
diff --git a/src/library/scala/runtime/ShortRef.java b/src/library/scala/runtime/ShortRef.java
index 461b521e5f..e5e8de3d8b 100644
--- a/src/library/scala/runtime/ShortRef.java
+++ b/src/library/scala/runtime/ShortRef.java
@@ -17,4 +17,7 @@ public class ShortRef implements java.io.Serializable {
public short elem;
public ShortRef(short elem) { this.elem = elem; }
public String toString() { return java.lang.Short.toString(elem); }
+
+ public static ShortRef create(short e) { return new ShortRef(e); }
+ public static ShortRef zero() { return new ShortRef((short)0); }
}
diff --git a/src/library/scala/runtime/VolatileBooleanRef.java b/src/library/scala/runtime/VolatileBooleanRef.java
index e3bd182345..ef5b691118 100755
--- a/src/library/scala/runtime/VolatileBooleanRef.java
+++ b/src/library/scala/runtime/VolatileBooleanRef.java
@@ -17,4 +17,7 @@ public class VolatileBooleanRef implements java.io.Serializable {
volatile public boolean elem;
public VolatileBooleanRef(boolean elem) { this.elem = elem; }
public String toString() { return String.valueOf(elem); }
+
+ public static VolatileBooleanRef create(boolean e) { return new VolatileBooleanRef(e); }
+ public static VolatileBooleanRef zero() { return new VolatileBooleanRef(false); }
}
diff --git a/src/library/scala/runtime/VolatileByteRef.java b/src/library/scala/runtime/VolatileByteRef.java
index 034b003017..d792b0a386 100755
--- a/src/library/scala/runtime/VolatileByteRef.java
+++ b/src/library/scala/runtime/VolatileByteRef.java
@@ -17,4 +17,7 @@ public class VolatileByteRef implements java.io.Serializable {
volatile public byte elem;
public VolatileByteRef(byte elem) { this.elem = elem; }
public String toString() { return java.lang.Byte.toString(elem); }
+
+ public static VolatileByteRef create(byte e) { return new VolatileByteRef(e); }
+ public static VolatileByteRef zero() { return new VolatileByteRef((byte)0); }
}
diff --git a/src/library/scala/runtime/VolatileCharRef.java b/src/library/scala/runtime/VolatileCharRef.java
index f90648c5e9..555b171283 100755
--- a/src/library/scala/runtime/VolatileCharRef.java
+++ b/src/library/scala/runtime/VolatileCharRef.java
@@ -17,4 +17,7 @@ public class VolatileCharRef implements java.io.Serializable {
volatile public char elem;
public VolatileCharRef(char elem) { this.elem = elem; }
public String toString() { return java.lang.Character.toString(elem); }
+
+ public static VolatileCharRef create(char e) { return new VolatileCharRef(e); }
+ public static VolatileCharRef zero() { return new VolatileCharRef((char)0); }
}
diff --git a/src/library/scala/runtime/VolatileDoubleRef.java b/src/library/scala/runtime/VolatileDoubleRef.java
index d47c9578c6..1932055c6a 100755
--- a/src/library/scala/runtime/VolatileDoubleRef.java
+++ b/src/library/scala/runtime/VolatileDoubleRef.java
@@ -16,4 +16,7 @@ public class VolatileDoubleRef implements java.io.Serializable {
volatile public double elem;
public VolatileDoubleRef(double elem) { this.elem = elem; }
public String toString() { return java.lang.Double.toString(elem); }
+
+ public static VolatileDoubleRef create(double e) { return new VolatileDoubleRef(e); }
+ public static VolatileDoubleRef zero() { return new VolatileDoubleRef(0); }
}
diff --git a/src/library/scala/runtime/VolatileFloatRef.java b/src/library/scala/runtime/VolatileFloatRef.java
index 97da95f7cc..3a81be1146 100755
--- a/src/library/scala/runtime/VolatileFloatRef.java
+++ b/src/library/scala/runtime/VolatileFloatRef.java
@@ -17,4 +17,7 @@ public class VolatileFloatRef implements java.io.Serializable {
volatile public float elem;
public VolatileFloatRef(float elem) { this.elem = elem; }
public String toString() { return java.lang.Float.toString(elem); }
+
+ public static VolatileFloatRef create(float e) { return new VolatileFloatRef(e); }
+ public static VolatileFloatRef zero() { return new VolatileFloatRef(0); }
}
diff --git a/src/library/scala/runtime/VolatileIntRef.java b/src/library/scala/runtime/VolatileIntRef.java
index e8a68a1a9a..ae015bc8b1 100755
--- a/src/library/scala/runtime/VolatileIntRef.java
+++ b/src/library/scala/runtime/VolatileIntRef.java
@@ -16,4 +16,7 @@ public class VolatileIntRef implements java.io.Serializable {
volatile public int elem;
public VolatileIntRef(int elem) { this.elem = elem; }
public String toString() { return java.lang.Integer.toString(elem); }
+
+ public static VolatileIntRef create(int e) { return new VolatileIntRef(e); }
+ public static VolatileIntRef zero() { return new VolatileIntRef(0); }
}
diff --git a/src/library/scala/runtime/VolatileLongRef.java b/src/library/scala/runtime/VolatileLongRef.java
index 80e627cd4b..e596f5aa69 100755
--- a/src/library/scala/runtime/VolatileLongRef.java
+++ b/src/library/scala/runtime/VolatileLongRef.java
@@ -17,4 +17,7 @@ public class VolatileLongRef implements java.io.Serializable {
volatile public long elem;
public VolatileLongRef(long elem) { this.elem = elem; }
public String toString() { return java.lang.Long.toString(elem); }
+
+ public static VolatileLongRef create(long e) { return new VolatileLongRef(e); }
+ public static VolatileLongRef zero() { return new VolatileLongRef(0); }
}
diff --git a/src/library/scala/runtime/VolatileObjectRef.java b/src/library/scala/runtime/VolatileObjectRef.java
index 848b0632ea..9f1f3ac0cf 100755
--- a/src/library/scala/runtime/VolatileObjectRef.java
+++ b/src/library/scala/runtime/VolatileObjectRef.java
@@ -17,4 +17,7 @@ public class VolatileObjectRef<T> implements java.io.Serializable {
volatile public T elem;
public VolatileObjectRef(T elem) { this.elem = elem; }
public String toString() { return String.valueOf(elem); }
+
+ public static <U> VolatileObjectRef create(U e) { return new VolatileObjectRef(e); }
+ public static VolatileObjectRef zero() { return new VolatileObjectRef(null); }
}
diff --git a/src/library/scala/runtime/VolatileShortRef.java b/src/library/scala/runtime/VolatileShortRef.java
index 4e91d0dc70..0a2825941f 100755
--- a/src/library/scala/runtime/VolatileShortRef.java
+++ b/src/library/scala/runtime/VolatileShortRef.java
@@ -17,4 +17,7 @@ public class VolatileShortRef implements java.io.Serializable {
volatile public short elem;
public VolatileShortRef(short elem) { this.elem = elem; }
public String toString() { return java.lang.Short.toString(elem); }
+
+ public static VolatileShortRef create(short e) { return new VolatileShortRef(e); }
+ public static VolatileShortRef zero() { return new VolatileShortRef((short)0); }
}
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index 31b3102c19..a20307882d 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -590,6 +590,7 @@ trait StdNames {
val clone_ : NameType = "clone"
val conforms: NameType = "conforms"
val copy: NameType = "copy"
+ val create: NameType = "create"
val currentMirror: NameType = "currentMirror"
val delayedInit: NameType = "delayedInit"
val delayedInitArg: NameType = "delayedInit$body"
@@ -698,6 +699,7 @@ trait StdNames {
val view_ : NameType = "view"
val wait_ : NameType = "wait"
val withFilter: NameType = "withFilter"
+ val zero: NameType = "zero"
// unencoded operators
object raw {
diff --git a/test/files/run/t6028.check b/test/files/run/t6028.check
index 2ec639fce2..57fd58f7d3 100644
--- a/test/files/run/t6028.check
+++ b/test/files/run/t6028.check
@@ -15,11 +15,11 @@ package <empty> {
}
};
def bar(barParam: Int): Object = {
- @volatile var MethodLocalObject$module: runtime.VolatileObjectRef = new runtime.VolatileObjectRef(null);
+ @volatile var MethodLocalObject$module: runtime.VolatileObjectRef = scala.runtime.VolatileObjectRef.zero();
T.this.MethodLocalObject$1(barParam, MethodLocalObject$module)
};
def tryy(tryyParam: Int): Function0 = {
- var tryyLocal: runtime.IntRef = new runtime.IntRef(0);
+ var tryyLocal: runtime.IntRef = scala.runtime.IntRef.create(0);
{
(new anonymous class $anonfun$tryy$1(T.this, tryyParam, tryyLocal): Function0)
}