summaryrefslogtreecommitdiffstats
path: root/js/src/tests/ecma_6/TypedArray
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /js/src/tests/ecma_6/TypedArray
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'js/src/tests/ecma_6/TypedArray')
-rw-r--r--js/src/tests/ecma_6/TypedArray/Tconstructor-fromTypedArray-byteLength.js17
-rw-r--r--js/src/tests/ecma_6/TypedArray/browser.js0
-rw-r--r--js/src/tests/ecma_6/TypedArray/constructor-ArrayBuffer-species-wrap.js63
-rw-r--r--js/src/tests/ecma_6/TypedArray/constructor-ArrayBuffer-species.js51
-rw-r--r--js/src/tests/ecma_6/TypedArray/constructor-iterable-generator.js16
-rw-r--r--js/src/tests/ecma_6/TypedArray/constructor-iterable-modified-array-iterator-next.js28
-rw-r--r--js/src/tests/ecma_6/TypedArray/constructor-iterable-modified-array-iterator.js28
-rw-r--r--js/src/tests/ecma_6/TypedArray/constructor-iterable-nonpacked-array.js17
-rw-r--r--js/src/tests/ecma_6/TypedArray/constructor-iterable-not-callable.js15
-rw-r--r--js/src/tests/ecma_6/TypedArray/constructor-iterable-packed-array-side-effect.js17
-rw-r--r--js/src/tests/ecma_6/TypedArray/constructor-iterable-packed-array.js16
-rw-r--r--js/src/tests/ecma_6/TypedArray/constructor-iterable-undefined-or-null.js22
-rw-r--r--js/src/tests/ecma_6/TypedArray/constructor-iterator-primitive.js29
-rw-r--r--js/src/tests/ecma_6/TypedArray/constructor-non-detached.js15
-rw-r--r--js/src/tests/ecma_6/TypedArray/constructor-not-callable.js10
-rw-r--r--js/src/tests/ecma_6/TypedArray/constructor-undefined-args.js14
-rw-r--r--js/src/tests/ecma_6/TypedArray/constructor_bad-args.js13
-rw-r--r--js/src/tests/ecma_6/TypedArray/detached-array-buffer-checks.js109
-rw-r--r--js/src/tests/ecma_6/TypedArray/element-setting-converts-using-ToNumber.js90
-rw-r--r--js/src/tests/ecma_6/TypedArray/entries.js38
-rw-r--r--js/src/tests/ecma_6/TypedArray/every-and-some.js249
-rw-r--r--js/src/tests/ecma_6/TypedArray/fill.js65
-rw-r--r--js/src/tests/ecma_6/TypedArray/filter-species.js56
-rw-r--r--js/src/tests/ecma_6/TypedArray/find-and-findIndex.js52
-rw-r--r--js/src/tests/ecma_6/TypedArray/forEach.js93
-rw-r--r--js/src/tests/ecma_6/TypedArray/from_basics.js42
-rw-r--r--js/src/tests/ecma_6/TypedArray/from_constructor.js36
-rw-r--r--js/src/tests/ecma_6/TypedArray/from_errors.js76
-rw-r--r--js/src/tests/ecma_6/TypedArray/from_iterable.js49
-rw-r--r--js/src/tests/ecma_6/TypedArray/from_mapping.js45
-rw-r--r--js/src/tests/ecma_6/TypedArray/from_realms.js32
-rw-r--r--js/src/tests/ecma_6/TypedArray/from_string.js24
-rw-r--r--js/src/tests/ecma_6/TypedArray/from_surfaces.js12
-rw-r--r--js/src/tests/ecma_6/TypedArray/from_this.js59
-rw-r--r--js/src/tests/ecma_6/TypedArray/getter-name.js16
-rw-r--r--js/src/tests/ecma_6/TypedArray/has-property-op.js22
-rw-r--r--js/src/tests/ecma_6/TypedArray/includes.js40
-rw-r--r--js/src/tests/ecma_6/TypedArray/indexOf-and-lastIndexOf.js117
-rw-r--r--js/src/tests/ecma_6/TypedArray/indexOf-never-returns-negative-zero.js7
-rw-r--r--js/src/tests/ecma_6/TypedArray/iterator.js42
-rw-r--r--js/src/tests/ecma_6/TypedArray/join.js48
-rw-r--r--js/src/tests/ecma_6/TypedArray/keys.js36
-rw-r--r--js/src/tests/ecma_6/TypedArray/lastIndexOf-never-returns-negative-zero.js7
-rw-r--r--js/src/tests/ecma_6/TypedArray/map-and-filter.js274
-rw-r--r--js/src/tests/ecma_6/TypedArray/map-species.js56
-rw-r--r--js/src/tests/ecma_6/TypedArray/object-defineproperty.js68
-rw-r--r--js/src/tests/ecma_6/TypedArray/of.js92
-rw-r--r--js/src/tests/ecma_6/TypedArray/prototype-constructor-identity.js55
-rw-r--r--js/src/tests/ecma_6/TypedArray/reduce-and-reduceRight.js188
-rw-r--r--js/src/tests/ecma_6/TypedArray/reverse.js38
-rw-r--r--js/src/tests/ecma_6/TypedArray/seal-and-freeze.js48
-rw-r--r--js/src/tests/ecma_6/TypedArray/set-negative-offset.js35
-rw-r--r--js/src/tests/ecma_6/TypedArray/set-same-buffer-different-source-target-types.js41
-rw-r--r--js/src/tests/ecma_6/TypedArray/set.js21
-rw-r--r--js/src/tests/ecma_6/TypedArray/shell.js114
-rw-r--r--js/src/tests/ecma_6/TypedArray/slice-species.js49
-rw-r--r--js/src/tests/ecma_6/TypedArray/slice.js45
-rw-r--r--js/src/tests/ecma_6/TypedArray/sort_basics.js73
-rw-r--r--js/src/tests/ecma_6/TypedArray/sort_comparators.js32
-rw-r--r--js/src/tests/ecma_6/TypedArray/sort_errors.js87
-rw-r--r--js/src/tests/ecma_6/TypedArray/sort_globals.js9
-rw-r--r--js/src/tests/ecma_6/TypedArray/sort_small.js38
-rw-r--r--js/src/tests/ecma_6/TypedArray/sort_snans.js72
-rw-r--r--js/src/tests/ecma_6/TypedArray/sorting_buffer_access.js15
-rw-r--r--js/src/tests/ecma_6/TypedArray/subarray-species.js63
-rw-r--r--js/src/tests/ecma_6/TypedArray/subarray.js29
-rw-r--r--js/src/tests/ecma_6/TypedArray/toLocaleString-detached.js38
-rw-r--r--js/src/tests/ecma_6/TypedArray/toLocaleString-nointl.js40
-rw-r--r--js/src/tests/ecma_6/TypedArray/toLocaleString.js80
-rw-r--r--js/src/tests/ecma_6/TypedArray/toString.js69
-rw-r--r--js/src/tests/ecma_6/TypedArray/uint8clamped-constructor.js9
-rw-r--r--js/src/tests/ecma_6/TypedArray/values.js37
72 files changed, 3648 insertions, 0 deletions
diff --git a/js/src/tests/ecma_6/TypedArray/Tconstructor-fromTypedArray-byteLength.js b/js/src/tests/ecma_6/TypedArray/Tconstructor-fromTypedArray-byteLength.js
new file mode 100644
index 000000000..6aadca5c8
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/Tconstructor-fromTypedArray-byteLength.js
@@ -0,0 +1,17 @@
+var g = newGlobal();
+
+var arr = [1, 2, 3];
+for (var constructor of anyTypedArrayConstructors) {
+ var tarr = new constructor(arr);
+ for (var constructor2 of anyTypedArrayConstructors) {
+ var copied = new constructor2(tarr);
+ assertEq(copied.buffer.byteLength, arr.length * constructor2.BYTES_PER_ELEMENT);
+
+ g.tarr = tarr;
+ copied = g.eval(`new ${constructor2.name}(tarr);`);
+ assertEq(copied.buffer.byteLength, arr.length * constructor2.BYTES_PER_ELEMENT);
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/browser.js b/js/src/tests/ecma_6/TypedArray/browser.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/browser.js
diff --git a/js/src/tests/ecma_6/TypedArray/constructor-ArrayBuffer-species-wrap.js b/js/src/tests/ecma_6/TypedArray/constructor-ArrayBuffer-species-wrap.js
new file mode 100644
index 000000000..67a50fc91
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/constructor-ArrayBuffer-species-wrap.js
@@ -0,0 +1,63 @@
+// |reftest| skip-if(!xulRuntime.shell)
+
+let g = newGlobal();
+
+// Both TypedArray and ArrayBuffer from different global.
+for (let ctor of typedArrayConstructors) {
+ let a = g.eval(`new ${ctor.name}([1, 2, 3, 4, 5]);`);
+ for (let ctor2 of typedArrayConstructors) {
+ let b = new ctor2(a);
+ assertEq(Object.getPrototypeOf(b).constructor, ctor2);
+ assertEq(Object.getPrototypeOf(b.buffer).constructor, g.ArrayBuffer);
+ }
+}
+
+// Only ArrayBuffer from different global.
+let called = false;
+let origSpecies = Object.getOwnPropertyDescriptor(ArrayBuffer, Symbol.species);
+let modSpecies = {
+ get() {
+ called = true;
+ return g.ArrayBuffer;
+ }
+};
+for (let ctor of typedArrayConstructors) {
+ let a = new ctor([1, 2, 3, 4, 5]);
+ for (let ctor2 of typedArrayConstructors) {
+ called = false;
+ Object.defineProperty(ArrayBuffer, Symbol.species, modSpecies);
+ let b = new ctor2(a);
+ Object.defineProperty(ArrayBuffer, Symbol.species, origSpecies);
+ assertEq(called, true);
+ assertEq(Object.getPrototypeOf(b).constructor, ctor2);
+ assertEq(Object.getPrototypeOf(b.buffer).constructor, g.ArrayBuffer);
+ }
+}
+
+// Only TypedArray from different global.
+g.otherArrayBuffer = ArrayBuffer;
+g.eval(`
+var called = false;
+var origSpecies = Object.getOwnPropertyDescriptor(ArrayBuffer, Symbol.species);
+var modSpecies = {
+ get() {
+ called = true;
+ return otherArrayBuffer;
+ }
+};
+`);
+for (let ctor of typedArrayConstructors) {
+ let a = g.eval(`new ${ctor.name}([1, 2, 3, 4, 5]);`);
+ for (let ctor2 of typedArrayConstructors) {
+ g.called = false;
+ g.eval(`Object.defineProperty(ArrayBuffer, Symbol.species, modSpecies);`);
+ let b = new ctor2(a);
+ g.eval(`Object.defineProperty(ArrayBuffer, Symbol.species, origSpecies);`);
+ assertEq(g.called, true);
+ assertEq(Object.getPrototypeOf(b).constructor, ctor2);
+ assertEq(Object.getPrototypeOf(b.buffer).constructor, ArrayBuffer);
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/constructor-ArrayBuffer-species.js b/js/src/tests/ecma_6/TypedArray/constructor-ArrayBuffer-species.js
new file mode 100644
index 000000000..4ff511848
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/constructor-ArrayBuffer-species.js
@@ -0,0 +1,51 @@
+let logs = [];
+for (let ctor of typedArrayConstructors) {
+ let arr = new ctor([1, 2, 3, 4, 5, 6, 7, 8]);
+
+ let ctorObj = {};
+
+ let proxyProto = new Proxy({}, {
+ get(that, name) {
+ logs.push("get proto." + String(name));
+ if (name == "constructor")
+ return ctorObj;
+ throw new Error("unexpected prop access");
+ }
+ });
+
+ arr.buffer.constructor = {
+ get [Symbol.species]() {
+ logs.push("get @@species");
+ let C = new Proxy(function(...args) {
+ logs.push("call ctor");
+ return new ArrayBuffer(...args);
+ }, {
+ get(that, name) {
+ logs.push("get ctor." + String(name));
+ if (name == "prototype") {
+ return proxyProto;
+ }
+ throw new Error("unexpected prop access");
+ }
+ });
+ return C;
+ }
+ };
+
+ for (let ctor2 of typedArrayConstructors) {
+ logs.length = 0;
+ let arr2 = new ctor2(arr);
+ assertDeepEq(logs, ["get @@species", "get ctor.prototype"]);
+
+ logs.length = 0;
+ assertEq(Object.getPrototypeOf(arr2.buffer), proxyProto);
+ assertDeepEq(logs, []);
+
+ logs.length = 0;
+ assertEq(arr2.buffer.constructor, ctorObj);
+ assertDeepEq(logs, ["get proto.constructor"]);
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/constructor-iterable-generator.js b/js/src/tests/ecma_6/TypedArray/constructor-iterable-generator.js
new file mode 100644
index 000000000..233eeb9d9
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/constructor-iterable-generator.js
@@ -0,0 +1,16 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Construct typed array from generator.
+for (let constructor of anyTypedArrayConstructors) {
+ for (let array of [[], [1], [2, 3], [4, 5, 6], Array(1024).fill(0).map((v, i) => i % 128)]) {
+ let typedArray = new constructor(function*(){ yield* array; }());
+
+ assertEq(typedArray.length, array.length);
+ assertEqArray(typedArray, array);
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/constructor-iterable-modified-array-iterator-next.js b/js/src/tests/ecma_6/TypedArray/constructor-iterable-modified-array-iterator-next.js
new file mode 100644
index 000000000..76eaaae46
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/constructor-iterable-modified-array-iterator-next.js
@@ -0,0 +1,28 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Construct typed array from array with modified array iterator next method.
+const ArrayIteratorPrototype = Object.getPrototypeOf([][Symbol.iterator]());
+const origNext = ArrayIteratorPrototype.next;
+const modifiedNext = function() {
+ let {value, done} = origNext.call(this);
+ return {value: value * 5, done};
+};
+for (let constructor of anyTypedArrayConstructors) {
+ for (let array of [[], [1], [2, 3], [4, 5, 6], Array(1024).fill(0).map((v, i) => i % 24)]) {
+ ArrayIteratorPrototype.next = modifiedNext;
+ let typedArray;
+ try {
+ typedArray = new constructor(array);
+ } finally {
+ ArrayIteratorPrototype.next = origNext;
+ }
+
+ assertEq(typedArray.length, array.length);
+ assertEqArray(typedArray, array.map(v => v * 5));
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/constructor-iterable-modified-array-iterator.js b/js/src/tests/ecma_6/TypedArray/constructor-iterable-modified-array-iterator.js
new file mode 100644
index 000000000..7c3192a6a
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/constructor-iterable-modified-array-iterator.js
@@ -0,0 +1,28 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Construct typed array from array with modified array iterator.
+const origIterator = Array.prototype[Symbol.iterator];
+const modifiedIterator = function*() {
+ for (let v of origIterator.call(this)) {
+ yield v * 5;
+ }
+};
+for (let constructor of anyTypedArrayConstructors) {
+ for (let array of [[], [1], [2, 3], [4, 5, 6], Array(1024).fill(0).map((v, i) => i % 24)]) {
+ Array.prototype[Symbol.iterator] = modifiedIterator;
+ let typedArray;
+ try {
+ typedArray = new constructor(array)
+ } finally {
+ Array.prototype[Symbol.iterator] = origIterator;
+ }
+
+ assertEq(typedArray.length, array.length);
+ assertEqArray(typedArray, array.map(v => v * 5));
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/constructor-iterable-nonpacked-array.js b/js/src/tests/ecma_6/TypedArray/constructor-iterable-nonpacked-array.js
new file mode 100644
index 000000000..b9586a57e
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/constructor-iterable-nonpacked-array.js
@@ -0,0 +1,17 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Construct typed array from iterable non-packed array.
+for (let constructor of anyTypedArrayConstructors) {
+ for (let array of [[,], [,,], Array(1024)]) {
+ let typedArray = new constructor(array);
+
+ assertEq(typedArray.length, array.length);
+ let expectedArray = Array(array.length).fill(isFloatConstructor(constructor) ? NaN : 0);
+ assertEqArray(typedArray, expectedArray);
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/constructor-iterable-not-callable.js b/js/src/tests/ecma_6/TypedArray/constructor-iterable-not-callable.js
new file mode 100644
index 000000000..824760900
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/constructor-iterable-not-callable.js
@@ -0,0 +1,15 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Construct typed array from object with non-callable [Symbol.iterator] property.
+for (let constructor of anyTypedArrayConstructors) {
+ for (let iterator of [true, 0, Math.PI, "", "10", Symbol.iterator, {}, []]) {
+ assertThrowsInstanceOf(() => new constructor({
+ [Symbol.iterator]: iterator
+ }), TypeError);
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/constructor-iterable-packed-array-side-effect.js b/js/src/tests/ecma_6/TypedArray/constructor-iterable-packed-array-side-effect.js
new file mode 100644
index 000000000..3c00af0de
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/constructor-iterable-packed-array-side-effect.js
@@ -0,0 +1,17 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Construct typed array from iterable packed array, array contains object with modifying
+// valueOf() method.
+for (let constructor of anyTypedArrayConstructors) {
+ let array = [
+ 0, 1, {valueOf() { array[3] = 30; return 2; }}, 3, 4
+ ];
+ let typedArray = new constructor(array);
+ assertEq(typedArray.length, array.length);
+ assertEqArray(typedArray, [0, 1, 2, 3, 4]);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/constructor-iterable-packed-array.js b/js/src/tests/ecma_6/TypedArray/constructor-iterable-packed-array.js
new file mode 100644
index 000000000..495c2da49
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/constructor-iterable-packed-array.js
@@ -0,0 +1,16 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Construct typed array from iterable packed array.
+for (let constructor of anyTypedArrayConstructors) {
+ for (let array of [[], [1], [2, 3], [4, 5, 6], Array(1024).fill(0).map((v, i) => i % 128)]) {
+ let typedArray = new constructor(array);
+
+ assertEq(typedArray.length, array.length);
+ assertEqArray(typedArray, array);
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/constructor-iterable-undefined-or-null.js b/js/src/tests/ecma_6/TypedArray/constructor-iterable-undefined-or-null.js
new file mode 100644
index 000000000..48e5aaa64
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/constructor-iterable-undefined-or-null.js
@@ -0,0 +1,22 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Construct typed array from object with undefined or null [Symbol.iterator] property.
+for (let constructor of anyTypedArrayConstructors) {
+ for (let iterator of [undefined, null]) {
+ let arrayLike = {
+ [Symbol.iterator]: iterator,
+ length: 2,
+ 0: 10,
+ 1: 20,
+ };
+ let typedArray = new constructor(arrayLike);
+
+ assertEq(typedArray.length, arrayLike.length);
+ assertEqArray(typedArray, arrayLike);
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/constructor-iterator-primitive.js b/js/src/tests/ecma_6/TypedArray/constructor-iterator-primitive.js
new file mode 100644
index 000000000..5a14d7d5a
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/constructor-iterator-primitive.js
@@ -0,0 +1,29 @@
+var BUGNUMBER = 1021835;
+var summary = "Returning non-object from @@iterator should throw";
+
+print(BUGNUMBER + ": " + summary);
+
+let primitives = [
+ 1,
+ true,
+ undefined,
+ null,
+ "foo",
+ Symbol.iterator
+];
+
+for (let ctor of typedArrayConstructors) {
+ for (let primitive of primitives) {
+ let arg = {
+ [Symbol.iterator]() {
+ return primitive;
+ }
+ };
+ assertThrowsInstanceOf(() => {
+ new ctor(arg);
+ }, TypeError);
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/TypedArray/constructor-non-detached.js b/js/src/tests/ecma_6/TypedArray/constructor-non-detached.js
new file mode 100644
index 000000000..bbfb317dc
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/constructor-non-detached.js
@@ -0,0 +1,15 @@
+// |reftest| skip-if(!xulRuntime.shell) -- needs detachArrayBuffer
+
+for (var constructor of typedArrayConstructors) {
+ var buf = new constructor();
+ detachArrayBuffer(buf.buffer);
+ assertThrowsInstanceOf(() => new constructor(buf), TypeError);
+
+ var buffer = new ArrayBuffer();
+ detachArrayBuffer(buffer);
+ assertThrowsInstanceOf(() => new constructor(buffer), TypeError);
+}
+
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/constructor-not-callable.js b/js/src/tests/ecma_6/TypedArray/constructor-not-callable.js
new file mode 100644
index 000000000..a3a2f8d1d
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/constructor-not-callable.js
@@ -0,0 +1,10 @@
+for (var constructor of anyTypedArrayConstructors) {
+ assertThrowsInstanceOf(() => constructor(), TypeError);
+ assertThrowsInstanceOf(() => constructor(1), TypeError);
+ assertThrowsInstanceOf(() => constructor.call(null), TypeError);
+ assertThrowsInstanceOf(() => constructor.apply(null, []), TypeError);
+ assertThrowsInstanceOf(() => Reflect.apply(constructor, null, []), TypeError);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/constructor-undefined-args.js b/js/src/tests/ecma_6/TypedArray/constructor-undefined-args.js
new file mode 100644
index 000000000..91a557a2c
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/constructor-undefined-args.js
@@ -0,0 +1,14 @@
+// Bug 1040402
+
+var ab = new ArrayBuffer(16);
+
+assertEq(new Int32Array(ab).length, 4);
+assertEq(new Int32Array(ab, undefined).length, 4);
+assertEq(new Int32Array(ab, undefined, undefined).length, 4);
+assertEq(new Int32Array(ab, 0).length, 4);
+assertEq(new Int32Array(ab, 0, undefined).length, 4);
+assertEq(new Int32Array(ab, 4).length, 3);
+assertEq(new Int32Array(ab, 4, undefined).length, 3);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/constructor_bad-args.js b/js/src/tests/ecma_6/TypedArray/constructor_bad-args.js
new file mode 100644
index 000000000..00bbf884c
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/constructor_bad-args.js
@@ -0,0 +1,13 @@
+// Bug 1227207
+
+var AB = new ArrayBuffer(12); // Length divides 4
+var BC = new ArrayBuffer(14); // Length does not divide 4
+
+assertThrowsInstanceOf(() => new Int32Array(AB, -1), RangeError); // 22.2.4.5 #8
+assertThrowsInstanceOf(() => new Int32Array(AB, 2), RangeError); // 22.2.4.5 #10
+assertThrowsInstanceOf(() => new Int32Array(BC), RangeError); // 22.2.4.5 #13.a
+assertThrowsInstanceOf(() => new Int32Array(AB, 16), RangeError); // 22.2.4.5 #13.c
+assertThrowsInstanceOf(() => new Int32Array(AB, 0, 4), RangeError); // 22.2.4.5 #14.c
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/detached-array-buffer-checks.js b/js/src/tests/ecma_6/TypedArray/detached-array-buffer-checks.js
new file mode 100644
index 000000000..76a00d886
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/detached-array-buffer-checks.js
@@ -0,0 +1,109 @@
+// |reftest| skip-if(!xulRuntime.shell) -- needs detachArrayBuffer
+
+// Nearly every %TypedArray%.prototype method should throw a TypeError when called
+// atop a detached array buffer. Here we check verify that this holds true for
+// all relevant functions.
+let buffer = new ArrayBuffer(32);
+let array = new Int32Array(buffer);
+detachArrayBuffer(buffer);
+
+// A nice poisoned callable to ensure that we fail on a detached buffer check
+// before a method attempts to do anything with its arguments.
+var POISON = (function() {
+ var internalTarget = {};
+ var throwForAllTraps =
+ new Proxy(internalTarget, { get(target, prop, receiver) {
+ assertEq(target, internalTarget);
+ assertEq(receiver, throwForAllTraps);
+ throw "FAIL: " + prop + " trap invoked";
+ }});
+ return new Proxy(throwForAllTraps, throwForAllTraps);
+});
+
+
+assertThrowsInstanceOf(() => {
+ array.copyWithin(POISON);
+}, TypeError);
+
+assertThrowsInstanceOf(() => {
+ array.entries();
+}, TypeError);
+
+assertThrowsInstanceOf(() => {
+ array.fill(POISON);
+}, TypeError);
+
+assertThrowsInstanceOf(() => {
+ array.filter(POISON);
+}, TypeError);
+
+assertThrowsInstanceOf(() => {
+ array.find(POISON);
+}, TypeError);
+
+assertThrowsInstanceOf(() => {
+ array.findIndex(POISON);
+}, TypeError);
+
+assertThrowsInstanceOf(() => {
+ array.forEach(POISON);
+}, TypeError);
+
+assertThrowsInstanceOf(() => {
+ array.indexOf(POISON);
+}, TypeError);
+
+assertThrowsInstanceOf(() => {
+ array.includes(POISON);
+}, TypeError);
+
+assertThrowsInstanceOf(() => {
+ array.join(POISON);
+}, TypeError);
+
+assertThrowsInstanceOf(() => {
+ array.keys();
+}, TypeError);
+
+assertThrowsInstanceOf(() => {
+ array.lastIndexOf(POISON);
+}, TypeError);
+
+assertThrowsInstanceOf(() => {
+ array.map(POISON);
+}, TypeError);
+
+assertThrowsInstanceOf(() => {
+ array.reduce(POISON);
+}, TypeError);
+
+assertThrowsInstanceOf(() => {
+ array.reduceRight(POISON);
+}, TypeError);
+
+assertThrowsInstanceOf(() => {
+ array.reverse();
+}, TypeError);
+
+assertThrowsInstanceOf(() => {
+ array.slice(POISON, POISON);
+}, TypeError);
+
+assertThrowsInstanceOf(() => {
+ array.some(POISON);
+}, TypeError);
+
+assertThrowsInstanceOf(() => {
+ array.values();
+}, TypeError);
+
+assertThrowsInstanceOf(() => {
+ array.every(POISON);
+}, TypeError);
+
+assertThrowsInstanceOf(() => {
+ array.sort(POISON);
+}, TypeError);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/element-setting-converts-using-ToNumber.js b/js/src/tests/ecma_6/TypedArray/element-setting-converts-using-ToNumber.js
new file mode 100644
index 000000000..8cfef6769
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/element-setting-converts-using-ToNumber.js
@@ -0,0 +1,90 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var gTestfile = 'element-setting-converts-using-ToNumber.js';
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 985733;
+var summary =
+ "Typed array element-setting should convert to target type using ToNumber "
+ "followed by an element-type-specific truncation function";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+anyTypedArrayConstructors.forEach(function(TypedArray) {
+ var ta = new TypedArray(1);
+ assertEq(ta[0], 0);
+
+ var count = 0;
+ function setToObject()
+ {
+ for (var i = 0; i < 1e4; i++)
+ {
+ assertEq(count, i);
+ ta[0] = { valueOf: function() { count++; return 17; } };
+ }
+ }
+ setToObject();
+ assertEq(count, 1e4);
+ assertEq(ta[0], 17);
+
+ function setToString()
+ {
+ for (var i = 0; i < 2e4; i++)
+ ta[0] = "17.0000000000000000000000000000000000000000000000000000001";
+ }
+ setToString();
+ assertEq(ta[0], 17);
+
+ count = 0;
+ var arrayConstructed =
+ new TypedArray([{ valueOf: function() { count++; return 17; } },
+ "17.0000000000000000000000000000000000000000000000000001"]);
+ assertEq(count, 1);
+ assertEq(arrayConstructed[0], 17);
+ assertEq(arrayConstructed[1], 17);
+
+ count = 0;
+ var arraySet = new TypedArray(5);
+ arraySet.set({ 0: 17,
+ 1: "17.000000000000000000000000000000000000000000000000000",
+ get 2() {
+ return { valueOf: undefined,
+ toString: function() { count++; return 42; } };
+ },
+ get 3() { return true; },
+ set 3(v) { throw "FAIL"; },
+ 4: { valueOf: function() { count++; return 127; } },
+ length: 5 });
+ assertEq(count, 2);
+ assertEq(arraySet[0], 17);
+ assertEq(arraySet[1], 17);
+ assertEq(arraySet[2], 42);
+ assertEq(arraySet[3], 1);
+ assertEq(arraySet[4], 127);
+
+ var bigLen = 1e4;
+ var big = new TypedArray(bigLen);
+ function initBig()
+ {
+ for (var i = 0; i < bigLen; i++)
+ big[i] = (i % 2) ? 3 : { valueOf: function() { return 3; } };
+ }
+ initBig();
+ for (var i = 0; i < bigLen; i++)
+ {
+ assertEq(big[i], 3,
+ "(" + Object.prototype.toString.call(big) + ")");
+ }
+});
+
+/******************************************************************************/
+
+reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_6/TypedArray/entries.js b/js/src/tests/ecma_6/TypedArray/entries.js
new file mode 100644
index 000000000..c55a959e3
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/entries.js
@@ -0,0 +1,38 @@
+for (var constructor of anyTypedArrayConstructors) {
+ assertEq(constructor.prototype.entries.length, 0);
+ assertEq(constructor.prototype.entries.name, "entries");
+
+ assertDeepEq([...new constructor(0).entries()], []);
+ assertDeepEq([...new constructor(1).entries()], [[0, 0]]);
+ assertDeepEq([...new constructor(2).entries()], [[0, 0], [1, 0]]);
+ assertDeepEq([...new constructor([15]).entries()], [[0, 15]]);
+
+ var arr = new constructor([1, 2, 3]);
+ var iterator = arr.entries();
+ assertDeepEq(iterator.next(), {value: [0, 1], done: false});
+ assertDeepEq(iterator.next(), {value: [1, 2], done: false});
+ assertDeepEq(iterator.next(), {value: [2, 3], done: false});
+ assertDeepEq(iterator.next(), {value: undefined, done: true});
+
+ // Called from other globals.
+ if (typeof newGlobal === "function") {
+ var otherGlobal = newGlobal();
+ var entries = otherGlobal[constructor.name].prototype.entries;
+ assertDeepEq([...entries.call(new constructor(2))],
+ [new otherGlobal.Array(0, 0), new otherGlobal.Array(1, 0)]);
+ arr = new (newGlobal()[constructor.name])(2);
+ assertEq([...constructor.prototype.entries.call(arr)].toString(), "0,0,1,0");
+ }
+
+ // Throws if `this` isn't a TypedArray.
+ var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+ new Proxy(new constructor(), {})];
+ invalidReceivers.forEach(invalidReceiver => {
+ assertThrowsInstanceOf(() => {
+ constructor.prototype.entries.call(invalidReceiver);
+ }, TypeError, "Assert that entries fails if this value is not a TypedArray");
+ });
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/every-and-some.js b/js/src/tests/ecma_6/TypedArray/every-and-some.js
new file mode 100644
index 000000000..940ac736f
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/every-and-some.js
@@ -0,0 +1,249 @@
+// Tests for TypedArray#every.
+for (var constructor of anyTypedArrayConstructors) {
+ assertEq(constructor.prototype.every.length, 1);
+
+ // Basic tests.
+ assertEq(new constructor([1, 3, 5]).every(v => v % 2), true);
+ assertEq(new constructor([1, 3, 5]).every(v => v > 2), false);
+ assertEq(new constructor(10).every(v => v === 0), true);
+ assertEq(new constructor().every(v => v > 1), true);
+
+ var arr = new constructor([1, 2, 3, 4, 5]);
+ var sum = 0;
+ var count = 0;
+ assertEq(arr.every((v, k, o) => {
+ count++;
+ sum += v;
+ assertEq(k, v - 1);
+ assertEq(o, arr);
+ return v < 3;
+ }), false);
+ assertEq(sum, 6);
+ assertEq(count, 3);
+
+ // Tests for `thisArg` argument.
+ function assertThisArg(thisArg, thisValue) {
+ // In sloppy mode, `this` could be global object or a wrapper of `thisArg`.
+ assertEq(arr.every(function() {
+ assertDeepEq(this, thisValue);
+ return true;
+ }, thisArg), true);
+
+ // In strict mode, `this` strictly equals `thisArg`.
+ assertEq(arr.every(function() {
+ "use strict";
+ assertDeepEq(this, thisArg);
+ return true;
+ }, thisArg), true);
+
+ // Passing `thisArg` has no effect if callback is an arrow function.
+ var self = this;
+ assertEq(arr.every(() => {
+ assertEq(this, self);
+ return true;
+ }, thisArg), true);
+ }
+ assertThisArg([1, 2, 3], [1, 2, 3]);
+ assertThisArg(Object, Object);
+ assertThisArg(1, Object(1));
+ assertThisArg("1", Object("1"));
+ assertThisArg(false, Object(false));
+ assertThisArg(undefined, this);
+ assertThisArg(null, this);
+
+ // Throw an exception in the callback.
+ var sum = 0;
+ var count = 0;
+ var thrown = false;
+ try {
+ arr.every((v, k, o) => {
+ count++;
+ sum += v;
+ assertEq(k, v - 1);
+ assertEq(o, arr);
+ if (v === 3) {
+ throw "every";
+ }
+ return true
+ })
+ } catch(e) {
+ assertEq(e, "every");
+ thrown = true;
+ }
+ assertEq(thrown, true);
+ assertEq(sum, 6);
+ assertEq(count, 3);
+
+ // There is no callback or callback is not a function.
+ assertThrowsInstanceOf(() => {
+ arr.every();
+ }, TypeError);
+ var invalidCallbacks = [undefined, null, 1, false, "", Symbol(), [], {}, /./];
+ invalidCallbacks.forEach(callback => {
+ assertThrowsInstanceOf(() => {
+ arr.every(callback);
+ }, TypeError);
+ })
+
+ // Callback is a generator.
+ arr.every(function*(){
+ throw "This line will not be executed";
+ });
+
+ // Called from other globals.
+ if (typeof newGlobal === "function") {
+ var every = newGlobal()[constructor.name].prototype.every;
+ var sum = 0;
+ assertEq(every.call(new constructor([1, 2, 3]), v => sum += v), true);
+ assertEq(sum, 6);
+ }
+
+ // Throws if `this` isn't a TypedArray.
+ var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+ new Proxy(new constructor(), {})];
+ invalidReceivers.forEach(invalidReceiver => {
+ assertThrowsInstanceOf(() => {
+ constructor.prototype.every.call(invalidReceiver, () => true);
+ }, TypeError, "Assert that every fails if this value is not a TypedArray");
+ });
+
+ // Test that the length getter is never called.
+ assertEq(Object.defineProperty(new constructor([1, 2, 3]), "length", {
+ get() {
+ throw new Error("length accessor called");
+ }
+ }).every(() => true), true);
+}
+
+for (let constructor of anyTypedArrayConstructors.filter(isFloatConstructor)) {
+ assertEq(new constructor([undefined, , NaN]).every(v => Object.is(v, NaN)), true);
+}
+
+// Tests for TypedArray#some.
+for (var constructor of anyTypedArrayConstructors) {
+ assertEq(constructor.prototype.some.length, 1);
+
+ // Basic tests.
+ assertEq(new constructor([1, 2, 3]).some(v => v % 2), true);
+ assertEq(new constructor([0, 2, 4]).some(v => v % 2), false);
+ assertEq(new constructor([1, 3, 5]).some(v => v > 2), true);
+ assertEq(new constructor([1, 3, 5]).some(v => v < 0), false);
+ assertEq(new constructor(10).some(v => v !== 0), false);
+ assertEq(new constructor().some(v => v > 1), false);
+
+ var arr = new constructor([1, 2, 3, 4, 5]);
+ var sum = 0;
+ var count = 0;
+ assertEq(arr.some((v, k, o) => {
+ count++;
+ sum += v;
+ assertEq(k, v - 1);
+ assertEq(o, arr);
+ return v > 2;
+ }), true);
+ assertEq(sum, 6);
+ assertEq(count, 3);
+
+ // Tests for `thisArg` argument.
+ function assertThisArg(thisArg, thisValue) {
+ // In sloppy mode, `this` could be global object or a wrapper of `thisArg`.
+ assertEq(arr.some(function() {
+ assertDeepEq(this, thisValue);
+ return false;
+ }, thisArg), false);
+
+ // In strict mode, `this` strictly equals `thisArg`.
+ assertEq(arr.some(function() {
+ "use strict";
+ assertDeepEq(this, thisArg);
+ return false;
+ }, thisArg), false);
+
+ // Passing `thisArg` has no effect if callback is an arrow function.
+ var self = this;
+ assertEq(arr.some(() => {
+ assertEq(this, self);
+ return false;
+ }, thisArg), false);
+ }
+ assertThisArg([1, 2, 3], [1, 2, 3]);
+ assertThisArg(Object, Object);
+ assertThisArg(1, Object(1));
+ assertThisArg("1", Object("1"));
+ assertThisArg(false, Object(false));
+ assertThisArg(undefined, this);
+ assertThisArg(null, this);
+
+ // Throw an exception in the callback.
+ var sum = 0;
+ var count = 0;
+ var thrown = false;
+ try {
+ arr.some((v, k, o) => {
+ count++;
+ sum += v;
+ assertEq(k, v - 1);
+ assertEq(o, arr);
+ if (v === 3) {
+ throw "some";
+ }
+ return false
+ })
+ } catch(e) {
+ assertEq(e, "some");
+ thrown = true;
+ }
+ assertEq(thrown, true);
+ assertEq(sum, 6);
+ assertEq(count, 3);
+
+ // There is no callback or callback is not a function.
+ assertThrowsInstanceOf(() => {
+ arr.some();
+ }, TypeError);
+ var invalidCallbacks = [undefined, null, 1, false, "", Symbol(), [], {}, /./];
+ invalidCallbacks.forEach(callback => {
+ assertThrowsInstanceOf(() => {
+ arr.some(callback);
+ }, TypeError);
+ })
+
+ // Callback is a generator.
+ arr.some(function*(){
+ throw "This line will not be executed";
+ });
+
+ // Called from other globals.
+ if (typeof newGlobal === "function") {
+ var some = newGlobal()[constructor.name].prototype.some;
+ var sum = 0;
+ assertEq(some.call(new constructor([1, 2, 3]), v => {
+ sum += v;
+ return false;
+ }), false);
+ assertEq(sum, 6);
+ }
+
+ // Throws if `this` isn't a TypedArray.
+ var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+ new Proxy(new constructor(), {})];
+ invalidReceivers.forEach(invalidReceiver => {
+ assertThrowsInstanceOf(() => {
+ constructor.prototype.some.call(invalidReceiver, () => true);
+ }, TypeError, "Assert that some fails if this value is not a TypedArray");
+ });
+
+ // Test that the length getter is never called.
+ assertEq(Object.defineProperty(new constructor([1, 2, 3]), "length", {
+ get() {
+ throw new Error("length accessor called");
+ }
+ }).some(() => false), false);
+}
+
+for (let constructor of anyTypedArrayConstructors.filter(isFloatConstructor)) {
+ assertEq(new constructor([undefined, , NaN]).some(v => v === v), false);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/fill.js b/js/src/tests/ecma_6/TypedArray/fill.js
new file mode 100644
index 000000000..4349da06a
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/fill.js
@@ -0,0 +1,65 @@
+for (var constructor of anyTypedArrayConstructors) {
+ assertDeepEq(constructor.prototype.fill.length, 1);
+
+ assertDeepEq(new constructor([]).fill(1), new constructor([]));
+ assertDeepEq(new constructor([1,1,1]).fill(2), new constructor([2,2,2]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, 1), new constructor([1,2,2]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, 1, 2), new constructor([1,2,1]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, -2), new constructor([1,2,2]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, -2, -1), new constructor([1,2,1]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, undefined), new constructor([2,2,2]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, undefined, undefined), new constructor([2,2,2]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, 1, undefined), new constructor([1,2,2]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, undefined, 1), new constructor([2,1,1]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, 2, 1), new constructor([1,1,1]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, -1, 1), new constructor([1,1,1]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, -2, 1), new constructor([1,1,1]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, 1, -2), new constructor([1,1,1]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, 0.1), new constructor([2,2,2]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, 0.9), new constructor([2,2,2]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, 1.1), new constructor([1,2,2]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, 0.1, 0.9), new constructor([1,1,1]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, 0.1, 1.9), new constructor([2,1,1]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, 0.1, 1.9), new constructor([2,1,1]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, -0), new constructor([2,2,2]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, 0, -0), new constructor([1,1,1]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, NaN), new constructor([2,2,2]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, 0, NaN), new constructor([1,1,1]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, false), new constructor([2,2,2]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, true), new constructor([1,2,2]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, "0"), new constructor([2,2,2]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, "1"), new constructor([1,2,2]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, "-2"), new constructor([1,2,2]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, "-2", "-1"), new constructor([1,2,1]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, {valueOf: ()=>1}), new constructor([1,2,2]));
+ assertDeepEq(new constructor([1,1,1]).fill(2, 0, {valueOf: ()=>1}), new constructor([2,1,1]));
+
+ // Called from other globals.
+ if (typeof newGlobal === "function") {
+ var fill = newGlobal()[constructor.name].prototype.fill;
+ assertDeepEq(fill.call(new constructor([3, 2, 1]), 2), new constructor([2, 2, 2]));
+ }
+
+ // Throws if `this` isn't a TypedArray.
+ var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+ new Proxy(new constructor(), {})];
+ invalidReceivers.forEach(invalidReceiver => {
+ assertThrowsInstanceOf(() => {
+ constructor.prototype.fill.call(invalidReceiver, 1);
+ }, TypeError);
+ });
+
+ // Test that the length getter is never called.
+ Object.defineProperty(new constructor([1, 2, 3]), "length", {
+ get() {
+ throw new Error("length accessor called");
+ }
+ }).fill(1);
+}
+
+for (let constructor of anyTypedArrayConstructors.filter(isFloatConstructor)) {
+ assertDeepEq(new constructor([0, 0]).fill(NaN), new constructor([NaN, NaN]));
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/filter-species.js b/js/src/tests/ecma_6/TypedArray/filter-species.js
new file mode 100644
index 000000000..2de4e254e
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/filter-species.js
@@ -0,0 +1,56 @@
+function test(constructor, constructor2, from=[1, 2, 3, 4, 5], to=[2, 4]) {
+ var modifiedConstructor = new constructor(from);
+ modifiedConstructor.constructor = constructor2;
+ assertDeepEq(modifiedConstructor.filter(x => x % 2 == 0), new constructor2(to));
+ var modifiedSpecies = new constructor(from);
+ modifiedSpecies.constructor = { [Symbol.species]: constructor2 };
+ assertDeepEq(modifiedSpecies.filter(x => x % 2 == 0), new constructor2(to));
+}
+
+// same size, same sign
+
+test(Int8Array, Uint8Array);
+test(Int8Array, Uint8ClampedArray);
+
+test(Uint8Array, Int8Array);
+test(Uint8Array, Uint8ClampedArray);
+
+test(Uint8ClampedArray, Int8Array);
+test(Uint8ClampedArray, Uint8Array);
+
+test(Int16Array, Uint16Array);
+test(Uint16Array, Int16Array);
+
+test(Int32Array, Uint32Array);
+test(Uint32Array, Int32Array);
+
+// same size, different sign
+
+test(Int8Array, Uint8Array, [-1, -2, -3, -4, -5], [0xFE, 0xFC]);
+test(Int8Array, Uint8ClampedArray, [-1, -2, -3, -4, -5], [0, 0]);
+
+test(Uint8Array, Int8Array, [0xFF, 0xFE, 0xFD, 0xFC, 0xFB], [-2, -4]);
+test(Uint8ClampedArray, Int8Array, [0xFF, 0xFE, 0xFD, 0xFC, 0xFB], [-2, -4]);
+
+test(Int16Array, Uint16Array, [-1, -2, -3, -4, -5], [0xFFFE, 0xFFFC]);
+test(Uint16Array, Int16Array, [0xFFFF, 0xFFFE, 0xFFFD, 0xFFFC, 0xFFFB], [-2, -4]);
+
+test(Int32Array, Uint32Array, [-1, -2, -3, -4, -5], [0xFFFFFFFE, 0xFFFFFFFC]);
+test(Uint32Array, Int32Array, [0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFC, 0xFFFFFFFB], [-2, -4]);
+
+// different size
+
+test(Uint8Array, Uint16Array);
+test(Uint16Array, Uint8Array);
+
+test(Uint8Array, Uint32Array);
+test(Uint32Array, Uint8Array);
+
+test(Uint16Array, Uint32Array);
+test(Uint32Array, Uint16Array);
+
+test(Float32Array, Float64Array);
+test(Float64Array, Float32Array);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/find-and-findIndex.js b/js/src/tests/ecma_6/TypedArray/find-and-findIndex.js
new file mode 100644
index 000000000..125ababd0
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/find-and-findIndex.js
@@ -0,0 +1,52 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var BUGNUMBER = 1078975;
+var summary = "Implement %TypedArray%.prototype.{find, findIndex}";
+print(BUGNUMBER + ": " + summary);
+
+const methods = ["find", "findIndex"];
+
+anyTypedArrayConstructors.forEach(constructor => {
+ methods.forEach(method => {
+ var arr = new constructor([0, 1, 2, 3, 4, 5]);
+ // test that this.length is never called
+ Object.defineProperty(arr, "length", {
+ get() {
+ throw new Error("length accessor called");
+ }
+ });
+ assertEq(arr[method].length, 1);
+ assertEq(arr[method](v => v === 3), 3);
+ assertEq(arr[method](v => v === 6), method === "find" ? undefined : -1);
+
+ var thisValues = [undefined, null, true, 1, "foo", [], {}];
+ if (typeof Symbol == "function")
+ thisValues.push(Symbol());
+
+ thisValues.forEach(thisArg =>
+ assertThrowsInstanceOf(() => arr[method].call(thisArg, () => true), TypeError)
+ );
+
+ assertThrowsInstanceOf(() => arr[method](), TypeError);
+ assertThrowsInstanceOf(() => arr[method](1), TypeError);
+ });
+});
+
+anyTypedArrayConstructors.filter(isFloatConstructor).forEach(constructor => {
+ var arr = new constructor([-0, 0, 1, 5, NaN, 6]);
+ assertEq(arr.find(v => Number.isNaN(v)), NaN);
+ assertEq(arr.findIndex(v => Number.isNaN(v)), 4);
+
+ assertEq(arr.find(v => Object.is(v, 0)), 0);
+ assertEq(arr.findIndex(v => Object.is(v, 0)), 1);
+
+ assertEq(arr.find(v => Object.is(v, -0)), -0);
+ assertEq(arr.findIndex(v => Object.is(v, -0)), 0);
+})
+
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/forEach.js b/js/src/tests/ecma_6/TypedArray/forEach.js
new file mode 100644
index 000000000..9daa690e2
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/forEach.js
@@ -0,0 +1,93 @@
+// Tests for TypedArray#forEach
+for (var constructor of anyTypedArrayConstructors) {
+ assertEq(constructor.prototype.forEach.length, 1);
+
+ var arr = new constructor([1, 2, 3, 4, 5]);
+ // Tests for `thisArg` argument.
+ function assertThisArg(thisArg, thisValue) {
+ // In sloppy mode, `this` could be global object or a wrapper of `thisArg`.
+ arr.forEach(function() {
+ assertDeepEq(this, thisValue);
+ return false;
+ }, thisArg);
+
+ // In strict mode, `this` strictly equals `thisArg`.
+ arr.forEach(function() {
+ "use strict";
+ assertDeepEq(this, thisArg);
+ return false;
+ }, thisArg);
+
+ // Passing `thisArg` has no effect if callback is an arrow function.
+ var self = this;
+ arr.forEach(() => {
+ assertEq(this, self);
+ return false;
+ }, thisArg);
+ }
+ assertThisArg([1, 2, 3], [1, 2, 3]);
+ assertThisArg(Object, Object);
+ assertThisArg(1, Object(1));
+ assertThisArg("1", Object("1"));
+ assertThisArg(false, Object(false));
+ assertThisArg(undefined, this);
+ assertThisArg(null, this);
+
+ // Throw an exception in the callback.
+ var sum = 0;
+ var count = 0;
+ var thrown = false;
+ try {
+ assertEq(arr.forEach((v) => {
+ count++;
+ sum += v;
+ if (v === 3) {
+ throw "forEach";
+ }
+ }), undefined)
+ } catch(e) {
+ assertEq(e, "forEach");
+ thrown = true;
+ }
+ assertEq(thrown, true);
+ assertEq(sum, 6);
+ assertEq(count, 3);
+
+ // There is no callback or callback is not a function.
+ assertThrowsInstanceOf(() => {
+ arr.forEach();
+ }, TypeError);
+ var invalidCallbacks = [undefined, null, 1, false, "", Symbol(), [], {}, /./];
+ invalidCallbacks.forEach(callback => {
+ assertThrowsInstanceOf(() => {
+ arr.forEach(callback);
+ }, TypeError);
+ })
+
+ // Callback is a generator.
+ arr.forEach(function*(){
+ throw "This line will not be executed";
+ });
+
+ // Called from other globals.
+ if (typeof newGlobal === "function") {
+ var forEach = newGlobal()[constructor.name].prototype.forEach;
+ var sum = 0;
+ forEach.call(new constructor([1, 2, 3]), v => {
+ sum += v;
+ });
+ assertEq(sum, 6);
+ }
+
+ // Throws if `this` isn't a TypedArray.
+ var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+ new Proxy(new constructor(), {})];
+ invalidReceivers.forEach(invalidReceiver => {
+ assertThrowsInstanceOf(() => {
+ constructor.prototype.forEach.call(invalidReceiver, () => true);
+ }, TypeError, "Assert that some fails if this value is not a TypedArray");
+ });
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/from_basics.js b/js/src/tests/ecma_6/TypedArray/from_basics.js
new file mode 100644
index 000000000..9f53feb72
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/from_basics.js
@@ -0,0 +1,42 @@
+for (var constructor of anyTypedArrayConstructors) {
+ // 'from' method is identical for all typed array constructors.
+ assertEq(anyTypedArrayConstructors[0].from === constructor.from, true);
+
+ // %TypedArray%.from copies arrays.
+ var src = new constructor([1, 2, 3]), copy = constructor.from(src);
+ assertEq(copy === src, false);
+ assertEq(copy instanceof constructor, true);
+ assertDeepEq(copy, src);
+
+ // Non-element properties are not copied.
+ var a = new constructor([0, 1]);
+ a.name = "lisa";
+ assertDeepEq(constructor.from(a), new constructor([0, 1]));
+
+ // %TypedArray%.from can copy non-iterable objects, if they're array-like.
+ src = {0: 0, 1: 1, length: 2};
+ copy = constructor.from(src);
+ assertEq(copy instanceof constructor, true);
+ assertDeepEq(copy, new constructor([0, 1]));
+
+ // Properties past the .length are not copied.
+ src = {0: "0", 1: "1", 2: "two", 9: "nine", name: "lisa", length: 2};
+ assertDeepEq(constructor.from(src), new constructor([0, 1]));
+
+ // If an object has neither an @@iterator method nor .length,
+ // then it's treated as zero-length.
+ assertDeepEq(constructor.from({}), new constructor());
+
+ // Primitives will be coerced to primitive wrapper first.
+ assertDeepEq(constructor.from(1), new constructor());
+ assertDeepEq(constructor.from("123"), new constructor([1, 2, 3]));
+ assertDeepEq(constructor.from(true), new constructor());
+ assertDeepEq(constructor.from(Symbol()), new constructor());
+
+ // Source object property order doesn't matter.
+ src = {length: 2, 1: "1", 0: "0"};
+ assertDeepEq(constructor.from(src), new constructor([0, 1]));
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/from_constructor.js b/js/src/tests/ecma_6/TypedArray/from_constructor.js
new file mode 100644
index 000000000..0b0773b85
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/from_constructor.js
@@ -0,0 +1,36 @@
+for (var constructor of anyTypedArrayConstructors) {
+ // Note %TypedArray%.from(iterable) calls 'this' with an argument whose value is
+ // `[...iterable].length`, while Array.from(iterable) doesn't pass any argument.
+ constructor.from.call(function(len){
+ assertEq(len, 3);
+ return new constructor(len);
+ }, Array(3));
+
+ // If the 'this' value passed to %TypedArray.from is not a constructor,
+ // then an exception is thrown, while Array.from will use Array as it's constructor.
+ var arr = [3, 4, 5];
+ var nonconstructors = [
+ {}, Math, Object.getPrototypeOf, undefined, 17,
+ () => ({}) // arrow functions are not constructors
+ ];
+ for (var v of nonconstructors) {
+ assertThrowsInstanceOf(() => {
+ constructor.from.call(v, arr);
+ }, TypeError);
+ }
+
+ // %TypedArray%.from does not get confused if global constructors for typed arrays
+ // are replaced with another constructor.
+ function NotArray(...rest) {
+ return new constructor(...rest);
+ }
+ var RealArray = constructor;
+ NotArray.from = constructor.from;
+ this[constructor.name] = NotArray;
+ assertEq(RealArray.from([1]) instanceof RealArray, true);
+ assertEq(NotArray.from([1]) instanceof RealArray, true);
+ this[constructor.name] = RealArray;
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/from_errors.js b/js/src/tests/ecma_6/TypedArray/from_errors.js
new file mode 100644
index 000000000..281b1b512
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/from_errors.js
@@ -0,0 +1,76 @@
+for (var constructor of anyTypedArrayConstructors) {
+ // %TypedArray%.from throws if the argument is undefined or null.
+ assertThrowsInstanceOf(() => constructor.from(), TypeError);
+ assertThrowsInstanceOf(() => constructor.from(undefined), TypeError);
+ assertThrowsInstanceOf(() => constructor.from(null), TypeError);
+
+ // Unlike Array.from, %TypedArray%.from doesn't get or set the length property.
+ function ObjectWithThrowingLengthGetterSetter(...rest) {
+ var ta = new constructor(...rest);
+ Object.defineProperty(ta, "length", {
+ configurable: true,
+ get() { throw new RangeError("getter!"); },
+ set() { throw new RangeError("setter!"); }
+ });
+ return ta;
+ }
+ ObjectWithThrowingLengthGetterSetter.from = constructor.from;
+ assertEq(ObjectWithThrowingLengthGetterSetter.from([123])[0], 123);
+
+ // %TypedArray%.from throws if mapfn is neither callable nor undefined.
+ assertThrowsInstanceOf(() => constructor.from([3, 4, 5], {}), TypeError);
+ assertThrowsInstanceOf(() => constructor.from([3, 4, 5], "also not a function"), TypeError);
+ assertThrowsInstanceOf(() => constructor.from([3, 4, 5], null), TypeError);
+
+ // Even if the function would not have been called.
+ assertThrowsInstanceOf(() => constructor.from([], JSON), TypeError);
+
+ // If mapfn is not undefined and not callable, the error happens before anything else.
+ // Before calling the constructor, before touching the arrayLike.
+ var log = "";
+ var obj;
+ function C(...rest) {
+ log += "C";
+ obj = new constructor(...rest);
+ return obj;
+ }
+ var p = new Proxy({}, {
+ has: function () { log += "1"; },
+ get: function () { log += "2"; },
+ getOwnPropertyDescriptor: function () { log += "3"; }
+ });
+ assertThrowsInstanceOf(() => constructor.from.call(C, p, {}), TypeError);
+ assertEq(log, "");
+
+ // If mapfn throws, the new object has already been created.
+ var arrayish = {
+ get length() { log += "l"; return 1; },
+ get 0() { log += "0"; return "q"; }
+ };
+ log = "";
+ var exc = {surprise: "ponies"};
+ assertThrowsValue(() => constructor.from.call(C, arrayish, () => { throw exc; }), exc);
+ assertEq(log, "lC0");
+ assertEq(obj instanceof constructor, true);
+
+ // It's a TypeError if the @@iterator property is a primitive (except null and undefined).
+ for (var primitive of ["foo", 17, Symbol(), true]) {
+ assertThrowsInstanceOf(() => constructor.from({[Symbol.iterator] : primitive}), TypeError);
+ }
+ assertDeepEq(constructor.from({[Symbol.iterator]: null}), new constructor());
+ assertDeepEq(constructor.from({[Symbol.iterator]: undefined}), new constructor());
+
+ // It's a TypeError if the iterator's .next() method returns a primitive.
+ for (var primitive of [undefined, null, "foo", 17, Symbol(), true]) {
+ assertThrowsInstanceOf(
+ () => constructor.from({
+ [Symbol.iterator]() {
+ return {next() { return primitive; }};
+ }
+ }),
+ TypeError);
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/from_iterable.js b/js/src/tests/ecma_6/TypedArray/from_iterable.js
new file mode 100644
index 000000000..889c81589
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/from_iterable.js
@@ -0,0 +1,49 @@
+for (var constructor of anyTypedArrayConstructors) {
+ // %TypedArray%.from works on arguments objects.
+ (function () {
+ assertDeepEq(constructor.from(arguments), new constructor(["0", "1", undefined]));
+ })("0", "1", undefined);
+
+ // If an object has both .length and [@@iterator] properties, [@@iterator] is used.
+ var a = ['0', '1', '2', '3', '4'];
+ a[Symbol.iterator] = function* () {
+ for (var i = 5; i--; )
+ yield this[i];
+ };
+
+ var log = '';
+ function f(x) {
+ log += x;
+ return x + x;
+ }
+
+ var b = constructor.from(a, f);
+ assertDeepEq(b, new constructor(['44', '33', '22', '11', '00']));
+ assertEq(log, '43210');
+
+ // In fact, if [@@iterator] is present, .length isn't queried at all.
+ var pa = new Proxy(a, {
+ has: function (target, id) {
+ if (id === "length")
+ throw new Error(".length should not be queried (has)");
+ return id in target;
+ },
+ get: function (target, id) {
+ if (id === "length")
+ throw new Error(".length should not be queried (get)");
+ return target[id];
+ },
+ getOwnPropertyDescriptor: function (target, id) {
+ if (id === "length")
+ throw new Error(".length should not be queried (getOwnPropertyDescriptor)");
+ return Object.getOwnPropertyDescriptor(target, id)
+ }
+ });
+ log = "";
+ b = constructor.from(pa, f);
+ assertDeepEq(b, new constructor(['44', '33', '22', '11', '00']));
+ assertEq(log, '43210');
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/from_mapping.js b/js/src/tests/ecma_6/TypedArray/from_mapping.js
new file mode 100644
index 000000000..1c2481541
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/from_mapping.js
@@ -0,0 +1,45 @@
+for (var constructor of anyTypedArrayConstructors) {
+ // If the mapfn argument to %TypedArray%.from is undefined, don't map.
+ assertDeepEq(constructor.from([3, 4, 5], undefined), new constructor([3, 4, 5]));
+ assertDeepEq(constructor.from([4, 5, 6], undefined, Math), new constructor([4, 5, 6]));
+
+ // mapfn is called with two arguments: value and index.
+ var log = [];
+ function f(...args) {
+ log.push(args);
+ return log.length;
+ }
+ assertDeepEq(constructor.from(['a', 'e', 'i', 'o', 'u'], f), new constructor([1, 2, 3, 4, 5]));
+ assertDeepEq(log, [['a', 0], ['e', 1], ['i', 2], ['o', 3], ['u', 4]]);
+
+ // If the object to be copied is non-iterable, mapfn is still called with two
+ // arguments.
+ log = [];
+ assertDeepEq(constructor.from({0: "zero", 1: "one", length: 2}, f), new constructor([1, 2]));
+ assertDeepEq(log, [["zero", 0], ["one", 1]]);
+
+ // If the object to be copied is iterable and the constructor is not Array,
+ // mapfn is still called with two arguments.
+ log = [];
+ function C(...rest) {
+ return new constructor(...rest);
+ }
+ C.from = constructor.from;
+ var c = new C(2);
+ c[0] = 1;
+ c[1] = 2;
+ assertDeepEq(C.from(["zero", "one"], f), c);
+ assertDeepEq(log, [["zero", 0], ["one", 1]]);
+
+ // The mapfn is called even if the value to be mapped is undefined.
+ assertDeepEq(constructor.from([0, 1, , 3], String), new constructor(["0", "1", "undefined", "3"]));
+ var arraylike = {length: 4, "0": 0, "1": 1, "3": 3};
+ assertDeepEq(constructor.from(arraylike, String), new constructor(["0", "1", "undefined", "3"]));
+}
+
+// %TypedArray%.from(obj, map) is not exactly the same as %TypedArray%.from(obj).map(mapFn).
+assertDeepEq(Int8Array.from([150], v => v / 2), new Int8Array([75]));
+assertDeepEq(Int8Array.from([150]).map(v => v / 2), new Int8Array([-53]));
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/from_realms.js b/js/src/tests/ecma_6/TypedArray/from_realms.js
new file mode 100644
index 000000000..590589392
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/from_realms.js
@@ -0,0 +1,32 @@
+for (var constructor of anyTypedArrayConstructors) {
+ if (typeof newGlobal !== 'function')
+ break;
+
+ // G[constructor.name].from, where G is any global, produces an array whose prototype
+ // is G[constructor.name].prototype.
+ var g = newGlobal();
+ var ga = g[constructor.name].from([1, 2, 3]);
+ assertEq(ga instanceof g[constructor.name], true);
+
+ // %TypedArray%.from can be applied to a constructor from another realm.
+ var p = constructor.from.call(g[constructor.name], [1, 2, 3]);
+ assertEq(p instanceof g[constructor.name], true);
+ var q = g[constructor.name].from.call(constructor, [3, 4, 5]);
+ assertEq(q instanceof constructor, true);
+
+ // The default 'this' value received by a non-strict mapping function is
+ // that function's global, not %TypedArray%.from's global or the caller's global.
+ var h = newGlobal(), result = undefined;
+ h.mainGlobal = this;
+ h.eval("function f() { mainGlobal.result = this; }");
+ g[constructor.name].from.call(constructor, [5, 6, 7], h.f);
+ // (Give each global in the test a name, for better error messages. But use
+ // globalName, because window.name is complicated.)
+ this.globalName = "main";
+ g.globalName = "g";
+ h.globalName = "h";
+ assertEq(result.globalName, "h");
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/from_string.js b/js/src/tests/ecma_6/TypedArray/from_string.js
new file mode 100644
index 000000000..09a2c3671
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/from_string.js
@@ -0,0 +1,24 @@
+// %TypedArray%.from called on Array should also handle strings correctly.
+var from = Int8Array.from.bind(Uint32Array);
+var toCodePoint = s => s.codePointAt(0);
+
+// %TypedArray%.from on a string iterates over the string.
+assertEqArray(from("test string", toCodePoint),
+ ['t', 'e', 's', 't', ' ', 's', 't', 'r', 'i', 'n', 'g'].map(toCodePoint));
+
+// %TypedArray%.from on a string handles surrogate pairs correctly.
+var gclef = "\uD834\uDD1E"; // U+1D11E MUSICAL SYMBOL G CLEF
+assertEqArray(from(gclef, toCodePoint), [gclef].map(toCodePoint));
+assertEqArray(from(gclef + " G", toCodePoint), [gclef, " ", "G"].map(toCodePoint));
+
+// %TypedArray%.from on a string calls the @@iterator method.
+String.prototype[Symbol.iterator] = function* () { yield 1; yield 2; };
+assertEqArray(from("anything"), [1, 2]);
+
+// If the iterator method is deleted, Strings are still arraylike.
+delete String.prototype[Symbol.iterator];
+assertEqArray(from("works", toCodePoint), ['w', 'o', 'r', 'k', 's'].map(toCodePoint));
+assertEqArray(from(gclef, toCodePoint), ['\uD834', '\uDD1E'].map(toCodePoint));
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/from_surfaces.js b/js/src/tests/ecma_6/TypedArray/from_surfaces.js
new file mode 100644
index 000000000..ef1553637
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/from_surfaces.js
@@ -0,0 +1,12 @@
+for (var constructor of anyTypedArrayConstructors) {
+ // Check superficial features of %TypeArray%.from.
+ var desc = Object.getOwnPropertyDescriptor(constructor.__proto__, "from");
+ assertEq(desc.configurable, true);
+ assertEq(desc.enumerable, false);
+ assertEq(desc.writable, true);
+ assertEq(constructor.from.length, 1);
+ assertThrowsInstanceOf(() => new constructor.from(), TypeError); // not a constructor
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/from_this.js b/js/src/tests/ecma_6/TypedArray/from_this.js
new file mode 100644
index 000000000..95af053b8
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/from_this.js
@@ -0,0 +1,59 @@
+for (var constructor of anyTypedArrayConstructors) {
+ // The third argument to %TypedArray%.from is passed as the 'this' value to the
+ // mapping function.
+ var hits = 0, obj = {};
+ function f(x) {
+ assertEq(this, obj);
+ hits++;
+ }
+ constructor.from(["a", "b", "c"], f, obj);
+ assertEq(hits, 3);
+
+ // Without an argument, undefined is passed...
+ hits = 0;
+ function gs(x) {
+ "use strict";
+ assertEq(this, undefined);
+ hits++;
+ }
+ constructor.from("def", gs);
+ assertEq(hits, 3);
+
+ // ...and if the mapping function is non-strict, that means the global is
+ // passed.
+ var global = this;
+ hits = 0;
+ function g(x) {
+ assertEq(this, global);
+ hits++;
+ }
+ constructor.from("ghi", g);
+ assertEq(hits, 3);
+
+ // A primitive value can be passed.
+ for (var v of [0, "str", undefined]) {
+ hits = 0;
+ var mapfn = function h(x) {
+ "use strict";
+ assertEq(this, v);
+ hits++;
+ };
+ constructor.from("pq", mapfn, v);
+ assertEq(hits, 2);
+ }
+
+ // ...and if the mapping function is non-strict, primitive values will
+ // be wrapped to objects.
+ for (var v of [0, "str", true]) {
+ hits = 0;
+ var mapfn = function h(x) {
+ assertDeepEq(this, Object(v));
+ hits++;
+ };
+ constructor.from("pq", mapfn, v);
+ assertEq(hits, 2);
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/getter-name.js b/js/src/tests/ecma_6/TypedArray/getter-name.js
new file mode 100644
index 000000000..47050e3c1
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/getter-name.js
@@ -0,0 +1,16 @@
+var BUGNUMBER = 1180290;
+var summary = 'TypedArray getters should have get prefix';
+
+print(BUGNUMBER + ": " + summary);
+
+let TypedArray = Object.getPrototypeOf(Float32Array.prototype).constructor;
+
+assertEq(Object.getOwnPropertyDescriptor(TypedArray, Symbol.species).get.name, "get [Symbol.species]");
+assertEq(Object.getOwnPropertyDescriptor(TypedArray.prototype, "buffer").get.name, "get buffer");
+assertEq(Object.getOwnPropertyDescriptor(TypedArray.prototype, "byteLength").get.name, "get byteLength");
+assertEq(Object.getOwnPropertyDescriptor(TypedArray.prototype, "byteOffset").get.name, "get byteOffset");
+assertEq(Object.getOwnPropertyDescriptor(TypedArray.prototype, "length").get.name, "get length");
+assertEq(Object.getOwnPropertyDescriptor(TypedArray.prototype, Symbol.toStringTag).get.name, "get [Symbol.toStringTag]");
+
+if (typeof reportCompare === 'function')
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/has-property-op.js b/js/src/tests/ecma_6/TypedArray/has-property-op.js
new file mode 100644
index 000000000..7ae70ef36
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/has-property-op.js
@@ -0,0 +1,22 @@
+for (var constructor of anyTypedArrayConstructors) {
+ var obj = new constructor(5);
+
+ for (var i = 0; i < obj.length; i++)
+ assertEq(i in obj, true);
+
+ for (var v of [20, 300, -1, 5, -10, Math.pow(2, 32) - 1, -Math.pow(2, 32)])
+ assertEq(v in obj, false);
+
+ // Don't inherit elements
+ obj.__proto__[50] = "hello";
+ assertEq(obj.__proto__[50], "hello");
+ assertEq(50 in obj, false);
+
+ // Do inherit normal properties
+ obj.__proto__.a = "world";
+ assertEq(obj.__proto__.a, "world");
+ assertEq("a" in obj, true);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/includes.js b/js/src/tests/ecma_6/TypedArray/includes.js
new file mode 100644
index 000000000..bcc50a257
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/includes.js
@@ -0,0 +1,40 @@
+for (var constructor of anyTypedArrayConstructors) {
+ assertEq(constructor.prototype.includes.length, 1);
+
+ assertEq(new constructor([1, 2, 3]).includes(1), true);
+ assertEq(new constructor([1, 2, 3]).includes(2), true);
+ assertEq(new constructor([1, 2, 3]).includes(3), true);
+ assertEq(new constructor([1, 2, 3]).includes(2, 1), true);
+ assertEq(new constructor([1, 2, 3]).includes(2, -2), true);
+ assertEq(new constructor([1, 2, 3]).includes(2, -100), true);
+
+ assertEq(new constructor([1, 2, 3]).includes("2"), false);
+ assertEq(new constructor([1, 2, 3]).includes(2, 2), false);
+ assertEq(new constructor([1, 2, 3]).includes(2, -1), false);
+ assertEq(new constructor([1, 2, 3]).includes(2, 100), false);
+
+ // Called from other globals.
+ if (typeof newGlobal === "function") {
+ var includes = newGlobal()[constructor.name].prototype.includes;
+ assertEq(includes.call(new constructor([1, 2, 3]), 2), true);
+ }
+
+ // Throws if `this` isn't a TypedArray.
+ var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+ new Proxy(new constructor(), {})];
+ invalidReceivers.forEach(invalidReceiver => {
+ assertThrowsInstanceOf(() => {
+ constructor.prototype.includes.call(invalidReceiver);
+ }, TypeError, "Assert that reverse fails if this value is not a TypedArray");
+ });
+
+ // Test that the length getter is never called.
+ assertEq(Object.defineProperty(new constructor([1, 2, 3]), "length", {
+ get() {
+ throw new Error("length accessor called");
+ }
+ }).includes(2), true);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/indexOf-and-lastIndexOf.js b/js/src/tests/ecma_6/TypedArray/indexOf-and-lastIndexOf.js
new file mode 100644
index 000000000..33c775485
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/indexOf-and-lastIndexOf.js
@@ -0,0 +1,117 @@
+// Tests for TypedArray#indexOf.
+for (var constructor of anyTypedArrayConstructors) {
+ assertEq(constructor.prototype.indexOf.length, 1);
+
+ // Works with one argument.
+ assertEq(new constructor([1, 2, 3, 4, 5]).indexOf(0), -1);
+ assertEq(new constructor([1, 2, 3, 4, 5]).indexOf(1), 0);
+ assertEq(new constructor([1, 2, 3, 4, 5]).indexOf(5), 4);
+ assertEq(new constructor([1, 2, 3, 4, 5]).indexOf(6), -1);
+ assertEq(new constructor([1, 2, 1, 2, 1]).indexOf(1), 0);
+
+ if (isFloatConstructor(constructor)) {
+ assertEq(new constructor([NaN, 0, -0]).indexOf(NaN), -1);
+ assertEq(new constructor([NaN, 0, -0]).indexOf(0), 1);
+ assertEq(new constructor([NaN, 0, -0]).indexOf(-0), 1);
+ } else {
+ // [NaN, 0, -0] will be coerced to [0, 0, 0]
+ assertEq(new constructor([NaN, 0, -0]).indexOf(NaN), -1);
+ assertEq(new constructor([NaN, 0, -0]).indexOf(0), 0);
+ assertEq(new constructor([NaN, 0, -0]).indexOf(-0), 0);
+ }
+
+ // Works with two arguments.
+ assertEq(new constructor([1, 2, 3, 4, 5]).indexOf(1, 1), -1);
+ assertEq(new constructor([1, 2, 3, 4, 5]).indexOf(1, -100), 0);
+ assertEq(new constructor([1, 2, 3, 4, 5]).indexOf(3, 100), -1);
+ assertEq(new constructor([1, 2, 3, 4, 5]).indexOf(5, -1), 4);
+ assertEq(new constructor([1, 2, 1, 2, 1]).indexOf(1, 2), 2);
+ assertEq(new constructor([1, 2, 1, 2, 1]).indexOf(1, -2), 4);
+
+ // Throws if `this` isn't a TypedArray.
+ var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+ new Proxy(new constructor(), {})];
+ invalidReceivers.forEach(invalidReceiver => {
+ assertThrowsInstanceOf(() => {
+ constructor.prototype.indexOf.call(invalidReceiver);
+ }, TypeError, "Assert that indexOf fails if this value is not a TypedArray");
+ });
+
+ // test that this.length is never called
+ assertEq(Object.defineProperty(new constructor([0, 1, 2, 3, 5]), "length", {
+ get() {
+ throw new Error("length accessor called");
+ }
+ }).indexOf(1), 1);
+}
+
+for (let constructor of anyTypedArrayConstructors.filter(isFloatConstructor)) {
+ if (constructor.BYTES_PER_ELEMENT === 4) {
+ assertEq(new constructor([.1, .2, .3]).indexOf(.2), -1);
+ assertEq(new constructor([.1, .2, .3]).indexOf(Math.fround(.2)), 1);
+ } else {
+ assertEq(constructor.BYTES_PER_ELEMENT, 8);
+ assertEq(new constructor([.1, .2, .3]).indexOf(.2), 1);
+ }
+}
+
+// Tests for TypedArray#lastIndexOf.
+for (var constructor of anyTypedArrayConstructors) {
+
+ assertEq(constructor.prototype.lastIndexOf.length, 1);
+
+ // Works with one arguments.
+ assertEq(new constructor([1, 2, 3, 4, 5]).lastIndexOf(0), -1);
+ assertEq(new constructor([1, 2, 3, 4, 5]).lastIndexOf(1), 0);
+ assertEq(new constructor([1, 2, 3, 4, 5]).lastIndexOf(5), 4);
+ assertEq(new constructor([1, 2, 3, 4, 5]).lastIndexOf(6), -1);
+ assertEq(new constructor([1, 2, 1, 2, 1]).lastIndexOf(1), 4);
+
+ if (isFloatConstructor(constructor)) {
+ assertEq(new constructor([NaN, 0, -0]).lastIndexOf(NaN), -1);
+ assertEq(new constructor([NaN, 0, -0]).lastIndexOf(0), 2);
+ assertEq(new constructor([NaN, 0, -0]).lastIndexOf(-0), 2);
+ } else {
+ // [NaN, 0, -0] will be coerced to [0, 0, 0].
+ assertEq(new constructor([NaN, 0, -0]).lastIndexOf(NaN), -1);
+ assertEq(new constructor([NaN, 0, -0]).lastIndexOf(0), 2);
+ assertEq(new constructor([NaN, 0, -0]).lastIndexOf(-0), 2);
+ }
+
+ // Works with two arguments.
+ assertEq(new constructor([1, 2, 3, 4, 5]).lastIndexOf(1, 1), 0);
+ assertEq(new constructor([1, 2, 3, 4, 5]).lastIndexOf(1, -100), -1);
+ assertEq(new constructor([1, 2, 3, 4, 5]).lastIndexOf(3, 100), 2);
+ assertEq(new constructor([1, 2, 3, 4, 5]).lastIndexOf(5, -1), 4);
+ assertEq(new constructor([1, 2, 1, 2, 1]).lastIndexOf(1, 2), 2);
+ assertEq(new constructor([1, 2, 1, 2, 1]).lastIndexOf(1, -2), 2);
+
+ // Throws if `this` isn't a TypedArray.
+ var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+ new Proxy(new constructor(), {})];
+ invalidReceivers.forEach(invalidReceiver => {
+ assertThrowsInstanceOf(() => {
+ constructor.prototype.lastIndexOf.call(invalidReceiver);
+ }, TypeError, "Assert that lastIndexOf fails if this value is not a TypedArray");
+ });
+
+ // Test that the length getter is never called.
+ assertEq(Object.defineProperty(new constructor([0, 1, 2, 3, 5]), "length", {
+ get() {
+ throw new Error("length accessor called");
+ }
+ }).lastIndexOf(1), 1);
+}
+
+for (let constructor of anyTypedArrayConstructors.filter(isFloatConstructor)) {
+ if (constructor.BYTES_PER_ELEMENT === 4) {
+ assertEq(new constructor([.1, .2, .3]).lastIndexOf(.2), -1);
+ assertEq(new constructor([.1, .2, .3]).lastIndexOf(Math.fround(.2)), 1);
+ } else {
+ assertEq(constructor.BYTES_PER_ELEMENT, 8);
+ assertEq(new constructor([.1, .2, .3]).lastIndexOf(.2), 1);
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/indexOf-never-returns-negative-zero.js b/js/src/tests/ecma_6/TypedArray/indexOf-never-returns-negative-zero.js
new file mode 100644
index 000000000..72f834215
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/indexOf-never-returns-negative-zero.js
@@ -0,0 +1,7 @@
+var ta = new Uint8Array(1);
+ta[0] = 17;
+
+assertEq(ta.indexOf(17, -0), +0);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/iterator.js b/js/src/tests/ecma_6/TypedArray/iterator.js
new file mode 100644
index 000000000..3f943aa70
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/iterator.js
@@ -0,0 +1,42 @@
+// Ensure that we're using [[ArrayLength]] to determine the number of
+// values to produce instead of the length property.
+
+function testIterationCount(iterator, expectedLength) {
+ for (let i = 0; i < expectedLength; i++)
+ assertEq(iterator.next().done, false);
+ assertEq(iterator.next().done, true);
+}
+
+let i8Array = new Int8Array(4);
+Object.defineProperty(i8Array, "length", {value: 0});
+let i8Iterator = i8Array[Symbol.iterator]();
+testIterationCount(i8Iterator, 4);
+
+// Veryify that the length property isn't even touched
+i8Array = new Int8Array();
+Object.defineProperty(i8Array, "length", {
+ get() {
+ throw TypeError;
+ }
+});
+i8Iterator = i8Array[Symbol.iterator]();
+testIterationCount(i8Iterator, 0);
+
+// Verify that it works for set as well
+i8Array = new Uint8Array(1);
+// Try setting a high length which would trigger failure
+Object.defineProperty(i8Array, "length", {value: 15});
+// Works if the fake length is ignored
+(new Uint8Array(4)).set(i8Array, 3);
+
+// Ensure that it works across globals
+let g2 = newGlobal();
+
+i8Array = new Int8Array(8);
+Object.defineProperty(i8Array, "length", {value: 0});
+let iterator = i8Array[Symbol.iterator]();
+iterator.next = g2.Array.prototype[Symbol.iterator]().next;
+testIterationCount(iterator, 8);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/join.js b/js/src/tests/ecma_6/TypedArray/join.js
new file mode 100644
index 000000000..0e797320f
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/join.js
@@ -0,0 +1,48 @@
+for (var constructor of anyTypedArrayConstructors) {
+ assertEq(constructor.prototype.join.length, 1);
+
+ assertEq(new constructor([1, 2, 3]).join(), "1,2,3");
+ assertEq(new constructor([1, 2, 3]).join(undefined), "1,2,3");
+ assertEq(new constructor([1, 2, 3]).join(null), "1null2null3");
+ assertEq(new constructor([1, 2, 3]).join(""), "123");
+ assertEq(new constructor([1, 2, 3]).join("+"), "1+2+3");
+ assertEq(new constructor([1, 2, 3]).join(.1), "10.120.13");
+ assertEq(new constructor([1, 2, 3]).join({toString(){return "foo"}}), "1foo2foo3");
+ assertEq(new constructor([1]).join("-"), "1");
+ assertEq(new constructor().join(), "");
+ assertEq(new constructor().join("*"), "");
+ assertEq(new constructor(1).join(), "0");
+ assertEq(new constructor(3).join(), "0,0,0");
+
+ assertThrowsInstanceOf(() => new constructor().join({toString(){throw new TypeError}}), TypeError);
+ assertThrowsInstanceOf(() => new constructor().join(Symbol()), TypeError);
+
+ // Called from other globals.
+ if (typeof newGlobal === "function") {
+ var join = newGlobal()[constructor.name].prototype.join;
+ assertEq(join.call(new constructor([1, 2, 3]), "\t"), "1\t2\t3");
+ }
+
+ // Throws if `this` isn't a TypedArray.
+ var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+ new Proxy(new constructor(), {})];
+ invalidReceivers.forEach(invalidReceiver => {
+ assertThrowsInstanceOf(() => {
+ constructor.prototype.join.call(invalidReceiver);
+ }, TypeError, "Assert that join fails if this value is not a TypedArray");
+ });
+
+ // Test that the length getter is never called.
+ assertEq(Object.defineProperty(new constructor([1, 2, 3]), "length", {
+ get() {
+ throw new Error("length accessor called");
+ }
+ }).join("\0"), "1\0002\0003");
+}
+
+for (let constructor of anyTypedArrayConstructors.filter(isFloatConstructor)) {
+ assertDeepEq(new constructor([null, , NaN]).join(), "0,NaN,NaN");
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/keys.js b/js/src/tests/ecma_6/TypedArray/keys.js
new file mode 100644
index 000000000..88477cd75
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/keys.js
@@ -0,0 +1,36 @@
+for (var constructor of anyTypedArrayConstructors) {
+ assertEq(constructor.prototype.keys.length, 0);
+ assertEq(constructor.prototype.keys.name, "keys");
+
+ assertDeepEq([...new constructor(0).keys()], []);
+ assertDeepEq([...new constructor(1).keys()], [0]);
+ assertDeepEq([...new constructor(2).keys()], [0, 1]);
+ assertDeepEq([...new constructor([15]).keys()], [0]);
+
+ var arr = new constructor([1, 2, 3]);
+ var iterator = arr.keys();
+ assertDeepEq(iterator.next(), {value: 0, done: false});
+ assertDeepEq(iterator.next(), {value: 1, done: false});
+ assertDeepEq(iterator.next(), {value: 2, done: false});
+ assertDeepEq(iterator.next(), {value: undefined, done: true});
+
+ // Called from other globals.
+ if (typeof newGlobal === "function") {
+ var keys = newGlobal()[constructor.name].prototype.keys;
+ assertDeepEq([...keys.call(new constructor(2))], [0, 1]);
+ arr = new (newGlobal()[constructor.name])(2);
+ assertEq([...constructor.prototype.keys.call(arr)].toString(), "0,1");
+ }
+
+ // Throws if `this` isn't a TypedArray.
+ var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+ new Proxy(new constructor(), {})];
+ invalidReceivers.forEach(invalidReceiver => {
+ assertThrowsInstanceOf(() => {
+ constructor.prototype.keys.call(invalidReceiver);
+ }, TypeError, "Assert that keys fails if this value is not a TypedArray");
+ });
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/lastIndexOf-never-returns-negative-zero.js b/js/src/tests/ecma_6/TypedArray/lastIndexOf-never-returns-negative-zero.js
new file mode 100644
index 000000000..bffc05af7
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/lastIndexOf-never-returns-negative-zero.js
@@ -0,0 +1,7 @@
+var ta = new Uint8Array(1);
+ta[0] = 17;
+
+assertEq(ta.lastIndexOf(17, -0), +0);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/map-and-filter.js b/js/src/tests/ecma_6/TypedArray/map-and-filter.js
new file mode 100644
index 000000000..0d86fc02b
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/map-and-filter.js
@@ -0,0 +1,274 @@
+// Tests for TypedArray#map.
+for (var constructor of anyTypedArrayConstructors) {
+ assertEq(constructor.prototype.map.length, 1);
+
+ // Basic tests.
+ assertDeepEq(new constructor([1, 3, 5]).map(v => v * 2), new constructor([2,6,10]));
+ assertDeepEq(new constructor([-1, 13, 5]).map(v => v - 2), new constructor([-3, 11, 3]));
+ assertDeepEq(new constructor(10).map(v => v), new constructor(10));
+ assertDeepEq(new constructor().map(v => v + 1), new constructor);
+ assertDeepEq(new constructor([1,2,3]).map(v => v), new constructor([1,2,3]));
+
+ var arr = new constructor([1, 2, 3, 4, 5]);
+ var sum = 0;
+ var count = 0;
+ assertDeepEq(arr.map((v, k, o) => {
+ count++;
+ sum += v;
+ assertEq(k, v - 1);
+ assertEq(o, arr);
+ return v;
+ }), arr);
+ assertEq(sum, 15);
+ assertEq(count, 5);
+
+ // Test that changing elements that have been visited does not affect the result.
+ var changeArr = new constructor([1,2,3,4,5]);
+ assertDeepEq(arr.map((v,k) => {
+ changeArr[k] = v + 1;
+ return v;
+ }), new constructor([1,2,3,4,5]));
+
+ // Tests for `thisArg` argument.
+ function assertThisArg(thisArg, thisValue) {
+ // In sloppy mode, `this` could be global object or a wrapper of `thisArg`.
+ assertDeepEq(arr.map(function(v) {
+ assertDeepEq(this, thisValue);
+ return v;
+ }, thisArg), arr);
+
+ // In strict mode, `this` strictly equals `thisArg`.
+ assertDeepEq(arr.map(function(v) {
+ "use strict";
+ assertDeepEq(this, thisArg);
+ return v;
+ }, thisArg), arr);
+
+ // Passing `thisArg` has no effect if callback is an arrow function.
+ var self = this;
+ assertDeepEq(arr.map((v) => {
+ assertEq(this, self);
+ return v;
+ }, thisArg), arr);
+ }
+ assertThisArg([1, 2, 3], [1, 2, 3]);
+ assertThisArg(Object, Object);
+ assertThisArg(1, Object(1));
+ assertThisArg("1", Object("1"));
+ assertThisArg(false, Object(false));
+ assertThisArg(undefined, this);
+ assertThisArg(null, this);
+
+ // Throw an exception in the callback.
+ var sum = 0;
+ var count = 0;
+ var thrown = false;
+ try {
+ arr.map((v, k, o) => {
+ count++;
+ sum += v;
+ assertEq(k, v - 1);
+ assertEq(o, arr);
+ if (v === 3) {
+ throw "map";
+ }
+ return v;
+ })
+ } catch(e) {
+ assertEq(e, "map");
+ thrown = true;
+ }
+ assertEq(thrown, true);
+ assertEq(sum, 6);
+ assertEq(count, 3);
+
+ // There is no callback or callback is not a function.
+ assertThrowsInstanceOf(() => {
+ arr.map();
+ }, TypeError);
+ var invalidCallbacks = [undefined, null, 1, false, "", Symbol(), [], {}, /./];
+ invalidCallbacks.forEach(callback => {
+ assertThrowsInstanceOf(() => {
+ arr.map(callback);
+ }, TypeError);
+ })
+
+ // Callback is a generator.
+ arr.map(function*(){
+ throw "This line will not be executed";
+ });
+
+ // Called from other globals.
+ if (typeof newGlobal === "function") {
+ var map = newGlobal()[constructor.name].prototype.map;
+ var sum = 0;
+ assertDeepEq(map.call(new constructor([1, 2, 3]), v => sum += v), new constructor([1,3,6]));
+ assertEq(sum, 6);
+ }
+
+ // Throws if `this` isn't a TypedArray.
+ var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+ new Proxy(new constructor(), {})];
+ invalidReceivers.forEach(invalidReceiver => {
+ assertThrowsInstanceOf(() => {
+ constructor.prototype.filter.call(invalidReceiver, () => true);
+ }, TypeError, "Assert that map fails if this value is not a TypedArray");
+ });
+
+ // Test that the length getter is never called.
+ assertDeepEq(Object.defineProperty(new constructor([1, 2, 3]), "length", {
+ get() {
+ throw new Error("length accessor called");
+ }
+ }).map((b) => b), new constructor([1,2,3]));
+}
+
+// Test For TypedArray#filter.
+for (var constructor of anyTypedArrayConstructors) {
+ assertEq(constructor.prototype.filter.length, 1)
+
+ // Basic tests.
+ assertDeepEq(new constructor([1,2,3]).filter(x => x == x), new constructor([1,2,3]));
+ assertDeepEq(new constructor([1,2,3,4]).filter(x => x % 2 == 0), new constructor([2,4]));
+ assertDeepEq(new constructor([1,2,3,4,5]).filter(x => x < 4), new constructor([1,2,3]));
+ assertDeepEq(new constructor().filter(x => x * 2 == 4), new constructor());
+
+ var arr = new constructor([1,2,3,4,5]);
+ var sum = 0;
+ var count = 0;
+ assertDeepEq(arr.filter((v, k, o) => {
+ count++;
+ sum += v;
+ assertEq(k, v - 1);
+ assertEq(o, arr);
+ return (v < 4);
+ }), new constructor([1,2,3]));
+ assertEq(sum, 15);
+ assertEq(count, 5);
+
+ // Test that changing elements that have been visited does not affect the result.
+ var changeArr = new constructor([1,2,3,4,5]);
+ assertDeepEq(arr.filter((v,k) => {
+ changeArr[k] = v + 1;
+ return true;
+ }), new constructor([1,2,3,4,5]));
+
+ // Tests for `thisArg` argument.
+ function assertThisArg(thisArg, thisValue) {
+ // In sloppy mode, `this` could be global object or a wrapper of `thisArg`.
+ assertDeepEq(arr.filter(function(v) {
+ assertDeepEq(this, thisValue);
+ return v;
+ }, thisArg), arr);
+
+ // In strict mode, `this` strictly equals `thisArg`.
+ assertDeepEq(arr.filter(function(v) {
+ "use strict";
+ assertDeepEq(this, thisArg);
+ return v;
+ }, thisArg), arr);
+
+ // Passing `thisArg` has no effect if callback is an arrow function.
+ var self = this;
+ assertDeepEq(arr.filter((v) => {
+ assertEq(this, self);
+ return v;
+ }, thisArg), arr);
+ }
+ assertThisArg([1, 2, 3], [1, 2, 3]);
+ assertThisArg(Object, Object);
+ assertThisArg(1, Object(1));
+ assertThisArg("1", Object("1"));
+ assertThisArg(false, Object(false));
+ assertThisArg(undefined, this);
+ assertThisArg(null, this);
+
+ // Throw an exception in the callback.
+ var sum = 0;
+ var count = 0;
+ var thrown = false;
+ try {
+ arr.filter((v, k, o) => {
+ count++;
+ sum += v;
+ assertEq(k, v - 1);
+ assertEq(o, arr);
+ if (v === 3) {
+ throw "filter";
+ }
+ return v;
+ })
+ } catch(e) {
+ assertEq(e, "filter");
+ thrown = true;
+ }
+ assertEq(thrown, true);
+ assertEq(sum, 6);
+ assertEq(count, 3);
+
+ // There is no callback or callback is not a function.
+ assertThrowsInstanceOf(() => {
+ arr.filter();
+ }, TypeError);
+ var invalidCallbacks = [undefined, null, 1, false, "", Symbol(), [], {}, /./];
+ invalidCallbacks.forEach(callback => {
+ assertThrowsInstanceOf(() => {
+ arr.filter(callback);
+ }, TypeError);
+ })
+
+ // Callback is a generator.
+ arr.filter(function*(){
+ throw "This line will not be executed";
+ });
+
+ // Called from other globals.
+ if (typeof newGlobal === "function") {
+ var filter = newGlobal()[constructor.name].prototype.filter;
+ var sum = 0;
+ assertDeepEq(filter.call(new constructor([1, 2, 3]), v => {sum += v; return true}),
+ new constructor([1,2,3]));
+ assertEq(sum, 6);
+ }
+
+ // Throws if `this` isn't a TypedArray.
+ var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+ new Proxy(new constructor(), {})];
+ invalidReceivers.forEach(invalidReceiver => {
+ assertThrowsInstanceOf(() => {
+ constructor.prototype.filter.call(invalidReceiver, () => true);
+ }, TypeError, "Assert that filter fails if this value is not a TypedArray");
+ });
+
+ // Test that the length getter is never called.
+ assertDeepEq(Object.defineProperty(new constructor([1, 2, 3]), "length", {
+ get() {
+ throw new Error("length accessor called");
+ }
+ }).filter((b) => true), new constructor([1,2,3]));
+}
+
+// Test that changing Array.prototype[Symbol.iterator] does not affect the
+// behaviour of filter. See https://bugzilla.mozilla.org/show_bug.cgi?id=1121936#c18
+// for more details.
+
+var arr = new Uint16Array([1,2,3]);
+
+// save
+var old = Array.prototype[Symbol.iterator];
+
+Array.prototype[Symbol.iterator] = () => { throw new Error("unreachable"); };
+assertDeepEq(arr.filter(v => true), arr);
+
+// restore
+Array.prototype[Symbol.iterator] = old;
+
+// Test that defining accessors on Array.prototype doesn't affect the behaviour
+// of filter. See https://bugzilla.mozilla.org/show_bug.cgi?id=1121936#c18
+// for more details.
+Object.defineProperty(Array.prototype, 0, {configurable: true, get: function() { return 1; }, set: function() { this.b = 1; }});
+assertDeepEq(new Uint16Array([1,2,3]).filter(v => true), new Uint16Array([1,2,3]));
+delete Array.prototype[0];
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/map-species.js b/js/src/tests/ecma_6/TypedArray/map-species.js
new file mode 100644
index 000000000..8353d914b
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/map-species.js
@@ -0,0 +1,56 @@
+function test(constructor, constructor2, from=[1, 2, 3, 4, 5], to=[2, 4, 6, 8, 10]) {
+ var modifiedConstructor = new constructor(from);
+ modifiedConstructor.constructor = constructor2;
+ assertDeepEq(modifiedConstructor.map(x => x * 2), new constructor2(to));
+ var modifiedSpecies = new constructor(from);
+ modifiedSpecies.constructor = { [Symbol.species]: constructor2 };
+ assertDeepEq(modifiedSpecies.map(x => x * 2), new constructor2(to));
+}
+
+// same size, same sign
+
+test(Int8Array, Uint8Array);
+test(Int8Array, Uint8ClampedArray);
+
+test(Uint8Array, Int8Array);
+test(Uint8Array, Uint8ClampedArray);
+
+test(Uint8ClampedArray, Int8Array);
+test(Uint8ClampedArray, Uint8Array);
+
+test(Int16Array, Uint16Array);
+test(Uint16Array, Int16Array);
+
+test(Int32Array, Uint32Array);
+test(Uint32Array, Int32Array);
+
+// same size, different sign
+
+test(Int8Array, Uint8Array, [-1, -2, -3, -4, -5], [0xFE, 0xFC, 0xFA, 0xF8, 0xF6]);
+test(Int8Array, Uint8ClampedArray, [-1, -2, -3, -4, -5], [0, 0, 0, 0, 0]);
+
+test(Uint8Array, Int8Array, [0xFF, 0xFE, 0xFD, 0xFC, 0xFB], [-2, -4, -6, -8, -10]);
+test(Uint8ClampedArray, Int8Array, [0xFF, 0xFE, 0xFD, 0xFC, 0xFB], [-2, -4, -6, -8, -10]);
+
+test(Int16Array, Uint16Array, [-1, -2, -3, -4, -5], [0xFFFE, 0xFFFC, 0xFFFA, 0xFFF8, 0xFFF6]);
+test(Uint16Array, Int16Array, [0xFFFF, 0xFFFE, 0xFFFD, 0xFFFC, 0xFFFB], [-2, -4, -6, -8, -10]);
+
+test(Int32Array, Uint32Array, [-1, -2, -3, -4, -5], [0xFFFFFFFE, 0xFFFFFFFC, 0xFFFFFFFA, 0xFFFFFFF8, 0xFFFFFFF6]);
+test(Uint32Array, Int32Array, [0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFC, 0xFFFFFFFB], [-2, -4, -6, -8, -10]);
+
+// different size
+
+test(Uint8Array, Uint16Array);
+test(Uint16Array, Uint8Array);
+
+test(Uint8Array, Uint32Array);
+test(Uint32Array, Uint8Array);
+
+test(Uint16Array, Uint32Array);
+test(Uint32Array, Uint16Array);
+
+test(Float32Array, Float64Array);
+test(Float64Array, Float32Array);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/object-defineproperty.js b/js/src/tests/ecma_6/TypedArray/object-defineproperty.js
new file mode 100644
index 000000000..1f25f6552
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/object-defineproperty.js
@@ -0,0 +1,68 @@
+var obj = new Int32Array(2);
+obj[0] = 100;
+
+var throws = [
+ // Disallow accessors
+ {get: undefined},
+ {set: undefined},
+ {get: undefined, set: undefined},
+ {get: function() {}},
+ {set: function() {}},
+ {get: function() {}, set: function() {}},
+
+ {configurable: true},
+ {enumerable: false},
+ {writable: false},
+
+ {configurable: true, writable: true},
+ {enumerable: false, configurable: false},
+
+ {configurable: true, value: 15}
+];
+
+for (var desc of throws) {
+ assertThrowsInstanceOf(function() { Object.defineProperty(obj, 0, desc); }, TypeError);
+ assertThrowsInstanceOf(function() { Object.defineProperties(obj, {0: desc}); }, TypeError);
+}
+
+Object.defineProperty(obj, 0, {});
+Object.defineProperty(obj, 0, {configurable: false});
+Object.defineProperty(obj, 0, {enumerable: true});
+Object.defineProperty(obj, 0, {writable: true});
+
+assertEq(obj[0], 100);
+
+Object.defineProperty(obj, 0, {configurable: false, value: 15});
+assertEq(obj[0], 15);
+Object.defineProperty(obj, 0, {enumerable: true, value: 16});
+assertEq(obj[0], 16);
+Object.defineProperty(obj, 0, {writable: true, value: 17});
+assertEq(obj[0], 17);
+Object.defineProperty(obj, 0, {value: 18});
+assertEq(obj[0], 18);
+
+var desc = Object.getOwnPropertyDescriptor(obj, 0);
+assertEq(desc.configurable, false);
+assertEq(desc.enumerable, true);
+assertEq(desc.writable, true);
+assertEq(desc.value, 18);
+assertEq('get' in desc, false);
+assertEq('set' in desc, false);
+
+Object.defineProperties(obj, {0: {value: 20}, 1: {value: 42}});
+assertEq(obj[0], 20);
+assertEq(obj[1], 42);
+
+anyTypedArrayConstructors.forEach(constructor => {
+ var obj = new constructor(4);
+ obj[0] = 100;
+ obj[1] = 200;
+
+ for (var v of [20, 300, -10, Math.pow(2, 32), -Math.pow(2, 32), NaN]) {
+ Object.defineProperty(obj, 0, {value: v});
+ obj[1] = v;
+ assertEq(obj[0], obj[1]);
+ }
+});
+
+reportCompare(true, true, "test");
diff --git a/js/src/tests/ecma_6/TypedArray/of.js b/js/src/tests/ecma_6/TypedArray/of.js
new file mode 100644
index 000000000..fffc06325
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/of.js
@@ -0,0 +1,92 @@
+for (var constructor of anyTypedArrayConstructors) {
+ assertEq(constructor.of.length, 0);
+
+ assertDeepEq(Object.getOwnPropertyDescriptor(constructor.__proto__, "of"), {
+ value: constructor.of,
+ writable: true,
+ enumerable: false,
+ configurable: true
+ });
+
+ // Basic tests.
+ assertEq(constructor.of().constructor, constructor);
+ assertEq(constructor.of() instanceof constructor, true);
+ assertDeepEq(constructor.of(10), new constructor([10]));
+ assertDeepEq(constructor.of(1, 2, 3), new constructor([1, 2, 3]));
+ assertDeepEq(constructor.of("1", "2", "3"), new constructor([1, 2, 3]));
+
+ // This method can't be transplanted to other constructors.
+ assertThrows(() => constructor.of.call(Array), TypeError);
+ assertThrows(() => constructor.of.call(Array, 1, 2, 3), TypeError);
+
+ var hits = 0;
+ assertDeepEq(constructor.of.call(function(len) {
+ assertEq(arguments.length, 1);
+ assertEq(len, 3);
+ hits++;
+ return new constructor(len);
+ }, 10, 20, 30), new constructor([10, 20, 30]));
+ assertEq(hits, 1);
+
+ // Behavior across compartments.
+ if (typeof newGlobal === "function") {
+ var newC = newGlobal()[constructor.name];
+ assertEq(newC.of() instanceof newC, true);
+ assertEq(newC.of() instanceof constructor, false);
+ assertEq(newC.of.call(constructor) instanceof constructor, true);
+ }
+
+ // Throws if `this` isn't a constructor.
+ var invalidConstructors = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+ constructor.of, () => {}];
+ invalidConstructors.forEach(C => {
+ assertThrowsInstanceOf(() => {
+ constructor.of.call(C);
+ }, TypeError);
+ });
+
+ // Throw if `this` is a method definition or a getter/setter function.
+ assertThrowsInstanceOf(() => {
+ constructor.of.call({method() {}}.method);
+ }, TypeError);
+ assertThrowsInstanceOf(() => {
+ constructor.of.call(Object.getOwnPropertyDescriptor({get getter() {}}, "getter").get);
+ }, TypeError);
+
+ // Generators are not legal constructors.
+ assertThrowsInstanceOf(() => {
+ constructor.of.call(function*(len) {
+ return len;
+ }, "a")
+ }, TypeError);
+
+ // An exception might be thrown in a strict assignment to the new object's indexed properties.
+ assertThrowsInstanceOf(() => {
+ constructor.of.call(function() {
+ return {get 0() {}};
+ }, "a");
+ }, TypeError);
+
+ assertThrowsInstanceOf(() => {
+ constructor.of.call(function() {
+ return Object("1");
+ }, "a");
+ }, TypeError);
+
+ assertThrowsInstanceOf(() => {
+ constructor.of.call(function() {
+ return Object.create({
+ set 0(v) {
+ throw new TypeError;
+ }
+ });
+ }, "a");
+ }, TypeError);
+}
+
+for (let constructor of anyTypedArrayConstructors.filter(isFloatConstructor)) {
+ assertDeepEq(constructor.of(0.1, null, undefined, NaN), new constructor([0.1, 0, NaN, NaN]));
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/prototype-constructor-identity.js b/js/src/tests/ecma_6/TypedArray/prototype-constructor-identity.js
new file mode 100644
index 000000000..10324f572
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/prototype-constructor-identity.js
@@ -0,0 +1,55 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var gTestfile = 'prototype-constructor-identity.js';
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 896116;
+var summary =
+ "Typed array prototypes/constructors should be largely empty, inheriting "
+ "most functionality from %TypedArray% and %TypedArray%.prototype";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+var TypedArray = Object.getPrototypeOf(Int8Array);
+
+assertEq(TypedArray !== Function.prototype, true,
+ "%TypedArray% should be in constructors' [[Prototype]] chains");
+assertEq(Object.getPrototypeOf(TypedArray), Function.prototype,
+ "%TypedArray%.prototype should inherit from Function.prototype");
+
+assertEq(TypedArray.prototype.constructor, TypedArray,
+ "bad %TypedArray%.prototype.constructor");
+
+// Check a few different functions we implement are here, as a sanity check.
+var typedArrayProps = Object.getOwnPropertyNames(TypedArray.prototype);
+assertEq(typedArrayProps.indexOf("copyWithin") >= 0, true);
+assertEq(typedArrayProps.indexOf("subarray") >= 0, true);
+assertEq(typedArrayProps.indexOf("set") >= 0, true);
+
+anyTypedArrayConstructors.forEach(function(ctor) {
+ assertEq(Object.getPrototypeOf(ctor), TypedArray);
+
+ var proto = ctor.prototype;
+
+ // Inherited functions aren't present.
+ var props = Object.getOwnPropertyNames(proto).sort();
+ assertEq(props[0], "BYTES_PER_ELEMENT");
+ assertEq(props[1], "constructor");
+ assertEq(props.length, 2);
+
+ // The inheritance chain should be set up properly.
+ assertEq(Object.getPrototypeOf(proto), TypedArray.prototype,
+ "prototype should inherit from %TypedArray%.prototype");
+});
+
+/******************************************************************************/
+
+reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_6/TypedArray/reduce-and-reduceRight.js b/js/src/tests/ecma_6/TypedArray/reduce-and-reduceRight.js
new file mode 100644
index 000000000..21a7d99e9
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/reduce-and-reduceRight.js
@@ -0,0 +1,188 @@
+// Tests for TypedArray#reduce.
+for (var constructor of anyTypedArrayConstructors) {
+ assertEq(constructor.prototype.reduce.length, 1);
+
+ // Basic tests.
+ var arr = new constructor([1, 2, 3, 4, 5]);
+
+ assertEq(arr.reduce((previous, current) => previous + current), 15);
+ assertEq(arr.reduce((previous, current) => current - previous), 3);
+
+ var count = 0;
+ var sum = 0;
+ assertEq(arr.reduce((previous, current, index, array) => {
+ count++;
+ sum += current;
+ assertEq(current - 1, index);
+ assertEq(current, arr[index]);
+ assertEq(array, arr);
+ return previous * current;
+ }), 120);
+ assertEq(count, 4);
+ assertEq(sum, 14);
+
+ // Tests for `initialValue` argument.
+ assertEq(arr.reduce((previous, current) => previous + current, -15), 0);
+ assertEq(arr.reduce((previous, current) => previous + current, ""), "12345");
+ assertDeepEq(arr.reduce((previous, current) => previous.concat(current), []), [1, 2, 3, 4, 5]);
+
+ // Tests for `this` value.
+ var global = this;
+ arr.reduce(function(){
+ assertEq(this, global);
+ });
+ arr.reduce(function(){
+ "use strict";
+ assertEq(this, undefined);
+ });
+ arr.reduce(() => assertEq(this, global));
+
+ // Throw an exception in the callback.
+ var count = 0;
+ var sum = 0;
+ assertThrowsInstanceOf(() => {
+ arr.reduce((previous, current, index, array) => {
+ count++;
+ sum += current;
+ if (index === 3) {
+ throw TypeError("reduce");
+ }
+ })
+ }, TypeError);
+ assertEq(count, 3);
+ assertEq(sum, 9);
+
+ // There is no callback or callback is not a function.
+ assertThrowsInstanceOf(() => {
+ arr.reduce();
+ }, TypeError);
+ var invalidCallbacks = [undefined, null, 1, false, "", Symbol(), [], {}, /./];
+ invalidCallbacks.forEach(callback => {
+ assertThrowsInstanceOf(() => {
+ arr.reduce(callback);
+ }, TypeError);
+ })
+
+ // Callback is a generator.
+ arr.reduce(function*(){
+ throw "This line will not be executed";
+ });
+
+ // Called from other globals.
+ if (typeof newGlobal === "function") {
+ var reduce = newGlobal()[constructor.name].prototype.reduce;
+ assertEq(reduce.call(arr, (previous, current) => Math.min(previous, current)), 1);
+ }
+
+ // Throws if `this` isn't a TypedArray.
+ var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+ new Proxy(new constructor(3), {})];
+ invalidReceivers.forEach(invalidReceiver => {
+ assertThrowsInstanceOf(() => {
+ constructor.prototype.reduce.call(invalidReceiver, () => {});
+ }, TypeError, "Assert that reduce fails if this value is not a TypedArray");
+ });
+
+ // Test that the length getter is never called.
+ assertEq(Object.defineProperty(arr, "length", {
+ get() {
+ throw new Error("length accessor called");
+ }
+ }).reduce((previous, current) => Math.max(previous, current)), 5);
+}
+
+// Tests for TypedArray#reduceRight.
+for (var constructor of anyTypedArrayConstructors) {
+ assertEq(constructor.prototype.reduceRight.length, 1);
+
+ // Basic tests.
+ var arr = new constructor([1, 2, 3, 4, 5]);
+
+ assertEq(arr.reduceRight((previous, current) => previous + current), 15);
+ assertEq(arr.reduceRight((previous, current) => current - previous), 3);
+
+ var count = 0;
+ var sum = 0;
+ assertEq(arr.reduceRight((previous, current, index, array) => {
+ count++;
+ sum += current;
+ assertEq(current - 1, index);
+ assertEq(current, arr[index]);
+ assertEq(array, arr);
+ return previous * current;
+ }), 120);
+ assertEq(count, 4);
+ assertEq(sum, 10);
+
+ // Tests for `initialValue` argument.
+ assertEq(arr.reduceRight((previous, current) => previous + current, -15), 0);
+ assertEq(arr.reduceRight((previous, current) => previous + current, ""), "54321");
+ assertDeepEq(arr.reduceRight((previous, current) => previous.concat(current), []), [5, 4, 3, 2, 1]);
+
+ // Tests for `this` value.
+ var global = this;
+ arr.reduceRight(function(){
+ assertEq(this, global);
+ });
+ arr.reduceRight(function(){
+ "use strict";
+ assertEq(this, undefined);
+ });
+ arr.reduceRight(() => assertEq(this, global));
+
+ // Throw an exception in the callback.
+ var count = 0;
+ var sum = 0;
+ assertThrowsInstanceOf(() => {
+ arr.reduceRight((previous, current, index, array) => {
+ count++;
+ sum += current;
+ if (index === 1) {
+ throw TypeError("reduceRight");
+ }
+ })
+ }, TypeError);
+ assertEq(count, 3);
+ assertEq(sum, 9);
+
+ // There is no callback or callback is not a function.
+ assertThrowsInstanceOf(() => {
+ arr.reduceRight();
+ }, TypeError);
+ var invalidCallbacks = [undefined, null, 1, false, "", Symbol(), [], {}, /./];
+ invalidCallbacks.forEach(callback => {
+ assertThrowsInstanceOf(() => {
+ arr.reduceRight(callback);
+ }, TypeError);
+ })
+
+ // Callback is a generator.
+ arr.reduceRight(function*(){
+ throw "This line will not be executed";
+ });
+
+ // Called from other globals.
+ if (typeof newGlobal === "function") {
+ var reduceRight = newGlobal()[constructor.name].prototype.reduceRight;
+ assertEq(reduceRight.call(arr, (previous, current) => Math.min(previous, current)), 1);
+ }
+
+ // Throws if `this` isn't a TypedArray.
+ var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+ new Proxy(new constructor(3), {})];
+ invalidReceivers.forEach(invalidReceiver => {
+ assertThrowsInstanceOf(() => {
+ constructor.prototype.reduceRight.call(invalidReceiver, () => {});
+ }, TypeError, "Assert that reduceRight fails if this value is not a TypedArray");
+ });
+
+ // Test that the length getter is never called.
+ assertEq(Object.defineProperty(arr, "length", {
+ get() {
+ throw new Error("length accessor called");
+ }
+ }).reduceRight((previous, current) => Math.max(previous, current)), 5);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/reverse.js b/js/src/tests/ecma_6/TypedArray/reverse.js
new file mode 100644
index 000000000..f8146506c
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/reverse.js
@@ -0,0 +1,38 @@
+for (var constructor of anyTypedArrayConstructors) {
+ assertDeepEq(constructor.prototype.reverse.length, 0);
+
+ assertDeepEq(new constructor().reverse(), new constructor());
+ assertDeepEq(new constructor(10).reverse(), new constructor(10));
+ assertDeepEq(new constructor([]).reverse(), new constructor([]));
+ assertDeepEq(new constructor([1]).reverse(), new constructor([1]));
+ assertDeepEq(new constructor([1, 2]).reverse(), new constructor([2, 1]));
+ assertDeepEq(new constructor([1, 2, 3]).reverse(), new constructor([3, 2, 1]));
+ assertDeepEq(new constructor([1, 2, 3, 4]).reverse(), new constructor([4, 3, 2, 1]));
+ assertDeepEq(new constructor([1, 2, 3, 4, 5]).reverse(), new constructor([5, 4, 3, 2, 1]));
+ assertDeepEq(new constructor([.1, .2, .3]).reverse(), new constructor([.3, .2, .1]));
+
+ // Called from other globals.
+ if (typeof newGlobal === "function") {
+ var reverse = newGlobal()[constructor.name].prototype.reverse;
+ assertDeepEq(reverse.call(new constructor([3, 2, 1])), new constructor([1, 2, 3]));
+ }
+
+ // Throws if `this` isn't a TypedArray.
+ var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+ new Proxy(new constructor(), {})];
+ invalidReceivers.forEach(invalidReceiver => {
+ assertThrowsInstanceOf(() => {
+ constructor.prototype.reverse.call(invalidReceiver);
+ }, TypeError, "Assert that reverse fails if this value is not a TypedArray");
+ });
+
+ // Test that the length getter is never called.
+ Object.defineProperty(new constructor([1, 2, 3]), "length", {
+ get() {
+ throw new Error("length accessor called");
+ }
+ }).reverse();
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/seal-and-freeze.js b/js/src/tests/ecma_6/TypedArray/seal-and-freeze.js
new file mode 100644
index 000000000..f3919f7ea
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/seal-and-freeze.js
@@ -0,0 +1,48 @@
+"use strict";
+
+// Seal
+assertEq(Object.isSealed(new Int32Array(2)), false);
+assertEq(Object.isSealed(new Int32Array(0)), false);
+
+var array = new Int32Array(0);
+Object.preventExtensions(array);
+assertEq(Object.isSealed(array), true);
+
+array = new Int32Array(1);
+array.b = "test";
+Object.preventExtensions(array);
+assertEq(Object.isSealed(array), false);
+Object.defineProperty(array, "b", {configurable: false});
+assertEq(Object.isSealed(array), true);
+
+array = new Int32Array(2);
+array.b = "test";
+Object.seal(array);
+assertEq(Object.isSealed(array), true);
+assertThrowsInstanceOf(() => array.c = 15, TypeError);
+
+// Freeze
+assertEq(Object.isFrozen(new Int32Array(2)), false);
+assertEq(Object.isFrozen(new Int32Array(0)), false);
+
+// Empty non-extensible typed-array is trvially frozen
+var array = new Int32Array(0);
+Object.preventExtensions(array);
+assertEq(Object.isFrozen(array), true);
+
+array = new Int32Array(0);
+array.b = "test";
+assertEq(Object.isFrozen(array), false);
+Object.preventExtensions(array);
+assertEq(Object.isFrozen(array), false);
+Object.defineProperty(array, "b", {configurable: false, writable: false});
+assertEq(Object.isFrozen(array), true);
+
+// Non-empty typed arrays can never be frozen, because the elements stay writable
+array = new Int32Array(1);
+assertThrowsInstanceOf(() => Object.freeze(array), TypeError);
+assertEq(Object.isExtensible(array), false);
+assertEq(Object.isFrozen(array), false);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/set-negative-offset.js b/js/src/tests/ecma_6/TypedArray/set-negative-offset.js
new file mode 100644
index 000000000..6d9c45ffb
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/set-negative-offset.js
@@ -0,0 +1,35 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var gTestfile = "set-negative-offset.js";
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 1140752;
+var summary =
+ "%TypedArray%.prototype.set must throw a RangeError when passed a negative " +
+ "offset";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+try
+{
+ new Uint8Array().set([], -1);
+ throw new Error("didn't throw at all");
+}
+catch (e)
+{
+ assertEq(e instanceof RangeError, true,
+ "expected RangeError, instead got: " + e);
+}
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_6/TypedArray/set-same-buffer-different-source-target-types.js b/js/src/tests/ecma_6/TypedArray/set-same-buffer-different-source-target-types.js
new file mode 100644
index 000000000..9084ce883
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/set-same-buffer-different-source-target-types.js
@@ -0,0 +1,41 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var gTestfile = "set-same-buffer-different-source-target-types.js";
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 896116;
+var summary =
+ "When setting a typed array from an overlapping typed array of different " +
+ "element type, copy the source elements into properly-sized temporary " +
+ "memory, and properly copy them into the target without overflow (of " +
+ "either source *or* target) when finished";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+// smallest 2**n triggering segfaults in a pre-patch build locally, then
+// quadrupled in case the boundary ever changes, or is different in some other
+// memory-allocating implementation
+var srclen = 65536;
+
+var ta = new Uint8Array(srclen * Float64Array.BYTES_PER_ELEMENT);
+var ta2 = new Float64Array(ta.buffer, 0, srclen);
+ta.set(ta2);
+
+// This test mostly exists to check for no crash above, but it's worth testing
+// for no uninitialized memory (in case of buffer overflow) being copied into
+// the array, too.
+for (var i = 0, len = ta.length; i < len; i++)
+ assertEq(ta[i], 0, "zero-bits double should convert to zero");
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_6/TypedArray/set.js b/js/src/tests/ecma_6/TypedArray/set.js
new file mode 100644
index 000000000..2af5a129a
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/set.js
@@ -0,0 +1,21 @@
+const TypedArrayPrototype = Object.getPrototypeOf(Int8Array.prototype);
+
+// %TypedArrayPrototype% has an own "set" function property.
+assertEq(TypedArrayPrototype.hasOwnProperty("set"), true);
+assertEq(typeof TypedArrayPrototype.set, "function");
+
+// The concrete TypedArray prototypes do not have an own "set" property.
+assertEq(anyTypedArrayConstructors.every(c => !c.hasOwnProperty("set")), true);
+
+assertDeepEq(Object.getOwnPropertyDescriptor(TypedArrayPrototype, "set"), {
+ value: TypedArrayPrototype.set,
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+assertEq(TypedArrayPrototype.set.name, "set");
+assertEq(TypedArrayPrototype.set.length, 1);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/shell.js b/js/src/tests/ecma_6/TypedArray/shell.js
new file mode 100644
index 000000000..2fb0ab8f1
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/shell.js
@@ -0,0 +1,114 @@
+(function(global) {
+ "use strict";
+
+ const {
+ Float32Array, Float64Array, Object, Reflect, SharedArrayBuffer, WeakMap,
+ assertEq
+ } = global;
+ const {
+ apply: Reflect_apply,
+ construct: Reflect_construct,
+ } = Reflect;
+ const {
+ get: WeakMap_prototype_get,
+ has: WeakMap_prototype_has,
+ } = WeakMap.prototype;
+
+ const sharedConstructors = new WeakMap();
+
+ // Synthesize a constructor for a shared memory array from the constructor
+ // for unshared memory. This has "good enough" fidelity for many uses. In
+ // cases where it's not good enough, call isSharedConstructor for local
+ // workarounds.
+ function sharedConstructor(baseConstructor) {
+ // Create SharedTypedArray as a subclass of %TypedArray%, following the
+ // built-in %TypedArray% subclasses.
+ class SharedTypedArray extends Object.getPrototypeOf(baseConstructor) {
+ constructor(...args) {
+ var array = Reflect_construct(baseConstructor, args);
+ var {buffer, byteOffset, length} = array;
+ var sharedBuffer = new SharedArrayBuffer(buffer.byteLength);
+ var sharedArray = Reflect_construct(baseConstructor,
+ [sharedBuffer, byteOffset, length],
+ new.target);
+ for (var i = 0; i < length; i++)
+ sharedArray[i] = array[i];
+ assertEq(sharedArray.buffer, sharedBuffer);
+ return sharedArray;
+ }
+ }
+
+ // 22.2.5.1 TypedArray.BYTES_PER_ELEMENT
+ Object.defineProperty(SharedTypedArray, "BYTES_PER_ELEMENT",
+ {__proto__: null, value: baseConstructor.BYTES_PER_ELEMENT});
+
+ // 22.2.6.1 TypedArray.prototype.BYTES_PER_ELEMENT
+ Object.defineProperty(SharedTypedArray.prototype, "BYTES_PER_ELEMENT",
+ {__proto__: null, value: baseConstructor.BYTES_PER_ELEMENT});
+
+ // Share the same name with the base constructor to avoid calling
+ // isSharedConstructor() in multiple places.
+ Object.defineProperty(SharedTypedArray, "name",
+ {__proto__: null, value: baseConstructor.name});
+
+ sharedConstructors.set(SharedTypedArray, baseConstructor);
+
+ return SharedTypedArray;
+ }
+
+ /**
+ * All TypedArray constructors for unshared memory.
+ */
+ const typedArrayConstructors = Object.freeze([
+ Int8Array,
+ Uint8Array,
+ Uint8ClampedArray,
+ Int16Array,
+ Uint16Array,
+ Int32Array,
+ Uint32Array,
+ Float32Array,
+ Float64Array,
+ ]);
+
+ /**
+ * All TypedArray constructors for shared memory.
+ */
+ const sharedTypedArrayConstructors = Object.freeze(
+ typeof SharedArrayBuffer === "function"
+ ? typedArrayConstructors.map(sharedConstructor)
+ : []
+ );
+
+ /**
+ * All TypedArray constructors for unshared and shared memory.
+ */
+ const anyTypedArrayConstructors = Object.freeze([
+ ...typedArrayConstructors, ...sharedTypedArrayConstructors,
+ ]);
+
+ /**
+ * Returns `true` if `constructor` is a TypedArray constructor for shared
+ * memory.
+ */
+ function isSharedConstructor(constructor) {
+ return Reflect_apply(WeakMap_prototype_has, sharedConstructors, [constructor]);
+ }
+
+ /**
+ * Returns `true` if `constructor` is a TypedArray constructor for shared
+ * or unshared memory, with an underlying element type of either Float32 or
+ * Float64.
+ */
+ function isFloatConstructor(constructor) {
+ if (isSharedConstructor(constructor))
+ constructor = Reflect_apply(WeakMap_prototype_get, sharedConstructors, [constructor]);
+ return constructor == Float32Array || constructor == Float64Array;
+ }
+
+ global.typedArrayConstructors = typedArrayConstructors;
+ global.sharedTypedArrayConstructors = sharedTypedArrayConstructors;
+ global.anyTypedArrayConstructors = anyTypedArrayConstructors;
+ global.isSharedConstructor = isSharedConstructor;
+ global.isFloatConstructor = isFloatConstructor;
+})(this);
diff --git a/js/src/tests/ecma_6/TypedArray/slice-species.js b/js/src/tests/ecma_6/TypedArray/slice-species.js
new file mode 100644
index 000000000..8a03f2f6e
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/slice-species.js
@@ -0,0 +1,49 @@
+for (var constructor of typedArrayConstructors) {
+ // Basic tests for our SpeciesConstructor implementation.
+ var undefConstructor = new constructor(2);
+ undefConstructor.constructor = undefined;
+ assertDeepEq(undefConstructor.slice(1), new constructor(1));
+
+ assertThrowsInstanceOf(() => {
+ var strConstructor = new constructor;
+ strConstructor.constructor = "not a constructor";
+ strConstructor.slice(123);
+ }, TypeError, "Assert that we have an invalid constructor");
+
+ // If obj.constructor[@@species] is undefined or null then the default
+ // constructor is used.
+ var mathConstructor = new constructor(8);
+ mathConstructor.constructor = Math.sin;
+ assertDeepEq(mathConstructor.slice(4), new constructor(4));
+
+ var undefSpecies = new constructor(2);
+ undefSpecies.constructor = { [Symbol.species]: undefined };
+ assertDeepEq(undefSpecies.slice(1), new constructor(1));
+
+ var nullSpecies = new constructor(2);
+ nullSpecies.constructor = { [Symbol.species]: null };
+ assertDeepEq(nullSpecies.slice(1), new constructor(1));
+
+ // If obj.constructor[@@species] is different constructor, it should be
+ // used.
+ for (var constructor2 of typedArrayConstructors) {
+ var modifiedConstructor = new constructor(2);
+ modifiedConstructor.constructor = constructor2;
+ assertDeepEq(modifiedConstructor.slice(1), new constructor2(1));
+
+ var modifiedSpecies = new constructor(2);
+ modifiedSpecies.constructor = { [Symbol.species]: constructor2 };
+ assertDeepEq(modifiedSpecies.slice(1), new constructor2(1));
+ }
+
+ // If obj.constructor[@@species] is neither undefined nor null, and it's
+ // not a constructor, TypeError should be thrown.
+ assertThrowsInstanceOf(() => {
+ var strSpecies = new constructor;
+ strSpecies.constructor = { [Symbol.species]: "not a constructor" };
+ strSpecies.slice(123);
+ }, TypeError);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/slice.js b/js/src/tests/ecma_6/TypedArray/slice.js
new file mode 100644
index 000000000..0a5ce4c50
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/slice.js
@@ -0,0 +1,45 @@
+for (var constructor of anyTypedArrayConstructors) {
+ assertDeepEq(constructor.prototype.slice.length, 2);
+
+ assertDeepEq(new constructor().slice(0), new constructor());
+ assertDeepEq(new constructor().slice(0, 4), new constructor());
+ assertDeepEq(new constructor(10).slice(0, 2), new constructor(2));
+
+ assertDeepEq(new constructor([1, 2]).slice(1), new constructor([2]));
+ assertDeepEq(new constructor([1, 2]).slice(0), new constructor([1, 2]));
+ assertDeepEq(new constructor([1, 2, 3]).slice(-1), new constructor([3]));
+ assertDeepEq(new constructor([1, 2, 3, 4]).slice(-3, -1), new constructor([2, 3]));
+ assertDeepEq(new constructor([.1, .2]).slice(0), new constructor([.1, .2]));
+
+ assertDeepEq(new constructor([1, 2]).slice(-3), new constructor([1, 2]));
+ assertDeepEq(new constructor([1, 2]).slice(0, -3), new constructor());
+ assertDeepEq(new constructor([1, 2]).slice(4), new constructor());
+ assertDeepEq(new constructor([1, 2]).slice(1, 5), new constructor([2]));
+
+ // Called from other globals.
+ if (typeof newGlobal === "function") {
+ var slice = newGlobal()[constructor.name].prototype.slice;
+ assertDeepEq(slice.call(new constructor([3, 2, 1]), 1),
+ new constructor([2, 1]));
+ }
+
+ // Throws if `this` isn't a TypedArray.
+ var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+ new Proxy(new constructor(), {})];
+ invalidReceivers.forEach(invalidReceiver => {
+ assertThrowsInstanceOf(() => {
+ constructor.prototype.slice.call(invalidReceiver, 0);
+ }, TypeError, "Assert that slice fails if this value is not a TypedArray");
+ });
+
+ // Test that the length getter is never called.
+ Object.defineProperty(new constructor([1, 2, 3]), "length", {
+ get() {
+ throw new Error("length accessor called");
+ }
+ }).slice(2);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
diff --git a/js/src/tests/ecma_6/TypedArray/sort_basics.js b/js/src/tests/ecma_6/TypedArray/sort_basics.js
new file mode 100644
index 000000000..cbfc53e91
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/sort_basics.js
@@ -0,0 +1,73 @@
+// Note: failed runs should include their "SEED" value in error messages,
+// setting "const SEED" to that value will recreate the data from any such run.
+const SEED = (Math.random() * 10) + 1;
+
+// Fill up an array buffer with random values and return it in raw form.
+// 'size' is the desired length of the view we will place atop the buffer,
+// 'width' is the bit-width of the view we plan on placing atop the buffer,
+// and 'seed' is an initial value supplied to a pseudo-random number generator.
+function genRandomArrayBuffer(size, width, seed) {
+ let buf = new ArrayBuffer((width / 8) * size);
+ let arr = new Uint8Array(buf);
+ let len = 0;
+ // We generate a random number, n, where 0 <= n <= 255 for every space
+ // available in our buffer.
+ for (let n of XorShiftGenerator(seed, buf.byteLength))
+ arr[len++] = n;
+ return buf;
+}
+
+// Because we can generate any possible combination of bits, some floating point
+// entries will take on -Infinity, Infinity, and NaN values. This function ensures
+// that a is <= b, where, like the default comparator, -Infinity < Infinity and
+// every non-NaN < NaN.
+function lte(a, b) {
+ if (isNaN(b))
+ return true;
+ return a <= b;
+}
+
+// A a >= b counterpart to the helper function above.
+function gte(a, b) {
+ return lte(b, a);
+}
+
+// A custom comparator.
+function cmp(a, b) {
+ return lte(a, b) ? gte(a, b) ? 0 : -1 : 1;
+}
+
+function SortTest(dataType, dataSource) {
+ let typedArray = new dataType(dataSource);
+ let originalValues = Array.from(typedArray);
+
+ // Test the default comparator
+ typedArray.sort();
+
+ // Test against regular array sort
+ assertDeepEq(Array.from(typedArray), Array.from(originalValues).sort(cmp),
+ `The array is not properly sorted! seed: ${SEED}`);
+
+ // Another sanity check
+ for (let i=0; i < typedArray.length - 1; i++)
+ assertEq(lte(typedArray[i], typedArray[i + 1]), true,
+ `The array is not properly sorted! ${typedArray[i]} > ${typedArray[i + 1]}, seed: ${SEED}`)
+
+ // Test custom comparators
+ typedArray.sort((x, y) => cmp(y, x));
+
+ // The array should be in reverse order
+ for (let i=typedArray.length - 2; i >= 0; i--)
+ assertEq(gte(typedArray[i], typedArray[i + 1]), true,
+ `The array is not properly sorted! ${typedArray[i]} < ${typedArray[i + 1]}, seed: ${SEED}`)
+}
+
+for (let constructor of anyTypedArrayConstructors) {
+ for (let arrayLength of [256, 16, 0]) {
+ let source = genRandomArrayBuffer(arrayLength, constructor.BYTES_PER_ELEMENT * 8, SEED);
+ SortTest(constructor, source);
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/sort_comparators.js b/js/src/tests/ecma_6/TypedArray/sort_comparators.js
new file mode 100644
index 000000000..ca190948f
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/sort_comparators.js
@@ -0,0 +1,32 @@
+// Ensure that sorts finish even if a comparator adds items
+// Note: the array is not expected to be properly sorted.
+let outsideArray = new Int32Array([1, 99, 2]);
+function addingComparator(x, y) {
+ if (x == 99 || y == 99) {
+ outsideArray[0] = 101;
+ outsideArray[outsideArray.length - 1] = 102;
+ }
+ return x - y;
+}
+outsideArray.sort(addingComparator);
+assertEq(outsideArray.every(x => [1, 2, 99, 101, 102].includes(x)), true);
+
+// Ensure that sorts finish even if a comparator calls sort again
+// Note: the array is not expected to be properly sorted.
+outsideArray = new Int32Array([1, 99, 2]);
+function recursiveComparator(x, y) {
+ outsideArray.sort();
+ return x - y;
+}
+outsideArray.sort(recursiveComparator);
+assertEq(outsideArray.every(x => outsideArray.includes(x)), true)
+
+// Ensure that NaN's returned from custom comparators behave as / are converted
+// to +0s.
+let nanComparatorData = [2112, 42, 1111, 34];
+let nanComparatorArray = new Int32Array(nanComparatorData);
+nanComparatorArray.sort((x, y) => NaN);
+assertEq(nanComparatorData.every(x => nanComparatorArray.includes(x)), true);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/sort_errors.js b/js/src/tests/ecma_6/TypedArray/sort_errors.js
new file mode 100644
index 000000000..2b8921be9
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/sort_errors.js
@@ -0,0 +1,87 @@
+// Ensure that TypedArrays throw when attempting to sort a detached ArrayBuffer
+if (typeof detachArrayBuffer === "function") {
+ assertThrowsInstanceOf(() => {
+ let buffer = new ArrayBuffer(32);
+ let array = new Int32Array(buffer);
+ detachArrayBuffer(buffer);
+ array.sort();
+ }, TypeError);
+}
+
+// Ensure detachment check works when buffer is detached in comparator.
+if (typeof detachArrayBuffer === "function") {
+ let detached = false;
+ let ta = new Int32Array(3);
+ assertThrowsInstanceOf(() => {
+ ta.sort(function(a, b) {
+ assertEq(detached, false);
+ detached = true;
+ detachArrayBuffer(ta.buffer);
+ return a - b;
+ });
+ }, TypeError);
+}
+
+// Ensure detachment check doesn't choke on wrapped typed array.
+if (typeof newGlobal === "function") {
+ let ta = new Int32Array(3);
+ let otherGlobal = newGlobal();
+ otherGlobal.Int32Array.prototype.sort.call(ta, function(a, b) {
+ return a - b;
+ });
+}
+
+// Ensure detachment check works for wrapped typed arrays.
+if (typeof newGlobal === "function" && typeof detachArrayBuffer === "function") {
+ let detached = false;
+ let ta = new Int32Array(3);
+ let otherGlobal = newGlobal();
+ assertThrowsInstanceOf(() => {
+ otherGlobal.Int32Array.prototype.sort.call(ta, function(a,b) {
+ assertEq(detached, false);
+ detached = true;
+ detachArrayBuffer(ta.buffer);
+ return a - b;
+ });
+ }, TypeError);
+}
+
+// Ensure that TypedArray.prototype.sort will not sort non-TypedArrays
+assertThrowsInstanceOf(() => {
+ let array = [4, 3, 2, 1];
+ Int32Array.prototype.sort.call(array);
+}, TypeError);
+
+assertThrowsInstanceOf(() => {
+ Int32Array.prototype.sort.call({a: 1, b: 2});
+}, TypeError);
+
+assertThrowsInstanceOf(() => {
+ Int32Array.prototype.sort.call(Int32Array.prototype);
+}, TypeError);
+
+assertThrowsInstanceOf(() => {
+ let buf = new ArrayBuffer(32);
+ Int32Array.prototype.sort.call(buf);
+}, TypeError);
+
+// Ensure that comparator errors are propagataed
+function badComparator(x, y) {
+ if (x == 99 && y == 99)
+ throw new TypeError;
+ return x - y;
+}
+
+assertThrowsInstanceOf(() => {
+ let array = new Uint8Array([99, 99, 99, 99]);
+ array.sort(badComparator);
+}, TypeError);
+
+assertThrowsInstanceOf(() => {
+ let array = new Uint8Array([1, 99, 2, 99]);
+ array.sort(badComparator);
+}, TypeError);
+
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/sort_globals.js b/js/src/tests/ecma_6/TypedArray/sort_globals.js
new file mode 100644
index 000000000..6bab6a391
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/sort_globals.js
@@ -0,0 +1,9 @@
+// TypedArray.prototype.sort should work across globals
+let g2 = newGlobal();
+assertEqArray(
+ Int32Array.prototype.sort.call(new g2.Int32Array([3, 2, 1])),
+ new Int32Array([1, 2, 3])
+);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/sort_small.js b/js/src/tests/ecma_6/TypedArray/sort_small.js
new file mode 100644
index 000000000..22f9dc69a
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/sort_small.js
@@ -0,0 +1,38 @@
+const testCases = {
+ // Pre-sorted test data, it's important that these arrays remain in ascending order.
+ [Int8Array.name]: [[-128, 127]],
+ [Int16Array.name]: [[-32768, -999, 1942, 32767]],
+ [Int32Array.name]: [[-2147483648, -320000, -244000, 2147483647]],
+ [Uint8Array.name]: [[255]],
+ [Uint16Array.name]: [[0, 65535, 65535]],
+ [Uint32Array.name]: [[0, 987632, 4294967295]],
+ [Uint8ClampedArray.name]: [[255]],
+
+ // Test the behavior in the default comparator as described in 22.2.3.26.
+ // The spec boils down to, -0s come before +0s, and NaNs always come last.
+ // Float Arrays are used because all other types convert -0 and NaN to +0.
+ [Float32Array.name]: [
+ [-2147483647, -2147483646.99, -0, 0, 2147483646.99, NaN],
+ [1/undefined, NaN, Number.NaN]
+ ],
+ [Float64Array.name]: [
+ [-2147483646.99, -0, 0, 4147483646.99, NaN],
+ [1/undefined, NaN, Number.NaN]
+ ],
+};
+
+// Sort every possible permutation of an arrays
+function sortAllPermutations(dataType, testData) {
+ let reference = new dataType(testData);
+ for (let permutation of Permutations(testData))
+ assertDeepEq((new dataType(permutation)).sort(), reference);
+}
+
+for (let constructor of sharedTypedArrayConstructors) {
+ for (let data of testCases[constructor.name]) {
+ sortAllPermutations(constructor, data);
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/sort_snans.js b/js/src/tests/ecma_6/TypedArray/sort_snans.js
new file mode 100644
index 000000000..9e3ad1698
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/sort_snans.js
@@ -0,0 +1,72 @@
+// Ensure that signaling NaN's don't cause problems while sorting
+
+function getNaNArray(length) {
+ let a = [];
+ for (let i = 0; i < length; i++)
+ a.push(NaN);
+ return a;
+}
+
+// Test every skipNth value in some range n, where start <= n <= end
+// and start/stop should be 32-bit integers with bit patterns that
+// form Float32 NaNs.
+function testFloat32NaNRanges(start, end) {
+ let skipN = 10e3;
+
+ // sample the space of possible NaNs to save time
+ let sampleSize = Math.floor((end - start)/ skipN);
+
+ let NaNArray = new Float32Array(getNaNArray(sampleSize));
+ let buffer = new ArrayBuffer(4 * sampleSize);
+ let uintView = new Uint32Array(buffer);
+ let floatView = new Float32Array(buffer);
+
+ uintView[0] = start;
+ for (let i = 1; i < sampleSize; i++) {
+ uintView[i] = uintView[0] + (i * skipN);
+ }
+
+ floatView.sort();
+ assertDeepEq(floatView, NaNArray);
+}
+
+// Test every skipNth value in some range n, where start <= n <= end
+// and startHi, startLow and endHi, endLow should be 32-bit integers which,
+// when combined (Hi + Low), form Float64 NaNs.
+function testFloat64NaNRanges(startHi, startLow, endHi, endLow) {
+ let skipN = 10e6;
+
+ let sampleSizeHi = Math.floor((endHi - startHi)/skipN);
+ let sampleSizeLow = Math.floor((endLow - startLow)/skipN);
+
+ let NaNArray = new Float64Array(getNaNArray(sampleSizeHi + sampleSizeLow));
+ let buffer = new ArrayBuffer(8 * (sampleSizeHi + sampleSizeLow));
+ let uintView = new Uint32Array(buffer);
+ let floatView = new Float64Array(buffer);
+
+ // Fill in all of the low bits first.
+ for (let i = 0; i <= sampleSizeLow; i++) {
+ uintView[i * 2] = startLow + (i * skipN);
+ uintView[(i * 2) + 1] = startHi;
+ }
+
+ // Then the high bits.
+ for (let i = sampleSizeLow; i <= sampleSizeLow + sampleSizeHi; i++) {
+ uintView[i * 2] = endLow;
+ uintView[(i * 2) + 1] = startHi + ((i - sampleSizeLow) * skipN);
+ }
+
+ floatView.sort();
+ assertDeepEq(floatView, NaNArray);
+}
+
+// Float32 Signaling NaN ranges
+testFloat32NaNRanges(0x7F800001, 0x7FBFFFFF);
+testFloat32NaNRanges(0xFF800001, 0xFFBFFFFF);
+
+// Float64 Signaling NaN ranges
+testFloat64NaNRanges(0x7FF00000, 0x00000001, 0x7FF7FFFF, 0xFFFFFFFF);
+testFloat64NaNRanges(0xFFF00000, 0x00000001, 0xFFF7FFFF, 0xFFFFFFFF);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/sorting_buffer_access.js b/js/src/tests/ecma_6/TypedArray/sorting_buffer_access.js
new file mode 100644
index 000000000..c31f4ca16
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/sorting_buffer_access.js
@@ -0,0 +1,15 @@
+// Ensure that when sorting arrays of size greater than 128, which
+// calls RadixSort under the hood, we don't access the 'buffer'
+// property of the typed array directly.
+
+
+// The buggy behavior in the RadixSort is only exposed when we use
+// float arrays, but checking everything just to be sure.
+for (var ctor of anyTypedArrayConstructors) {
+ var testArray = new ctor(1024);
+ Object.defineProperty(testArray, "buffer", { get() { throw new Error("FAIL: Buffer accessed directly"); } });
+ testArray.sort();
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/subarray-species.js b/js/src/tests/ecma_6/TypedArray/subarray-species.js
new file mode 100644
index 000000000..91c34e80c
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/subarray-species.js
@@ -0,0 +1,63 @@
+function test(constructor, constructor2, from=[1, 2, 3, 4, 5], to=[3, 4], begin=2, end=4) {
+ var modifiedConstructor = new constructor(from);
+ modifiedConstructor.constructor = constructor2;
+ assertDeepEq(modifiedConstructor.subarray(begin, end), new constructor2(to));
+ var modifiedSpecies = new constructor(from);
+ modifiedSpecies.constructor = { [Symbol.species]: constructor2 };
+ assertDeepEq(modifiedSpecies.subarray(begin, end), new constructor2(to));
+}
+
+// same size, same sign
+
+test(Int8Array, Uint8Array);
+test(Int8Array, Uint8ClampedArray);
+
+test(Uint8Array, Int8Array);
+test(Uint8Array, Uint8ClampedArray);
+
+test(Uint8ClampedArray, Int8Array);
+test(Uint8ClampedArray, Uint8Array);
+
+test(Int16Array, Uint16Array);
+test(Uint16Array, Int16Array);
+
+test(Int32Array, Uint32Array);
+test(Uint32Array, Int32Array);
+
+// same size, different sign
+
+test(Int8Array, Uint8Array, [-1, -2, -3, -4, -5], [0xFD, 0xFC]);
+test(Int8Array, Uint8ClampedArray, [-1, -2, -3, -4, -5], [0xFD, 0xFC]);
+
+test(Uint8Array, Int8Array, [0xFF, 0xFE, 0xFD, 0xFC, 0xFB], [-3, -4]);
+test(Uint8ClampedArray, Int8Array, [0xFF, 0xFE, 0xFD, 0xFC, 0xFB], [-3, -4]);
+
+test(Int16Array, Uint16Array, [-1, -2, -3, -4, -5], [0xFFFD, 0xFFFC]);
+test(Uint16Array, Int16Array, [0xFFFF, 0xFFFE, 0xFFFD, 0xFFFC, 0xFFFB], [-3, -4]);
+
+test(Int32Array, Uint32Array, [-1, -2, -3, -4, -5], [0xFFFFFFFD, 0xFFFFFFFC]);
+test(Uint32Array, Int32Array, [0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFC, 0xFFFFFFFB], [-3, -4]);
+
+// different size
+
+// To avoid handling endian, use ArrayBuffer as an argument.
+var a = new Int8Array([0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0,
+ 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
+ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
+ 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x0F]);
+
+test(Uint8Array, Uint16Array, a.buffer, a.slice(2, 6).buffer);
+test(Uint16Array, Uint8Array, a.buffer, a.slice(4, 6).buffer);
+
+test(Uint8Array, Uint32Array, a.buffer, a.slice(4, 12).buffer, 4, 6);
+test(Uint32Array, Uint8Array, a.buffer, a.slice(8, 10).buffer);
+
+test(Uint16Array, Uint32Array, a.buffer, a.slice(4, 12).buffer);
+test(Uint32Array, Uint16Array, a.buffer, a.slice(8, 12).buffer);
+
+test(Float32Array, Float64Array, a.buffer, a.slice(8, 24).buffer);
+test(Float64Array, Float32Array, a.buffer, a.slice(16, 24).buffer);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
diff --git a/js/src/tests/ecma_6/TypedArray/subarray.js b/js/src/tests/ecma_6/TypedArray/subarray.js
new file mode 100644
index 000000000..a7bfab0ef
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/subarray.js
@@ -0,0 +1,29 @@
+// Bug 1291003
+if (typeof detachArrayBuffer === "function") {
+ for (let constructor of typedArrayConstructors) {
+ const elementSize = constructor.BYTES_PER_ELEMENT;
+
+ let targetOffset;
+ let buffer = new ArrayBuffer(2 * elementSize);
+ let typedArray = new constructor(buffer, 1 * elementSize, 1);
+ typedArray.constructor = {
+ [Symbol.species]: function(ab, offset, length) {
+ targetOffset = offset;
+ return new constructor(1);
+ }
+ };
+
+ let beginIndex = {
+ valueOf() {
+ detachArrayBuffer(buffer);
+ return 0;
+ }
+ };
+ typedArray.subarray(beginIndex);
+
+ assertEq(targetOffset, 1 * elementSize);
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/toLocaleString-detached.js b/js/src/tests/ecma_6/TypedArray/toLocaleString-detached.js
new file mode 100644
index 000000000..fe95ae689
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/toLocaleString-detached.js
@@ -0,0 +1,38 @@
+if (typeof detachArrayBuffer === "function") {
+ const originalNumberToLocaleString = Number.prototype.toLocaleString;
+
+ // Throws if array buffer is detached.
+ for (let constructor of typedArrayConstructors) {
+ let typedArray = new constructor(42);
+ detachArrayBuffer(typedArray.buffer);
+ assertThrowsInstanceOf(() => typedArray.toLocaleString(), TypeError);
+ }
+
+ // Throws a TypeError if detached in Number.prototype.toLocaleString.
+ for (let constructor of typedArrayConstructors) {
+ Number.prototype.toLocaleString = function() {
+ "use strict";
+ if (!detached) {
+ detachArrayBuffer(typedArray.buffer);
+ detached = true;
+ }
+ return this;
+ };
+
+ // No error for single element arrays.
+ let detached = false;
+ let typedArray = new constructor(1);
+ assertEq(typedArray.toLocaleString(), "0");
+ assertEq(detached, true);
+
+ // TypeError if more than one element is present.
+ detached = false;
+ typedArray = new constructor(2);
+ assertThrowsInstanceOf(() => typedArray.toLocaleString(), TypeError);
+ assertEq(detached, true);
+ }
+ Number.prototype.toLocaleString = originalNumberToLocaleString;
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/toLocaleString-nointl.js b/js/src/tests/ecma_6/TypedArray/toLocaleString-nointl.js
new file mode 100644
index 000000000..f2870efbe
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/toLocaleString-nointl.js
@@ -0,0 +1,40 @@
+if (typeof Intl !== "object") {
+ const localeSep = [,,].toLocaleString();
+
+ const originalNumberToLocaleString = Number.prototype.toLocaleString;
+
+ // Ensure no arguments are passed to the array elements.
+ for (let constructor of anyTypedArrayConstructors) {
+ Number.prototype.toLocaleString = function() {
+ assertEq(arguments.length, 0);
+ return "pass";
+ };
+
+ // Single element case.
+ assertEq(new constructor(1).toLocaleString(), "pass");
+
+ // More than one element.
+ assertEq(new constructor(2).toLocaleString(), "pass" + localeSep + "pass");
+ }
+ Number.prototype.toLocaleString = originalNumberToLocaleString;
+
+ // Ensure no arguments are passed to the array elements even if supplied.
+ for (let constructor of anyTypedArrayConstructors) {
+ Number.prototype.toLocaleString = function() {
+ assertEq(arguments.length, 0);
+ return "pass";
+ };
+ let locales = {};
+ let options = {};
+
+ // Single element case.
+ assertEq(new constructor(1).toLocaleString(locales, options), "pass");
+
+ // More than one element.
+ assertEq(new constructor(2).toLocaleString(locales, options), "pass" + localeSep + "pass");
+ }
+ Number.prototype.toLocaleString = originalNumberToLocaleString;
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/toLocaleString.js b/js/src/tests/ecma_6/TypedArray/toLocaleString.js
new file mode 100644
index 000000000..78049ec22
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/toLocaleString.js
@@ -0,0 +1,80 @@
+const TypedArrayPrototype = Object.getPrototypeOf(Int8Array.prototype);
+
+// %TypedArrayPrototype% has an own "toLocaleString" function property.
+assertEq(TypedArrayPrototype.hasOwnProperty("toLocaleString"), true);
+assertEq(typeof TypedArrayPrototype.toLocaleString, "function");
+
+// The initial value of %TypedArrayPrototype%.toLocaleString is not Array.prototype.toLocaleString.
+assertEq(TypedArrayPrototype.toLocaleString === Array.prototype.toLocaleString, false);
+
+// The concrete TypedArray prototypes do not have an own "toLocaleString" property.
+assertEq(anyTypedArrayConstructors.every(c => !c.hasOwnProperty("toLocaleString")), true);
+
+assertDeepEq(Object.getOwnPropertyDescriptor(TypedArrayPrototype, "toLocaleString"), {
+ value: TypedArrayPrototype.toLocaleString,
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+assertEq(TypedArrayPrototype.toLocaleString.name, "toLocaleString");
+assertEq(TypedArrayPrototype.toLocaleString.length, 0);
+
+// It's not a generic method.
+assertThrowsInstanceOf(() => TypedArrayPrototype.toLocaleString.call(), TypeError);
+for (let invalid of [void 0, null, {}, [], function(){}, true, 0, "", Symbol()]) {
+ assertThrowsInstanceOf(() => TypedArrayPrototype.toLocaleString.call(invalid), TypeError);
+}
+
+const localeOne = 1..toLocaleString(),
+ localeTwo = 2..toLocaleString(),
+ localeSep = [,,].toLocaleString();
+
+for (let constructor of anyTypedArrayConstructors) {
+ assertEq(new constructor([]).toLocaleString(), "");
+ assertEq(new constructor([1]).toLocaleString(), localeOne);
+ assertEq(new constructor([1, 2]).toLocaleString(), localeOne + localeSep + localeTwo);
+}
+
+const originalNumberToLocaleString = Number.prototype.toLocaleString;
+
+// Calls Number.prototype.toLocaleString on each element.
+for (let constructor of anyTypedArrayConstructors) {
+ Number.prototype.toLocaleString = function() {
+ "use strict";
+
+ // Ensure this-value is not boxed.
+ assertEq(typeof this, "number");
+
+ // Test ToString is applied.
+ return {
+ valueOf: () => {
+ throw new Error("valueOf called");
+ },
+ toString: () => {
+ return this + 10;
+ }
+ };
+ };
+ let typedArray = new constructor([1, 2]);
+ assertEq(typedArray.toLocaleString(), "11" + localeSep + "12");
+}
+Number.prototype.toLocaleString = originalNumberToLocaleString;
+
+// Calls Number.prototype.toLocaleString from the current Realm.
+const otherGlobal = newGlobal();
+for (let constructor of anyTypedArrayConstructors) {
+ Number.prototype.toLocaleString = function() {
+ "use strict";
+ called = true;
+ return this;
+ };
+ let typedArray = new otherGlobal[constructor.name]([1]);
+ let called = false;
+ assertEq(TypedArrayPrototype.toLocaleString.call(typedArray), "1");
+ assertEq(called, true);
+}
+Number.prototype.toLocaleString = originalNumberToLocaleString;
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/toString.js b/js/src/tests/ecma_6/TypedArray/toString.js
new file mode 100644
index 000000000..0879b8b31
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/toString.js
@@ -0,0 +1,69 @@
+const TypedArrayPrototype = Object.getPrototypeOf(Int8Array.prototype);
+
+// %TypedArrayPrototype% has an own "toString" property.
+assertEq(TypedArrayPrototype.hasOwnProperty("toString"), true);
+
+// The initial value of %TypedArrayPrototype%.toString is Array.prototype.toString.
+assertEq(TypedArrayPrototype.toString, Array.prototype.toString);
+
+// The concrete TypedArray prototypes do not have an own "toString" property.
+assertEq(anyTypedArrayConstructors.every(c => !c.hasOwnProperty("toString")), true);
+
+assertDeepEq(Object.getOwnPropertyDescriptor(TypedArrayPrototype, "toString"), {
+ value: TypedArrayPrototype.toString,
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+for (let constructor of anyTypedArrayConstructors) {
+ assertEq(new constructor([]).toString(), "");
+ assertEq(new constructor([1]).toString(), "1");
+ assertEq(new constructor([1, 2]).toString(), "1,2");
+}
+
+const testCases = {
+ [Int8Array.name]: {
+ array: [-1, 2, -3, 4, NaN],
+ expected: "-1,2,-3,4,0",
+ },
+ [Int16Array.name]: {
+ array: [-1, 2, -3, 4, NaN],
+ expected: "-1,2,-3,4,0",
+ },
+ [Int32Array.name]: {
+ array: [-1, 2, -3, 4, NaN],
+ expected: "-1,2,-3,4,0",
+ },
+ [Uint8Array.name]: {
+ array: [255, 2, 3, 4, NaN],
+ expected: "255,2,3,4,0",
+ },
+ [Uint16Array.name]: {
+ array: [-1, 2, 3, 4, NaN],
+ expected: "65535,2,3,4,0",
+ },
+ [Uint32Array.name]: {
+ array: [-1, 2, 3, 4, NaN],
+ expected: "4294967295,2,3,4,0",
+ },
+ [Uint8ClampedArray.name]: {
+ array: [255, 256, 2, 3, 4, NaN],
+ expected: "255,255,2,3,4,0",
+ },
+ [Float32Array.name]: {
+ array: [-0, 0, 0.5, -0.5, NaN, Infinity, -Infinity],
+ expected: "0,0,0.5,-0.5,NaN,Infinity,-Infinity",
+ },
+ [Float64Array.name]: {
+ array: [-0, 0, 0.5, -0.5, NaN, Infinity, -Infinity],
+ expected: "0,0,0.5,-0.5,NaN,Infinity,-Infinity",
+ },
+};
+for (let constructor of anyTypedArrayConstructors) {
+ let {array, expected} = testCases[constructor.name];
+ assertEq(new constructor(array).toString(), expected);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/uint8clamped-constructor.js b/js/src/tests/ecma_6/TypedArray/uint8clamped-constructor.js
new file mode 100644
index 000000000..3eefe70f1
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/uint8clamped-constructor.js
@@ -0,0 +1,9 @@
+for (var v of [-300, 255.6, 300, 3.5, -3.9]) {
+ var a = new Uint8ClampedArray([v]);
+ var b = new Uint8ClampedArray(1);
+ b[0] = v;
+
+ assertEq(a[0], b[0]);
+}
+
+reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/TypedArray/values.js b/js/src/tests/ecma_6/TypedArray/values.js
new file mode 100644
index 000000000..bf486bfa0
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/values.js
@@ -0,0 +1,37 @@
+for (var constructor of anyTypedArrayConstructors) {
+ assertEq(constructor.prototype.values.length, 0);
+ assertEq(constructor.prototype.values.name, "values");
+ assertEq(constructor.prototype.values, constructor.prototype[Symbol.iterator]);
+
+ assertDeepEq([...new constructor(0).values()], []);
+ assertDeepEq([...new constructor(1).values()], [0]);
+ assertDeepEq([...new constructor(2).values()], [0, 0]);
+ assertDeepEq([...new constructor([15]).values()], [15]);
+
+ var arr = new constructor([1, 2, 3]);
+ var iterator = arr.values();
+ assertDeepEq(iterator.next(), {value: 1, done: false});
+ assertDeepEq(iterator.next(), {value: 2, done: false});
+ assertDeepEq(iterator.next(), {value: 3, done: false});
+ assertDeepEq(iterator.next(), {value: undefined, done: true});
+
+ // Called from other globals.
+ if (typeof newGlobal === "function") {
+ var values = newGlobal()[constructor.name].prototype.values;
+ assertDeepEq([...values.call(new constructor([42, 36]))], [42, 36]);
+ arr = new (newGlobal()[constructor.name])([42, 36]);
+ assertEq([...constructor.prototype.values.call(arr)].toString(), "42,36");
+ }
+
+ // Throws if `this` isn't a TypedArray.
+ var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
+ new Proxy(new constructor(), {})];
+ invalidReceivers.forEach(invalidReceiver => {
+ assertThrowsInstanceOf(() => {
+ constructor.prototype.values.call(invalidReceiver);
+ }, TypeError, "Assert that values fails if this value is not a TypedArray");
+ });
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);