FloatTypedArrayAdaptor::toJSValue should almost certainly not use jsNumber() since...
authorfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 25 Aug 2013 08:02:51 +0000 (08:02 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 25 Aug 2013 08:02:51 +0000 (08:02 +0000)
https://bugs.webkit.org/show_bug.cgi?id=120228

Source/JavaScriptCore:

Reviewed by Oliver Hunt.

It turns out that there were three problems:

- Using jsNumber() meant that we were converting doubles to integers and then
  possibly back again whenever doing a set() between floating point arrays.

- Slow-path accesses to double typed arrays were slower than necessary because
  of the to-int conversion attempt.

- The use of JSValue as an intermediate for converting between differen types
  in typedArray.set() resulted in worse code than I had previously expected.

This patch solves the problem by using template double-dispatch to ensure that
that C++ compiler sees the simplest possible combination of casts between any
combination of typed array types, while still preserving JS and typed array
conversion semantics. Conversions are done as follows:

    SourceAdaptor::convertTo<TargetAdaptor>(value)

Internally, convertTo() calls one of three possible methods on TargetAdaptor,
with one method for each of int32_t, uint32_t, and double. This means that the
C++ compiler will at worst see a widening cast to one of those types followed
by a narrowing conversion (not necessarily a cast - may have clamping or the
JS toInt32() function).

This change doesn't just affect typedArray.set(); it also affects slow-path
accesses to typed arrays as well. This patch also adds a bunch of new test
coverage.

This change is a ~50% speed-up on typedArray.set() involving floating point
types.

* GNUmakefile.list.am:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* runtime/GenericTypedArrayView.h:
(JSC::GenericTypedArrayView::set):
* runtime/JSDataViewPrototype.cpp:
(JSC::setData):
* runtime/JSGenericTypedArrayView.h:
(JSC::JSGenericTypedArrayView::setIndexQuicklyToDouble):
(JSC::JSGenericTypedArrayView::setIndexQuickly):
* runtime/JSGenericTypedArrayViewInlines.h:
(JSC::::setWithSpecificType):
(JSC::::set):
* runtime/ToNativeFromValue.h: Added.
(JSC::toNativeFromValue):
* runtime/TypedArrayAdaptors.h:
(JSC::IntegralTypedArrayAdaptor::toJSValue):
(JSC::IntegralTypedArrayAdaptor::toDouble):
(JSC::IntegralTypedArrayAdaptor::toNativeFromInt32):
(JSC::IntegralTypedArrayAdaptor::toNativeFromUint32):
(JSC::IntegralTypedArrayAdaptor::toNativeFromDouble):
(JSC::IntegralTypedArrayAdaptor::convertTo):
(JSC::FloatTypedArrayAdaptor::toJSValue):
(JSC::FloatTypedArrayAdaptor::toDouble):
(JSC::FloatTypedArrayAdaptor::toNativeFromInt32):
(JSC::FloatTypedArrayAdaptor::toNativeFromUint32):
(JSC::FloatTypedArrayAdaptor::toNativeFromDouble):
(JSC::FloatTypedArrayAdaptor::convertTo):
(JSC::Uint8ClampedAdaptor::toJSValue):
(JSC::Uint8ClampedAdaptor::toDouble):
(JSC::Uint8ClampedAdaptor::toNativeFromInt32):
(JSC::Uint8ClampedAdaptor::toNativeFromUint32):
(JSC::Uint8ClampedAdaptor::toNativeFromDouble):
(JSC::Uint8ClampedAdaptor::convertTo):

LayoutTests:

Reviewed by Oliver Hunt.

Add coverage for three things:

- Typed array accesses with corner-case values.

- Typed array set() (i.e. copy) between arrays of different types.

- Performance of typedArray.set() involving different types.

This required some changes to our test harnesses, since they previously
couldn't consistently do numerical array comparisons in a reliable way.

* fast/js/regress/Float32Array-to-Float64Array-set-expected.txt: Added.
* fast/js/regress/Float32Array-to-Float64Array-set.html: Added.
* fast/js/regress/Float64Array-to-Int16Array-set-expected.txt: Added.
* fast/js/regress/Float64Array-to-Int16Array-set.html: Added.
* fast/js/regress/Int16Array-to-Int32Array-set-expected.txt: Added.
* fast/js/regress/Int16Array-to-Int32Array-set.html: Added.
* fast/js/regress/script-tests/Float32Array-to-Float64Array-set.js: Added.
* fast/js/regress/script-tests/Float64Array-to-Int16Array-set.js: Added.
* fast/js/regress/script-tests/Int16Array-to-Int32Array-set.js: Added.
* fast/js/resources/js-test-pre.js:
(areNumbersEqual):
(areArraysEqual):
(isResultCorrect):
* fast/js/resources/standalone-pre.js:
(areNumbersEqual):
(areArraysEqual):
(isTypedArray):
(isResultCorrect):
(stringify):
(shouldBe):
* fast/js/script-tests/typed-array-access.js: Added.
(bitsToString):
(bitsToValue):
(valueToBits):
(roundTrip):
* fast/js/script-tests/typed-array-set-different-types.js: Added.
(MyRandom):
(.reference):
(.usingConstruct):
* fast/js/typed-array-access-expected.txt: Added.
* fast/js/typed-array-access.html: Added.
* fast/js/typed-array-set-different-types-expected.txt: Added.
* fast/js/typed-array-set-different-types.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@154569 268f45cc-cd09-0410-ab3c-d52691b4dbfc

28 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/js/regress/Float32Array-to-Float64Array-set-expected.txt [new file with mode: 0644]
LayoutTests/fast/js/regress/Float32Array-to-Float64Array-set.html [new file with mode: 0644]
LayoutTests/fast/js/regress/Float64Array-to-Int16Array-set-expected.txt [new file with mode: 0644]
LayoutTests/fast/js/regress/Float64Array-to-Int16Array-set.html [new file with mode: 0644]
LayoutTests/fast/js/regress/Int16Array-to-Int32Array-set-expected.txt [new file with mode: 0644]
LayoutTests/fast/js/regress/Int16Array-to-Int32Array-set.html [new file with mode: 0644]
LayoutTests/fast/js/regress/script-tests/Float32Array-to-Float64Array-set.js [new file with mode: 0644]
LayoutTests/fast/js/regress/script-tests/Float64Array-to-Int16Array-set.js [new file with mode: 0644]
LayoutTests/fast/js/regress/script-tests/Int16Array-to-Int32Array-set.js [new file with mode: 0644]
LayoutTests/fast/js/resources/js-test-pre.js
LayoutTests/fast/js/resources/standalone-pre.js
LayoutTests/fast/js/script-tests/typed-array-access.js [new file with mode: 0644]
LayoutTests/fast/js/script-tests/typed-array-set-different-types.js [new file with mode: 0644]
LayoutTests/fast/js/typed-array-access-expected.txt [new file with mode: 0644]
LayoutTests/fast/js/typed-array-access.html [new file with mode: 0644]
LayoutTests/fast/js/typed-array-set-different-types-expected.txt [new file with mode: 0644]
LayoutTests/fast/js/typed-array-set-different-types.html [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/GNUmakefile.list.am
Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/runtime/GenericTypedArrayView.h
Source/JavaScriptCore/runtime/JSDataViewPrototype.cpp
Source/JavaScriptCore/runtime/JSGenericTypedArrayView.h
Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h
Source/JavaScriptCore/runtime/ToNativeFromValue.h [new file with mode: 0644]
Source/JavaScriptCore/runtime/TypedArrayAdaptors.h

index e902b7c..92e3652 100644 (file)
@@ -1,3 +1,55 @@
+2013-08-24  Filip Pizlo  <fpizlo@apple.com>
+
+        FloatTypedArrayAdaptor::toJSValue should almost certainly not use jsNumber() since that attempts int conversions
+        https://bugs.webkit.org/show_bug.cgi?id=120228
+
+        Reviewed by Oliver Hunt.
+        
+        Add coverage for three things:
+        
+        - Typed array accesses with corner-case values.
+        
+        - Typed array set() (i.e. copy) between arrays of different types.
+        
+        - Performance of typedArray.set() involving different types.
+        
+        This required some changes to our test harnesses, since they previously
+        couldn't consistently do numerical array comparisons in a reliable way.
+
+        * fast/js/regress/Float32Array-to-Float64Array-set-expected.txt: Added.
+        * fast/js/regress/Float32Array-to-Float64Array-set.html: Added.
+        * fast/js/regress/Float64Array-to-Int16Array-set-expected.txt: Added.
+        * fast/js/regress/Float64Array-to-Int16Array-set.html: Added.
+        * fast/js/regress/Int16Array-to-Int32Array-set-expected.txt: Added.
+        * fast/js/regress/Int16Array-to-Int32Array-set.html: Added.
+        * fast/js/regress/script-tests/Float32Array-to-Float64Array-set.js: Added.
+        * fast/js/regress/script-tests/Float64Array-to-Int16Array-set.js: Added.
+        * fast/js/regress/script-tests/Int16Array-to-Int32Array-set.js: Added.
+        * fast/js/resources/js-test-pre.js:
+        (areNumbersEqual):
+        (areArraysEqual):
+        (isResultCorrect):
+        * fast/js/resources/standalone-pre.js:
+        (areNumbersEqual):
+        (areArraysEqual):
+        (isTypedArray):
+        (isResultCorrect):
+        (stringify):
+        (shouldBe):
+        * fast/js/script-tests/typed-array-access.js: Added.
+        (bitsToString):
+        (bitsToValue):
+        (valueToBits):
+        (roundTrip):
+        * fast/js/script-tests/typed-array-set-different-types.js: Added.
+        (MyRandom):
+        (.reference):
+        (.usingConstruct):
+        * fast/js/typed-array-access-expected.txt: Added.
+        * fast/js/typed-array-access.html: Added.
+        * fast/js/typed-array-set-different-types-expected.txt: Added.
+        * fast/js/typed-array-set-different-types.html: Added.
+
 2013-08-25  Ryuan Choi  <ryuan.choi@samsung.com>
 
         Unreviewed EFL gardening.
diff --git a/LayoutTests/fast/js/regress/Float32Array-to-Float64Array-set-expected.txt b/LayoutTests/fast/js/regress/Float32Array-to-Float64Array-set-expected.txt
new file mode 100644 (file)
index 0000000..8ce5801
--- /dev/null
@@ -0,0 +1,10 @@
+JSRegress/Float32Array-to-Float64Array-set
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/js/regress/Float32Array-to-Float64Array-set.html b/LayoutTests/fast/js/regress/Float32Array-to-Float64Array-set.html
new file mode 100644 (file)
index 0000000..62e2d7d
--- /dev/null
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="../resources/js-test-pre.js"></script>
+</head>
+<body>
+<script src="resources/regress-pre.js"></script>
+<script src="script-tests/Float32Array-to-Float64Array-set.js"></script>
+<script src="resources/regress-post.js"></script>
+<script src="../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/js/regress/Float64Array-to-Int16Array-set-expected.txt b/LayoutTests/fast/js/regress/Float64Array-to-Int16Array-set-expected.txt
new file mode 100644 (file)
index 0000000..77e092e
--- /dev/null
@@ -0,0 +1,10 @@
+JSRegress/Float64Array-to-Int16Array-set
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/js/regress/Float64Array-to-Int16Array-set.html b/LayoutTests/fast/js/regress/Float64Array-to-Int16Array-set.html
new file mode 100644 (file)
index 0000000..67c0342
--- /dev/null
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="../resources/js-test-pre.js"></script>
+</head>
+<body>
+<script src="resources/regress-pre.js"></script>
+<script src="script-tests/Float64Array-to-Int16Array-set.js"></script>
+<script src="resources/regress-post.js"></script>
+<script src="../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/js/regress/Int16Array-to-Int32Array-set-expected.txt b/LayoutTests/fast/js/regress/Int16Array-to-Int32Array-set-expected.txt
new file mode 100644 (file)
index 0000000..121c619
--- /dev/null
@@ -0,0 +1,10 @@
+JSRegress/Int16Array-to-Int32Array-set
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/js/regress/Int16Array-to-Int32Array-set.html b/LayoutTests/fast/js/regress/Int16Array-to-Int32Array-set.html
new file mode 100644 (file)
index 0000000..0e51233
--- /dev/null
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="../resources/js-test-pre.js"></script>
+</head>
+<body>
+<script src="resources/regress-pre.js"></script>
+<script src="script-tests/Int16Array-to-Int32Array-set.js"></script>
+<script src="resources/regress-post.js"></script>
+<script src="../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/js/regress/script-tests/Float32Array-to-Float64Array-set.js b/LayoutTests/fast/js/regress/script-tests/Float32Array-to-Float64Array-set.js
new file mode 100644 (file)
index 0000000..cf4291d
--- /dev/null
@@ -0,0 +1,17 @@
+(function() {
+    var result = 0;
+    
+    for (var i = 0; i < 100000; ++i) {
+        var array1 = new Float32Array(15);
+        for (var j = 0; j < array1.length; ++j)
+            array1[j] = i - j;
+        var array2 = new Float64Array(15);
+        for (var j = 0; j < 10; ++j)
+            array2.set(array1);
+        for (var j = 0; j < array2.length; ++j)
+            result += array2[j];
+    }
+    
+    if (result != 74988750000)
+        throw "Error: bad result: " + result;
+})();
diff --git a/LayoutTests/fast/js/regress/script-tests/Float64Array-to-Int16Array-set.js b/LayoutTests/fast/js/regress/script-tests/Float64Array-to-Int16Array-set.js
new file mode 100644 (file)
index 0000000..7cba49f
--- /dev/null
@@ -0,0 +1,17 @@
+(function() {
+    var result = 0;
+    
+    for (var i = 0; i < 100000; ++i) {
+        var array1 = new Float64Array(15);
+        for (var j = 0; j < array1.length; ++j)
+            array1[j] = i - j;
+        var array2 = new Int16Array(15);
+        for (var j = 0; j < 10; ++j)
+            array2.set(array1);
+        for (var j = 0; j < array2.length; ++j)
+            result += array2[j];
+    }
+    
+    if (result != 7243531440)
+        throw "Error: bad result: " + result;
+})();
diff --git a/LayoutTests/fast/js/regress/script-tests/Int16Array-to-Int32Array-set.js b/LayoutTests/fast/js/regress/script-tests/Int16Array-to-Int32Array-set.js
new file mode 100644 (file)
index 0000000..800bf90
--- /dev/null
@@ -0,0 +1,17 @@
+(function() {
+    var result = 0;
+    
+    for (var i = 0; i < 100000; ++i) {
+        var array1 = new Int16Array(15);
+        for (var j = 0; j < array1.length; ++j)
+            array1[j] = i - j;
+        var array2 = new Int32Array(15);
+        for (var j = 0; j < 10; ++j)
+            array2.set(array1);
+        for (var j = 0; j < array2.length; ++j)
+            result += array2[j];
+    }
+    
+    if (result != 7243531440)
+        throw "Error: bad result: " + result;
+})();
index a02bdd0..d99e17c 100644 (file)
@@ -112,13 +112,24 @@ function testFailed(msg)
     debug('<span><span class="fail">FAIL</span> ' + escapeHTML(msg) + '</span>');
 }
 
+function areNumbersEqual(_actual, _expected)
+{
+    if (_expected === 0)
+        return _actual === _expected && (1/_actual) === (1/_expected);
+    if (_actual === _expected)
+        return true;
+    if (typeof(_expected) == "number" && isNaN(_expected))
+        return typeof(_actual) == "number" && isNaN(_actual);
+    return false;
+}
+
 function areArraysEqual(_a, _b)
 {
     try {
         if (_a.length !== _b.length)
             return false;
         for (var i = 0; i < _a.length; i++)
-            if (_a[i] !== _b[i])
+            if (!areNumbersEqual(_a[i], _b[i]))
                 return false;
     } catch (ex) {
         return false;
@@ -148,12 +159,8 @@ function isTypedArray(array)
 
 function isResultCorrect(_actual, _expected)
 {
-    if (_expected === 0)
-        return _actual === _expected && (1/_actual) === (1/_expected);
-    if (_actual === _expected)
+    if (areNumbersEqual(_actual, _expected))
         return true;
-    if (typeof(_expected) == "number" && isNaN(_expected))
-        return typeof(_actual) == "number" && isNaN(_actual);
     if (_expected
         && (Object.prototype.toString.call(_expected) ==
             Object.prototype.toString.call([])
index 4b3d725..2da6648 100644 (file)
@@ -30,15 +30,28 @@ function testFailed(msg)
     print("FAIL", escapeString(msg));
 }
 
+function areNumbersEqual(_actual, _expected)
+{
+    if (_expected === 0)
+        return _actual === _expected && (1/_actual) === (1/_expected);
+    if (_actual === _expected)
+        return true;
+    if (typeof(_expected) == "number" && isNaN(_expected))
+        return typeof(_actual) == "number" && isNaN(_actual);
+    return false;
+}
+
 function areArraysEqual(_a, _b)
 {
-    if (Object.prototype.toString.call(_a) != Object.prototype.toString.call([]))
-        return false;
-    if (_a.length !== _b.length)
-        return false;
-    for (var i = 0; i < _a.length; i++)
-        if (_a[i] !== _b[i])
+    try {
+        if (_a.length !== _b.length)
             return false;
+        for (var i = 0; i < _a.length; i++)
+            if (!areNumbersEqual(_a[i], _b[i]))
+                return false;
+    } catch (ex) {
+        return false;
+    }
     return true;
 }
 
@@ -49,15 +62,27 @@ function isMinusZero(n)
     return n === 0 && 1/n < 0;
 }
 
+function isTypedArray(array)
+{
+    return array instanceof Int8Array
+        || array instanceof Int16Array
+        || array instanceof Int32Array
+        || array instanceof Uint8Array
+        || array instanceof Uint8ClampedArray
+        || array instanceof Uint16Array
+        || array instanceof Uint32Array
+        || array instanceof Float32Array
+        || array instanceof Float64Array;
+}
+
 function isResultCorrect(_actual, _expected)
 {
-    if (_expected === 0)
-        return _actual === _expected && (1/_actual) === (1/_expected);
-    if (_actual === _expected)
+    if (areNumbersEqual(_actual, _expected))
         return true;
-    if (typeof(_expected) == "number" && isNaN(_expected))
-        return typeof(_actual) == "number" && isNaN(_actual);
-    if (Object.prototype.toString.call(_expected) == Object.prototype.toString.call([]))
+    if (_expected
+        && (Object.prototype.toString.call(_expected) ==
+            Object.prototype.toString.call([])
+            || isTypedArray(_expected)))
         return areArraysEqual(_actual, _expected);
     return false;
 }
@@ -66,7 +91,10 @@ function stringify(v)
 {
     if (v === 0 && 1/v < 0)
         return "-0";
-    else return "" + v;
+    else if (isTypedArray(v))
+        return v.__proto__.constructor.name + ":[" + Array.prototype.join.call(v, ",") + "]";
+    else
+        return "" + v;
 }
 
 function shouldBe(_a, _b)
@@ -83,13 +111,13 @@ function shouldBe(_a, _b)
   var _bv = eval(_b);
 
   if (exception)
-    testFailed(_a + " should be " + _bv + ". Threw exception " + exception);
+    testFailed(_a + " should be " + stringify(_bv) + ". Threw exception " + exception);
   else if (isResultCorrect(_av, _bv))
     testPassed(_a + " is " + _b);
   else if (typeof(_av) == typeof(_bv))
-    testFailed(_a + " should be " + _bv + ". Was " + stringify(_av) + ".");
+    testFailed(_a + " should be " + stringify(_bv) + ". Was " + stringify(_av) + ".");
   else
-    testFailed(_a + " should be " + _bv + " (of type " + typeof _bv + "). Was " + _av + " (of type " + typeof _av + ").");
+    testFailed(_a + " should be " + stringify(_bv) + " (of type " + typeof _bv + "). Was " + _av + " (of type " + typeof _av + ").");
 }
 
 function shouldBeTrue(_a) { shouldBe(_a, "true"); }
diff --git a/LayoutTests/fast/js/script-tests/typed-array-access.js b/LayoutTests/fast/js/script-tests/typed-array-access.js
new file mode 100644 (file)
index 0000000..b2869b1
--- /dev/null
@@ -0,0 +1,154 @@
+description(
+"Tests that accesses to typed arrays handle value conversions correctly."
+);
+
+// FIXME: This test assumes little-endian. It would take some hackage to convert
+// it to a big-endian test.
+
+function bitsToString(array) {
+    return Array.prototype.join.call(array, ":");
+}
+    
+// Call this like so:
+//
+//    bitsToValue(type, expectedJavascriptValue, first32Bits, second32Bits)
+//
+// Note that the second32Bits are optional.
+//
+// Where 'type' is for example "Int32".
+function bitsToValue(type, expected) {
+    var baseArray = new Int32Array(arguments.length - 2);
+    for (var i = 0; i < arguments.length - 2; ++i)
+        baseArray[i] = arguments[i + 2];
+    
+    var actual = (new this[type + "Array"](baseArray.buffer, 0, 1))[0];
+    if (isResultCorrect(actual, expected))
+        testPassed("Reading bit pattern " + bitsToString(baseArray) + " with " + type + " resulted in " + stringify(actual));
+    else
+        testFailed("Reading bit pattern " + bitsToString(baseArray) + " with " + type + " should result in " + stringify(expected) + " but instead was " + stringify(actual));
+}
+
+// Same signature as bitsToValue, except that the meaning is reversed.
+function valueToBits(type, input) {
+    var buffer = new ArrayBuffer((arguments.length - 2) * 4);
+    
+    var baseArray = new this[type + "Array"](buffer);
+    baseArray[0] = input;
+    
+    var expectedArray = new Int32Array(arguments.length - 2);
+    for (var i = 0; i < arguments.length - 2; ++i)
+        expectedArray[i] = arguments[i + 2];
+    
+    var actualArray = new Int32Array(buffer);
+    if (isResultCorrect(actualArray, expectedArray))
+        testPassed("Writing the value " + stringify(input) + " with type " + type + " results in bit pattern " + bitsToString(actualArray));
+    else
+        testFailed("Writing the value " + stringify(input) + " with type " + type + " should result in bit pattern " + bitsToString(expectedArray) + " but instead was " + bitsToString(actualArray));
+}
+
+// Test that both directions work.
+function roundTrip() {
+    bitsToValue.apply(this, arguments);
+    valueToBits.apply(this, arguments);
+}
+
+roundTrip("Int8", 0, 0);
+roundTrip("Int8", 42, 42);
+roundTrip("Int8", -1, 255);
+bitsToValue("Int8", 112, -400);
+bitsToValue("Int8", -112, 400);
+valueToBits("Int8", 1000, 232);
+valueToBits("Int8", -1000, 24);
+valueToBits("Int8", 0.5, 0);
+valueToBits("Int8", -0.5, 0);
+valueToBits("Int8", -1.5, 255);
+valueToBits("Int8", 6326266464264213, 21);
+valueToBits("Int8", -6326266464264213, 235);
+
+roundTrip("Uint8", 0, 0);
+roundTrip("Uint8", 42, 42);
+roundTrip("Uint8", 255, 255);
+bitsToValue("Uint8", 144, 400);
+bitsToValue("Uint8", 112, -400);
+valueToBits("Uint8", 1000, 232);
+valueToBits("Uint8", -1000, 24);
+valueToBits("Uint8", 0.5, 0);
+valueToBits("Uint8", -0.5, 0);
+valueToBits("Uint8", -1.5, 255);
+valueToBits("Uint8", 6326266464264213, 21);
+valueToBits("Uint8", -6326266464264213, 235);
+
+roundTrip("Uint8Clamped", 0, 0);
+roundTrip("Uint8Clamped", 42, 42);
+roundTrip("Uint8Clamped", 255, 255);
+bitsToValue("Uint8Clamped", 144, 400);
+bitsToValue("Uint8Clamped", 112, -400);
+valueToBits("Uint8Clamped", 1000, 255);
+valueToBits("Uint8Clamped", -1000, 0);
+valueToBits("Uint8Clamped", 0.5, 0);
+valueToBits("Uint8Clamped", -0.5, 0);
+valueToBits("Uint8Clamped", -1.5, 0);
+valueToBits("Uint8Clamped", 6326266464264213, 255);
+valueToBits("Uint8Clamped", -6326266464264213, 0);
+
+roundTrip("Int16", 0, 0);
+roundTrip("Int16", 42, 42);
+roundTrip("Int16", 400, 400);
+roundTrip("Int16", -1, 65535);
+roundTrip("Int16", -400, 65136);
+roundTrip("Int16", 30901, 30901);
+bitsToValue("Int16", 6784, 400000);
+bitsToValue("Int16", -6784, -400000);
+valueToBits("Int16", 100000, 34464);
+valueToBits("Int16", -100000, 31072);
+valueToBits("Int16", 0.5, 0);
+valueToBits("Int16", -0.5, 0);
+valueToBits("Int16", -1.5, 65535);
+valueToBits("Int16", 6326266464264213, 24597);
+valueToBits("Int16", -6326266464264213, 40939);
+
+roundTrip("Uint16", 0, 0);
+roundTrip("Uint16", 42, 42);
+roundTrip("Uint16", 400, 400);
+roundTrip("Uint16", 30901, 30901);
+bitsToValue("Uint16", 6784, 400000);
+bitsToValue("Uint16", 58752, -400000);
+valueToBits("Int16", 100000, 34464);
+valueToBits("Int16", -100000, 31072);
+valueToBits("Uint16", -1, 65535);
+valueToBits("Uint16", -400, 65136);
+valueToBits("Uint16", 0.5, 0);
+valueToBits("Uint16", 6326266464264213, 24597);
+valueToBits("Uint16", -6326266464264213, 40939);
+
+roundTrip("Int32", 0, 0);
+roundTrip("Int32", 42, 42);
+roundTrip("Int32", 1000000000, 1000000000);
+roundTrip("Int32", -42, -42);
+roundTrip("Int32", -1000000000, -1000000000);
+valueToBits("Int32", 0.5, 0);
+valueToBits("Int32", -0.5, 0);
+valueToBits("Int32", -1.5, -1);
+valueToBits("Int32", 6326266464264213, -1319411691);
+valueToBits("Int32", -6326266464264213, 1319411691);
+
+roundTrip("Uint32", 0, 0);
+roundTrip("Uint32", 42, 42);
+roundTrip("Uint32", 1000000000, 1000000000);
+valueToBits("Uint32", -42, -42);
+bitsToValue("Uint32", (-42)>>>0, -42);
+valueToBits("Uint32", -1000000000, -1000000000);
+bitsToValue("Uint32", (-1000000000)>>>0, -1000000000);
+valueToBits("Uint32", 0.5, 0);
+valueToBits("Uint32", -0.5, 0);
+valueToBits("Uint32", -1.5, -1);
+valueToBits("Uint32", 6326266464264213, -1319411691);
+valueToBits("Uint32", -6326266464264213, 1319411691);
+
+roundTrip("Float32", 0, 0);
+roundTrip("Float32", 1.5, 1069547520);
+valueToBits("Float32", 1000000000, 1315859240);
+
+roundTrip("Float64", 0, 0, 0);
+roundTrip("Float64", 1.5, 0, 1073217536);
+roundTrip("Float64", 1000000000, 0, 1104006501);
diff --git a/LayoutTests/fast/js/script-tests/typed-array-set-different-types.js b/LayoutTests/fast/js/script-tests/typed-array-set-different-types.js
new file mode 100644 (file)
index 0000000..5f656c9
--- /dev/null
@@ -0,0 +1,89 @@
+description(
+"Tests that typedArray.set(otherTypedArray) does the right conversions when dealing with different types."
+);
+
+function MyRandom(z, w) {
+    this.z = (z == null ? 42 : z);
+    this.w = (w == null ? 23 : w);
+}
+
+MyRandom.prototype.get = function() {
+    this.z = (36969 * (this.z & 65535) + (this.z >> 16)) | 0;
+    this.w = (18000 * (this.w & 65535) + (this.w >> 16)) | 0;
+    return ((this.z << 16) + this.w) | 0;
+};
+
+function testArraySet(fromType, toType) {
+    // This function tests type conversions of set() by asserting that they are
+    // equivalent to converting via JSValue.
+    
+    var rand = new MyRandom();
+    
+    function createIntArray() {
+        var numSequences = 3;
+        var numPerSequence = 4;
+        var masks = [255, 65535, -1];
+        
+        var array = new fromType(numSequences * numPerSequence);
+        for (var i = 0; i < numSequences; ++i) {
+            for (var j = 0; j < numPerSequence; ++j)
+                array[i * numPerSequence + j] = rand.get() & masks[i];
+        }
+        
+        return array;
+    }
+    
+    function createFloatArray() {
+        var array = [0, 0/-1, 1, 42, 1.5, -2.5, 1/0, -1/0, 0/0];
+        for (var i = 3; i--;)
+            array.push(rand.get());
+        
+        return new fromType(array);
+    }
+    
+    var sourceArray;
+    if (fromType == Float32Array || fromType == Float64Array)
+        sourceArray = createFloatArray();
+    else
+        sourceArray = createIntArray();
+    
+    function reference() {
+        var array = new toType(sourceArray.length);
+        for (var i = 0; i < sourceArray.length; ++i)
+            array[i] = sourceArray[i];
+        return array;
+    }
+    
+    function usingConstruct() {
+        return new toType(sourceArray);
+    }
+    
+    function usingSet() {
+        var array = new toType(sourceArray.length);
+        array.set(sourceArray);
+        return array;
+    }
+    
+    var referenceArray = reference();
+    
+    var actualConstructArray = usingConstruct();
+    
+    if (isResultCorrect(referenceArray, actualConstructArray))
+        testPassed("Copying " + stringify(sourceArray) + " to an array of type " + toType.name + " using the constructor resulted in " + stringify(actualConstructArray));
+    else
+        testFailed("Copying " + stringify(sourceArray) + " to an array of type " + toType.name + " using the constructor should have resulted in " + stringify(referenceArray) + " but instead resulted in " + stringify(actualConstructArray));
+    
+    var actualSetArray = usingSet();
+
+    if (isResultCorrect(referenceArray, actualSetArray))
+        testPassed("Copying " + stringify(sourceArray) + " to an array of type " + toType.name + " using typedArray.set() resulted in " + stringify(actualSetArray));
+    else
+        testFailed("Copying " + stringify(sourceArray) + " to an array of type " + toType.name + " using typedArray.set() should have resulted in " + stringify(referenceArray) + " but instead resulted in " + stringify(actualSetArray));
+}
+
+var types = [Int8Array, Int16Array, Int32Array, Uint8Array, Uint8ClampedArray, Uint16Array, Uint32Array, Float32Array, Float64Array];
+
+for (var i = 0; i < types.length; ++i) {
+    for (var j = 0; j < types.length; ++j)
+        testArraySet(types[i], types[j]);
+}
diff --git a/LayoutTests/fast/js/typed-array-access-expected.txt b/LayoutTests/fast/js/typed-array-access-expected.txt
new file mode 100644 (file)
index 0000000..7271c3e
--- /dev/null
@@ -0,0 +1,133 @@
+Tests that accesses to typed arrays handle value conversions correctly.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Reading bit pattern 0 with Int8 resulted in 0
+PASS Writing the value 0 with type Int8 results in bit pattern 0
+PASS Reading bit pattern 42 with Int8 resulted in 42
+PASS Writing the value 42 with type Int8 results in bit pattern 42
+PASS Reading bit pattern 255 with Int8 resulted in -1
+PASS Writing the value -1 with type Int8 results in bit pattern 255
+PASS Reading bit pattern -400 with Int8 resulted in 112
+PASS Reading bit pattern 400 with Int8 resulted in -112
+PASS Writing the value 1000 with type Int8 results in bit pattern 232
+PASS Writing the value -1000 with type Int8 results in bit pattern 24
+PASS Writing the value 0.5 with type Int8 results in bit pattern 0
+PASS Writing the value -0.5 with type Int8 results in bit pattern 0
+PASS Writing the value -1.5 with type Int8 results in bit pattern 255
+PASS Writing the value 6326266464264213 with type Int8 results in bit pattern 21
+PASS Writing the value -6326266464264213 with type Int8 results in bit pattern 235
+PASS Reading bit pattern 0 with Uint8 resulted in 0
+PASS Writing the value 0 with type Uint8 results in bit pattern 0
+PASS Reading bit pattern 42 with Uint8 resulted in 42
+PASS Writing the value 42 with type Uint8 results in bit pattern 42
+PASS Reading bit pattern 255 with Uint8 resulted in 255
+PASS Writing the value 255 with type Uint8 results in bit pattern 255
+PASS Reading bit pattern 400 with Uint8 resulted in 144
+PASS Reading bit pattern -400 with Uint8 resulted in 112
+PASS Writing the value 1000 with type Uint8 results in bit pattern 232
+PASS Writing the value -1000 with type Uint8 results in bit pattern 24
+PASS Writing the value 0.5 with type Uint8 results in bit pattern 0
+PASS Writing the value -0.5 with type Uint8 results in bit pattern 0
+PASS Writing the value -1.5 with type Uint8 results in bit pattern 255
+PASS Writing the value 6326266464264213 with type Uint8 results in bit pattern 21
+PASS Writing the value -6326266464264213 with type Uint8 results in bit pattern 235
+PASS Reading bit pattern 0 with Uint8Clamped resulted in 0
+PASS Writing the value 0 with type Uint8Clamped results in bit pattern 0
+PASS Reading bit pattern 42 with Uint8Clamped resulted in 42
+PASS Writing the value 42 with type Uint8Clamped results in bit pattern 42
+PASS Reading bit pattern 255 with Uint8Clamped resulted in 255
+PASS Writing the value 255 with type Uint8Clamped results in bit pattern 255
+PASS Reading bit pattern 400 with Uint8Clamped resulted in 144
+PASS Reading bit pattern -400 with Uint8Clamped resulted in 112
+PASS Writing the value 1000 with type Uint8Clamped results in bit pattern 255
+PASS Writing the value -1000 with type Uint8Clamped results in bit pattern 0
+PASS Writing the value 0.5 with type Uint8Clamped results in bit pattern 0
+PASS Writing the value -0.5 with type Uint8Clamped results in bit pattern 0
+PASS Writing the value -1.5 with type Uint8Clamped results in bit pattern 0
+PASS Writing the value 6326266464264213 with type Uint8Clamped results in bit pattern 255
+PASS Writing the value -6326266464264213 with type Uint8Clamped results in bit pattern 0
+PASS Reading bit pattern 0 with Int16 resulted in 0
+PASS Writing the value 0 with type Int16 results in bit pattern 0
+PASS Reading bit pattern 42 with Int16 resulted in 42
+PASS Writing the value 42 with type Int16 results in bit pattern 42
+PASS Reading bit pattern 400 with Int16 resulted in 400
+PASS Writing the value 400 with type Int16 results in bit pattern 400
+PASS Reading bit pattern 65535 with Int16 resulted in -1
+PASS Writing the value -1 with type Int16 results in bit pattern 65535
+PASS Reading bit pattern 65136 with Int16 resulted in -400
+PASS Writing the value -400 with type Int16 results in bit pattern 65136
+PASS Reading bit pattern 30901 with Int16 resulted in 30901
+PASS Writing the value 30901 with type Int16 results in bit pattern 30901
+PASS Reading bit pattern 400000 with Int16 resulted in 6784
+PASS Reading bit pattern -400000 with Int16 resulted in -6784
+PASS Writing the value 100000 with type Int16 results in bit pattern 34464
+PASS Writing the value -100000 with type Int16 results in bit pattern 31072
+PASS Writing the value 0.5 with type Int16 results in bit pattern 0
+PASS Writing the value -0.5 with type Int16 results in bit pattern 0
+PASS Writing the value -1.5 with type Int16 results in bit pattern 65535
+PASS Writing the value 6326266464264213 with type Int16 results in bit pattern 24597
+PASS Writing the value -6326266464264213 with type Int16 results in bit pattern 40939
+PASS Reading bit pattern 0 with Uint16 resulted in 0
+PASS Writing the value 0 with type Uint16 results in bit pattern 0
+PASS Reading bit pattern 42 with Uint16 resulted in 42
+PASS Writing the value 42 with type Uint16 results in bit pattern 42
+PASS Reading bit pattern 400 with Uint16 resulted in 400
+PASS Writing the value 400 with type Uint16 results in bit pattern 400
+PASS Reading bit pattern 30901 with Uint16 resulted in 30901
+PASS Writing the value 30901 with type Uint16 results in bit pattern 30901
+PASS Reading bit pattern 400000 with Uint16 resulted in 6784
+PASS Reading bit pattern -400000 with Uint16 resulted in 58752
+PASS Writing the value 100000 with type Int16 results in bit pattern 34464
+PASS Writing the value -100000 with type Int16 results in bit pattern 31072
+PASS Writing the value -1 with type Uint16 results in bit pattern 65535
+PASS Writing the value -400 with type Uint16 results in bit pattern 65136
+PASS Writing the value 0.5 with type Uint16 results in bit pattern 0
+PASS Writing the value 6326266464264213 with type Uint16 results in bit pattern 24597
+PASS Writing the value -6326266464264213 with type Uint16 results in bit pattern 40939
+PASS Reading bit pattern 0 with Int32 resulted in 0
+PASS Writing the value 0 with type Int32 results in bit pattern 0
+PASS Reading bit pattern 42 with Int32 resulted in 42
+PASS Writing the value 42 with type Int32 results in bit pattern 42
+PASS Reading bit pattern 1000000000 with Int32 resulted in 1000000000
+PASS Writing the value 1000000000 with type Int32 results in bit pattern 1000000000
+PASS Reading bit pattern -42 with Int32 resulted in -42
+PASS Writing the value -42 with type Int32 results in bit pattern -42
+PASS Reading bit pattern -1000000000 with Int32 resulted in -1000000000
+PASS Writing the value -1000000000 with type Int32 results in bit pattern -1000000000
+PASS Writing the value 0.5 with type Int32 results in bit pattern 0
+PASS Writing the value -0.5 with type Int32 results in bit pattern 0
+PASS Writing the value -1.5 with type Int32 results in bit pattern -1
+PASS Writing the value 6326266464264213 with type Int32 results in bit pattern -1319411691
+PASS Writing the value -6326266464264213 with type Int32 results in bit pattern 1319411691
+PASS Reading bit pattern 0 with Uint32 resulted in 0
+PASS Writing the value 0 with type Uint32 results in bit pattern 0
+PASS Reading bit pattern 42 with Uint32 resulted in 42
+PASS Writing the value 42 with type Uint32 results in bit pattern 42
+PASS Reading bit pattern 1000000000 with Uint32 resulted in 1000000000
+PASS Writing the value 1000000000 with type Uint32 results in bit pattern 1000000000
+PASS Writing the value -42 with type Uint32 results in bit pattern -42
+PASS Reading bit pattern -42 with Uint32 resulted in 4294967254
+PASS Writing the value -1000000000 with type Uint32 results in bit pattern -1000000000
+PASS Reading bit pattern -1000000000 with Uint32 resulted in 3294967296
+PASS Writing the value 0.5 with type Uint32 results in bit pattern 0
+PASS Writing the value -0.5 with type Uint32 results in bit pattern 0
+PASS Writing the value -1.5 with type Uint32 results in bit pattern -1
+PASS Writing the value 6326266464264213 with type Uint32 results in bit pattern -1319411691
+PASS Writing the value -6326266464264213 with type Uint32 results in bit pattern 1319411691
+PASS Reading bit pattern 0 with Float32 resulted in 0
+PASS Writing the value 0 with type Float32 results in bit pattern 0
+PASS Reading bit pattern 1069547520 with Float32 resulted in 1.5
+PASS Writing the value 1.5 with type Float32 results in bit pattern 1069547520
+PASS Writing the value 1000000000 with type Float32 results in bit pattern 1315859240
+PASS Reading bit pattern 0:0 with Float64 resulted in 0
+PASS Writing the value 0 with type Float64 results in bit pattern 0:0
+PASS Reading bit pattern 0:1073217536 with Float64 resulted in 1.5
+PASS Writing the value 1.5 with type Float64 results in bit pattern 0:1073217536
+PASS Reading bit pattern 0:1104006501 with Float64 resulted in 1000000000
+PASS Writing the value 1000000000 with type Float64 results in bit pattern 0:1104006501
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/js/typed-array-access.html b/LayoutTests/fast/js/typed-array-access.html
new file mode 100644 (file)
index 0000000..a2837f4
--- /dev/null
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="resources/js-test-pre.js"></script>
+</head>
+<body>
+<script src="script-tests/typed-array-access.js"></script>
+<script src="resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/js/typed-array-set-different-types-expected.txt b/LayoutTests/fast/js/typed-array-set-different-types-expected.txt
new file mode 100644 (file)
index 0000000..25e923f
--- /dev/null
@@ -0,0 +1,171 @@
+Tests that typedArray.set(otherTypedArray) does the right conversions when dealing with different types.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Copying Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46] to an array of type Int8Array using the constructor resulted in Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46]
+PASS Copying Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46] to an array of type Int8Array using typedArray.set() resulted in Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46]
+PASS Copying Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46] to an array of type Int16Array using the constructor resulted in Int16Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46]
+PASS Copying Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46] to an array of type Int16Array using typedArray.set() resulted in Int16Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46]
+PASS Copying Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46] to an array of type Int32Array using the constructor resulted in Int32Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46]
+PASS Copying Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46] to an array of type Int32Array using typedArray.set() resulted in Int32Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46]
+PASS Copying Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46] to an array of type Uint8Array using the constructor resulted in Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46]
+PASS Copying Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46] to an array of type Uint8Array using typedArray.set() resulted in Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46]
+PASS Copying Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46] to an array of type Uint8ClampedArray using the constructor resulted in Uint8ClampedArray:[48,6,44,0,0,0,56,74,92,90,117,46]
+PASS Copying Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46] to an array of type Uint8ClampedArray using typedArray.set() resulted in Uint8ClampedArray:[48,6,44,0,0,0,56,74,92,90,117,46]
+PASS Copying Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46] to an array of type Uint16Array using the constructor resulted in Uint16Array:[48,6,44,65443,65445,65498,56,74,92,90,117,46]
+PASS Copying Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46] to an array of type Uint16Array using typedArray.set() resulted in Uint16Array:[48,6,44,65443,65445,65498,56,74,92,90,117,46]
+PASS Copying Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46] to an array of type Uint32Array using the constructor resulted in Uint32Array:[48,6,44,4294967203,4294967205,4294967258,56,74,92,90,117,46]
+PASS Copying Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46] to an array of type Uint32Array using typedArray.set() resulted in Uint32Array:[48,6,44,4294967203,4294967205,4294967258,56,74,92,90,117,46]
+PASS Copying Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46] to an array of type Float32Array using the constructor resulted in Float32Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46]
+PASS Copying Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46] to an array of type Float32Array using typedArray.set() resulted in Float32Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46]
+PASS Copying Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46] to an array of type Float64Array using the constructor resulted in Float64Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46]
+PASS Copying Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46] to an array of type Float64Array using typedArray.set() resulted in Float64Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46]
+PASS Copying Int16Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350] to an array of type Int8Array using the constructor resulted in Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46]
+PASS Copying Int16Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350] to an array of type Int8Array using typedArray.set() resulted in Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46]
+PASS Copying Int16Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350] to an array of type Int16Array using the constructor resulted in Int16Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350]
+PASS Copying Int16Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350] to an array of type Int16Array using typedArray.set() resulted in Int16Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350]
+PASS Copying Int16Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350] to an array of type Int32Array using the constructor resulted in Int32Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350]
+PASS Copying Int16Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350] to an array of type Int32Array using typedArray.set() resulted in Int32Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350]
+PASS Copying Int16Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350] to an array of type Uint8Array using the constructor resulted in Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46]
+PASS Copying Int16Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350] to an array of type Uint8Array using typedArray.set() resulted in Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46]
+PASS Copying Int16Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350] to an array of type Uint8ClampedArray using the constructor resulted in Uint8ClampedArray:[48,6,44,163,255,255,0,0,255,255,255,255]
+PASS Copying Int16Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350] to an array of type Uint8ClampedArray using typedArray.set() resulted in Uint8ClampedArray:[48,6,44,163,255,255,0,0,255,255,255,255]
+PASS Copying Int16Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350] to an array of type Uint16Array using the constructor resulted in Uint16Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350]
+PASS Copying Int16Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350] to an array of type Uint16Array using typedArray.set() resulted in Uint16Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350]
+PASS Copying Int16Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350] to an array of type Uint32Array using the constructor resulted in Uint32Array:[48,6,44,163,25253,13786,4294937400,4294959178,31068,21082,31093,2350]
+PASS Copying Int16Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350] to an array of type Uint32Array using typedArray.set() resulted in Uint32Array:[48,6,44,163,25253,13786,4294937400,4294959178,31068,21082,31093,2350]
+PASS Copying Int16Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350] to an array of type Float32Array using the constructor resulted in Float32Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350]
+PASS Copying Int16Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350] to an array of type Float32Array using typedArray.set() resulted in Float32Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350]
+PASS Copying Int16Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350] to an array of type Float64Array using the constructor resulted in Float64Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350]
+PASS Copying Int16Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350] to an array of type Float64Array using typedArray.set() resulted in Float64Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350]
+PASS Copying Int32Array:[48,6,44,163,25253,13786,35640,57418,-1230538404,1472221786,-590710411,1209665838] to an array of type Int8Array using the constructor resulted in Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46]
+PASS Copying Int32Array:[48,6,44,163,25253,13786,35640,57418,-1230538404,1472221786,-590710411,1209665838] to an array of type Int8Array using typedArray.set() resulted in Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46]
+PASS Copying Int32Array:[48,6,44,163,25253,13786,35640,57418,-1230538404,1472221786,-590710411,1209665838] to an array of type Int16Array using the constructor resulted in Int16Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350]
+PASS Copying Int32Array:[48,6,44,163,25253,13786,35640,57418,-1230538404,1472221786,-590710411,1209665838] to an array of type Int16Array using typedArray.set() resulted in Int16Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350]
+PASS Copying Int32Array:[48,6,44,163,25253,13786,35640,57418,-1230538404,1472221786,-590710411,1209665838] to an array of type Int32Array using the constructor resulted in Int32Array:[48,6,44,163,25253,13786,35640,57418,-1230538404,1472221786,-590710411,1209665838]
+PASS Copying Int32Array:[48,6,44,163,25253,13786,35640,57418,-1230538404,1472221786,-590710411,1209665838] to an array of type Int32Array using typedArray.set() resulted in Int32Array:[48,6,44,163,25253,13786,35640,57418,-1230538404,1472221786,-590710411,1209665838]
+PASS Copying Int32Array:[48,6,44,163,25253,13786,35640,57418,-1230538404,1472221786,-590710411,1209665838] to an array of type Uint8Array using the constructor resulted in Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46]
+PASS Copying Int32Array:[48,6,44,163,25253,13786,35640,57418,-1230538404,1472221786,-590710411,1209665838] to an array of type Uint8Array using typedArray.set() resulted in Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46]
+PASS Copying Int32Array:[48,6,44,163,25253,13786,35640,57418,-1230538404,1472221786,-590710411,1209665838] to an array of type Uint8ClampedArray using the constructor resulted in Uint8ClampedArray:[48,6,44,163,255,255,255,255,0,255,0,255]
+PASS Copying Int32Array:[48,6,44,163,25253,13786,35640,57418,-1230538404,1472221786,-590710411,1209665838] to an array of type Uint8ClampedArray using typedArray.set() resulted in Uint8ClampedArray:[48,6,44,163,255,255,255,255,0,255,0,255]
+PASS Copying Int32Array:[48,6,44,163,25253,13786,35640,57418,-1230538404,1472221786,-590710411,1209665838] to an array of type Uint16Array using the constructor resulted in Uint16Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350]
+PASS Copying Int32Array:[48,6,44,163,25253,13786,35640,57418,-1230538404,1472221786,-590710411,1209665838] to an array of type Uint16Array using typedArray.set() resulted in Uint16Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350]
+PASS Copying Int32Array:[48,6,44,163,25253,13786,35640,57418,-1230538404,1472221786,-590710411,1209665838] to an array of type Uint32Array using the constructor resulted in Uint32Array:[48,6,44,163,25253,13786,35640,57418,3064428892,1472221786,3704256885,1209665838]
+PASS Copying Int32Array:[48,6,44,163,25253,13786,35640,57418,-1230538404,1472221786,-590710411,1209665838] to an array of type Uint32Array using typedArray.set() resulted in Uint32Array:[48,6,44,163,25253,13786,35640,57418,3064428892,1472221786,3704256885,1209665838]
+PASS Copying Int32Array:[48,6,44,163,25253,13786,35640,57418,-1230538404,1472221786,-590710411,1209665838] to an array of type Float32Array using the constructor resulted in Float32Array:[48,6,44,163,25253,13786,35640,57418,-1230538368,1472221824,-590710400,1209665792]
+PASS Copying Int32Array:[48,6,44,163,25253,13786,35640,57418,-1230538404,1472221786,-590710411,1209665838] to an array of type Float32Array using typedArray.set() resulted in Float32Array:[48,6,44,163,25253,13786,35640,57418,-1230538368,1472221824,-590710400,1209665792]
+PASS Copying Int32Array:[48,6,44,163,25253,13786,35640,57418,-1230538404,1472221786,-590710411,1209665838] to an array of type Float64Array using the constructor resulted in Float64Array:[48,6,44,163,25253,13786,35640,57418,-1230538404,1472221786,-590710411,1209665838]
+PASS Copying Int32Array:[48,6,44,163,25253,13786,35640,57418,-1230538404,1472221786,-590710411,1209665838] to an array of type Float64Array using typedArray.set() resulted in Float64Array:[48,6,44,163,25253,13786,35640,57418,-1230538404,1472221786,-590710411,1209665838]
+PASS Copying Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46] to an array of type Int8Array using the constructor resulted in Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46]
+PASS Copying Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46] to an array of type Int8Array using typedArray.set() resulted in Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46]
+PASS Copying Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46] to an array of type Int16Array using the constructor resulted in Int16Array:[48,6,44,163,165,218,56,74,92,90,117,46]
+PASS Copying Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46] to an array of type Int16Array using typedArray.set() resulted in Int16Array:[48,6,44,163,165,218,56,74,92,90,117,46]
+PASS Copying Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46] to an array of type Int32Array using the constructor resulted in Int32Array:[48,6,44,163,165,218,56,74,92,90,117,46]
+PASS Copying Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46] to an array of type Int32Array using typedArray.set() resulted in Int32Array:[48,6,44,163,165,218,56,74,92,90,117,46]
+PASS Copying Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46] to an array of type Uint8Array using the constructor resulted in Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46]
+PASS Copying Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46] to an array of type Uint8Array using typedArray.set() resulted in Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46]
+PASS Copying Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46] to an array of type Uint8ClampedArray using the constructor resulted in Uint8ClampedArray:[48,6,44,163,165,218,56,74,92,90,117,46]
+PASS Copying Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46] to an array of type Uint8ClampedArray using typedArray.set() resulted in Uint8ClampedArray:[48,6,44,163,165,218,56,74,92,90,117,46]
+PASS Copying Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46] to an array of type Uint16Array using the constructor resulted in Uint16Array:[48,6,44,163,165,218,56,74,92,90,117,46]
+PASS Copying Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46] to an array of type Uint16Array using typedArray.set() resulted in Uint16Array:[48,6,44,163,165,218,56,74,92,90,117,46]
+PASS Copying Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46] to an array of type Uint32Array using the constructor resulted in Uint32Array:[48,6,44,163,165,218,56,74,92,90,117,46]
+PASS Copying Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46] to an array of type Uint32Array using typedArray.set() resulted in Uint32Array:[48,6,44,163,165,218,56,74,92,90,117,46]
+PASS Copying Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46] to an array of type Float32Array using the constructor resulted in Float32Array:[48,6,44,163,165,218,56,74,92,90,117,46]
+PASS Copying Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46] to an array of type Float32Array using typedArray.set() resulted in Float32Array:[48,6,44,163,165,218,56,74,92,90,117,46]
+PASS Copying Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46] to an array of type Float64Array using the constructor resulted in Float64Array:[48,6,44,163,165,218,56,74,92,90,117,46]
+PASS Copying Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46] to an array of type Float64Array using typedArray.set() resulted in Float64Array:[48,6,44,163,165,218,56,74,92,90,117,46]
+PASS Copying Uint8ClampedArray:[48,6,44,163,255,255,255,255,0,255,0,255] to an array of type Int8Array using the constructor resulted in Int8Array:[48,6,44,-93,-1,-1,-1,-1,0,-1,0,-1]
+PASS Copying Uint8ClampedArray:[48,6,44,163,255,255,255,255,0,255,0,255] to an array of type Int8Array using typedArray.set() resulted in Int8Array:[48,6,44,-93,-1,-1,-1,-1,0,-1,0,-1]
+PASS Copying Uint8ClampedArray:[48,6,44,163,255,255,255,255,0,255,0,255] to an array of type Int16Array using the constructor resulted in Int16Array:[48,6,44,163,255,255,255,255,0,255,0,255]
+PASS Copying Uint8ClampedArray:[48,6,44,163,255,255,255,255,0,255,0,255] to an array of type Int16Array using typedArray.set() resulted in Int16Array:[48,6,44,163,255,255,255,255,0,255,0,255]
+PASS Copying Uint8ClampedArray:[48,6,44,163,255,255,255,255,0,255,0,255] to an array of type Int32Array using the constructor resulted in Int32Array:[48,6,44,163,255,255,255,255,0,255,0,255]
+PASS Copying Uint8ClampedArray:[48,6,44,163,255,255,255,255,0,255,0,255] to an array of type Int32Array using typedArray.set() resulted in Int32Array:[48,6,44,163,255,255,255,255,0,255,0,255]
+PASS Copying Uint8ClampedArray:[48,6,44,163,255,255,255,255,0,255,0,255] to an array of type Uint8Array using the constructor resulted in Uint8Array:[48,6,44,163,255,255,255,255,0,255,0,255]
+PASS Copying Uint8ClampedArray:[48,6,44,163,255,255,255,255,0,255,0,255] to an array of type Uint8Array using typedArray.set() resulted in Uint8Array:[48,6,44,163,255,255,255,255,0,255,0,255]
+PASS Copying Uint8ClampedArray:[48,6,44,163,255,255,255,255,0,255,0,255] to an array of type Uint8ClampedArray using the constructor resulted in Uint8ClampedArray:[48,6,44,163,255,255,255,255,0,255,0,255]
+PASS Copying Uint8ClampedArray:[48,6,44,163,255,255,255,255,0,255,0,255] to an array of type Uint8ClampedArray using typedArray.set() resulted in Uint8ClampedArray:[48,6,44,163,255,255,255,255,0,255,0,255]
+PASS Copying Uint8ClampedArray:[48,6,44,163,255,255,255,255,0,255,0,255] to an array of type Uint16Array using the constructor resulted in Uint16Array:[48,6,44,163,255,255,255,255,0,255,0,255]
+PASS Copying Uint8ClampedArray:[48,6,44,163,255,255,255,255,0,255,0,255] to an array of type Uint16Array using typedArray.set() resulted in Uint16Array:[48,6,44,163,255,255,255,255,0,255,0,255]
+PASS Copying Uint8ClampedArray:[48,6,44,163,255,255,255,255,0,255,0,255] to an array of type Uint32Array using the constructor resulted in Uint32Array:[48,6,44,163,255,255,255,255,0,255,0,255]
+PASS Copying Uint8ClampedArray:[48,6,44,163,255,255,255,255,0,255,0,255] to an array of type Uint32Array using typedArray.set() resulted in Uint32Array:[48,6,44,163,255,255,255,255,0,255,0,255]
+PASS Copying Uint8ClampedArray:[48,6,44,163,255,255,255,255,0,255,0,255] to an array of type Float32Array using the constructor resulted in Float32Array:[48,6,44,163,255,255,255,255,0,255,0,255]
+PASS Copying Uint8ClampedArray:[48,6,44,163,255,255,255,255,0,255,0,255] to an array of type Float32Array using typedArray.set() resulted in Float32Array:[48,6,44,163,255,255,255,255,0,255,0,255]
+PASS Copying Uint8ClampedArray:[48,6,44,163,255,255,255,255,0,255,0,255] to an array of type Float64Array using the constructor resulted in Float64Array:[48,6,44,163,255,255,255,255,0,255,0,255]
+PASS Copying Uint8ClampedArray:[48,6,44,163,255,255,255,255,0,255,0,255] to an array of type Float64Array using typedArray.set() resulted in Float64Array:[48,6,44,163,255,255,255,255,0,255,0,255]
+PASS Copying Uint16Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350] to an array of type Int8Array using the constructor resulted in Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46]
+PASS Copying Uint16Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350] to an array of type Int8Array using typedArray.set() resulted in Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46]
+PASS Copying Uint16Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350] to an array of type Int16Array using the constructor resulted in Int16Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350]
+PASS Copying Uint16Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350] to an array of type Int16Array using typedArray.set() resulted in Int16Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350]
+PASS Copying Uint16Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350] to an array of type Int32Array using the constructor resulted in Int32Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350]
+PASS Copying Uint16Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350] to an array of type Int32Array using typedArray.set() resulted in Int32Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350]
+PASS Copying Uint16Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350] to an array of type Uint8Array using the constructor resulted in Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46]
+PASS Copying Uint16Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350] to an array of type Uint8Array using typedArray.set() resulted in Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46]
+PASS Copying Uint16Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350] to an array of type Uint8ClampedArray using the constructor resulted in Uint8ClampedArray:[48,6,44,163,255,255,255,255,255,255,255,255]
+PASS Copying Uint16Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350] to an array of type Uint8ClampedArray using typedArray.set() resulted in Uint8ClampedArray:[48,6,44,163,255,255,255,255,255,255,255,255]
+PASS Copying Uint16Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350] to an array of type Uint16Array using the constructor resulted in Uint16Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350]
+PASS Copying Uint16Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350] to an array of type Uint16Array using typedArray.set() resulted in Uint16Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350]
+PASS Copying Uint16Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350] to an array of type Uint32Array using the constructor resulted in Uint32Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350]
+PASS Copying Uint16Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350] to an array of type Uint32Array using typedArray.set() resulted in Uint32Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350]
+PASS Copying Uint16Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350] to an array of type Float32Array using the constructor resulted in Float32Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350]
+PASS Copying Uint16Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350] to an array of type Float32Array using typedArray.set() resulted in Float32Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350]
+PASS Copying Uint16Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350] to an array of type Float64Array using the constructor resulted in Float64Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350]
+PASS Copying Uint16Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350] to an array of type Float64Array using typedArray.set() resulted in Float64Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350]
+PASS Copying Uint32Array:[48,6,44,163,25253,13786,35640,57418,3064428892,1472221786,3704256885,1209665838] to an array of type Int8Array using the constructor resulted in Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46]
+PASS Copying Uint32Array:[48,6,44,163,25253,13786,35640,57418,3064428892,1472221786,3704256885,1209665838] to an array of type Int8Array using typedArray.set() resulted in Int8Array:[48,6,44,-93,-91,-38,56,74,92,90,117,46]
+PASS Copying Uint32Array:[48,6,44,163,25253,13786,35640,57418,3064428892,1472221786,3704256885,1209665838] to an array of type Int16Array using the constructor resulted in Int16Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350]
+PASS Copying Uint32Array:[48,6,44,163,25253,13786,35640,57418,3064428892,1472221786,3704256885,1209665838] to an array of type Int16Array using typedArray.set() resulted in Int16Array:[48,6,44,163,25253,13786,-29896,-8118,31068,21082,31093,2350]
+PASS Copying Uint32Array:[48,6,44,163,25253,13786,35640,57418,3064428892,1472221786,3704256885,1209665838] to an array of type Int32Array using the constructor resulted in Int32Array:[48,6,44,163,25253,13786,35640,57418,-1230538404,1472221786,-590710411,1209665838]
+PASS Copying Uint32Array:[48,6,44,163,25253,13786,35640,57418,3064428892,1472221786,3704256885,1209665838] to an array of type Int32Array using typedArray.set() resulted in Int32Array:[48,6,44,163,25253,13786,35640,57418,-1230538404,1472221786,-590710411,1209665838]
+PASS Copying Uint32Array:[48,6,44,163,25253,13786,35640,57418,3064428892,1472221786,3704256885,1209665838] to an array of type Uint8Array using the constructor resulted in Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46]
+PASS Copying Uint32Array:[48,6,44,163,25253,13786,35640,57418,3064428892,1472221786,3704256885,1209665838] to an array of type Uint8Array using typedArray.set() resulted in Uint8Array:[48,6,44,163,165,218,56,74,92,90,117,46]
+PASS Copying Uint32Array:[48,6,44,163,25253,13786,35640,57418,3064428892,1472221786,3704256885,1209665838] to an array of type Uint8ClampedArray using the constructor resulted in Uint8ClampedArray:[48,6,44,163,255,255,255,255,255,255,255,255]
+PASS Copying Uint32Array:[48,6,44,163,25253,13786,35640,57418,3064428892,1472221786,3704256885,1209665838] to an array of type Uint8ClampedArray using typedArray.set() resulted in Uint8ClampedArray:[48,6,44,163,255,255,255,255,255,255,255,255]
+PASS Copying Uint32Array:[48,6,44,163,25253,13786,35640,57418,3064428892,1472221786,3704256885,1209665838] to an array of type Uint16Array using the constructor resulted in Uint16Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350]
+PASS Copying Uint32Array:[48,6,44,163,25253,13786,35640,57418,3064428892,1472221786,3704256885,1209665838] to an array of type Uint16Array using typedArray.set() resulted in Uint16Array:[48,6,44,163,25253,13786,35640,57418,31068,21082,31093,2350]
+PASS Copying Uint32Array:[48,6,44,163,25253,13786,35640,57418,3064428892,1472221786,3704256885,1209665838] to an array of type Uint32Array using the constructor resulted in Uint32Array:[48,6,44,163,25253,13786,35640,57418,3064428892,1472221786,3704256885,1209665838]
+PASS Copying Uint32Array:[48,6,44,163,25253,13786,35640,57418,3064428892,1472221786,3704256885,1209665838] to an array of type Uint32Array using typedArray.set() resulted in Uint32Array:[48,6,44,163,25253,13786,35640,57418,3064428892,1472221786,3704256885,1209665838]
+PASS Copying Uint32Array:[48,6,44,163,25253,13786,35640,57418,3064428892,1472221786,3704256885,1209665838] to an array of type Float32Array using the constructor resulted in Float32Array:[48,6,44,163,25253,13786,35640,57418,3064428800,1472221824,3704256768,1209665792]
+PASS Copying Uint32Array:[48,6,44,163,25253,13786,35640,57418,3064428892,1472221786,3704256885,1209665838] to an array of type Float32Array using typedArray.set() resulted in Float32Array:[48,6,44,163,25253,13786,35640,57418,3064428800,1472221824,3704256768,1209665792]
+PASS Copying Uint32Array:[48,6,44,163,25253,13786,35640,57418,3064428892,1472221786,3704256885,1209665838] to an array of type Float64Array using the constructor resulted in Float64Array:[48,6,44,163,25253,13786,35640,57418,3064428892,1472221786,3704256885,1209665838]
+PASS Copying Uint32Array:[48,6,44,163,25253,13786,35640,57418,3064428892,1472221786,3704256885,1209665838] to an array of type Float64Array using typedArray.set() resulted in Float64Array:[48,6,44,163,25253,13786,35640,57418,3064428892,1472221786,3704256885,1209665838]
+PASS Copying Float32Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321185024,1731034880,1126525952] to an array of type Int8Array using the constructor resulted in Int8Array:[0,0,1,42,1,-2,0,0,0,0,0,0]
+PASS Copying Float32Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321185024,1731034880,1126525952] to an array of type Int8Array using typedArray.set() resulted in Int8Array:[0,0,1,42,1,-2,0,0,0,0,0,0]
+PASS Copying Float32Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321185024,1731034880,1126525952] to an array of type Int16Array using the constructor resulted in Int16Array:[0,0,1,42,1,-2,0,0,0,20736,32512,27648]
+PASS Copying Float32Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321185024,1731034880,1126525952] to an array of type Int16Array using typedArray.set() resulted in Int16Array:[0,0,1,42,1,-2,0,0,0,20736,32512,27648]
+PASS Copying Float32Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321185024,1731034880,1126525952] to an array of type Int32Array using the constructor resulted in Int32Array:[0,0,1,42,1,-2,0,0,0,-1321185024,1731034880,1126525952]
+PASS Copying Float32Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321185024,1731034880,1126525952] to an array of type Int32Array using typedArray.set() resulted in Int32Array:[0,0,1,42,1,-2,0,0,0,-1321185024,1731034880,1126525952]
+PASS Copying Float32Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321185024,1731034880,1126525952] to an array of type Uint8Array using the constructor resulted in Uint8Array:[0,0,1,42,1,254,0,0,0,0,0,0]
+PASS Copying Float32Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321185024,1731034880,1126525952] to an array of type Uint8Array using typedArray.set() resulted in Uint8Array:[0,0,1,42,1,254,0,0,0,0,0,0]
+PASS Copying Float32Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321185024,1731034880,1126525952] to an array of type Uint8ClampedArray using the constructor resulted in Uint8ClampedArray:[0,0,1,42,2,0,255,0,0,0,255,255]
+PASS Copying Float32Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321185024,1731034880,1126525952] to an array of type Uint8ClampedArray using typedArray.set() resulted in Uint8ClampedArray:[0,0,1,42,2,0,255,0,0,0,255,255]
+PASS Copying Float32Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321185024,1731034880,1126525952] to an array of type Uint16Array using the constructor resulted in Uint16Array:[0,0,1,42,1,65534,0,0,0,20736,32512,27648]
+PASS Copying Float32Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321185024,1731034880,1126525952] to an array of type Uint16Array using typedArray.set() resulted in Uint16Array:[0,0,1,42,1,65534,0,0,0,20736,32512,27648]
+PASS Copying Float32Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321185024,1731034880,1126525952] to an array of type Uint32Array using the constructor resulted in Uint32Array:[0,0,1,42,1,4294967294,0,0,0,2973782272,1731034880,1126525952]
+PASS Copying Float32Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321185024,1731034880,1126525952] to an array of type Uint32Array using typedArray.set() resulted in Uint32Array:[0,0,1,42,1,4294967294,0,0,0,2973782272,1731034880,1126525952]
+PASS Copying Float32Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321185024,1731034880,1126525952] to an array of type Float32Array using the constructor resulted in Float32Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321185024,1731034880,1126525952]
+PASS Copying Float32Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321185024,1731034880,1126525952] to an array of type Float32Array using typedArray.set() resulted in Float32Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321185024,1731034880,1126525952]
+PASS Copying Float32Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321185024,1731034880,1126525952] to an array of type Float64Array using the constructor resulted in Float64Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321185024,1731034880,1126525952]
+PASS Copying Float32Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321185024,1731034880,1126525952] to an array of type Float64Array using typedArray.set() resulted in Float64Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321185024,1731034880,1126525952]
+PASS Copying Float64Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321184976,1731034886,1126525996] to an array of type Int8Array using the constructor resulted in Int8Array:[0,0,1,42,1,-2,0,0,0,48,6,44]
+PASS Copying Float64Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321184976,1731034886,1126525996] to an array of type Int8Array using typedArray.set() resulted in Int8Array:[0,0,1,42,1,-2,0,0,0,48,6,44]
+PASS Copying Float64Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321184976,1731034886,1126525996] to an array of type Int16Array using the constructor resulted in Int16Array:[0,0,1,42,1,-2,0,0,0,20784,32518,27692]
+PASS Copying Float64Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321184976,1731034886,1126525996] to an array of type Int16Array using typedArray.set() resulted in Int16Array:[0,0,1,42,1,-2,0,0,0,20784,32518,27692]
+PASS Copying Float64Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321184976,1731034886,1126525996] to an array of type Int32Array using the constructor resulted in Int32Array:[0,0,1,42,1,-2,0,0,0,-1321184976,1731034886,1126525996]
+PASS Copying Float64Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321184976,1731034886,1126525996] to an array of type Int32Array using typedArray.set() resulted in Int32Array:[0,0,1,42,1,-2,0,0,0,-1321184976,1731034886,1126525996]
+PASS Copying Float64Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321184976,1731034886,1126525996] to an array of type Uint8Array using the constructor resulted in Uint8Array:[0,0,1,42,1,254,0,0,0,48,6,44]
+PASS Copying Float64Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321184976,1731034886,1126525996] to an array of type Uint8Array using typedArray.set() resulted in Uint8Array:[0,0,1,42,1,254,0,0,0,48,6,44]
+PASS Copying Float64Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321184976,1731034886,1126525996] to an array of type Uint8ClampedArray using the constructor resulted in Uint8ClampedArray:[0,0,1,42,2,0,255,0,0,0,255,255]
+PASS Copying Float64Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321184976,1731034886,1126525996] to an array of type Uint8ClampedArray using typedArray.set() resulted in Uint8ClampedArray:[0,0,1,42,2,0,255,0,0,0,255,255]
+PASS Copying Float64Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321184976,1731034886,1126525996] to an array of type Uint16Array using the constructor resulted in Uint16Array:[0,0,1,42,1,65534,0,0,0,20784,32518,27692]
+PASS Copying Float64Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321184976,1731034886,1126525996] to an array of type Uint16Array using typedArray.set() resulted in Uint16Array:[0,0,1,42,1,65534,0,0,0,20784,32518,27692]
+PASS Copying Float64Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321184976,1731034886,1126525996] to an array of type Uint32Array using the constructor resulted in Uint32Array:[0,0,1,42,1,4294967294,0,0,0,2973782320,1731034886,1126525996]
+PASS Copying Float64Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321184976,1731034886,1126525996] to an array of type Uint32Array using typedArray.set() resulted in Uint32Array:[0,0,1,42,1,4294967294,0,0,0,2973782320,1731034886,1126525996]
+PASS Copying Float64Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321184976,1731034886,1126525996] to an array of type Float32Array using the constructor resulted in Float32Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321185024,1731034880,1126525952]
+PASS Copying Float64Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321184976,1731034886,1126525996] to an array of type Float32Array using typedArray.set() resulted in Float32Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321185024,1731034880,1126525952]
+PASS Copying Float64Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321184976,1731034886,1126525996] to an array of type Float64Array using the constructor resulted in Float64Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321184976,1731034886,1126525996]
+PASS Copying Float64Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321184976,1731034886,1126525996] to an array of type Float64Array using typedArray.set() resulted in Float64Array:[0,0,1,42,1.5,-2.5,Infinity,-Infinity,NaN,-1321184976,1731034886,1126525996]
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/js/typed-array-set-different-types.html b/LayoutTests/fast/js/typed-array-set-different-types.html
new file mode 100644 (file)
index 0000000..a16000b
--- /dev/null
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="resources/js-test-pre.js"></script>
+</head>
+<body>
+<script src="script-tests/typed-array-set-different-types.js"></script>
+<script src="resources/js-test-post.js"></script>
+</body>
+</html>
index d182f96..7cdaea7 100644 (file)
@@ -1,3 +1,76 @@
+2013-08-24  Filip Pizlo  <fpizlo@apple.com>
+
+        FloatTypedArrayAdaptor::toJSValue should almost certainly not use jsNumber() since that attempts int conversions
+        https://bugs.webkit.org/show_bug.cgi?id=120228
+
+        Reviewed by Oliver Hunt.
+        
+        It turns out that there were three problems:
+        
+        - Using jsNumber() meant that we were converting doubles to integers and then
+          possibly back again whenever doing a set() between floating point arrays.
+        
+        - Slow-path accesses to double typed arrays were slower than necessary because
+          of the to-int conversion attempt.
+        
+        - The use of JSValue as an intermediate for converting between differen types
+          in typedArray.set() resulted in worse code than I had previously expected.
+        
+        This patch solves the problem by using template double-dispatch to ensure that
+        that C++ compiler sees the simplest possible combination of casts between any
+        combination of typed array types, while still preserving JS and typed array
+        conversion semantics. Conversions are done as follows:
+        
+            SourceAdaptor::convertTo<TargetAdaptor>(value)
+        
+        Internally, convertTo() calls one of three possible methods on TargetAdaptor,
+        with one method for each of int32_t, uint32_t, and double. This means that the
+        C++ compiler will at worst see a widening cast to one of those types followed
+        by a narrowing conversion (not necessarily a cast - may have clamping or the
+        JS toInt32() function).
+        
+        This change doesn't just affect typedArray.set(); it also affects slow-path
+        accesses to typed arrays as well. This patch also adds a bunch of new test
+        coverage.
+        
+        This change is a ~50% speed-up on typedArray.set() involving floating point
+        types.
+
+        * GNUmakefile.list.am:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * runtime/GenericTypedArrayView.h:
+        (JSC::GenericTypedArrayView::set):
+        * runtime/JSDataViewPrototype.cpp:
+        (JSC::setData):
+        * runtime/JSGenericTypedArrayView.h:
+        (JSC::JSGenericTypedArrayView::setIndexQuicklyToDouble):
+        (JSC::JSGenericTypedArrayView::setIndexQuickly):
+        * runtime/JSGenericTypedArrayViewInlines.h:
+        (JSC::::setWithSpecificType):
+        (JSC::::set):
+        * runtime/ToNativeFromValue.h: Added.
+        (JSC::toNativeFromValue):
+        * runtime/TypedArrayAdaptors.h:
+        (JSC::IntegralTypedArrayAdaptor::toJSValue):
+        (JSC::IntegralTypedArrayAdaptor::toDouble):
+        (JSC::IntegralTypedArrayAdaptor::toNativeFromInt32):
+        (JSC::IntegralTypedArrayAdaptor::toNativeFromUint32):
+        (JSC::IntegralTypedArrayAdaptor::toNativeFromDouble):
+        (JSC::IntegralTypedArrayAdaptor::convertTo):
+        (JSC::FloatTypedArrayAdaptor::toJSValue):
+        (JSC::FloatTypedArrayAdaptor::toDouble):
+        (JSC::FloatTypedArrayAdaptor::toNativeFromInt32):
+        (JSC::FloatTypedArrayAdaptor::toNativeFromUint32):
+        (JSC::FloatTypedArrayAdaptor::toNativeFromDouble):
+        (JSC::FloatTypedArrayAdaptor::convertTo):
+        (JSC::Uint8ClampedAdaptor::toJSValue):
+        (JSC::Uint8ClampedAdaptor::toDouble):
+        (JSC::Uint8ClampedAdaptor::toNativeFromInt32):
+        (JSC::Uint8ClampedAdaptor::toNativeFromUint32):
+        (JSC::Uint8ClampedAdaptor::toNativeFromDouble):
+        (JSC::Uint8ClampedAdaptor::convertTo):
+
 2013-08-24  Dan Bernstein  <mitz@apple.com>
 
         [mac] link against libz in a more civilized manner
