summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library/scala/Array.scala67
-rw-r--r--test/files/run/bug1300.check1
-rw-r--r--test/files/run/bug1300.scala12
3 files changed, 36 insertions, 44 deletions
diff --git a/src/library/scala/Array.scala b/src/library/scala/Array.scala
index 99b3332ac6..45d12b433e 100644
--- a/src/library/scala/Array.scala
+++ b/src/library/scala/Array.scala
@@ -21,6 +21,24 @@ import compat.Platform.arraycopy
* @version 1.0
*/
object Array {
+ import runtime.BoxedArray;
+ import scala.runtime.ScalaRunTime.boxArray;
+ private def slowcopy(
+ src : AnyRef,
+ srcPos : Int,
+ dest : AnyRef,
+ destPos : Int,
+ length : Int) {
+
+ val srcArray = boxArray(src).asInstanceOf[BoxedArray[AnyRef]]
+ val destArray = boxArray(dest).asInstanceOf[BoxedArray[AnyRef]]
+
+ var i = 0;
+ while(i < length) {
+ destArray(destPos + i) = srcArray(srcPos + i)
+ i += 1
+ }
+ }
/** Copy one array to another.
* Equivalent to
@@ -34,50 +52,11 @@ object Array {
* @param length ...
*/
def copy(src: AnyRef, srcPos: Int, dest: AnyRef, destPos: Int, length: Int) {
- src match {
- case xs: runtime.BoxedArray[_] =>
- xs.copyTo(srcPos, dest, destPos, length)
- case _ =>
- dest match {
- case xs: runtime.BoxedArray[_] =>
- xs.copyFrom(src, srcPos, destPos, length)
- case _ =>
- def fillDest[T](da: Array[T], sa: Int=>T) {
- var d = destPos
- for (s <- srcPos to srcPos+length-1) {
- da(d) = sa(s); d += 1
- }
- }
- if (dest.isInstanceOf[Array[Any]]) {
- def fill(sa: Int=>Any) = fillDest(dest.asInstanceOf[Array[Any]], sa)
- src match {
- case sa:Array[Int] => fill(s=>Int.box(sa(s)))
- case sa:Array[Long] => fill(s=>Long.box(sa(s)))
- case sa:Array[Char] => fill(s=>Char.box(sa(s)))
- case sa:Array[Boolean] => fill(s=>Boolean.box(sa(s)))
- case sa:Array[Byte] => fill(s=>Byte.box(sa(s)))
- case sa:Array[Short] => fill(s=>Short.box(sa(s)))
- case sa:Array[Double] => fill(s=>Double.box(sa(s)))
- case sa:Array[Float] => fill(s=>Float.box(sa(s)))
- case _ => arraycopy(src, srcPos, dest, destPos, length)
- }
- } else if (dest.isInstanceOf[Array[AnyVal]]) {
- def fill(sa: Int=>AnyVal) = fillDest(dest.asInstanceOf[Array[AnyVal]], sa)
- src match {
- case sa:Array[Int] => fill(sa(_))
- case sa:Array[Long] => fill(sa(_))
- case sa:Array[Char] => fill(sa(_))
- case sa:Array[Boolean] => fill(sa(_))
- case sa:Array[Byte] => fill(sa(_))
- case sa:Array[Short] => fill(sa(_))
- case sa:Array[Double] => fill(sa(_))
- case sa:Array[Float] => fill(sa(_))
- case _ => arraycopy(src, srcPos, dest, destPos, length)
- }
- } else
- arraycopy(src, srcPos, dest, destPos, length)
- }
- }
+ val srcClass = src.getClass
+ if (srcClass.isArray && dest.getClass.isAssignableFrom(srcClass))
+ arraycopy(src, srcPos, dest, destPos, length)
+ else
+ slowcopy(src, srcPos, dest, destPos, length)
}
/** Concatenate all argument sequences into a single array.
diff --git a/test/files/run/bug1300.check b/test/files/run/bug1300.check
new file mode 100644
index 0000000000..0f29a1fef5
--- /dev/null
+++ b/test/files/run/bug1300.check
@@ -0,0 +1 @@
+abcdabcdabcd
diff --git a/test/files/run/bug1300.scala b/test/files/run/bug1300.scala
new file mode 100644
index 0000000000..3d26c0f4da
--- /dev/null
+++ b/test/files/run/bug1300.scala
@@ -0,0 +1,12 @@
+object Test extends Application
+{
+ val a1 = Array(0,1,2,3).toArray[Any]
+ val a2 = Array('a','b','c','d').toArray[Any]
+ val a3 = Array("e","f","g","h").toArray[Any]
+
+ Array.copy(a3, 0, a1, 0, 4)
+ Array.copy(a2, 0, a3, 0, 4)
+ Array.copy(a2, 0, a1, 0, 4)
+
+ println(a1.mkString + a2.mkString + a3.mkString)
+} \ No newline at end of file