summaryrefslogtreecommitdiff
path: root/src/library
diff options
context:
space:
mode:
authorGilles Dubochet <gilles.dubochet@epfl.ch>2007-04-30 18:14:11 +0000
committerGilles Dubochet <gilles.dubochet@epfl.ch>2007-04-30 18:14:11 +0000
commit750e57765b10d0f072eff68274047daa1c2040ae (patch)
tree8a3b19243e0ccc7ef54d6f5aaf4dd931120fd57d /src/library
parent10aa20170079d81f3e80d1cf5d0fc821336ae2d9 (diff)
downloadscala-750e57765b10d0f072eff68274047daa1c2040ae.tar.gz
scala-750e57765b10d0f072eff68274047daa1c2040ae.tar.bz2
scala-750e57765b10d0f072eff68274047daa1c2040ae.zip
Changed Scala's value boxing scheme to be compa...
Changed Scala's value boxing scheme to be compatible with java's wrapping classes. - “Definitions” redefines what the boxed correspondants of value types are. - “GenJVM” uses the new (un)boxing methods defined in “BoxesUtility” (MSIL not updated yet). - “GenICode” special cases the “equals” method (to that of “Comparator”) in some cases to deal with Java's silly definition of equality on wrapped values. - Various other fixes (in erasure to deal properly with boxing of labelled expressions, big integers, etc.).
Diffstat (limited to 'src/library')
-rw-r--r--src/library/scala/BigInt.scala13
-rw-r--r--src/library/scala/runtime/BoxedAnyArray.scala150
-rw-r--r--src/library/scala/runtime/BoxedBooleanArray.scala4
-rw-r--r--src/library/scala/runtime/BoxedByteArray.scala4
-rw-r--r--src/library/scala/runtime/BoxedCharArray.scala4
-rw-r--r--src/library/scala/runtime/BoxedDoubleArray.scala4
-rw-r--r--src/library/scala/runtime/BoxedFloatArray.scala4
-rw-r--r--src/library/scala/runtime/BoxedIntArray.scala4
-rw-r--r--src/library/scala/runtime/BoxedLongArray.scala4
-rw-r--r--src/library/scala/runtime/BoxedShortArray.scala4
-rw-r--r--src/library/scala/runtime/BoxesUtility.java167
-rw-r--r--src/library/scala/runtime/Comparator.java40
12 files changed, 305 insertions, 97 deletions
diff --git a/src/library/scala/BigInt.scala b/src/library/scala/BigInt.scala
index 9e98ec5a3e..bcdff55261 100644
--- a/src/library/scala/BigInt.scala
+++ b/src/library/scala/BigInt.scala
@@ -115,7 +115,7 @@ object BigInt {
* @version 1.0, 15/07/2003
*/
@serializable
-class BigInt(val bigInteger: BigInteger) extends runtime.BoxedNumber {
+class BigInt(val bigInteger: BigInteger) extends java.lang.Number {
/** Returns the hash code for this BigInt. */
override def hashCode(): Int = this.bigInteger.hashCode()
@@ -123,9 +123,10 @@ class BigInt(val bigInteger: BigInteger) extends runtime.BoxedNumber {
/** Compares this BigInt with the specified value for equality.
*/
override def equals (that: Any): boolean = that match {
- case that: runtime.BoxedDouble => this.bigInteger.doubleValue == that.doubleValue
- case that: runtime.BoxedFloat => this.bigInteger.floatValue == that.floatValue
- case that: runtime.BoxedNumber => this equals BigInt(that.longValue)
+ case that: java.lang.Double => this.bigInteger.doubleValue == that.doubleValue
+ case that: java.lang.Float => this.bigInteger.floatValue == that.floatValue
+ case that: java.lang.Number => this equals BigInt(that.longValue)
+ case that: java.lang.Character => this equals BigInt(that.charValue.asInstanceOf[Int])
case _ => false
}
@@ -300,14 +301,14 @@ class BigInt(val bigInteger: BigInteger) extends runtime.BoxedNumber {
* Note that this conversion can lose information about the overall magnitude of the
* BigInt value as well as return a result with the opposite sign.
*/
- def byteValue = intValue.toByte
+ override def byteValue = intValue.toByte
/** Converts this BigInt to a <tt>short</tt>.
* If the BigInt is too big to fit in a byte, only the low-order 16 bits are returned.
* Note that this conversion can lose information about the overall magnitude of the
* BigInt value as well as return a result with the opposite sign.
*/
- def shortValue = intValue.toShort
+ override def shortValue = intValue.toShort
/** Converts this BigInt to a <tt>char</tt>.
* If the BigInt is too big to fit in a char, only the low-order 16 bits are returned.
diff --git a/src/library/scala/runtime/BoxedAnyArray.scala b/src/library/scala/runtime/BoxedAnyArray.scala
index 2c8711d763..d6093fe027 100644
--- a/src/library/scala/runtime/BoxedAnyArray.scala
+++ b/src/library/scala/runtime/BoxedAnyArray.scala
@@ -31,21 +31,21 @@ final class BoxedAnyArray(val length: Int) extends BoxedArray {
if (unboxed eq null)
boxed(index);
else if (elemClass eq classOf[Int])
- Int.box(unboxed.asInstanceOf[Array[Int]](index))
+ BoxesUtility.boxToInteger(unboxed.asInstanceOf[Array[Int]](index))
else if (elemClass eq classOf[Double])
- Double.box(unboxed.asInstanceOf[Array[Double]](index))
+ BoxesUtility.boxToDouble(unboxed.asInstanceOf[Array[Double]](index))
else if (elemClass eq classOf[Float])
- Float.box(unboxed.asInstanceOf[Array[Float]](index))
+ BoxesUtility.boxToFloat(unboxed.asInstanceOf[Array[Float]](index))
else if (elemClass eq classOf[Long])
- Long.box(unboxed.asInstanceOf[Array[Long]](index))
+ BoxesUtility.boxToLong(unboxed.asInstanceOf[Array[Long]](index))
else if (elemClass eq classOf[Char])
- Char.box(unboxed.asInstanceOf[Array[Char]](index))
+ BoxesUtility.boxToCharacter(unboxed.asInstanceOf[Array[Char]](index))
else if (elemClass eq classOf[Byte])
- Byte.box(unboxed.asInstanceOf[Array[Byte]](index))
+ BoxesUtility.boxToByte(unboxed.asInstanceOf[Array[Byte]](index))
else if (elemClass eq classOf[Short])
- Short.box(unboxed.asInstanceOf[Array[Short]](index))
+ BoxesUtility.boxToShort(unboxed.asInstanceOf[Array[Short]](index))
else if (elemClass eq classOf[Boolean])
- Boolean.box(unboxed.asInstanceOf[Array[Boolean]](index))
+ BoxesUtility.boxToBoolean(unboxed.asInstanceOf[Array[Boolean]](index))
else
unboxed.asInstanceOf[Array[AnyRef]](index)
}
@@ -55,21 +55,21 @@ final class BoxedAnyArray(val length: Int) extends BoxedArray {
if (unboxed eq null)
boxed(index) = elem
else if (elemClass eq classOf[Int])
- unboxed.asInstanceOf[Array[Int]](index) = Int.unbox(elem)
+ unboxed.asInstanceOf[Array[Int]](index) = BoxesUtility.unboxToInt(elem)
else if (elemClass eq classOf[Double])
- unboxed.asInstanceOf[Array[Double]](index) = Double.unbox(elem)
+ unboxed.asInstanceOf[Array[Double]](index) = BoxesUtility.unboxToDouble(elem)
else if (elemClass eq classOf[Float])
- unboxed.asInstanceOf[Array[Float]](index) = Float.unbox(elem)
+ unboxed.asInstanceOf[Array[Float]](index) = BoxesUtility.unboxToFloat(elem)
else if (elemClass eq classOf[Long])
- unboxed.asInstanceOf[Array[Long]](index) = Long.unbox(elem)
+ unboxed.asInstanceOf[Array[Long]](index) = BoxesUtility.unboxToLong(elem)
else if (elemClass eq classOf[Char])
- unboxed.asInstanceOf[Array[Char]](index) = Char.unbox(elem)
+ unboxed.asInstanceOf[Array[Char]](index) = BoxesUtility.unboxToChar(elem)
else if (elemClass eq classOf[Byte])
- unboxed.asInstanceOf[Array[Byte]](index) = Byte.unbox(elem)
+ unboxed.asInstanceOf[Array[Byte]](index) = BoxesUtility.unboxToByte(elem)
else if (elemClass eq classOf[Short])
- unboxed.asInstanceOf[Array[Short]](index) = Short.unbox(elem)
+ unboxed.asInstanceOf[Array[Short]](index) = BoxesUtility.unboxToShort(elem)
else if (elemClass eq classOf[Boolean])
- unboxed.asInstanceOf[Array[Boolean]](index) = Boolean.unbox(elem)
+ unboxed.asInstanceOf[Array[Boolean]](index) = BoxesUtility.unboxToBoolean(elem)
else
unboxed.asInstanceOf[Array[AnyRef]](index) = elem
}
@@ -89,75 +89,75 @@ final class BoxedAnyArray(val length: Int) extends BoxedArray {
if (unboxed eq null) {
this.elemClass = elemClass;
if (elemClass eq classOf[Int]) {
- val newvalue = new Array[Int](length)
- var i = 0
- while (i < length) {
- newvalue(i) = Int.unbox(boxed(i))
- i = i + 1
- }
- unboxed = newvalue
+ val newvalue = new Array[Int](length)
+ var i = 0
+ while (i < length) {
+ newvalue(i) = BoxesUtility.unboxToInt(boxed(i))
+ i = i + 1
+ }
+ unboxed = newvalue
} else if (elemClass eq classOf[Double]) {
- val newvalue = new Array[Double](length)
- var i = 0
- while (i < length) {
- newvalue(i) = Double.unbox(boxed(i))
- i = i + 1
- }
- unboxed = newvalue;
+ val newvalue = new Array[Double](length)
+ var i = 0
+ while (i < length) {
+ newvalue(i) = BoxesUtility.unboxToDouble(boxed(i))
+ i = i + 1
+ }
+ unboxed = newvalue;
} else if (elemClass eq classOf[Float]) {
- val newvalue = new Array[Float](length)
- var i = 0
- while (i < length) {
- newvalue(i) = Float.unbox(boxed(i))
- i = i + 1
- }
- unboxed = newvalue;
+ val newvalue = new Array[Float](length)
+ var i = 0
+ while (i < length) {
+ newvalue(i) = BoxesUtility.unboxToFloat(boxed(i))
+ i = i + 1
+ }
+ unboxed = newvalue;
} else if (elemClass eq classOf[Long]) {
- val newvalue = new Array[Long](length)
- var i = 0
- while (i < length) {
- newvalue(i) = Long.unbox(boxed(i))
- i = i + 1
- }
- unboxed = newvalue;
+ val newvalue = new Array[Long](length)
+ var i = 0
+ while (i < length) {
+ newvalue(i) = BoxesUtility.unboxToLong(boxed(i))
+ i = i + 1
+ }
+ unboxed = newvalue;
} else if (elemClass eq classOf[Char]) {
- val newvalue = new Array[Char](length)
- var i = 0
- while (i < length) {
- newvalue(i) = Char.unbox(boxed(i))
- i = i + 1
- }
- unboxed = newvalue
+ val newvalue = new Array[Char](length)
+ var i = 0
+ while (i < length) {
+ newvalue(i) = BoxesUtility.unboxToChar(boxed(i))
+ i = i + 1
+ }
+ unboxed = newvalue
} else if (elemClass eq classOf[Byte]) {
- val newvalue = new Array[Byte](length)
- var i = 0
- while (i < length) {
- newvalue(i) = Byte.unbox(boxed(i))
- i = i + 1
- }
- unboxed = newvalue;
+ val newvalue = new Array[Byte](length)
+ var i = 0
+ while (i < length) {
+ newvalue(i) = BoxesUtility.unboxToByte(boxed(i))
+ i = i + 1
+ }
+ unboxed = newvalue;
} else if (elemClass eq classOf[Short]) {
- val newvalue = new Array[Short](length)
- var i = 0
- while (i < length) {
- newvalue(i) = Short.unbox(boxed(i))
- i = i + 1
- }
- unboxed = newvalue;
+ val newvalue = new Array[Short](length)
+ var i = 0
+ while (i < length) {
+ newvalue(i) = BoxesUtility.unboxToShort(boxed(i))
+ i = i + 1
+ }
+ unboxed = newvalue;
} else if (elemClass eq classOf[Boolean]) {
- val newvalue = new Array[Boolean](length)
- var i = 0
- while (i < length) {
- newvalue(i) = Boolean.unbox(boxed(i))
- i = i + 1
- }
- unboxed = newvalue;
+ val newvalue = new Array[Boolean](length)
+ var i = 0
+ while (i < length) {
+ newvalue(i) = BoxesUtility.unboxToBoolean(boxed(i))
+ i = i + 1
+ }
+ unboxed = newvalue;
} else if (elemClass == boxed.getClass().getComponentType()) {
// todo: replace with ScalaRunTime.AnyRef.class
- unboxed = boxed
+ unboxed = boxed
} else {
- unboxed = Platform.createArray(elemClass, length);
- Platform.arraycopy(boxed, 0, unboxed, 0, length);
+ unboxed = Platform.createArray(elemClass, length);
+ Platform.arraycopy(boxed, 0, unboxed, 0, length);
}
boxed = null
}
diff --git a/src/library/scala/runtime/BoxedBooleanArray.scala b/src/library/scala/runtime/BoxedBooleanArray.scala
index 1f0567abad..e0ff708205 100644
--- a/src/library/scala/runtime/BoxedBooleanArray.scala
+++ b/src/library/scala/runtime/BoxedBooleanArray.scala
@@ -19,10 +19,10 @@ final class BoxedBooleanArray(val value: Array[Boolean]) extends BoxedArray {
def length: Int = value.length
- def apply(index: Int): Any = Boolean.box(value(index))
+ def apply(index: Int): Any = BoxesUtility.boxToBoolean(value(index))
def update(index: Int, elem: Any): Unit = {
- value(index) = Boolean.unbox(elem.asInstanceOf[AnyRef])
+ value(index) = BoxesUtility.unboxToBoolean(elem.asInstanceOf[AnyRef])
}
def unbox(elemTag: String): AnyRef = value
diff --git a/src/library/scala/runtime/BoxedByteArray.scala b/src/library/scala/runtime/BoxedByteArray.scala
index 753dbaea04..cf3d6bee6a 100644
--- a/src/library/scala/runtime/BoxedByteArray.scala
+++ b/src/library/scala/runtime/BoxedByteArray.scala
@@ -19,10 +19,10 @@ final class BoxedByteArray(val value: Array[Byte]) extends BoxedArray {
def length: Int = value.length
- def apply(index: Int): Any = Byte.box(value(index))
+ def apply(index: Int): Any = BoxesUtility.boxToByte(value(index))
def update(index: Int, elem: Any): Unit = {
- value(index) = Byte.unbox(elem.asInstanceOf[AnyRef])
+ value(index) = BoxesUtility.unboxToByte(elem.asInstanceOf[AnyRef])
}
def unbox(elemTag: String): AnyRef = value
diff --git a/src/library/scala/runtime/BoxedCharArray.scala b/src/library/scala/runtime/BoxedCharArray.scala
index adb14dda51..c13a31134a 100644
--- a/src/library/scala/runtime/BoxedCharArray.scala
+++ b/src/library/scala/runtime/BoxedCharArray.scala
@@ -19,10 +19,10 @@ final class BoxedCharArray(val value: Array[Char]) extends BoxedArray {
def length: Int = value.length
- def apply(index: Int): Any = Char.box(value(index))
+ def apply(index: Int): Any = BoxesUtility.boxToCharacter(value(index))
def update(index: Int, elem: Any): Unit = {
- value(index) = Char.unbox(elem.asInstanceOf[AnyRef])
+ value(index) = BoxesUtility.unboxToChar(elem.asInstanceOf[AnyRef])
}
def unbox(elemTag: String): AnyRef = value
diff --git a/src/library/scala/runtime/BoxedDoubleArray.scala b/src/library/scala/runtime/BoxedDoubleArray.scala
index 9a4564e439..08c3b6b843 100644
--- a/src/library/scala/runtime/BoxedDoubleArray.scala
+++ b/src/library/scala/runtime/BoxedDoubleArray.scala
@@ -19,10 +19,10 @@ final class BoxedDoubleArray(val value: Array[Double]) extends BoxedArray {
def length: Int = value.length
- def apply(index: Int): Any = Double.box(value(index))
+ def apply(index: Int): Any = BoxesUtility.boxToDouble(value(index))
def update(index: Int, elem: Any): Unit = {
- value(index) = Double.unbox(elem.asInstanceOf[AnyRef])
+ value(index) = BoxesUtility.unboxToDouble(elem.asInstanceOf[AnyRef])
}
def unbox(elemTag: String): AnyRef = value
diff --git a/src/library/scala/runtime/BoxedFloatArray.scala b/src/library/scala/runtime/BoxedFloatArray.scala
index 1b8ccb3797..13424f136b 100644
--- a/src/library/scala/runtime/BoxedFloatArray.scala
+++ b/src/library/scala/runtime/BoxedFloatArray.scala
@@ -19,10 +19,10 @@ final class BoxedFloatArray(val value: Array[Float]) extends BoxedArray {
def length: Int = value.length
- def apply(index: Int): Any = Float.box(value(index))
+ def apply(index: Int): Any = BoxesUtility.boxToFloat(value(index))
def update(index: Int, elem: Any): Unit = {
- value(index) = Float.unbox(elem.asInstanceOf[AnyRef])
+ value(index) = BoxesUtility.unboxToFloat(elem.asInstanceOf[AnyRef])
}
def unbox(elemTag: String): AnyRef = value
diff --git a/src/library/scala/runtime/BoxedIntArray.scala b/src/library/scala/runtime/BoxedIntArray.scala
index d2f5fd0371..a64f4fdb60 100644
--- a/src/library/scala/runtime/BoxedIntArray.scala
+++ b/src/library/scala/runtime/BoxedIntArray.scala
@@ -19,10 +19,10 @@ final class BoxedIntArray(val value: Array[Int]) extends BoxedArray {
def length: Int = value.length
- def apply(index: Int): Any = Int.box(value(index))
+ def apply(index: Int): Any = BoxesUtility.boxToInteger(value(index))
def update(index: Int, elem: Any): Unit = {
- value(index) = Int.unbox(elem.asInstanceOf[AnyRef])
+ value(index) = BoxesUtility.unboxToInt(elem.asInstanceOf[AnyRef])
}
def unbox(elemTag: String): AnyRef = value
diff --git a/src/library/scala/runtime/BoxedLongArray.scala b/src/library/scala/runtime/BoxedLongArray.scala
index 6accc84484..db4b266e1b 100644
--- a/src/library/scala/runtime/BoxedLongArray.scala
+++ b/src/library/scala/runtime/BoxedLongArray.scala
@@ -19,10 +19,10 @@ final class BoxedLongArray(val value: Array[Long]) extends BoxedArray {
def length: Int = value.length
- def apply(index: Int): Any = Long.box(value(index))
+ def apply(index: Int): Any = BoxesUtility.boxToLong(value(index))
def update(index: Int, elem: Any): Unit = {
- value(index) = Long.unbox(elem.asInstanceOf[AnyRef])
+ value(index) = BoxesUtility.unboxToLong(elem.asInstanceOf[AnyRef])
}
def unbox(elemTag: String): AnyRef = value
diff --git a/src/library/scala/runtime/BoxedShortArray.scala b/src/library/scala/runtime/BoxedShortArray.scala
index 161b7b921b..229ee46727 100644
--- a/src/library/scala/runtime/BoxedShortArray.scala
+++ b/src/library/scala/runtime/BoxedShortArray.scala
@@ -19,10 +19,10 @@ final class BoxedShortArray(val value: Array[Short]) extends BoxedArray {
def length: Int = value.length
- def apply(index: Int): Any = Short.box(value(index))
+ def apply(index: Int): Any = BoxesUtility.boxToShort(value(index))
def update(index: Int, elem: Any): Unit = {
- value(index) = Short.unbox(elem.asInstanceOf[AnyRef])
+ value(index) = BoxesUtility.unboxToShort(elem.asInstanceOf[AnyRef])
}
def unbox(elemTag: String): AnyRef = value
diff --git a/src/library/scala/runtime/BoxesUtility.java b/src/library/scala/runtime/BoxesUtility.java
new file mode 100644
index 0000000000..3edfef81f6
--- /dev/null
+++ b/src/library/scala/runtime/BoxesUtility.java
@@ -0,0 +1,167 @@
+package scala.runtime;
+
+public class BoxesUtility {
+
+ private static int charLowBound = 0;
+ private static int charUpBound = 255;
+ private static Character[] charCache = new Character[charUpBound - charLowBound + 1];
+
+ private static int byteLowBound = -128;
+ private static int byteUpBound = 127;
+ private static Byte[] byteCache = new Byte[byteUpBound - byteLowBound + 1];
+
+ private static int shortLowBound = -128;
+ private static int shortUpBound = 127;
+ private static Short[] shortCache = new Short[shortUpBound - shortLowBound + 1];
+
+ private static int intLowBound = -128;
+ private static int intUpBound = 1024;
+ private static Integer[] intCache = new Integer[intUpBound - intLowBound + 1];
+
+ private static int longLowBound = -128;
+ private static int longUpBound = 1024;
+ private static Long[] longCache = new Long[longUpBound - longLowBound + 1];
+
+ static {
+ int idx = 0;
+ while (idx <= charUpBound - charLowBound) {
+ charCache[idx] = new Character((char)(idx + charLowBound));
+ idx = idx + 1;
+ }
+ idx = 0;
+ while (idx <= byteUpBound - byteLowBound) {
+ byteCache[idx] = new Byte((byte)(idx + byteLowBound));
+ idx = idx + 1;
+ }
+ idx = 0;
+ while (idx <= shortUpBound - shortLowBound) {
+ shortCache[idx] = new Short((short)(idx + shortLowBound));
+ idx = idx + 1;
+ }
+ idx = 0;
+ while (idx <= intUpBound - intLowBound) {
+ intCache[idx] = new Integer((int)(idx + intLowBound));
+ idx = idx + 1;
+ }
+ idx = 0;
+ while (idx <= longUpBound - longLowBound) {
+ longCache[idx] = new Long((long)(idx + longLowBound));
+ idx = idx + 1;
+ }
+ }
+
+ public static Boolean boxToBoolean(boolean b) {
+ return b ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ public static Character boxToCharacter(char c) {
+ if (c >= charLowBound && c <= charUpBound)
+ return charCache[(int)c - charLowBound];
+ else
+ return new Character(c);
+ }
+
+ public static Byte boxToByte(byte b) {
+ if (b >= byteLowBound && b <= byteUpBound)
+ return byteCache[(int)b - byteLowBound];
+ else
+ return new Byte(b);
+ }
+
+ public static Short boxToShort(short s) {
+ if (s >= shortLowBound && s <= shortUpBound)
+ return shortCache[(int)s - shortLowBound];
+ else
+ return new Short(s);
+ }
+
+ public static Integer boxToInteger(int i) {
+ if (i >= intLowBound && i <= intUpBound)
+ return intCache[(int)i - intLowBound];
+ else
+ return new Integer(i);
+ }
+
+ public static Long boxToLong(long l) {
+ if (l >= longLowBound && l <= longUpBound)
+ return longCache[(int)l - longLowBound];
+ else
+ return new Long(l);
+ }
+
+ public static Float boxToFloat(float f) {
+ return new Float(f);
+ }
+
+ public static Double boxToDouble(double d) {
+ return new Double(d);
+ }
+
+ public static boolean unboxToBoolean(Object b) {
+ return b == null ? false : ((Boolean)b).booleanValue();
+ }
+
+ public static char unboxToChar(Object c) {
+ if (c == null)
+ return 0;
+ else if (c instanceof Character)
+ return ((Character)c).charValue();
+ else
+ return ((char)((Number)c).intValue());
+ }
+
+ public static byte unboxToByte(Object b) {
+ if (b == null)
+ return 0;
+ else if (b instanceof Number)
+ return ((Number)b).byteValue();
+ else
+ return ((byte)((Character)b).charValue());
+ }
+
+ public static short unboxToShort(Object s) {
+ if (s == null)
+ return 0;
+ else if (s instanceof Number)
+ return ((Number)s).shortValue();
+ else
+ return ((short)((Character)s).charValue());
+ }
+
+ public static int unboxToInt(Object i) {
+ if (i == null)
+ return 0;
+ else if (i instanceof Number)
+ return ((Number)i).intValue();
+ else
+ return ((int)((Character)i).charValue());
+ }
+
+ public static long unboxToLong(Object l) {
+ if (l == null)
+ return 0;
+ else if (l instanceof Number)
+ return ((Number)l).longValue();
+ else
+ return ((long)((Character)l).charValue());
+ }
+
+ public static float unboxToFloat(Object f) {
+ if (f == null)
+ return 0.0f;
+ else if (f instanceof Number)
+ return ((Number)f).floatValue();
+ else
+ return ((float)((Character)f).charValue());
+ }
+
+ public static double unboxToDouble(Object d) {
+ if (d == null)
+ return 0.0;
+ else if (d instanceof Number)
+ return ((Number)d).doubleValue();
+ else
+ return ((double)((Character)d).charValue());
+ }
+
+}
diff --git a/src/library/scala/runtime/Comparator.java b/src/library/scala/runtime/Comparator.java
new file mode 100644
index 0000000000..b090d5052e
--- /dev/null
+++ b/src/library/scala/runtime/Comparator.java
@@ -0,0 +1,40 @@
+package scala.runtime;
+
+public class Comparator {
+
+ /* A rich implementation of the equals method that overrides the default equals because Java's boxed primitives are
+ * utterly broken. This equals is inserted instead of a normal equals by the Scala compiler (in the icode phase,
+ * method genEqEqPrimitive) only when either side of the comparison is a subclass of AnyVal, of java.lang.Number, of
+ * java.lang.Character or is exactly Any or AnyRef. */
+ public static boolean equals(Object a, Object b) {
+ if (a == null)
+ return b == null;
+ else if (a.equals(b))
+ return true;
+ else if (a == b)
+ return true;
+ else if ((a instanceof Byte || a instanceof Short || a instanceof Integer) && b instanceof Number)
+ return ((Number)a).intValue() == ((Number)b).intValue();
+ else if (a instanceof Number && (b instanceof Byte || b instanceof Short || b instanceof Integer))
+ return ((Number)a).intValue() == ((Number)b).intValue();
+ else if (a instanceof Long && b instanceof Number)
+ return ((Long)a).longValue() == ((Number)b).longValue();
+ else if (a instanceof Number && b instanceof Long)
+ return ((Number)a).longValue() == ((Long)b).longValue();
+ else if (a instanceof Float && b instanceof Number)
+ return ((Float)a).floatValue() == ((Number)b).floatValue();
+ else if (a instanceof Number && b instanceof Float)
+ return ((Number)a).floatValue() == ((Float)b).floatValue();
+ else if (a instanceof Number && b instanceof Number)
+ return ((Number)a).doubleValue() == ((Number)b).doubleValue();
+ else if (a instanceof Number && b instanceof Character)
+ return ((Number)a).intValue() == ((Character)b).charValue();
+ else if (a instanceof Character && b instanceof Number)
+ return ((Character)a).charValue() == ((Number)b).intValue();
+ else if (a instanceof Character && b instanceof Character)
+ return ((Character)a).charValue() == ((Character)b).charValue();
+ else
+ return false;
+ }
+
+}