index 4f2dd28..2ad431f 100644 (file)
@@ -942,6 +942,7 @@ javascriptcore_sources += \
        Source/JavaScriptCore/runtime/StructureTransitionTable.h \
        Source/JavaScriptCore/runtime/SymbolTable.cpp \
        Source/JavaScriptCore/runtime/SymbolTable.h \
+       Source/JavaScriptCore/runtime/ToNativeFromValue.h \
        Source/JavaScriptCore/runtime/Tracing.h \
        Source/JavaScriptCore/runtime/TypedArrayAdaptors.h \
        Source/JavaScriptCore/runtime/TypedArrayBase.h \
index 4643c04..f0fb39c 100644 (file)
     <ClInclude Include="..\runtime\StructureTransitionTable.h" />\r
     <ClInclude Include="..\runtime\SymbolTable.h" />\r
     <ClInclude Include="..\runtime\Tracing.h" />\r
+    <ClInclude Include="..\runtime\ToNativeFromValue.h" />\r
     <ClInclude Include="..\runtime\TypedArrayAdaptors.h" />\r
     <ClInclude Include="..\runtime\TypedArrayController.h" />\r
     <ClInclude Include="..\runtime\TypedArrayInlines.h" />\r
index f8efcfc..f99a5d8 100644 (file)
                0F4B94DC17B9F07500DD03A4 /* TypedArrayInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4B94DB17B9F07500DD03A4 /* TypedArrayInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F5541B11613C1FB00CE3E25 /* SpecialPointer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F5541AF1613C1FB00CE3E25 /* SpecialPointer.cpp */; };
                0F5541B21613C1FB00CE3E25 /* SpecialPointer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5541B01613C1FB00CE3E25 /* SpecialPointer.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F55989817C86C5800A1E543 /* ToNativeFromValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F55989717C86C5600A1E543 /* ToNativeFromValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F55C19417276E4600CEABFD /* DFGAbstractValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F55C19317276E4600CEABFD /* DFGAbstractValue.cpp */; };
                0F55F0F414D1063900AC7649 /* AbstractPC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F55F0F114D1063600AC7649 /* AbstractPC.cpp */; };
                0F55F0F514D1063C00AC7649 /* AbstractPC.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F55F0F214D1063600AC7649 /* AbstractPC.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F4B94DB17B9F07500DD03A4 /* TypedArrayInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypedArrayInlines.h; sourceTree = "<group>"; };
                0F5541AF1613C1FB00CE3E25 /* SpecialPointer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpecialPointer.cpp; sourceTree = "<group>"; };
                0F5541B01613C1FB00CE3E25 /* SpecialPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpecialPointer.h; sourceTree = "<group>"; };
+               0F55989717C86C5600A1E543 /* ToNativeFromValue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ToNativeFromValue.h; sourceTree = "<group>"; };
                0F55C19317276E4600CEABFD /* DFGAbstractValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGAbstractValue.cpp; path = dfg/DFGAbstractValue.cpp; sourceTree = "<group>"; };
                0F55F0F114D1063600AC7649 /* AbstractPC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AbstractPC.cpp; sourceTree = "<group>"; };
                0F55F0F214D1063600AC7649 /* AbstractPC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AbstractPC.h; sourceTree = "<group>"; };
                                BC9041470EB9250900FE26FA /* StructureTransitionTable.h */,
                                0F919D2715856770004A4E7D /* SymbolTable.cpp */,
                                14A396A60CD2933100B5B4FF /* SymbolTable.h */,
+                               0F55989717C86C5600A1E543 /* ToNativeFromValue.h */,
                                5D53726D0E1C546B0021E549 /* Tracing.d */,
                                5D53726E0E1C54880021E549 /* Tracing.h */,
                                0F2B66D817B6B5AB00A7AE3F /* TypedArrayAdaptors.h */,
                                BCCF0D080EF0AAB900413C8F /* StructureStubInfo.h in Headers */,
                                BC9041480EB9250900FE26FA /* StructureTransitionTable.h in Headers */,
                                C2DF44301707AC0100A5CA96 /* SuperRegion.h in Headers */,
+                               0F55989817C86C5800A1E543 /* ToNativeFromValue.h in Headers */,
                                BC18C46B0E16F5CD00B34460 /* SymbolTable.h in Headers */,
                                A784A26411D16622005776AC /* SyntaxChecker.h in Headers */,
                                0F572D4F16879FDD00E57FBD /* ThunkGenerator.h in Headers */,
index b9cbbd2..414ab8d 100644 (file)
@@ -86,7 +86,7 @@ public:
     void set(unsigned index, double value) const
     {
         ASSERT_WITH_SECURITY_IMPLICATION(index < this->length());
-        data()[index] = Adaptor::toNative(value);
+        data()[index] = Adaptor::toNativeFromDouble(value);
     }
     
     bool checkInboundData(unsigned offset, unsigned pos) const
index 08e284e..5af7872 100644 (file)
@@ -30,6 +30,7 @@
 #include "JSDataView.h"
 #include "Lookup.h"
 #include "Operations.h"
+#include "ToNativeFromValue.h"
 #include "TypedArrayAdaptors.h"
 #include <wtf/FlipBytes.h>
 
@@ -138,7 +139,7 @@ EncodedJSValue setData(ExecState* exec)
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
     
-    typename Adaptor::Type value = Adaptor::toNative(exec, exec->argument(1));
+    typename Adaptor::Type value = toNativeFromValue<Adaptor>(exec, exec->argument(1));
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
     
index 1bf26dc..895acbf 100644 (file)
@@ -27,6 +27,7 @@
 #define JSGenericTypedArrayView_h
 
 #include "JSArrayBufferView.h"
+#include "ToNativeFromValue.h"
 
 namespace JSC {
 
@@ -74,11 +75,12 @@ JS_EXPORT_PRIVATE const ClassInfo* getFloat64ArrayClassInfo();
 //     typedef int8_t Type;
 //     typedef Int8Array ViewType;
 //     typedef JSInt8Array JSViewType;
-//     static int8_t toNative(double);
-//     static int8_t toNative(JSValue);
-//     static int8_t toNative(ExecState*, JSValue);
+//     static int8_t toNativeFromInt32(int32_t);
+//     static int8_t toNativeFromUint32(uint32_t);
+//     static int8_t toNativeFromDouble(double);
 //     static JSValue toJSValue(int8_t);
 //     static double toDouble(int8_t);
+//     template<T> static T::Type convertTo(uint8_t);
 // };
 
 template<typename Adaptor>
@@ -144,17 +146,17 @@ public:
     
     void setIndexQuicklyToDouble(unsigned i, double value)
     {
-        setIndexQuicklyToNativeValue(i, Adaptor::toNative(value));
+        setIndexQuicklyToNativeValue(i, toNativeFromValue<Adaptor>(value));
     }
     
     void setIndexQuickly(unsigned i, JSValue value)
     {
-        setIndexQuicklyToNativeValue(i, Adaptor::toNative(value));
+        setIndexQuicklyToNativeValue(i, toNativeFromValue<Adaptor>(value));
     }
     
     bool setIndexQuickly(ExecState* exec, unsigned i, JSValue jsValue)
     {
-        typename Adaptor::Type value = Adaptor::toNative(exec, jsValue);
+        typename Adaptor::Type value = toNativeFromValue<Adaptor>(exec, jsValue);
         if (exec->hadException())
             return false;
         setIndexQuicklyToNativeValue(i, value);
@@ -247,8 +249,10 @@ protected:
 
 private:
     // Returns true if successful, and false on error; it will throw on error.
-    template<typename OtherType>
-    bool setWithSpecificType(ExecState*, OtherType*, unsigned offset, unsigned length);
+    template<typename OtherAdaptor>
+    bool setWithSpecificType(
+        ExecState*, JSGenericTypedArrayView<OtherAdaptor>*,
+        unsigned offset, unsigned length);
 };
 
 template<typename Adaptor>
index 6505208..0a1edf2 100644 (file)
@@ -131,9 +131,10 @@ bool JSGenericTypedArrayView<Adaptor>::validateRange(
 }
 
 template<typename Adaptor>
-template<typename OtherType>
+template<typename OtherAdaptor>
 bool JSGenericTypedArrayView<Adaptor>::setWithSpecificType(
-    ExecState* exec, OtherType* other, unsigned offset, unsigned length)
+    ExecState* exec, JSGenericTypedArrayView<OtherAdaptor>* other,
+    unsigned offset, unsigned length)
 {
     // Handle the hilarious case: the act of getting the length could have resulted
     // in neutering. Well, no. That'll never happen because there cannot be
@@ -177,27 +178,37 @@ bool JSGenericTypedArrayView<Adaptor>::setWithSpecificType(
     
     // NB. Comparisons involving elementSize will be constant-folded by template
     // specialization.
+
+    unsigned otherElementSize = sizeof(typename OtherAdaptor::Type);
     
     // Handle cases (1) and (2B).
     if (!hasArrayBuffer() || !other->hasArrayBuffer()
         || existingBuffer() != other->existingBuffer()
-        || (elementSize == OtherType::elementSize && vector() > other->vector())) {
-        for (unsigned i = length; i--;)
-            setIndexQuickly(offset + i, other->getIndexQuickly(i));
+        || (elementSize == otherElementSize && vector() > other->vector())) {
+        for (unsigned i = length; i--;) {
+            setIndexQuicklyToNativeValue(
+                offset + i, OtherAdaptor::template convertTo<Adaptor>(
+                    other->getIndexQuicklyAsNativeValue(i)));
+        }
         return true;
     }
     
     // Now we either have (2A) or (3) - so first we try to cover (2A).
-    if (elementSize == OtherType::elementSize) {
-        for (unsigned i = 0; i < length; ++i)
-            setIndexQuickly(offset + i, other->getIndexQuickly(i));
+    if (elementSize == otherElementSize) {
+        for (unsigned i = 0; i < length; ++i) {
+            setIndexQuicklyToNativeValue(
+                offset + i, OtherAdaptor::template convertTo<Adaptor>(
+                    other->getIndexQuicklyAsNativeValue(i)));
+        }
         return true;
     }
     
     // Fail: we need an intermediate transfer buffer (i.e. case (3)).
     Vector<typename Adaptor::Type, 32> transferBuffer(length);
-    for (unsigned i = length; i--;)
-        transferBuffer[i] = Adaptor::toNative(other->getIndexQuickly(i));
+    for (unsigned i = length; i--;) {
+        transferBuffer[i] = OtherAdaptor::template convertTo<Adaptor>(
+            other->getIndexQuicklyAsNativeValue(i));
+    }
     for (unsigned i = length; i--;)
         setIndexQuicklyToNativeValue(offset + i, transferBuffer[i]);
     
@@ -223,23 +234,32 @@ bool JSGenericTypedArrayView<Adaptor>::set(
     
     switch (ci->typedArrayStorageType) {
     case TypeInt8:
-        return setWithSpecificType(exec, jsCast<JSInt8Array*>(object), offset, length);
+        return setWithSpecificType<Int8Adaptor>(
+            exec, jsCast<JSInt8Array*>(object), offset, length);
     case TypeInt16:
-        return setWithSpecificType(exec, jsCast<JSInt16Array*>(object), offset, length);
+        return setWithSpecificType<Int16Adaptor>(
+            exec, jsCast<JSInt16Array*>(object), offset, length);
     case TypeInt32:
-        return setWithSpecificType(exec, jsCast<JSInt32Array*>(object), offset, length);
+        return setWithSpecificType<Int32Adaptor>(
+            exec, jsCast<JSInt32Array*>(object), offset, length);
     case TypeUint8:
-        return setWithSpecificType(exec, jsCast<JSUint8Array*>(object), offset, length);
+        return setWithSpecificType<Uint8Adaptor>(
+            exec, jsCast<JSUint8Array*>(object), offset, length);
     case TypeUint8Clamped:
-        return setWithSpecificType(exec, jsCast<JSUint8ClampedArray*>(object), offset, length);
+        return setWithSpecificType<Uint8ClampedAdaptor>(
+            exec, jsCast<JSUint8ClampedArray*>(object), offset, length);
     case TypeUint16:
-        return setWithSpecificType(exec, jsCast<JSUint16Array*>(object), offset, length);
+        return setWithSpecificType<Uint16Adaptor>(
+            exec, jsCast<JSUint16Array*>(object), offset, length);
     case TypeUint32:
-        return setWithSpecificType(exec, jsCast<JSUint32Array*>(object), offset, length);
+        return setWithSpecificType<Uint32Adaptor>(
+            exec, jsCast<JSUint32Array*>(object), offset, length);
     case TypeFloat32:
-        return setWithSpecificType(exec, jsCast<JSFloat32Array*>(object), offset, length);
+        return setWithSpecificType<Float32Adaptor>(
+            exec, jsCast<JSFloat32Array*>(object), offset, length);
     case TypeFloat64:
-        return setWithSpecificType(exec, jsCast<JSFloat64Array*>(object), offset, length);
+        return setWithSpecificType<Float64Adaptor>(
+            exec, jsCast<JSFloat64Array*>(object), offset, length);
     case NotTypedArray:
     case TypeDataView: {
         if (!validateRange(exec, offset, length))
diff --git a/Source/JavaScriptCore/runtime/ToNativeFromValue.h b/Source/JavaScriptCore/runtime/ToNativeFromValue.h
new file mode 100644 (file)
index 0000000..1d871a6
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef ToNativeFromValue_h
+#define ToNativeFromValue_h
+
+#include "JSCJSValue.h"
+
+namespace JSC {
+
+template<typename Adaptor>
+typename Adaptor::Type toNativeFromValue(JSValue value)
+{
+    if (value.isInt32())
+        return Adaptor::toNativeFromInt32(value.asInt32());
+    return Adaptor::toNativeFromDouble(value.asDouble());
+}
+
+template<typename Adaptor>
+typename Adaptor::Type toNativeFromValue(ExecState* exec, JSValue value)
+{
+    if (value.isInt32())
+        return Adaptor::toNativeFromInt32(value.asInt32());
+    if (value.isNumber())
+        return Adaptor::toNativeFromDouble(value.asDouble());
+    return Adaptor::toNativeFromDouble(value.toNumber(exec));
+}
+
+} // namespace JSC
+
+#endif // ToNativeFromValue_h
+
index 1d8f93c..84d3db5 100644 (file)
@@ -41,33 +41,40 @@ struct IntegralTypedArrayAdaptor {
     typedef JSViewTypeArg JSViewType;
     static const TypedArrayType typeValue = typeValueArg;
 
-    static Type toNative(double value)
+    static JSValue toJSValue(Type value)
     {
-        return static_cast<Type>(static_cast<int64_t>(value));
+        return jsNumber(value);
     }
     
-    static Type toNative(JSValue value)
+    static double toDouble(Type value)
     {
-        if (value.isInt32())
-            return static_cast<Type>(value.asInt32());
-        return toNative(value.asNumber());
+        return static_cast<double>(value);
     }
     
-    static Type toNative(ExecState* exec, JSValue value)
+    static Type toNativeFromInt32(int32_t value)
     {
-        if (value.isInt32())
-            return static_cast<Type>(value.asInt32());
-        return toNative(value.toNumber(exec));
+        return static_cast<Type>(value);
     }
     
-    static JSValue toJSValue(Type value)
+    static Type toNativeFromUint32(uint32_t value)
     {
-        return jsNumber(value);
+        return static_cast<Type>(value);
     }
     
-    static double toDouble(Type value)
+    static Type toNativeFromDouble(double value)
     {
-        return static_cast<double>(value);
+        int32_t result = static_cast<int32_t>(value);
+        if (static_cast<double>(result) != value)
+            result = toInt32(value);
+        return static_cast<Type>(result);
+    }
+    
+    template<typename OtherAdaptor>
+    static typename OtherAdaptor::Type convertTo(Type value)
+    {
+        if (typeValue == TypeUint32)
+            return OtherAdaptor::toNativeFromUint32(value);
+        return OtherAdaptor::toNativeFromInt32(value);
     }
 };
 
@@ -80,31 +87,37 @@ struct FloatTypedArrayAdaptor {
     typedef JSViewTypeArg JSViewType;
     static const TypedArrayType typeValue = typeValueArg;
     
-    static Type toNative(double value)
+    static JSValue toJSValue(Type value)
     {
-        return static_cast<Type>(value);
+        if (value != value)
+            return jsDoubleNumber(QNaN);
+        return jsDoubleNumber(value);
     }
     
-    static Type toNative(JSValue value)
+    static double toDouble(Type value)
+    {
+        return static_cast<double>(value);
+    }
+
+    static Type toNativeFromInt32(int32_t value)
     {
-        return toNative(value.asNumber());
+        return static_cast<Type>(value);
     }
     
-    static Type toNative(ExecState* exec, JSValue value)
+    static Type toNativeFromUint32(uint32_t value)
     {
-        return toNative(value.toNumber(exec));
+        return static_cast<Type>(value);
     }
     
-    static JSValue toJSValue(Type value)
+    static Type toNativeFromDouble(double value)
     {
-        if (value != value)
-            return jsNumber(QNaN);
-        return jsNumber(value);
+        return value;
     }
     
-    static double toDouble(Type value)
+    template<typename OtherAdaptor>
+    static typename OtherAdaptor::Type convertTo(Type value)
     {
-        return static_cast<double>(value);
+        return OtherAdaptor::toNativeFromDouble(value);
     }
 };
 
@@ -155,37 +168,39 @@ struct Uint8ClampedAdaptor {
     typedef JSUint8ClampedArray JSViewType;
     static const TypedArrayType typeValue = TypeUint8Clamped;
     
-    static uint8_t toNative(double value)
+    static JSValue toJSValue(uint8_t value)
     {
-        if (std::isnan(value) || value < 0)
-            return 0;
-        if (value > 255)
-            return 255;
-        return static_cast<uint8_t>(lrint(value));
+        return jsNumber(value);
+    }
+    
+    static double toDouble(uint8_t value)
+    {
+        return static_cast<double>(value);
     }
     
-    static uint8_t toNative(JSValue value)
+    static Type toNativeFromInt32(int32_t value)
     {
-        if (value.isInt32())
-            return clamp(value.asInt32());
-        return toNative(value.asNumber());
+        return clamp(value);
     }
     
-    static uint8_t toNative(ExecState* exec, JSValue value)
+    static Type toNativeFromUint32(uint32_t value)
     {
-        if (value.isInt32())
-            return clamp(value.asInt32());
-        return toNative(value.toNumber(exec));
+        return std::min(static_cast<uint32_t>(255), value);
     }
     
-    static JSValue toJSValue(uint8_t value)
+    static Type toNativeFromDouble(double value)
     {
-        return jsNumber(value);
+        if (std::isnan(value) || value < 0)
+            return 0;
+        if (value > 255)
+            return 255;
+        return static_cast<uint8_t>(lrint(value));
     }
     
-    static double toDouble(uint8_t value)
+    template<typename OtherAdaptor>
+    static typename OtherAdaptor::Type convertTo(uint8_t value)
     {
-        return static_cast<double>(value);
+        return OtherAdaptor::toNativeFromInt32(value);
     }
     
 private: