summaryrefslogtreecommitdiffstats
path: root/js/src/tests/ecma_7
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/tests/ecma_7')
-rw-r--r--js/src/tests/ecma_7/Array/browser.js0
-rw-r--r--js/src/tests/ecma_7/Array/includes.js59
-rw-r--r--js/src/tests/ecma_7/Array/shell.js0
-rw-r--r--js/src/tests/ecma_7/AsyncFunctions/BoundNames.js21
-rw-r--r--js/src/tests/ecma_7/AsyncFunctions/EarlyErrors.js51
-rw-r--r--js/src/tests/ecma_7/AsyncFunctions/arguments_callee.js31
-rw-r--r--js/src/tests/ecma_7/AsyncFunctions/await-newline.js15
-rw-r--r--js/src/tests/ecma_7/AsyncFunctions/clone.js22
-rw-r--r--js/src/tests/ecma_7/AsyncFunctions/constructor.js33
-rw-r--r--js/src/tests/ecma_7/AsyncFunctions/identity.js14
-rw-r--r--js/src/tests/ecma_7/AsyncFunctions/length.js12
-rw-r--r--js/src/tests/ecma_7/AsyncFunctions/methods.js61
-rw-r--r--js/src/tests/ecma_7/AsyncFunctions/property.js49
-rw-r--r--js/src/tests/ecma_7/AsyncFunctions/semantics.js169
-rw-r--r--js/src/tests/ecma_7/AsyncFunctions/shell.js0
-rw-r--r--js/src/tests/ecma_7/AsyncFunctions/syntax-arrow.js104
-rw-r--r--js/src/tests/ecma_7/AsyncFunctions/syntax-modules.js25
-rw-r--r--js/src/tests/ecma_7/AsyncFunctions/syntax.js86
-rw-r--r--js/src/tests/ecma_7/AsyncFunctions/toString.js24
-rw-r--r--js/src/tests/ecma_7/AsyncFunctions/yield.js71
-rw-r--r--js/src/tests/ecma_7/Destructuring/browser.js0
-rw-r--r--js/src/tests/ecma_7/Destructuring/duplicate-__proto__.js54
-rw-r--r--js/src/tests/ecma_7/Destructuring/rest-parameter-aray-iterator.js40
-rw-r--r--js/src/tests/ecma_7/Destructuring/rest-parameter-arguments.js101
-rw-r--r--js/src/tests/ecma_7/Destructuring/rest-parameter-function-length.js41
-rw-r--r--js/src/tests/ecma_7/Destructuring/rest-parameter-spread-call-optimization.js29
-rw-r--r--js/src/tests/ecma_7/Destructuring/rest-parameter-syntax.js87
-rw-r--r--js/src/tests/ecma_7/Destructuring/rest-parameter.js54
-rw-r--r--js/src/tests/ecma_7/Destructuring/shell.js0
-rw-r--r--js/src/tests/ecma_7/Math/Pow.js117
-rw-r--r--js/src/tests/ecma_7/Math/shell.js0
-rw-r--r--js/src/tests/ecma_7/Object/browser.js0
-rw-r--r--js/src/tests/ecma_7/Object/defineGetter-defineSetter.js92
-rw-r--r--js/src/tests/ecma_7/Object/entries.js94
-rw-r--r--js/src/tests/ecma_7/Object/shell.js0
-rw-r--r--js/src/tests/ecma_7/Object/values.js94
-rw-r--r--js/src/tests/ecma_7/SIMD/ToSource.js56
-rw-r--r--js/src/tests/ecma_7/SIMD/binary-operations.js785
-rw-r--r--js/src/tests/ecma_7/SIMD/bug1023145.js14
-rw-r--r--js/src/tests/ecma_7/SIMD/bug953270.js24
-rw-r--r--js/src/tests/ecma_7/SIMD/check.js214
-rw-r--r--js/src/tests/ecma_7/SIMD/comparisons.js349
-rw-r--r--js/src/tests/ecma_7/SIMD/constructors.js226
-rw-r--r--js/src/tests/ecma_7/SIMD/conversions.js1261
-rw-r--r--js/src/tests/ecma_7/SIMD/float64x2-arithmetic.js69
-rw-r--r--js/src/tests/ecma_7/SIMD/load-floats.js19
-rw-r--r--js/src/tests/ecma_7/SIMD/load-int16x8.js17
-rw-r--r--js/src/tests/ecma_7/SIMD/load-int32x4.js18
-rw-r--r--js/src/tests/ecma_7/SIMD/load-int8x16.js17
-rw-r--r--js/src/tests/ecma_7/SIMD/load-sab-buffer-compat.js49
-rw-r--r--js/src/tests/ecma_7/SIMD/load-unsigned-integers.js22
-rw-r--r--js/src/tests/ecma_7/SIMD/minmax.js85
-rw-r--r--js/src/tests/ecma_7/SIMD/replaceLane.js226
-rw-r--r--js/src/tests/ecma_7/SIMD/select-bitselect.js133
-rw-r--r--js/src/tests/ecma_7/SIMD/shell.js580
-rw-r--r--js/src/tests/ecma_7/SIMD/shifts.js202
-rw-r--r--js/src/tests/ecma_7/SIMD/splat.js97
-rw-r--r--js/src/tests/ecma_7/SIMD/store.js264
-rw-r--r--js/src/tests/ecma_7/SIMD/swizzle-shuffle.js507
-rw-r--r--js/src/tests/ecma_7/SIMD/toString.js90
-rw-r--r--js/src/tests/ecma_7/SIMD/typedobjects.js1077
-rw-r--r--js/src/tests/ecma_7/SIMD/unary-operations.js410
-rw-r--r--js/src/tests/ecma_7/String/shell.js0
-rw-r--r--js/src/tests/ecma_7/String/string-pad-start-end.js99
-rw-r--r--js/src/tests/ecma_7/Syntax/browser.js0
-rw-r--r--js/src/tests/ecma_7/Syntax/non-simple-with-strict-directive.js140
-rw-r--r--js/src/tests/ecma_7/Syntax/shell.js0
-rw-r--r--js/src/tests/ecma_7/TypedArray/browser.js0
-rw-r--r--js/src/tests/ecma_7/TypedArray/filter-validation.js185
-rw-r--r--js/src/tests/ecma_7/TypedArray/from-iterable-validation.js140
-rw-r--r--js/src/tests/ecma_7/TypedArray/from-non-iterable-validation.js140
-rw-r--r--js/src/tests/ecma_7/TypedArray/map-validation.js149
-rw-r--r--js/src/tests/ecma_7/TypedArray/of-validation.js140
-rw-r--r--js/src/tests/ecma_7/TypedArray/shell.js114
-rw-r--r--js/src/tests/ecma_7/TypedArray/slice-validation.js187
-rw-r--r--js/src/tests/ecma_7/TypedArray/subarray-validation.js110
-rw-r--r--js/src/tests/ecma_7/TypedObject/architecture.js55
-rw-r--r--js/src/tests/ecma_7/TypedObject/arraybuffer_isview.js33
-rw-r--r--js/src/tests/ecma_7/TypedObject/arrayequiv.js59
-rw-r--r--js/src/tests/ecma_7/TypedObject/arrayofstructs.js29
-rw-r--r--js/src/tests/ecma_7/TypedObject/arraytype.js136
-rw-r--r--js/src/tests/ecma_7/TypedObject/arrayzerolen.js17
-rw-r--r--js/src/tests/ecma_7/TypedObject/atopbuffer.js27
-rw-r--r--js/src/tests/ecma_7/TypedObject/atopbufferwithoffset.js51
-rw-r--r--js/src/tests/ecma_7/TypedObject/map-neutered-midway.js43
-rw-r--r--js/src/tests/ecma_7/TypedObject/memory.js97
-rw-r--r--js/src/tests/ecma_7/TypedObject/method_build.js141
-rw-r--r--js/src/tests/ecma_7/TypedObject/method_filter.js47
-rw-r--r--js/src/tests/ecma_7/TypedObject/method_from.js238
-rw-r--r--js/src/tests/ecma_7/TypedObject/method_map.js136
-rw-r--r--js/src/tests/ecma_7/TypedObject/method_reduce.js91
-rw-r--r--js/src/tests/ecma_7/TypedObject/numerictypes.js189
-rw-r--r--js/src/tests/ecma_7/TypedObject/objecttype.js38
-rw-r--r--js/src/tests/ecma_7/TypedObject/redimension.js57
-rw-r--r--js/src/tests/ecma_7/TypedObject/referencetypealiasing.js33
-rw-r--r--js/src/tests/ecma_7/TypedObject/referencetypecoercions.js70
-rw-r--r--js/src/tests/ecma_7/TypedObject/referencetypemultiple.js22
-rw-r--r--js/src/tests/ecma_7/TypedObject/referencetypetrace.js80
-rw-r--r--js/src/tests/ecma_7/TypedObject/referencetypeuninit.js30
-rw-r--r--js/src/tests/ecma_7/TypedObject/scalar_types.js68
-rw-r--r--js/src/tests/ecma_7/TypedObject/shell.js29
-rw-r--r--js/src/tests/ecma_7/TypedObject/simpleequiv.js25
-rw-r--r--js/src/tests/ecma_7/TypedObject/size_and_alignment.js61
-rw-r--r--js/src/tests/ecma_7/TypedObject/storageopaque.js33
-rw-r--r--js/src/tests/ecma_7/TypedObject/structequiv.js61
-rw-r--r--js/src/tests/ecma_7/TypedObject/structtypeenumerate.js36
-rw-r--r--js/src/tests/ecma_7/TypedObject/structtypegetownproperty.js28
-rw-r--r--js/src/tests/ecma_7/TypedObject/structtypeindexedfields.js31
-rw-r--r--js/src/tests/ecma_7/TypedObject/structtypeprototype.js80
-rw-r--r--js/src/tests/ecma_7/TypedObject/structtypereflection.js47
-rw-r--r--js/src/tests/ecma_7/TypedObject/structtypestructuralassign.js94
-rw-r--r--js/src/tests/ecma_7/browser.js0
-rw-r--r--js/src/tests/ecma_7/extensions/browser.js0
-rw-r--r--js/src/tests/ecma_7/extensions/parse-rest-destructuring-parameter.js27
-rw-r--r--js/src/tests/ecma_7/extensions/shell.js0
-rw-r--r--js/src/tests/ecma_7/shell.js205
116 files changed, 12409 insertions, 0 deletions
diff --git a/js/src/tests/ecma_7/Array/browser.js b/js/src/tests/ecma_7/Array/browser.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/js/src/tests/ecma_7/Array/browser.js
diff --git a/js/src/tests/ecma_7/Array/includes.js b/js/src/tests/ecma_7/Array/includes.js
new file mode 100644
index 000000000..aa439571c
--- /dev/null
+++ b/js/src/tests/ecma_7/Array/includes.js
@@ -0,0 +1,59 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var BUGNUMBER = 1069063;
+var summary = "Implement Array.prototype.includes";
+
+print(BUGNUMBER + ": " + summary);
+
+assertEq(typeof [].includes, "function");
+assertEq([].includes.length, 1);
+
+assertTrue([1, 2, 3].includes(2));
+assertTrue([1,,2].includes(2));
+assertTrue([1, 2, 3].includes(2, 1));
+assertTrue([1, 2, 3].includes(2, -2));
+assertTrue([1, 2, 3].includes(2, -100));
+assertTrue([Object, Function, Array].includes(Function));
+assertTrue([-0].includes(0));
+assertTrue([NaN].includes(NaN));
+assertTrue([,].includes());
+assertTrue(staticIncludes("123", "2"));
+assertTrue(staticIncludes({length: 3, 1: 2}, 2));
+assertTrue(staticIncludes({length: 3, 1: 2, get 3(){throw ""}}, 2));
+assertTrue(staticIncludes({length: 3, get 1() {return 2}}, 2));
+assertTrue(staticIncludes({__proto__: {1: 2}, length: 3}, 2));
+assertTrue(staticIncludes(new Proxy([1], {get(){return 2}}), 2));
+
+assertFalse([1, 2, 3].includes("2"));
+assertFalse([1, 2, 3].includes(2, 2));
+assertFalse([1, 2, 3].includes(2, -1));
+assertFalse([undefined].includes(NaN));
+assertFalse([{}].includes({}));
+assertFalse(staticIncludes({length: 3, 1: 2}, 2, 2));
+assertFalse(staticIncludes({length: 3, get 0(){delete this[1]}, 1: 2}, 2));
+assertFalse(staticIncludes({length: -100, 0: 1}, 1));
+
+assertThrowsInstanceOf(() => staticIncludes(), TypeError);
+assertThrowsInstanceOf(() => staticIncludes(null), TypeError);
+assertThrowsInstanceOf(() => staticIncludes({get length(){throw TypeError()}}), TypeError);
+assertThrowsInstanceOf(() => staticIncludes({length: 3, get 1() {throw TypeError()}}, 2), TypeError);
+assertThrowsInstanceOf(() => staticIncludes({__proto__: {get 1() {throw TypeError()}}, length: 3}, 2), TypeError);
+assertThrowsInstanceOf(() => staticIncludes(new Proxy([1], {get(){throw TypeError()}})), TypeError);
+
+function assertTrue(v) {
+ assertEq(v, true);
+}
+
+function assertFalse(v) {
+ assertEq(v, false);
+}
+
+function staticIncludes(o, v, f) {
+ return [].includes.call(o, v, f);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_7/Array/shell.js b/js/src/tests/ecma_7/Array/shell.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/js/src/tests/ecma_7/Array/shell.js
diff --git a/js/src/tests/ecma_7/AsyncFunctions/BoundNames.js b/js/src/tests/ecma_7/AsyncFunctions/BoundNames.js
new file mode 100644
index 000000000..743f4fdcc
--- /dev/null
+++ b/js/src/tests/ecma_7/AsyncFunctions/BoundNames.js
@@ -0,0 +1,21 @@
+var BUGNUMBER = 1185106;
+var summary = "Bound names of async functions";
+
+print(BUGNUMBER + ": " + summary);
+
+async function test() {}
+assertEq(test.name, "test");
+
+var test2 = (async function test2() {});
+assertEq(test2.name, "test2");
+
+var anon = async function() {};
+assertEq(anon.name, "");
+
+if (typeof Reflect !== "undefined" && Reflect.parse) {
+ var tree = Reflect.parse("export default async function() {}", { target: "module" });
+ assertEq(tree.body[0].declaration.id.name, "*default*");
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_7/AsyncFunctions/EarlyErrors.js b/js/src/tests/ecma_7/AsyncFunctions/EarlyErrors.js
new file mode 100644
index 000000000..cb28d104b
--- /dev/null
+++ b/js/src/tests/ecma_7/AsyncFunctions/EarlyErrors.js
@@ -0,0 +1,51 @@
+var BUGNUMBER = 1185106;
+var summary = "EarlyErrors for async function";
+
+print(BUGNUMBER + ": " + summary);
+
+function assertThrowsSE(code) {
+ assertThrows(() => Reflect.parse(code), SyntaxError);
+}
+
+if (typeof Reflect !== "undefined" && Reflect.parse) {
+ // If FormalParameters Contains AwaitExpression is true.
+ assertThrowsSE("async function a(k = await 3) {}");
+ assertThrowsSE("(async function(k = await 3) {})");
+ assertThrowsSE("(async function a(k = await 3) {})");
+
+ // If BindingIdentifier is `eval` or `arguments`.
+ assertThrowsSE("'use strict'; async function eval() {}");
+ assertThrowsSE("'use strict'; (async function eval() {})");
+
+ assertThrowsSE("'use strict'; async function arguments() {}");
+ assertThrowsSE("'use strict'; (async function arguments() {})");
+
+ // If any element of the BoundNames of FormalParameters also occurs in the
+ // LexicallyDeclaredNames of AsyncFunctionBody.
+ assertThrowsSE("async function a(x) { let x; }");
+ assertThrowsSE("(async function(x) { let x; })");
+ assertThrowsSE("(async function a(x) { let x; })");
+
+ // If FormalParameters contains SuperProperty is true.
+ assertThrowsSE("async function a(k = super.prop) { }");
+ assertThrowsSE("(async function(k = super.prop) {})");
+ assertThrowsSE("(async function a(k = super.prop) {})");
+
+ // If AsyncFunctionBody contains SuperProperty is true.
+ assertThrowsSE("async function a() { super.prop(); }");
+ assertThrowsSE("(async function() { super.prop(); })");
+ assertThrowsSE("(async function a() { super.prop(); })");
+
+ // If FormalParameters contains SuperCall is true.
+ assertThrowsSE("async function a(k = super()) {}");
+ assertThrowsSE("(async function(k = super()) {})");
+ assertThrowsSE("(async function a(k = super()) {})");
+
+ // If AsyncFunctionBody contains SuperCall is true.
+ assertThrowsSE("async function a() { super(); }");
+ assertThrowsSE("(async function() { super(); })");
+ assertThrowsSE("(async function a() { super(); })");
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_7/AsyncFunctions/arguments_callee.js b/js/src/tests/ecma_7/AsyncFunctions/arguments_callee.js
new file mode 100644
index 000000000..2a577e0b9
--- /dev/null
+++ b/js/src/tests/ecma_7/AsyncFunctions/arguments_callee.js
@@ -0,0 +1,31 @@
+// |reftest| skip-if(!xulRuntime.shell) -- needs drainJobQueue
+
+var BUGNUMBER = 1185106;
+var summary = "arguments.callee in sloppy mode should return wrapped function";
+
+print(BUGNUMBER + ": " + summary);
+
+async function decl1() {
+ return arguments.callee;
+}
+assertEventuallyEq(decl1(), decl1);
+
+var expr1 = async function foo() {
+ return arguments.callee;
+};
+assertEventuallyEq(expr1(), expr1);
+
+var expr2 = async function() {
+ return arguments.callee;
+};
+assertEventuallyEq(expr2(), expr2);
+
+var obj = {
+ async method1() {
+ return arguments.callee;
+ }
+};
+assertEventuallyEq(obj.method1(), obj.method1);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_7/AsyncFunctions/await-newline.js b/js/src/tests/ecma_7/AsyncFunctions/await-newline.js
new file mode 100644
index 000000000..dc42fa481
--- /dev/null
+++ b/js/src/tests/ecma_7/AsyncFunctions/await-newline.js
@@ -0,0 +1,15 @@
+// |reftest| skip-if(!xulRuntime.shell) -- needs drainJobQueue
+
+var BUGNUMBER = 1331009;
+var summary = "Newline is allowed between await and operand";
+
+print(BUGNUMBER + ": " + summary);
+
+var expr = async function foo() {
+ return await
+ 10;
+};
+assertEventuallyEq(expr(), 10);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_7/AsyncFunctions/clone.js b/js/src/tests/ecma_7/AsyncFunctions/clone.js
new file mode 100644
index 000000000..2a4d5f8e0
--- /dev/null
+++ b/js/src/tests/ecma_7/AsyncFunctions/clone.js
@@ -0,0 +1,22 @@
+// |reftest| skip-if(!xulRuntime.shell) -- needs clone, cloneAndExecuteScript, drainJobQueue
+
+// Async function cannot be cloned.
+assertThrowsInstanceOf(() => clone(async function f() {}), TypeError);
+
+// unwrapped async function can be cloned.
+let g = newGlobal();
+cloneAndExecuteScript(`
+async function f() {
+ var a = await 1;
+ var b = await 2;
+ var c = await 3;
+ return a + b + c;
+}
+var V;
+f().then(v => V = v);
+drainJobQueue();
+`, g);
+assertEq(g.V, 6);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_7/AsyncFunctions/constructor.js b/js/src/tests/ecma_7/AsyncFunctions/constructor.js
new file mode 100644
index 000000000..ccacb4363
--- /dev/null
+++ b/js/src/tests/ecma_7/AsyncFunctions/constructor.js
@@ -0,0 +1,33 @@
+var BUGNUMBER = 1185106;
+var summary = "async function constructor and prototype";
+
+print(BUGNUMBER + ": " + summary);
+
+var f1 = async function() {};
+
+var AsyncFunction = f1.constructor;
+var AsyncFunctionPrototype = AsyncFunction.prototype;
+
+assertEq(AsyncFunction.name, "AsyncFunction");
+assertEq(AsyncFunction.length, 1);
+assertEq(Object.getPrototypeOf(async function() {}), AsyncFunctionPrototype);
+
+assertEq(AsyncFunctionPrototype.constructor, AsyncFunction);
+
+var f2 = AsyncFunction("await 1");
+assertEq(f2.constructor, AsyncFunction);
+assertEq(f2.length, 0);
+assertEq(Object.getPrototypeOf(f2), AsyncFunctionPrototype);
+
+var f3 = new AsyncFunction("await 1");
+assertEq(f3.constructor, AsyncFunction);
+assertEq(f3.length, 0);
+assertEq(Object.getPrototypeOf(f3), AsyncFunctionPrototype);
+
+var f4 = AsyncFunction("a", "b", "c", "await 1");
+assertEq(f4.constructor, AsyncFunction);
+assertEq(f4.length, 3);
+assertEq(Object.getPrototypeOf(f4), AsyncFunctionPrototype);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_7/AsyncFunctions/identity.js b/js/src/tests/ecma_7/AsyncFunctions/identity.js
new file mode 100644
index 000000000..f3876bf23
--- /dev/null
+++ b/js/src/tests/ecma_7/AsyncFunctions/identity.js
@@ -0,0 +1,14 @@
+// |reftest| skip-if(!xulRuntime.shell) -- needs drainJobQueue
+
+var BUGNUMBER = 1185106;
+var summary = "Named async function expression should get wrapped function for the name inside it";
+
+print(BUGNUMBER + ": " + summary);
+
+var expr = async function foo() {
+ return foo;
+};
+assertEventuallyEq(expr(), expr);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_7/AsyncFunctions/length.js b/js/src/tests/ecma_7/AsyncFunctions/length.js
new file mode 100644
index 000000000..da95e23b8
--- /dev/null
+++ b/js/src/tests/ecma_7/AsyncFunctions/length.js
@@ -0,0 +1,12 @@
+var BUGNUMBER = 1185106;
+var summary = "async function length";
+
+print(BUGNUMBER + ": " + summary);
+
+assertEq(async function() {}.length, 0);
+assertEq(async function(a) {}.length, 1);
+assertEq(async function(a, b, c) {}.length, 3);
+assertEq(async function(a, b, c, ...d) {}.length, 3);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_7/AsyncFunctions/methods.js b/js/src/tests/ecma_7/AsyncFunctions/methods.js
new file mode 100644
index 000000000..061a0e826
--- /dev/null
+++ b/js/src/tests/ecma_7/AsyncFunctions/methods.js
@@ -0,0 +1,61 @@
+// |reftest| skip-if(!xulRuntime.shell) -- needs drainJobQueue
+var BUGNUMBER = 1185106;
+var summary = "async methods semantics";
+
+print(BUGNUMBER + ": " + summary);
+
+class X {
+ constructor() {
+ this.value = 42;
+ }
+ async getValue() {
+ return this.value;
+ }
+ setValue(value) {
+ this.value = value;
+ }
+ async increment() {
+ var value = await this.getValue();
+ this.setValue(value + 1);
+ return this.getValue();
+ }
+ async getBaseClassName() {
+ return 'X';
+ }
+ static async getStaticValue() {
+ return 44;
+ }
+ async 10() {
+ return 46;
+ }
+ async ["foo"]() {
+ return 47;
+ }
+}
+
+class Y extends X {
+ async getBaseClassName() {
+ return super.getBaseClassName();
+ }
+}
+
+var objLiteral = {
+ async get() {
+ return 45;
+ },
+ someStuff: 5
+};
+
+var x = new X();
+var y = new Y();
+
+assertEventuallyEq(x.getValue(), 42);
+assertEventuallyEq(x.increment(), 43);
+assertEventuallyEq(x[10](), 46);
+assertEventuallyEq(x.foo(), 47);
+assertEventuallyEq(X.getStaticValue(), 44);
+assertEventuallyEq(objLiteral.get(), 45);
+assertEventuallyEq(y.getBaseClassName(), 'X');
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_7/AsyncFunctions/property.js b/js/src/tests/ecma_7/AsyncFunctions/property.js
new file mode 100644
index 000000000..53f779c33
--- /dev/null
+++ b/js/src/tests/ecma_7/AsyncFunctions/property.js
@@ -0,0 +1,49 @@
+var BUGNUMBER = 1185106;
+var summary = "async name token in property and object destructuring pattern";
+
+print(BUGNUMBER + ": " + summary);
+
+{
+ let a = { async: 10 };
+ assertEq(a.async, 10);
+}
+
+{
+ let a = { async() {} };
+ assertEq(a.async instanceof Function, true);
+ assertEq(a.async.name, "async");
+}
+
+{
+ let async = 11;
+ let a = { async };
+ assertEq(a.async, 11);
+}
+
+{
+ let { async } = { async: 12 };
+ assertEq(async, 12);
+}
+
+{
+ let { async = 13 } = {};
+ assertEq(async, 13);
+}
+
+{
+ let { async: a = 14 } = {};
+ assertEq(a, 14);
+}
+
+{
+ let { async, other } = { async: 15, other: 16 };
+ assertEq(async, 15);
+ assertEq(other, 16);
+
+ let a = { async, other };
+ assertEq(a.async, 15);
+ assertEq(a.other, 16);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_7/AsyncFunctions/semantics.js b/js/src/tests/ecma_7/AsyncFunctions/semantics.js
new file mode 100644
index 000000000..cb2a04c3f
--- /dev/null
+++ b/js/src/tests/ecma_7/AsyncFunctions/semantics.js
@@ -0,0 +1,169 @@
+// |reftest| skip-if(!xulRuntime.shell) -- needs drainJobQueue
+var BUGNUMBER = 1185106;
+var summary = "async functions semantics";
+
+print(BUGNUMBER + ": " + summary);
+
+async function empty() {
+}
+assertEventuallyEq(empty(), undefined);
+
+async function simpleReturn() {
+ return 1;
+}
+assertEventuallyEq(simpleReturn(), 1);
+
+async function simpleAwait() {
+ var result = await 2;
+ return result;
+}
+assertEventuallyEq(simpleAwait(), 2);
+
+async function simpleAwaitAsync() {
+ var result = await simpleReturn();
+ return 2 + result;
+}
+assertEventuallyEq(simpleAwaitAsync(), 3);
+
+async function returnOtherAsync() {
+ return 1 + await simpleAwaitAsync();
+}
+assertEventuallyEq(returnOtherAsync(), 4);
+
+async function simpleThrower() {
+ throw new Error();
+}
+assertEventuallyThrows(simpleThrower(), Error);
+
+async function delegatedThrower() {
+ var val = await simpleThrower();
+ return val;
+}
+
+async function tryCatch() {
+ try {
+ await delegatedThrower();
+ return 'FAILED';
+ } catch (_) {
+ return 5;
+ }
+}
+assertEventuallyEq(tryCatch(), 5);
+
+async function tryCatchThrow() {
+ try {
+ await delegatedThrower();
+ return 'FAILED';
+ } catch (_) {
+ return delegatedThrower();
+ }
+}
+assertEventuallyThrows(tryCatchThrow(), Error);
+
+async function wellFinally() {
+ try {
+ await delegatedThrower();
+ } catch (_) {
+ return 'FAILED';
+ } finally {
+ return 6;
+ }
+}
+assertEventuallyEq(wellFinally(), 6);
+
+async function finallyMayFail() {
+ try {
+ await delegatedThrower();
+ } catch (_) {
+ return 5;
+ } finally {
+ return delegatedThrower();
+ }
+}
+assertEventuallyThrows(finallyMayFail(), Error);
+
+async function embedded() {
+ async function inner() {
+ return 7;
+ }
+ return await inner();
+}
+assertEventuallyEq(embedded(), 7);
+
+// recursion, it works!
+async function fib(n) {
+ return (n == 0 || n == 1) ? n : await fib(n - 1) + await fib(n - 2);
+}
+assertEventuallyEq(fib(6), 8);
+
+// mutual recursion
+async function isOdd(n) {
+ async function isEven(n) {
+ return n === 0 || await isOdd(n - 1);
+ }
+ return n !== 0 && await isEven(n - 1);
+}
+assertEventuallyEq(isOdd(12).then(v => v ? "oops" : 12), 12);
+
+// recursion, take three!
+var hardcoreFib = async function fib2(n) {
+ return (n == 0 || n == 1) ? n : await fib2(n - 1) + await fib2(n - 2);
+}
+assertEventuallyEq(hardcoreFib(7), 13);
+
+var asyncExpr = async function() {
+ return 10;
+}
+assertEventuallyEq(asyncExpr(), 10);
+
+var namedAsyncExpr = async function simple() {
+ return 11;
+}
+assertEventuallyEq(namedAsyncExpr(), 11);
+
+async function executionOrder() {
+ var value = 0;
+ async function first() {
+ return (value = value === 0 ? 1 : value);
+ }
+ async function second() {
+ return (value = value === 0 ? 2 : value);
+ }
+ async function third() {
+ return (value = value === 0 ? 3 : value);
+ }
+ return await first() + await second() + await third() + 6;
+}
+assertEventuallyEq(executionOrder(), 9);
+
+async function miscellaneous() {
+ if (arguments.length === 3 &&
+ arguments.callee.name === "miscellaneous")
+ return 14;
+}
+assertEventuallyEq(miscellaneous(1, 2, 3), 14);
+
+function thrower() {
+ throw 15;
+}
+
+async function defaultArgs(arg = thrower()) {
+}
+assertEventuallyEq(defaultArgs().catch(e => e), 15);
+
+let arrowAwaitExpr = async () => await 2;
+assertEventuallyEq(arrowAwaitExpr(), 2);
+
+let arrowAwaitBlock = async () => { return await 2; };
+assertEventuallyEq(arrowAwaitBlock(), 2);
+
+// Async functions are not constructible
+assertThrows(() => {
+ async function Person() {
+
+ }
+ new Person();
+}, TypeError);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_7/AsyncFunctions/shell.js b/js/src/tests/ecma_7/AsyncFunctions/shell.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/js/src/tests/ecma_7/AsyncFunctions/shell.js
diff --git a/js/src/tests/ecma_7/AsyncFunctions/syntax-arrow.js b/js/src/tests/ecma_7/AsyncFunctions/syntax-arrow.js
new file mode 100644
index 000000000..6dc8d8621
--- /dev/null
+++ b/js/src/tests/ecma_7/AsyncFunctions/syntax-arrow.js
@@ -0,0 +1,104 @@
+var BUGNUMBER = 1185106;
+var summary = "async arrow function syntax";
+
+print(BUGNUMBER + ": " + summary);
+
+if (typeof Reflect !== "undefined" && Reflect.parse) {
+ // Parameters.
+ Reflect.parse("async () => 1");
+ Reflect.parse("async a => 1");
+ Reflect.parse("async (a) => 1");
+ Reflect.parse("async async => 1");
+ Reflect.parse("async (async) => 1");
+ Reflect.parse("async ([a]) => 1");
+ Reflect.parse("async ([a, b]) => 1");
+ Reflect.parse("async ({a}) => 1");
+ Reflect.parse("async ({a, b}) => 1");
+
+ assertThrows(() => Reflect.parse("async await => 1"), SyntaxError);
+ assertThrows(() => Reflect.parse("async (await) => 1"), SyntaxError);
+ assertThrows(() => Reflect.parse("async ([await]) => 1"), SyntaxError);
+ assertThrows(() => Reflect.parse("async ({await}) => 1"), SyntaxError);
+
+ assertThrows(() => Reflect.parse("async (a=await) => 1"), SyntaxError);
+ assertThrows(() => Reflect.parse("async ([a=await]) => 1"), SyntaxError);
+ assertThrows(() => Reflect.parse("async ({a=await}) => 1"), SyntaxError);
+
+ assertThrows(() => Reflect.parse("async (a=await 1) => 1"), SyntaxError);
+ assertThrows(() => Reflect.parse("async ([a=await 1]) => 1"), SyntaxError);
+ assertThrows(() => Reflect.parse("async ({a=await 1}) => 1"), SyntaxError);
+
+ assertThrows(() => Reflect.parse("async [a] => 1"), SyntaxError);
+ assertThrows(() => Reflect.parse("async [a, b] => 1"), SyntaxError);
+ assertThrows(() => Reflect.parse("async {a} => 1"), SyntaxError);
+ assertThrows(() => Reflect.parse("async {a: b} => 1"), SyntaxError);
+
+ // Expression body.
+ Reflect.parse("async a => a == b");
+
+ // Expression body with nested async function.
+ Reflect.parse("async a => async");
+ Reflect.parse("async a => async b => c");
+ Reflect.parse("async a => async function() {}");
+ Reflect.parse("async a => async function b() {}");
+
+ assertThrows(() => Reflect.parse("async a => async b"), SyntaxError);
+ assertThrows(() => Reflect.parse("async a => async function"), SyntaxError);
+ assertThrows(() => Reflect.parse("async a => async function()"), SyntaxError);
+
+ // Expression body with `await`.
+ Reflect.parse("async a => await 1");
+ Reflect.parse("async a => await await 1");
+ Reflect.parse("async a => await await await 1");
+
+ assertThrows(() => Reflect.parse("async a => await"), SyntaxError);
+ assertThrows(() => Reflect.parse("async a => await await"), SyntaxError);
+
+ // `await` is Unary Expression and it cannot have `async` function as an
+ // operand.
+ assertThrows(() => Reflect.parse("async a => await async X => Y"), SyntaxError);
+ Reflect.parse("async a => await (async X => Y)");
+ // But it can have `async` identifier as an operand.
+ Reflect.parse("async async => await async");
+
+ // Block body.
+ Reflect.parse("async X => {yield}");
+
+ // `yield` handling.
+ Reflect.parse("async X => yield");
+ Reflect.parse("async yield => X");
+ Reflect.parse("async yield => yield");
+ Reflect.parse("async X => {yield}");
+
+ Reflect.parse("async X => {yield}");
+ Reflect.parse("async yield => {X}");
+ Reflect.parse("async yield => {yield}");
+ Reflect.parse("function* g() { async X => yield }");
+
+ assertThrows(() => Reflect.parse("'use strict'; async yield => X"), SyntaxError);
+ assertThrows(() => Reflect.parse("'use strict'; async (yield) => X"), SyntaxError);
+ assertThrows(() => Reflect.parse("'use strict'; async X => yield"), SyntaxError);
+ assertThrows(() => Reflect.parse("'use strict'; async X => {yield}"), SyntaxError);
+
+ assertThrows(() => Reflect.parse("function* g() { async yield => X }"));
+ assertThrows(() => Reflect.parse("function* g() { async (yield) => X }"));
+ assertThrows(() => Reflect.parse("function* g() { async ([yield]) => X }"));
+ assertThrows(() => Reflect.parse("function* g() { async ({yield}) => X }"));
+
+ // Not async functions.
+ Reflect.parse("async ()");
+ Reflect.parse("async (a)");
+ Reflect.parse("async (async)");
+ Reflect.parse("async ([a])");
+ Reflect.parse("async ([a, b])");
+ Reflect.parse("async ({a})");
+ Reflect.parse("async ({a, b})");
+
+ // Async arrow function is assignment expression.
+ Reflect.parse("a ? async () => {1} : b");
+ Reflect.parse("a ? b : async () => {1}");
+ assertThrows(() => Reflect.parse("async () => {1} ? a : b"), SyntaxError);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_7/AsyncFunctions/syntax-modules.js b/js/src/tests/ecma_7/AsyncFunctions/syntax-modules.js
new file mode 100644
index 000000000..c83056f54
--- /dev/null
+++ b/js/src/tests/ecma_7/AsyncFunctions/syntax-modules.js
@@ -0,0 +1,25 @@
+var BUGNUMBER = 1185106;
+var summary = "async/await syntax in module";
+
+print(BUGNUMBER + ": " + summary);
+
+if (typeof parseModule === "function") {
+ parseModule("async function f() { await 3; }");
+ parseModule("async function f() { await 3; }");
+ assertThrows(() => parseModule("var await = 5;"), SyntaxError);
+ assertThrows(() => parseModule("await;"), SyntaxError);
+ assertThrows(() => parseModule("await 5;"), SyntaxError);
+ assertThrows(() => parseModule("function f() { await 5; }"), SyntaxError);
+ assertThrows(() => parseModule("() => { await 5; }"), SyntaxError);
+ assertThrows(() => parseModule("export var await;"), SyntaxError);
+ assertThrows(() => parseModule("await => 1;"), SyntaxError);
+ assertThrows(() => parseModule("async function f() { function g() { await 3; } }"), SyntaxError);
+
+ if (typeof Reflect !== "undefined" && Reflect.parse) {
+ assertThrows(() => Reflect.parse("export default async function() { yield; }", { target: "module" }), SyntaxError);
+ assertThrows(() => Reflect.parse("export default async function() { yield = 1; }", { target: "module" }), SyntaxError);
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_7/AsyncFunctions/syntax.js b/js/src/tests/ecma_7/AsyncFunctions/syntax.js
new file mode 100644
index 000000000..28e5febc1
--- /dev/null
+++ b/js/src/tests/ecma_7/AsyncFunctions/syntax.js
@@ -0,0 +1,86 @@
+var BUGNUMBER = 1185106;
+var summary = "async/await syntax";
+
+print(BUGNUMBER + ": " + summary);
+
+if (typeof Reflect !== "undefined" && Reflect.parse) {
+ assertEq(Reflect.parse("function a() {}").body[0].async, false);
+ assertEq(Reflect.parse("function* a() {}").body[0].async, false);
+ assertEq(Reflect.parse("async function a() {}").body[0].async, true);
+ assertEq(Reflect.parse("() => {}").body[0].async, undefined);
+
+ // Async generators are not allowed (with regards to spec)
+ assertThrows(() => Reflect.parse("async function* a() {}"), SyntaxError);
+
+ // No line terminator after async
+ assertEq(Reflect.parse("async\nfunction a(){}").body[0].expression.name, "async");
+
+ // Async function expressions
+ assertEq(Reflect.parse("(async function() {})()").body[0].expression.callee.async, true);
+ assertEq(Reflect.parse("var k = async function() {}").body[0].declarations[0].init.async, true);
+ assertEq(Reflect.parse("var nmd = async function named() {}").body[0].declarations[0].init.id.name, "named");
+
+ // `await` handling for function declaration name inherits.
+ assertEq(Reflect.parse("async function await() {}").body[0].id.name, "await");
+ assertThrows(() => Reflect.parse("async function f() { async function await() {} }"), SyntaxError);
+
+ // `await` is not allowed in function expression name.
+ assertThrows(() => Reflect.parse("(async function await() {})"), SyntaxError);
+
+ // Awaiting not directly inside an async function is not allowed
+ assertThrows(() => Reflect.parse("await 4;"), SyntaxError);
+ assertThrows(() => Reflect.parse("function a() { await 4; }"), SyntaxError);
+ assertThrows(() => Reflect.parse("function* a() { await 4; }"), SyntaxError);
+ assertThrows(() => Reflect.parse("async function k() { function a() { await 4; } }"), SyntaxError);
+
+ // Await is not allowed as a default expr.
+ assertThrows(() => Reflect.parse("async function a(k = await 3) {}"), SyntaxError);
+ assertThrows(() => Reflect.parse("async function a() { async function b(k = await 3) {} }"), SyntaxError);
+ assertThrows(() => Reflect.parse("async function a() { async function b(k = [await 3]) {} }"), SyntaxError);
+
+ assertThrows(() => Reflect.parse("async function a() { async function b([k = await 3]) {} }"), SyntaxError);
+ assertThrows(() => Reflect.parse("async function a() { async function b([k = [await 3]]) {} }"), SyntaxError);
+ assertThrows(() => Reflect.parse("async function a() { async function b({k = await 3}) {} }"), SyntaxError);
+ assertThrows(() => Reflect.parse("async function a() { async function b({k = [await 3]}) {} }"), SyntaxError);
+
+ // Await is not legal as an identifier in an async function.
+ assertThrows(() => Reflect.parse("async function a() { var await = 4; }"), SyntaxError);
+ assertThrows(() => Reflect.parse("async function a() { return await; }"), SyntaxError);
+
+ // Await is still available as an identifier name in strict mode code.
+ Reflect.parse("function a() { 'use strict'; var await = 3; }");
+ Reflect.parse("'use strict'; var await = 3;");
+
+ // Await is treated differently depending on context. Various cases.
+ Reflect.parse("var await = 3; async function a() { await 4; }");
+ Reflect.parse("async function a() { await 4; } var await = 5");
+ Reflect.parse("async function a() { function b() { return await; } }");
+
+ Reflect.parse("async function a() { var k = { async: 4 } }");
+
+ Reflect.parse("function a() { await: 4 }");
+
+ assertEq(Reflect.parse("async function a() { await 4; }")
+ .body[0].body.body[0].expression.operator, "await");
+
+ assertEq(Reflect.parse("async function a() { async function b() { await 4; } }")
+ .body[0].body.body[0].body.body[0].expression.operator, "await");
+
+ // operator priority test
+ assertEq(Reflect.parse("async function a() { await 2 + 3; }")
+ .body[0].body.body[0].expression.left.argument.value, 2);
+ assertEq(Reflect.parse("async function a() { await 2 + 3; }")
+ .body[0].body.body[0].expression.left.operator, "await");
+ assertEq(Reflect.parse("async function a() { await 2 + 3; }")
+ .body[0].body.body[0].expression.right.value, 3);
+
+ // blocks and other constructions
+ assertEq(Reflect.parse("{ async function a() { return 2; } }")
+ .body[0].body[0].async, true);
+
+ // Async function expression is primary expression.
+ Reflect.parse("(async function a() {}.constructor)");
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_7/AsyncFunctions/toString.js b/js/src/tests/ecma_7/AsyncFunctions/toString.js
new file mode 100644
index 000000000..39ae938c3
--- /dev/null
+++ b/js/src/tests/ecma_7/AsyncFunctions/toString.js
@@ -0,0 +1,24 @@
+var BUGNUMBER = 1185106;
+var summary = "async function toString";
+
+print(BUGNUMBER + ": " + summary);
+
+async function f1(a, b, c) { await a; }
+
+assertEq(f1.toString(),
+ "async function f1(a, b, c) { await a; }");
+
+assertEq(async function (a, b, c) { await a; }.toString(),
+ "async function (a, b, c) { await a; }");
+
+assertEq((async (a, b, c) => await a).toString(),
+ "async (a, b, c) => await a");
+
+assertEq((async (a, b, c) => { await a; }).toString(),
+ "async (a, b, c) => { await a; }");
+
+assertEq({ async foo(a, b, c) { await a; } }.foo.toString(),
+ "async function foo(a, b, c) { await a; }");
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_7/AsyncFunctions/yield.js b/js/src/tests/ecma_7/AsyncFunctions/yield.js
new file mode 100644
index 000000000..348d11f3d
--- /dev/null
+++ b/js/src/tests/ecma_7/AsyncFunctions/yield.js
@@ -0,0 +1,71 @@
+var BUGNUMBER = 1185106;
+var summary = "yield handling in async function";
+
+print(BUGNUMBER + ": " + summary);
+
+function testPassArgsBody(argsbody) {
+ Reflect.parse(`async function a${argsbody}`);
+ Reflect.parse(`(async function a${argsbody})`);
+ Reflect.parse(`(async function ${argsbody})`);
+ Reflect.parse(`({ async m${argsbody} })`);
+}
+
+function testErrorArgsBody(argsbody, prefix="") {
+ assertThrows(() => Reflect.parse(`${prefix} async function a${argsbody}`), SyntaxError);
+ assertThrows(() => Reflect.parse(`${prefix} (async function a${argsbody})`), SyntaxError);
+ assertThrows(() => Reflect.parse(`${prefix} (async function ${argsbody})`), SyntaxError);
+ assertThrows(() => Reflect.parse(`${prefix} ({ async m${argsbody} })`), SyntaxError);
+}
+
+function testErrorArgsBodyStrict(argsbody) {
+ testErrorArgsBody(argsbody);
+ testErrorArgsBody(argsbody, "'use strict'; ");
+ assertThrows(() => Reflect.parse(`class X { async m${argsbody} }`), SyntaxError);
+ assertThrows(() => Reflect.parse(`class X { static async m${argsbody} }`), SyntaxError);
+ assertThrows(() => Reflect.parse(`export default async function ${argsbody}`, { target: "module" }), SyntaxError);
+}
+
+if (typeof Reflect !== "undefined" && Reflect.parse) {
+ // `yield` handling is inherited in async function declaration name.
+ Reflect.parse("async function yield() {}");
+ Reflect.parse("function f() { async function yield() {} }");
+ assertThrows(() => Reflect.parse("function* g() { async function yield() {} }"), SyntaxError);
+ assertThrows(() => Reflect.parse("'use strict'; async function yield() {}"), SyntaxError);
+
+ // `yield` is treated as an identifier in an async function expression name.
+ // `yield` is not allowed as an identifier in strict code.
+ Reflect.parse("(async function yield() {});");
+ Reflect.parse("function f() { (async function yield() {}); }");
+ Reflect.parse("function* g() { (async function yield() {}); }");
+ assertThrows(() => Reflect.parse("'use strict'; (async function yield() {});"), SyntaxError);
+
+ // `yield` handling is inherited in async method name.
+ Reflect.parse("({ async yield() {} });");
+ Reflect.parse("function f() { ({ async yield() {} }); }");
+ Reflect.parse("function* g() { ({ async yield() {} }); }");
+ Reflect.parse("'use strict'; ({ async yield() {} });");
+ Reflect.parse("class X { async yield() {} }");
+
+ Reflect.parse("({ async [yield]() {} });");
+ Reflect.parse("function f() { ({ async [yield]() {} }); }");
+ Reflect.parse("function* g() { ({ async [yield]() {} }); }");
+ assertThrows(() => Reflect.parse("'use strict'; ({ async [yield]() {} });"), SyntaxError);
+ assertThrows(() => Reflect.parse("class X { async [yield]() {} }"), SyntaxError);
+
+ // `yield` is treated as an identifier in an async function parameter
+ // `yield` is not allowed as an identifier in strict code.
+ testPassArgsBody("(yield) {}");
+ testPassArgsBody("(yield = 1) {}");
+ testPassArgsBody("(a = yield) {}");
+ testErrorArgsBodyStrict("(yield 3) {}");
+ testErrorArgsBodyStrict("(a = yield 3) {}");
+
+ // `yield` is treated as an identifier in an async function body
+ // `yield` is not allowed as an identifier in strict code.
+ testPassArgsBody("() { yield; }");
+ testPassArgsBody("() { yield = 1; }");
+ testErrorArgsBodyStrict("() { yield 3; }");
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_7/Destructuring/browser.js b/js/src/tests/ecma_7/Destructuring/browser.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/js/src/tests/ecma_7/Destructuring/browser.js
diff --git a/js/src/tests/ecma_7/Destructuring/duplicate-__proto__.js b/js/src/tests/ecma_7/Destructuring/duplicate-__proto__.js
new file mode 100644
index 000000000..a8f76014e
--- /dev/null
+++ b/js/src/tests/ecma_7/Destructuring/duplicate-__proto__.js
@@ -0,0 +1,54 @@
+/* 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/. */
+
+
+// Destructuring assignment.
+var a, b;
+({__proto__: a, __proto__: b} = {});
+assertEq(a, Object.prototype);
+assertEq(b, Object.prototype);
+
+// Destructuring binding with "var".
+var {__proto__: a, __proto__: b} = {};
+assertEq(a, Object.prototype);
+assertEq(b, Object.prototype);
+
+// Destructuring binding with "let".
+{
+ let {__proto__: a, __proto__: b} = {};
+ assertEq(a, Object.prototype);
+ assertEq(b, Object.prototype);
+}
+
+// Destructuring binding with "const".
+{
+ const {__proto__: a, __proto__: b} = {};
+ assertEq(a, Object.prototype);
+ assertEq(b, Object.prototype);
+}
+
+// Function parameters.
+function f1({__proto__: a, __proto__: b}) {
+ assertEq(a, Object.prototype);
+ assertEq(b, Object.prototype);
+}
+f1({});
+
+// Arrow function parameters.
+var f2 = ({__proto__: a, __proto__: b}) => {
+ assertEq(a, Object.prototype);
+ assertEq(b, Object.prototype);
+};
+f2({});
+
+// Arrow function parameters with defaults (initially parsed as destructuring assignment).
+var f3 = ({__proto__: a, __proto__: b} = {}) => {
+ assertEq(a, Object.prototype);
+ assertEq(b, Object.prototype);
+};
+f3({});
+
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_7/Destructuring/rest-parameter-aray-iterator.js b/js/src/tests/ecma_7/Destructuring/rest-parameter-aray-iterator.js
new file mode 100644
index 000000000..bf9643fd7
--- /dev/null
+++ b/js/src/tests/ecma_7/Destructuring/rest-parameter-aray-iterator.js
@@ -0,0 +1,40 @@
+/* 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/. */
+
+// Destructuring rest arrays call the array iterator. This behaviour is
+// observable when Array.prototype[Symbol.iterator] is overridden.
+
+const oldArrayIterator = Array.prototype[Symbol.iterator];
+try {
+ let callCount = 0;
+ Array.prototype[Symbol.iterator] = function() {
+ callCount += 1;
+ return oldArrayIterator.call(this);
+ };
+
+ // Array iterator called exactly once.
+ function arrayIterCalledOnce(...[]) { }
+ assertEq(callCount, 0);
+ arrayIterCalledOnce();
+ assertEq(callCount, 1);
+
+ // Array iterator not called before rest parameter.
+ callCount = 0;
+ function arrayIterNotCalledBeforeRest(t = assertEq(callCount, 0), ...[]) { }
+ assertEq(callCount, 0);
+ arrayIterNotCalledBeforeRest();
+ assertEq(callCount, 1);
+
+ // Array iterator called when rest parameter is processed.
+ callCount = 0;
+ function arrayIterCalledWhenDestructuring(...[t = assertEq(callCount, 1)]) { }
+ assertEq(callCount, 0);
+ arrayIterCalledWhenDestructuring();
+ assertEq(callCount, 1);
+} finally {
+ Array.prototype[Symbol.iterator] = oldArrayIterator;
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_7/Destructuring/rest-parameter-arguments.js b/js/src/tests/ecma_7/Destructuring/rest-parameter-arguments.js
new file mode 100644
index 000000000..e87cdff33
--- /dev/null
+++ b/js/src/tests/ecma_7/Destructuring/rest-parameter-arguments.js
@@ -0,0 +1,101 @@
+/* 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/. */
+
+// Ensure the |arguments| object works as expected when a destructuring rest
+// parameter is present.
+
+// |arguments.length| with destructuring rest array.
+function argsLengthEmptyRestArray(...[]) {
+ return arguments.length;
+}
+assertEq(argsLengthEmptyRestArray(), 0);
+assertEq(argsLengthEmptyRestArray(10), 1);
+assertEq(argsLengthEmptyRestArray(10, 20), 2);
+
+function argsLengthRestArray(...[a]) {
+ return arguments.length;
+}
+assertEq(argsLengthRestArray(), 0);
+assertEq(argsLengthRestArray(10), 1);
+assertEq(argsLengthRestArray(10, 20), 2);
+
+function argsLengthRestArrayWithDefault(...[a = 0]) {
+ return arguments.length;
+}
+assertEq(argsLengthRestArrayWithDefault(), 0);
+assertEq(argsLengthRestArrayWithDefault(10), 1);
+assertEq(argsLengthRestArrayWithDefault(10, 20), 2);
+
+
+// |arguments.length| with destructuring rest object.
+function argsLengthEmptyRestObject(...{}) {
+ return arguments.length;
+}
+assertEq(argsLengthEmptyRestObject(), 0);
+assertEq(argsLengthEmptyRestObject(10), 1);
+assertEq(argsLengthEmptyRestObject(10, 20), 2);
+
+function argsLengthRestObject(...{a}) {
+ return arguments.length;
+}
+assertEq(argsLengthRestObject(), 0);
+assertEq(argsLengthRestObject(10), 1);
+assertEq(argsLengthRestObject(10, 20), 2);
+
+function argsLengthRestObjectWithDefault(...{a = 0}) {
+ return arguments.length;
+}
+assertEq(argsLengthRestObjectWithDefault(), 0);
+assertEq(argsLengthRestObjectWithDefault(10), 1);
+assertEq(argsLengthRestObjectWithDefault(10, 20), 2);
+
+
+// |arguments| access with destructuring rest array.
+function argsAccessEmptyRestArray(...[]) {
+ return arguments[0];
+}
+assertEq(argsAccessEmptyRestArray(), undefined);
+assertEq(argsAccessEmptyRestArray(10), 10);
+assertEq(argsAccessEmptyRestArray(10, 20), 10);
+
+function argsAccessRestArray(...[a]) {
+ return arguments[0];
+}
+assertEq(argsAccessRestArray(), undefined);
+assertEq(argsAccessRestArray(10), 10);
+assertEq(argsAccessRestArray(10, 20), 10);
+
+function argsAccessRestArrayWithDefault(...[a = 0]) {
+ return arguments[0];
+}
+assertEq(argsAccessRestArrayWithDefault(), undefined);
+assertEq(argsAccessRestArrayWithDefault(10), 10);
+assertEq(argsAccessRestArrayWithDefault(10, 20), 10);
+
+
+// |arguments| access with destructuring rest object.
+function argsAccessEmptyRestObject(...{}) {
+ return arguments[0];
+}
+assertEq(argsAccessEmptyRestObject(), undefined);
+assertEq(argsAccessEmptyRestObject(10), 10);
+assertEq(argsAccessEmptyRestObject(10, 20), 10);
+
+function argsAccessRestObject(...{a}) {
+ return arguments[0];
+}
+assertEq(argsAccessRestObject(), undefined);
+assertEq(argsAccessRestObject(10), 10);
+assertEq(argsAccessRestObject(10, 20), 10);
+
+function argsAccessRestObjectWithDefault(...{a = 0}) {
+ return arguments[0];
+}
+assertEq(argsAccessRestObjectWithDefault(), undefined);
+assertEq(argsAccessRestObjectWithDefault(10), 10);
+assertEq(argsAccessRestObjectWithDefault(10, 20), 10);
+
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_7/Destructuring/rest-parameter-function-length.js b/js/src/tests/ecma_7/Destructuring/rest-parameter-function-length.js
new file mode 100644
index 000000000..5924e799a
--- /dev/null
+++ b/js/src/tests/ecma_7/Destructuring/rest-parameter-function-length.js
@@ -0,0 +1,41 @@
+/* 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/. */
+
+// Ensure function length is set correctly when a destructuring rest parameter
+// is present.
+
+assertEq(function(...[]) {}.length, 0);
+assertEq(function(...[a]) {}.length, 0);
+assertEq(function(...[a = 0]) {}.length, 0);
+assertEq(function(...{}) {}.length, 0);
+assertEq(function(...{p: a}) {}.length, 0);
+assertEq(function(...{p: a = 0}) {}.length, 0);
+assertEq(function(...{a = 0}) {}.length, 0);
+
+assertEq(function(x, ...[]) {}.length, 1);
+assertEq(function(x, ...[a]) {}.length, 1);
+assertEq(function(x, ...[a = 0]) {}.length, 1);
+assertEq(function(x, ...{}) {}.length, 1);
+assertEq(function(x, ...{p: a}) {}.length, 1);
+assertEq(function(x, ...{p: a = 0}) {}.length, 1);
+assertEq(function(x, ...{a = 0}) {}.length, 1);
+
+assertEq(function(x, y, ...[]) {}.length, 2);
+assertEq(function(x, y, ...[a]) {}.length, 2);
+assertEq(function(x, y, ...[a = 0]) {}.length, 2);
+assertEq(function(x, y, ...{}) {}.length, 2);
+assertEq(function(x, y, ...{p: a}) {}.length, 2);
+assertEq(function(x, y, ...{p: a = 0}) {}.length, 2);
+assertEq(function(x, y, ...{a = 0}) {}.length, 2);
+
+assertEq(function(x, y = 0, ...[]) {}.length, 1);
+assertEq(function(x, y = 0, ...[a]) {}.length, 1);
+assertEq(function(x, y = 0, ...[a = 0]) {}.length, 1);
+assertEq(function(x, y = 0, ...{}) {}.length, 1);
+assertEq(function(x, y = 0, ...{p: a}) {}.length, 1);
+assertEq(function(x, y = 0, ...{p: a = 0}) {}.length, 1);
+assertEq(function(x, y = 0, ...{a = 0}) {}.length, 1);
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_7/Destructuring/rest-parameter-spread-call-optimization.js b/js/src/tests/ecma_7/Destructuring/rest-parameter-spread-call-optimization.js
new file mode 100644
index 000000000..20f6a529d
--- /dev/null
+++ b/js/src/tests/ecma_7/Destructuring/rest-parameter-spread-call-optimization.js
@@ -0,0 +1,29 @@
+/* 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/. */
+
+// Ensure the spread-call optimization doesn't break when a destructuring rest
+// parameter is used.
+
+function spreadTarget() { return arguments.length; }
+
+function spreadOpt(...[r]){ return spreadTarget(...r); }
+assertEq(spreadOpt([]), 0);
+assertEq(spreadOpt([10]), 1);
+assertEq(spreadOpt([10, 20]), 2);
+assertEq(spreadOpt([10, 20, 30]), 3);
+
+function spreadOpt2(...[...r]){ return spreadTarget(...r); }
+assertEq(spreadOpt2(), 0);
+assertEq(spreadOpt2(10), 1);
+assertEq(spreadOpt2(10, 20), 2);
+assertEq(spreadOpt2(10, 20, 30), 3);
+
+function spreadOpt3(r, ...[]){ return spreadTarget(...r); }
+assertEq(spreadOpt3([]), 0);
+assertEq(spreadOpt3([10]), 1);
+assertEq(spreadOpt3([10, 20]), 2);
+assertEq(spreadOpt3([10, 20, 30]), 3);
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_7/Destructuring/rest-parameter-syntax.js b/js/src/tests/ecma_7/Destructuring/rest-parameter-syntax.js
new file mode 100644
index 000000000..a145d1a2d
--- /dev/null
+++ b/js/src/tests/ecma_7/Destructuring/rest-parameter-syntax.js
@@ -0,0 +1,87 @@
+/* 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/. */
+
+
+const bindingPatterns = [
+ "[]",
+ "[a]",
+ "[a, b]",
+ "[a, ...b]",
+ "[...a]",
+ "[...[]]",
+
+ "{}",
+ "{p: a}",
+ "{p: a = 0}",
+ "{p: {}}",
+ "{p: a, q: b}",
+ "{a}",
+ "{a, b}",
+ "{a = 0}",
+];
+
+const functions = [
+ p => `function f(${p}) {}`,
+ p => `function* g(${p}) {}`,
+ p => `({m(${p}) {}});`,
+ p => `(class {m(${p}) {}});`,
+ p => `(${p}) => {};`,
+];
+
+for (let pattern of bindingPatterns) {
+ for (let fn of functions) {
+ // No leading parameters.
+ eval(fn(`...${pattern}`));
+
+ // Leading normal parameters.
+ eval(fn(`x, ...${pattern}`));
+ eval(fn(`x, y, ...${pattern}`));
+
+ // Leading parameters with defaults.
+ eval(fn(`x = 0, ...${pattern}`));
+ eval(fn(`x = 0, y = 0, ...${pattern}`));
+
+ // Leading array destructuring parameters.
+ eval(fn(`[], ...${pattern}`));
+ eval(fn(`[x], ...${pattern}`));
+ eval(fn(`[x = 0], ...${pattern}`));
+ eval(fn(`[...x], ...${pattern}`));
+
+ // Leading object destructuring parameters.
+ eval(fn(`{}, ...${pattern}`));
+ eval(fn(`{p: x}, ...${pattern}`));
+ eval(fn(`{x}, ...${pattern}`));
+ eval(fn(`{x = 0}, ...${pattern}`));
+
+ // Trailing parameters after rest parameter.
+ assertThrowsInstanceOf(() => eval(fn(`...${pattern},`)), SyntaxError);
+ assertThrowsInstanceOf(() => eval(fn(`...${pattern}, x`)), SyntaxError);
+ assertThrowsInstanceOf(() => eval(fn(`...${pattern}, x = 0`)), SyntaxError);
+ assertThrowsInstanceOf(() => eval(fn(`...${pattern}, ...x`)), SyntaxError);
+ assertThrowsInstanceOf(() => eval(fn(`...${pattern}, []`)), SyntaxError);
+ assertThrowsInstanceOf(() => eval(fn(`...${pattern}, {}`)), SyntaxError);
+
+ // Rest parameter with defaults.
+ assertThrowsInstanceOf(() => eval(fn(`...${pattern} = 0`)), SyntaxError);
+ }
+}
+
+for (let fn of functions) {
+ // Missing name, incomplete patterns.
+ assertThrowsInstanceOf(() => eval(fn(`...`)), SyntaxError);
+ assertThrowsInstanceOf(() => eval(fn(`...[`)), SyntaxError);
+ assertThrowsInstanceOf(() => eval(fn(`...{`)), SyntaxError);
+
+ // Invalid binding name.
+ assertThrowsInstanceOf(() => eval(fn(`...[0]`)), SyntaxError);
+ assertThrowsInstanceOf(() => eval(fn(`...[p.q]`)), SyntaxError);
+}
+
+// Rest parameters aren't valid in getter/setter methods.
+assertThrowsInstanceOf(() => eval(`({get p(...[]) {}})`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`({set p(...[]) {}})`), SyntaxError);
+
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_7/Destructuring/rest-parameter.js b/js/src/tests/ecma_7/Destructuring/rest-parameter.js
new file mode 100644
index 000000000..50d77f3cc
--- /dev/null
+++ b/js/src/tests/ecma_7/Destructuring/rest-parameter.js
@@ -0,0 +1,54 @@
+/* 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/. */
+
+// Simple functional test for destructuring rest parameters.
+
+function arrayRest(...[a, b]) {
+ return a + b;
+}
+assertEq(arrayRest(3, 7), 10);
+
+
+function arrayRestWithDefault(...[a, b = 1]) {
+ return a + b;
+}
+assertEq(arrayRestWithDefault(3, 7), 10);
+assertEq(arrayRestWithDefault(4), 5);
+assertEq(arrayRestWithDefault(4, undefined), 5);
+
+
+function objectRest(...{length: len}) {
+ return len;
+}
+assertEq(objectRest(), 0);
+assertEq(objectRest(10), 1);
+assertEq(objectRest(10, 20), 2);
+
+
+function objectRestWithDefault(...{0: a, 1: b = 1}) {
+ return a + b;
+}
+assertEq(objectRestWithDefault(3, 7), 10);
+assertEq(objectRestWithDefault(4), 5);
+assertEq(objectRestWithDefault(4, undefined), 5);
+
+
+function arrayRestWithNestedRest(...[...r]) {
+ return r.length;
+}
+assertEq(arrayRestWithNestedRest(), 0);
+assertEq(arrayRestWithNestedRest(10), 1);
+assertEq(arrayRestWithNestedRest(10, 20), 2);
+
+
+function arrayRestTDZ(...[a = a]) { }
+assertThrowsInstanceOf(() => arrayRestTDZ(), ReferenceError);
+
+
+function objectRestTDZ(...{a = a}) { }
+assertThrowsInstanceOf(() => objectRestTDZ(), ReferenceError);
+
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_7/Destructuring/shell.js b/js/src/tests/ecma_7/Destructuring/shell.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/js/src/tests/ecma_7/Destructuring/shell.js
diff --git a/js/src/tests/ecma_7/Math/Pow.js b/js/src/tests/ecma_7/Math/Pow.js
new file mode 100644
index 000000000..7c1af8c88
--- /dev/null
+++ b/js/src/tests/ecma_7/Math/Pow.js
@@ -0,0 +1,117 @@
+// |reftest| skip-if(!xulRuntime.shell)
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var BUGNUMBER = 1135708;
+var summary = "Implement the exponentiation operator";
+
+print(BUGNUMBER + ": " + summary);
+
+// Constant folding
+assertEq(2 ** 2 ** 3, 256);
+assertEq(1 ** 1 ** 4, 1);
+
+// No folding
+var two = 2;
+var three = 3;
+var four = 4;
+assertEq(two ** two ** three, 256);
+assertEq(1 ** 1 ** four, 1);
+
+// Operator precedence
+assertEq(2 ** 3 / 2 ** 3, 1);
+assertEq(2 ** 3 * 2 ** 3, 64);
+assertEq(2 ** 3 + 2 ** 3, 16);
+
+// With parentheses
+assertEq((2 ** 3) ** 2, 64);
+assertEq(2 ** (3 ** 2), 512);
+
+// Assignment operator
+var x = 2;
+assertEq(x **= 2 ** 3, 256);
+assertEq(x, 256);
+
+// Loop to test baseline and ION
+for (var i=0; i<10000; i++) {
+ assertEq((2 ** 3) ** 2, 64);
+ assertEq(2 ** (3 ** 2), 512);
+ var x = 2;
+ assertEq(x **= 2 ** 3, 256);
+ assertEq(x, 256);
+}
+
+// Comments should not be confused with exp operator
+var a, c, e;
+a = c = e = 2;
+assertEq(a**/**b**/c/**/**/**d**/e, 16);
+
+// Two stars separated should not parse as exp operator
+assertThrows(function() { return Reflect.parse("2 * * 3"); }, SyntaxError);
+
+// Left-hand side expression must not be a unary expression.
+for (let unaryOp of ["delete", "typeof", "void", "+", "-", "!", "~"]) {
+ assertThrowsInstanceOf(() => eval(unaryOp + " a ** 2"), SyntaxError);
+ assertThrowsInstanceOf(() => eval(unaryOp + " " + unaryOp + " a ** 2"), SyntaxError);
+}
+
+// Test the other |delete| operators (DELETENAME and DELETEEXPR are already tested above).
+assertThrowsInstanceOf(() => eval("delete a.name ** 2"), SyntaxError);
+assertThrowsInstanceOf(() => eval("delete a[0] ** 2"), SyntaxError);
+
+// Unary expression lhs is valid if parenthesized.
+for (let unaryOp of ["delete", "void", "+", "-", "!", "~"]) {
+ let a = 0;
+ eval("(" + unaryOp + " a) ** 2");
+ eval("(" + unaryOp + " " + unaryOp + " a) ** 2");
+}
+{
+ let a = {};
+ (delete a.name) ** 2;
+ (delete a[0]) ** 2;
+}
+
+// Check if error propagation works
+var thrower = {
+ get value() {
+ throw new Error();
+ }
+};
+
+assertThrowsInstanceOf(function() { return thrower.value ** 2; }, Error);
+assertThrowsInstanceOf(function() { return 2 ** thrower.value; }, Error);
+assertThrowsInstanceOf(function() { return 2 ** thrower.value ** 2; }, Error);
+
+var convertibleToPrimitive = {
+ valueOf: function() {
+ throw new Error("oops");
+ }
+};
+
+assertThrowsInstanceOf(function() { return convertibleToPrimitive ** 3; }, Error);
+assertThrowsInstanceOf(function() { return 3 ** convertibleToPrimitive; }, Error);
+
+assertEq(NaN ** 2, NaN);
+assertEq(2 ** NaN, NaN);
+assertEq(2 ** "3", 8);
+assertEq("2" ** 3, 8);
+
+// Reflect.parse generates a correct parse tree for simplest case
+var parseTree = Reflect.parse("a ** b");
+assertEq(parseTree.body[0].type, "ExpressionStatement");
+assertEq(parseTree.body[0].expression.operator, "**");
+assertEq(parseTree.body[0].expression.left.name, "a");
+assertEq(parseTree.body[0].expression.right.name, "b");
+
+// Reflect.parse generates a tree following the right-associativity rule
+var parseTree = Reflect.parse("a ** b ** c");
+assertEq(parseTree.body[0].type, "ExpressionStatement");
+assertEq(parseTree.body[0].expression.left.name, "a");
+assertEq(parseTree.body[0].expression.right.operator, "**");
+assertEq(parseTree.body[0].expression.right.left.name, "b");
+assertEq(parseTree.body[0].expression.right.right.name, "c");
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_7/Math/shell.js b/js/src/tests/ecma_7/Math/shell.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/js/src/tests/ecma_7/Math/shell.js
diff --git a/js/src/tests/ecma_7/Object/browser.js b/js/src/tests/ecma_7/Object/browser.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/js/src/tests/ecma_7/Object/browser.js
diff --git a/js/src/tests/ecma_7/Object/defineGetter-defineSetter.js b/js/src/tests/ecma_7/Object/defineGetter-defineSetter.js
new file mode 100644
index 000000000..b2bb21f67
--- /dev/null
+++ b/js/src/tests/ecma_7/Object/defineGetter-defineSetter.js
@@ -0,0 +1,92 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+let count = 0;
+let verifyProxy = new Proxy({}, {
+ defineProperty(target, property, descriptor) {
+ assertEq(property, "x");
+
+ assertEq(descriptor.enumerable, true);
+ assertEq(descriptor.configurable, true);
+
+ if ("set" in descriptor)
+ assertEq(descriptor.set, Object.prototype.__defineSetter__);
+ else
+ assertEq(descriptor.get, Object.prototype.__defineGetter__);
+
+ assertEq(Object.keys(descriptor).length, 3);
+
+ count++;
+ return true;
+ }
+});
+
+for (let define of [Object.prototype.__defineGetter__, Object.prototype.__defineSetter__]) {
+ // null/undefined |this| value
+ for (let thisv of [undefined, null])
+ assertThrowsInstanceOf(() => define.call(thisv, "x", define), TypeError);
+
+ // non-callable getter/setter
+ let nonCallable = [{}, [], new Proxy({}, {})];
+ for (let value of nonCallable)
+ assertThrowsInstanceOf(() => define.call(verifyProxy, "x", value), TypeError);
+
+ // ToPropertyKey
+ let key = {
+ [Symbol.toPrimitive](hint) {
+ assertEq(hint, "string");
+ // Throws, because non-primitive is returned
+ return {};
+ },
+ valueOf() { throw "wrongly invoked"; },
+ toString() { throw "wrongly invoked"; }
+ };
+ assertThrowsInstanceOf(() => define.call(verifyProxy, key, define), TypeError);
+
+ key = {
+ [Symbol.toPrimitive](hint) {
+ assertEq(hint, "string");
+ return "x";
+ },
+ valueOf() { throw "wrongly invoked"; },
+ toString() { throw "wrongly invoked"; }
+ }
+ define.call(verifyProxy, key, define);
+
+ key = {
+ [Symbol.toPrimitive]: undefined,
+
+ valueOf() { throw "wrongly invoked"; },
+ toString() { return "x"; }
+ }
+ define.call(verifyProxy, key, define);
+
+ // Bog standard call
+ define.call(verifyProxy, "x", define);
+
+ let obj = {};
+ define.call(obj, "x", define);
+ let descriptor = Object.getOwnPropertyDescriptor(obj, "x");
+
+ assertEq(descriptor.enumerable, true);
+ assertEq(descriptor.configurable, true);
+
+ if (define == Object.prototype.__defineSetter__) {
+ assertEq(descriptor.get, undefined);
+ assertEq(descriptor.set, define);
+ } else {
+ assertEq(descriptor.get, define);
+ assertEq(descriptor.set, undefined);
+ }
+
+ assertEq(Object.keys(descriptor).length, 4);
+
+
+}
+
+// Number of calls that should succeed
+assertEq(count, 6);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/ecma_7/Object/entries.js b/js/src/tests/ecma_7/Object/entries.js
new file mode 100644
index 000000000..ee339ae23
--- /dev/null
+++ b/js/src/tests/ecma_7/Object/entries.js
@@ -0,0 +1,94 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+if ("entries" in Object) {
+ assertEq(Object.entries.length, 1);
+
+ var o, entries;
+
+ o = { a: 3, b: 2 };
+ entries = Object.entries(o);
+ assertDeepEq(entries, [["a", 3], ["b", 2]]);
+
+ o = { get a() { return 17; }, b: 2 };
+ entries = Object.entries(o),
+ assertDeepEq(entries, [["a", 17], ["b", 2]]);
+
+ o = { __iterator__: function() { return Iterator({a: 2, b: 3}); } };
+ entries = Object.entries(o);
+ assertDeepEq(entries, [["__iterator__", o.__iterator__]]);
+
+ o = { a: 1, b: 2 };
+ delete o.a;
+ o.a = 3;
+ entries = Object.entries(o);
+ assertDeepEq(entries, [["b", 2], ["a", 3]]);
+
+ o = [0, 1, 2];
+ entries = Object.entries(o);
+ assertDeepEq(entries, [["0", 0], ["1", 1], ["2", 2]]);
+
+ o = /./.exec("abc");
+ entries = Object.entries(o);
+ assertDeepEq(entries, [["0", "a"], ["index", 0], ["input", "abc"]]);
+
+ o = { a: 1, b: 2, c: 3 };
+ delete o.b;
+ o.b = 5;
+ entries = Object.entries(o);
+ assertDeepEq(entries, [["a", 1], ["c", 3], ["b", 5]]);
+
+ function f() { }
+ f.prototype.p = 1;
+ o = new f();
+ o.g = 1;
+ entries = Object.entries(o);
+ assertDeepEq(entries, [["g", 1]]);
+
+ var o = {get a() {delete this.b; return 1}, b: 2, c: 3};
+ entries = Object.entries(o);
+ assertDeepEq(entries, [["a", 1], ["c", 3]]);
+
+ assertThrowsInstanceOf(() => Object.entries(), TypeError);
+ assertThrowsInstanceOf(() => Object.entries(undefined), TypeError);
+ assertThrowsInstanceOf(() => Object.entries(null), TypeError);
+
+ assertDeepEq(Object.entries(1), []);
+ assertDeepEq(Object.entries(true), []);
+ if (typeof Symbol === "function")
+ assertDeepEq(Object.entries(Symbol("foo")), []);
+
+ assertDeepEq(Object.entries("foo"), [["0", "f"], ["1", "o"], ["2", "o"]]);
+
+ entries = Object.entries({
+ get a(){
+ Object.defineProperty(this, "b", {enumerable: false});
+ return "A";
+ },
+ b: "B"
+ });
+ assertDeepEq(entries, [["a", "A"]]);
+
+ let ownKeysCallCount = 0;
+ let getOwnPropertyDescriptorCalls = [];
+ let target = { a: 1, b: 2, c: 3 };
+ o = new Proxy(target, {
+ ownKeys() {
+ ownKeysCallCount++;
+ return ["c", "a"];
+ },
+ getOwnPropertyDescriptor(target, key) {
+ getOwnPropertyDescriptorCalls.push(key);
+ return Object.getOwnPropertyDescriptor(target, key);
+ }
+ });
+ entries = Object.entries(o);
+ assertEq(ownKeysCallCount, 1);
+ assertDeepEq(entries, [["c", 3], ["a", 1]]);
+ assertDeepEq(getOwnPropertyDescriptorCalls, ["c", "a"]);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_7/Object/shell.js b/js/src/tests/ecma_7/Object/shell.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/js/src/tests/ecma_7/Object/shell.js
diff --git a/js/src/tests/ecma_7/Object/values.js b/js/src/tests/ecma_7/Object/values.js
new file mode 100644
index 000000000..78543c875
--- /dev/null
+++ b/js/src/tests/ecma_7/Object/values.js
@@ -0,0 +1,94 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+if ("values" in Object) {
+ assertEq(Object.values.length, 1);
+
+ var o, values;
+
+ o = { a: 3, b: 2 };
+ values = Object.values(o);
+ assertDeepEq(values, [3, 2]);
+
+ o = { get a() { return 17; }, b: 2 };
+ values = Object.values(o),
+ assertDeepEq(values, [17, 2]);
+
+ o = { __iterator__: function() { return Iterator({a: 2, b: 3}); } };
+ values = Object.values(o);
+ assertDeepEq(values, [o.__iterator__]);
+
+ o = { a: 1, b: 2 };
+ delete o.a;
+ o.a = 3;
+ values = Object.values(o);
+ assertDeepEq(values, [2, 3]);
+
+ o = [0, 1, 2];
+ values = Object.values(o);
+ assertDeepEq(values, [0, 1, 2]);
+
+ o = /./.exec("abc");
+ values = Object.values(o);
+ assertDeepEq(values, ["a", 0, "abc"]);
+
+ o = { a: 1, b: 2, c: 3 };
+ delete o.b;
+ o.b = 5;
+ values = Object.values(o);
+ assertDeepEq(values, [1, 3, 5]);
+
+ function f() { }
+ f.prototype.p = 1;
+ o = new f();
+ o.g = 1;
+ values = Object.values(o);
+ assertDeepEq(values, [1]);
+
+ var o = {get a() {delete this.b; return 1}, b: 2, c: 3};
+ values = Object.values(o);
+ assertDeepEq(values, [1, 3]);
+
+ assertThrowsInstanceOf(() => Object.values(), TypeError);
+ assertThrowsInstanceOf(() => Object.values(undefined), TypeError);
+ assertThrowsInstanceOf(() => Object.values(null), TypeError);
+
+ assertDeepEq(Object.values(1), []);
+ assertDeepEq(Object.values(true), []);
+ if (typeof Symbol === "function")
+ assertDeepEq(Object.values(Symbol("foo")), []);
+
+ assertDeepEq(Object.values("foo"), ["f", "o", "o"]);
+
+ values = Object.values({
+ get a(){
+ Object.defineProperty(this, "b", {enumerable: false});
+ return "A";
+ },
+ b: "B"
+ });
+ assertDeepEq(values, ["A"]);
+
+ let ownKeysCallCount = 0;
+ let getOwnPropertyDescriptorCalls = [];
+ let target = { a: 1, b: 2, c: 3 };
+ o = new Proxy(target, {
+ ownKeys() {
+ ownKeysCallCount++;
+ return ["c", "a"];
+ },
+ getOwnPropertyDescriptor(target, key) {
+ getOwnPropertyDescriptorCalls.push(key);
+ return Object.getOwnPropertyDescriptor(target, key);
+ }
+ });
+ values = Object.values(o);
+ assertEq(ownKeysCallCount, 1);
+ assertDeepEq(values, [3, 1]);
+ assertDeepEq(getOwnPropertyDescriptorCalls, ["c", "a"]);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_7/SIMD/ToSource.js b/js/src/tests/ecma_7/SIMD/ToSource.js
new file mode 100644
index 000000000..e5efa12a3
--- /dev/null
+++ b/js/src/tests/ecma_7/SIMD/ToSource.js
@@ -0,0 +1,56 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+
+function test() {
+ var Float32x4 = SIMD.Float32x4;
+ var f = Float32x4(11, 22, 33, 44);
+ assertEq(f.toSource(), "SIMD.Float32x4(11, 22, 33, 44)");
+
+ var Float64x2 = SIMD.Float64x2;
+ var f = Float64x2(11, 22, 33, 44);
+ assertEq(f.toSource(), "SIMD.Float64x2(11, 22)");
+
+ var Int8x16 = SIMD.Int8x16;
+ var f = Int8x16(11, 22, 33, 44, -11, -22, -33, -44, 1, 2, 3, 4, -1, -2, -3, -4);
+ assertEq(f.toSource(), "SIMD.Int8x16(11, 22, 33, 44, -11, -22, -33, -44, 1, 2, 3, 4, -1, -2, -3, -4)");
+
+ var Int16x8 = SIMD.Int16x8;
+ var f = Int16x8(11, 22, 33, 44, -11, -22, -33, -44);
+ assertEq(f.toSource(), "SIMD.Int16x8(11, 22, 33, 44, -11, -22, -33, -44)");
+
+ var Int32x4 = SIMD.Int32x4;
+ var f = Int32x4(11, 22, 33, 44);
+ assertEq(f.toSource(), "SIMD.Int32x4(11, 22, 33, 44)");
+
+ var Uint8x16 = SIMD.Uint8x16;
+ var f = Uint8x16(11, 22, 33, 44, 245, 234, 223, 212, 1, 2, 3, 4, 255, 254, 0, 250);
+ assertEq(f.toSource(), "SIMD.Uint8x16(11, 22, 33, 44, 245, 234, 223, 212, 1, 2, 3, 4, 255, 254, 0, 250)");
+
+ var Uint16x8 = SIMD.Uint16x8;
+ var f = Uint16x8(11, 22, 33, 44, 65535, 65534, 65533, 65532);
+ assertEq(f.toSource(), "SIMD.Uint16x8(11, 22, 33, 44, 65535, 65534, 65533, 65532)");
+
+ var Uint32x4 = SIMD.Uint32x4;
+ var f = Uint32x4(11, 22, 4294967295, 4294967294);
+ assertEq(f.toSource(), "SIMD.Uint32x4(11, 22, 4294967295, 4294967294)");
+
+ var Bool8x16 = SIMD.Bool8x16;
+ var f = Bool8x16(true, true, false, false, false, true, true, false, true, true, true, true, false, false, false, false);
+ assertEq(f.toSource(), "SIMD.Bool8x16(true, true, false, false, false, true, true, false, true, true, true, true, false, false, false, false)");
+
+ var Bool16x8 = SIMD.Bool16x8;
+ var f = Bool16x8(true, true, false, false, true, false, false, true);
+ assertEq(f.toSource(), "SIMD.Bool16x8(true, true, false, false, true, false, false, true)");
+
+ var Bool32x4 = SIMD.Bool32x4;
+ var f = Bool32x4(true, true, false, false);
+ assertEq(f.toSource(), "SIMD.Bool32x4(true, true, false, false)");
+
+ var Bool64x2 = SIMD.Bool64x2;
+ var f = Bool64x2(true, false);
+ assertEq(f.toSource(), "SIMD.Bool64x2(true, false)");
+
+ if (typeof reportCompare === "function")
+ reportCompare(true, true);
+}
+
+test();
diff --git a/js/src/tests/ecma_7/SIMD/binary-operations.js b/js/src/tests/ecma_7/SIMD/binary-operations.js
new file mode 100644
index 000000000..04b035309
--- /dev/null
+++ b/js/src/tests/ecma_7/SIMD/binary-operations.js
@@ -0,0 +1,785 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+var Float32x4 = SIMD.Float32x4;
+var Int8x16 = SIMD.Int8x16;
+var Int16x8 = SIMD.Int16x8;
+var Int32x4 = SIMD.Int32x4;
+var Uint8x16 = SIMD.Uint8x16;
+var Uint16x8 = SIMD.Uint16x8;
+var Uint32x4 = SIMD.Uint32x4;
+var Bool8x16 = SIMD.Bool8x16;
+var Bool16x8 = SIMD.Bool16x8;
+var Bool32x4 = SIMD.Bool32x4;
+var Bool64x2 = SIMD.Bool64x2;
+
+// Float32x4.
+function testFloat32x4add() {
+ function addf(a, b) {
+ return Math.fround(Math.fround(a) + Math.fround(b));
+ }
+
+ var vals = [
+ [[1, 2, 3, 4], [10, 20, 30, 40]],
+ [[1.57, 2.27, 3.57, 4.19], [10.31, 20.49, 30.41, 40.72]],
+ [[NaN, -0, Infinity, -Infinity], [0, -0, -Infinity, -Infinity]]
+ ];
+
+ for (var [v,w] of vals) {
+ testBinaryFunc(Float32x4(...v), Float32x4(...w), Float32x4.add, addf);
+ }
+}
+
+function testFloat32x4div() {
+ function divf(a, b) {
+ return Math.fround(Math.fround(a) / Math.fround(b));
+ }
+
+ var vals = [
+ [[1, 2, 3, 4], [10, 20, 30, 40]],
+ [[1.26, 2.03, 3.17, 4.59], [11.025, 17.3768, 29.1957, 46.4049]],
+ [[0, -0, Infinity, -Infinity], [1, 1, -Infinity, Infinity]]
+ ];
+
+ for (var [v,w] of vals) {
+ testBinaryFunc(Float32x4(...v), Float32x4(...w), Float32x4.div, divf);
+ }
+}
+
+function testFloat32x4mul() {
+ function mulf(a, b) {
+ return Math.fround(Math.fround(a) * Math.fround(b));
+ }
+
+ var vals = [
+ [[1, 2, 3, 4], [10, 20, 30, 40]],
+ [[1.66, 2.57, 3.73, 4.12], [10.67, 20.68, 30.02, 40.58]],
+ [[NaN, -0, Infinity, -Infinity], [NaN, -0, -Infinity, 0]]
+ ];
+
+ for (var [v,w] of vals) {
+ testBinaryFunc(Float32x4(...v), Float32x4(...w), Float32x4.mul, mulf);
+ }
+}
+
+function testFloat32x4sub() {
+ function subf(a, b) {
+ return Math.fround(Math.fround(a) - Math.fround(b));
+ }
+
+ var vals = [
+ [[1, 2, 3, 4], [10, 20, 30, 40]],
+ [[1.34, 2.95, 3.17, 4.29], [10.18, 20.43, 30.63, 40.38]],
+ [[NaN, -0, -Infinity, -Infinity], [NaN, -0, Infinity, -Infinity]]
+ ];
+
+ for (var [v,w] of vals) {
+ testBinaryFunc(Float32x4(...v), Float32x4(...w), Float32x4.sub, subf);
+ }
+}
+
+// Helper for saturating arithmetic.
+// See SIMD.js, 5.1.25 Saturate(descriptor, x)
+function saturate(lower, upper, x) {
+ x = x | 0;
+ if (x > upper)
+ return upper;
+ if (x < lower)
+ return lower;
+ return x;
+}
+
+var i8x16vals = [
+ [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
+ [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]],
+ [[INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, -2, -3, -4, -5, -6, -7, -8, -9],
+ [1, 1, -1, -1, INT8_MAX, INT8_MAX, INT8_MIN, INT8_MIN, 8, 9, 10, 11, 12, 13, 14, 15]]
+];
+
+// Int8x16.
+function testInt8x16add() {
+ function addi(a, b) {
+ return (a + b) << 24 >> 24;
+ }
+
+ for (var [v,w] of i8x16vals) {
+ testBinaryFunc(Int8x16(...v), Int8x16(...w), Int8x16.add, addi);
+ }
+}
+
+function testInt8x16and() {
+ function andi(a, b) {
+ return (a & b) << 24 >> 24;
+ }
+
+ for (var [v,w] of i8x16vals) {
+ testBinaryFunc(Int8x16(...v), Int8x16(...w), Int8x16.and, andi);
+ }
+}
+
+function testInt8x16mul() {
+ function muli(x, y) {
+ return (x * y) << 24 >> 24;
+ }
+
+ for (var [v,w] of i8x16vals) {
+ testBinaryFunc(Int8x16(...v), Int8x16(...w), Int8x16.mul, muli);
+ }
+}
+
+function testInt8x16or() {
+ function ori(a, b) {
+ return (a | b) << 24 >> 24;
+ }
+
+ for (var [v,w] of i8x16vals) {
+ testBinaryFunc(Int8x16(...v), Int8x16(...w), Int8x16.or, ori);
+ }
+}
+
+function testInt8x16sub() {
+ function subi(a, b) {
+ return (a - b) << 24 >> 24;
+ }
+
+ for (var [v,w] of i8x16vals) {
+ testBinaryFunc(Int8x16(...v), Int8x16(...w), Int8x16.sub, subi);
+ }
+}
+
+function testInt8x16xor() {
+ function xori(a, b) {
+ return (a ^ b) << 24 >> 24;
+ }
+
+ for (var [v,w] of i8x16vals) {
+ testBinaryFunc(Int8x16(...v), Int8x16(...w), Int8x16.xor, xori);
+ }
+}
+
+function testInt8x16addSaturate() {
+ function satadd(a, b) {
+ return saturate(INT8_MIN, INT8_MAX, a + b);
+ }
+
+ for (var [v,w] of i8x16vals) {
+ testBinaryFunc(Int8x16(...v), Int8x16(...w), Int8x16.addSaturate, satadd);
+ }
+}
+
+function testInt8x16subSaturate() {
+ function satsub(a, b) {
+ return saturate(INT8_MIN, INT8_MAX, a - b);
+ }
+
+ for (var [v,w] of i8x16vals) {
+ testBinaryFunc(Int8x16(...v), Int8x16(...w), Int8x16.subSaturate, satsub);
+ }
+}
+
+// Uint8x16.
+function testUint8x16add() {
+ function addi(a, b) {
+ return (a + b) << 24 >>> 24;
+ }
+
+ for (var [v,w] of i8x16vals) {
+ testBinaryFunc(Uint8x16(...v), Uint8x16(...w), Uint8x16.add, addi);
+ }
+}
+
+function testUint8x16and() {
+ function andi(a, b) {
+ return (a & b) << 24 >>> 24;
+ }
+
+ for (var [v,w] of i8x16vals) {
+ testBinaryFunc(Uint8x16(...v), Uint8x16(...w), Uint8x16.and, andi);
+ }
+}
+
+function testUint8x16mul() {
+ function muli(x, y) {
+ return (x * y) << 24 >>> 24;
+ }
+
+ for (var [v,w] of i8x16vals) {
+ testBinaryFunc(Uint8x16(...v), Uint8x16(...w), Uint8x16.mul, muli);
+ }
+}
+
+function testUint8x16or() {
+ function ori(a, b) {
+ return (a | b) << 24 >>> 24;
+ }
+
+ for (var [v,w] of i8x16vals) {
+ testBinaryFunc(Uint8x16(...v), Uint8x16(...w), Uint8x16.or, ori);
+ }
+}
+
+function testUint8x16sub() {
+ function subi(a, b) {
+ return (a - b) << 24 >>> 24;
+ }
+
+ for (var [v,w] of i8x16vals) {
+ testBinaryFunc(Uint8x16(...v), Uint8x16(...w), Uint8x16.sub, subi);
+ }
+}
+
+function testUint8x16xor() {
+ function xori(a, b) {
+ return (a ^ b) << 24 >>> 24;
+ }
+
+ for (var [v,w] of i8x16vals) {
+ testBinaryFunc(Uint8x16(...v), Uint8x16(...w), Uint8x16.xor, xori);
+ }
+}
+
+function testUint8x16addSaturate() {
+ function satadd(a, b) {
+ return saturate(0, UINT8_MAX, a + b);
+ }
+
+ for (var [v,w] of i8x16vals) {
+ testBinaryFunc(Uint8x16(...v), Uint8x16(...w), Uint8x16.addSaturate, satadd);
+ }
+}
+
+function testUint8x16subSaturate() {
+ function satsub(a, b) {
+ return saturate(0, UINT8_MAX, a - b);
+ }
+
+ for (var [v,w] of i8x16vals) {
+ testBinaryFunc(Uint8x16(...v), Uint8x16(...w), Uint8x16.subSaturate, satsub);
+ }
+}
+
+var i16x8vals = [
+ [[1, 2, 3, 4, 5, 6, 7, 8],
+ [10, 20, 30, 40, 50, 60, 70, 80]],
+ [[INT16_MAX, INT16_MIN, INT16_MAX, INT16_MIN, INT16_MAX, INT16_MIN, INT16_MAX, INT16_MIN],
+ [1, 1, -1, -1, INT16_MAX, INT16_MAX, INT16_MIN, INT16_MIN]]
+];
+
+// Int16x8.
+function testInt16x8add() {
+ function addi(a, b) {
+ return (a + b) << 16 >> 16;
+ }
+
+ for (var [v,w] of i16x8vals) {
+ testBinaryFunc(Int16x8(...v), Int16x8(...w), Int16x8.add, addi);
+ }
+}
+
+function testInt16x8and() {
+ function andi(a, b) {
+ return (a & b) << 16 >> 16;
+ }
+
+ for (var [v,w] of i16x8vals) {
+ testBinaryFunc(Int16x8(...v), Int16x8(...w), Int16x8.and, andi);
+ }
+}
+
+function testInt16x8mul() {
+ function muli(x, y) {
+ return (x * y) << 16 >> 16;
+ }
+
+ for (var [v,w] of i16x8vals) {
+ testBinaryFunc(Int16x8(...v), Int16x8(...w), Int16x8.mul, muli);
+ }
+}
+
+function testInt16x8or() {
+ function ori(a, b) {
+ return (a | b) << 16 >> 16;
+ }
+
+ for (var [v,w] of i16x8vals) {
+ testBinaryFunc(Int16x8(...v), Int16x8(...w), Int16x8.or, ori);
+ }
+}
+
+function testInt16x8sub() {
+ function subi(a, b) {
+ return (a - b) << 16 >> 16;
+ }
+
+ for (var [v,w] of i16x8vals) {
+ testBinaryFunc(Int16x8(...v), Int16x8(...w), Int16x8.sub, subi);
+ }
+}
+
+function testInt16x8xor() {
+ function xori(a, b) {
+ return (a ^ b) << 16 >> 16;
+ }
+
+ for (var [v,w] of i16x8vals) {
+ testBinaryFunc(Int16x8(...v), Int16x8(...w), Int16x8.xor, xori);
+ }
+}
+
+function testInt16x8addSaturate() {
+ function satadd(a, b) {
+ return saturate(INT16_MIN, INT16_MAX, a + b);
+ }
+
+ for (var [v,w] of i16x8vals) {
+ testBinaryFunc(Int16x8(...v), Int16x8(...w), Int16x8.addSaturate, satadd);
+ }
+}
+
+function testInt16x8subSaturate() {
+ function satsub(a, b) {
+ return saturate(INT16_MIN, INT16_MAX, a - b);
+ }
+
+ for (var [v,w] of i16x8vals) {
+ testBinaryFunc(Int16x8(...v), Int16x8(...w), Int16x8.subSaturate, satsub);
+ }
+}
+
+// Uint16x8.
+function testUint16x8add() {
+ function addi(a, b) {
+ return (a + b) << 16 >>> 16;
+ }
+
+ for (var [v,w] of i16x8vals) {
+ testBinaryFunc(Uint16x8(...v), Uint16x8(...w), Uint16x8.add, addi);
+ }
+}
+
+function testUint16x8and() {
+ function andi(a, b) {
+ return (a & b) << 16 >>> 16;
+ }
+
+ for (var [v,w] of i16x8vals) {
+ testBinaryFunc(Uint16x8(...v), Uint16x8(...w), Uint16x8.and, andi);
+ }
+}
+
+function testUint16x8mul() {
+ function muli(x, y) {
+ return (x * y) << 16 >>> 16;
+ }
+
+ for (var [v,w] of i16x8vals) {
+ testBinaryFunc(Uint16x8(...v), Uint16x8(...w), Uint16x8.mul, muli);
+ }
+}
+
+function testUint16x8or() {
+ function ori(a, b) {
+ return (a | b) << 16 >>> 16;
+ }
+
+ for (var [v,w] of i16x8vals) {
+ testBinaryFunc(Uint16x8(...v), Uint16x8(...w), Uint16x8.or, ori);
+ }
+}
+
+function testUint16x8sub() {
+ function subi(a, b) {
+ return (a - b) << 16 >>> 16;
+ }
+
+ for (var [v,w] of i16x8vals) {
+ testBinaryFunc(Uint16x8(...v), Uint16x8(...w), Uint16x8.sub, subi);
+ }
+}
+
+function testUint16x8xor() {
+ function xori(a, b) {
+ return (a ^ b) << 16 >>> 16;
+ }
+
+ for (var [v,w] of i16x8vals) {
+ testBinaryFunc(Uint16x8(...v), Uint16x8(...w), Uint16x8.xor, xori);
+ }
+}
+
+function testUint16x8addSaturate() {
+ function satadd(a, b) {
+ return saturate(0, UINT16_MAX, a + b);
+ }
+
+ for (var [v,w] of i16x8vals) {
+ testBinaryFunc(Uint16x8(...v), Uint16x8(...w), Uint16x8.addSaturate, satadd);
+ }
+}
+
+function testUint16x8subSaturate() {
+ function satsub(a, b) {
+ return saturate(0, UINT16_MAX, a - b);
+ }
+
+ for (var [v,w] of i16x8vals) {
+ testBinaryFunc(Uint16x8(...v), Uint16x8(...w), Uint16x8.subSaturate, satsub);
+ }
+}
+
+var i32x4vals = [
+ [[1, 2, 3, 4], [10, 20, 30, 40]],
+ [[INT32_MAX, INT32_MIN, INT32_MAX, INT32_MIN], [1, -1, 0, 0]],
+ [[INT32_MAX, INT32_MIN, INT32_MAX, INT32_MIN], [INT32_MIN, INT32_MAX, INT32_MAX, INT32_MIN]],
+ [[INT32_MAX, INT32_MIN, INT32_MAX, INT32_MIN], [-1, -1, INT32_MIN, INT32_MIN]],
+ [[INT32_MAX, INT32_MIN, INT32_MAX, INT32_MIN], [-1, 1, INT32_MAX, INT32_MIN]],
+ [[UINT32_MAX, 0, UINT32_MAX, 0], [1, -1, 0, 0]],
+ [[UINT32_MAX, 0, UINT32_MAX, 0], [-1, -1, INT32_MIN, INT32_MIN]],
+ [[UINT32_MAX, 0, UINT32_MAX, 0], [1, -1, 0, 0]],
+ [[UINT32_MAX, 0, UINT32_MAX, 0], [-1, 1, INT32_MAX, INT32_MIN]]
+];
+
+// Int32x4.
+function testInt32x4add() {
+ function addi(a, b) {
+ return (a + b) | 0;
+ }
+
+ for (var [v,w] of i32x4vals) {
+ testBinaryFunc(Int32x4(...v), Int32x4(...w), Int32x4.add, addi);
+ }
+}
+
+function testInt32x4and() {
+ function andi(a, b) {
+ return (a & b) | 0;
+ }
+
+ for (var [v,w] of i32x4vals) {
+ testBinaryFunc(Int32x4(...v), Int32x4(...w), Int32x4.and, andi);
+ }
+}
+
+function testInt32x4mul() {
+ function muli(x, y) {
+ // Deal with lost precision in the 53-bit double mantissa.
+ // Compute two 48-bit products. Truncate and combine them.
+ var hi = (x * (y >>> 16)) | 0;
+ var lo = (x * (y & 0xffff)) | 0;
+ return (lo + (hi << 16)) | 0;
+ }
+
+ for (var [v,w] of i32x4vals) {
+ testBinaryFunc(Int32x4(...v), Int32x4(...w), Int32x4.mul, muli);
+ }
+}
+
+function testInt32x4or() {
+ function ori(a, b) {
+ return (a | b) | 0;
+ }
+
+ for (var [v,w] of i32x4vals) {
+ testBinaryFunc(Int32x4(...v), Int32x4(...w), Int32x4.or, ori);
+ }
+}
+
+function testInt32x4sub() {
+ function subi(a, b) {
+ return (a - b) | 0;
+ }
+
+ for (var [v,w] of i32x4vals) {
+ testBinaryFunc(Int32x4(...v), Int32x4(...w), Int32x4.sub, subi);
+ }
+}
+
+function testInt32x4xor() {
+ function xori(a, b) {
+ return (a ^ b) | 0;
+ }
+
+ for (var [v,w] of i32x4vals) {
+ testBinaryFunc(Int32x4(...v), Int32x4(...w), Int32x4.xor, xori);
+ }
+}
+
+// Uint32x4.
+function testUint32x4add() {
+ function addi(a, b) {
+ return (a + b) >>> 0;
+ }
+
+ for (var [v,w] of i32x4vals) {
+ testBinaryFunc(Uint32x4(...v), Uint32x4(...w), Uint32x4.add, addi);
+ }
+}
+
+function testUint32x4and() {
+ function andi(a, b) {
+ return (a & b) >>> 0;
+ }
+
+ for (var [v,w] of i32x4vals) {
+ testBinaryFunc(Uint32x4(...v), Uint32x4(...w), Uint32x4.and, andi);
+ }
+}
+
+function testUint32x4mul() {
+ function muli(x, y) {
+ // Deal with lost precision in the 53-bit double mantissa.
+ // Compute two 48-bit products. Truncate and combine them.
+ var hi = (x * (y >>> 16)) >>> 0;
+ var lo = (x * (y & 0xffff)) >>> 0;
+ return (lo + (hi << 16)) >>> 0;
+ }
+
+ for (var [v,w] of i32x4vals) {
+ testBinaryFunc(Uint32x4(...v), Uint32x4(...w), Uint32x4.mul, muli);
+ }
+}
+
+function testUint32x4or() {
+ function ori(a, b) {
+ return (a | b) >>> 0;
+ }
+
+ for (var [v,w] of i32x4vals) {
+ testBinaryFunc(Uint32x4(...v), Uint32x4(...w), Uint32x4.or, ori);
+ }
+}
+
+function testUint32x4sub() {
+ function subi(a, b) {
+ return (a - b) >>> 0;
+ }
+
+ for (var [v,w] of i32x4vals) {
+ testBinaryFunc(Uint32x4(...v), Uint32x4(...w), Uint32x4.sub, subi);
+ }
+}
+
+function testUint32x4xor() {
+ function xori(a, b) {
+ return (a ^ b) >>> 0;
+ }
+
+ for (var [v,w] of i32x4vals) {
+ testBinaryFunc(Uint32x4(...v), Uint32x4(...w), Uint32x4.xor, xori);
+ }
+}
+
+var b8x16vals = [
+ [[true, true, true, true, false, false, false, false, true, true, true, true, false, false, false, false],
+ [false, true, false, true, false, true, false, true, true, true, true, true, false, false, false, false]]
+];
+
+function testBool8x16and() {
+ function andb(a, b) {
+ return a && b;
+ }
+
+ for (var [v,w] of b8x16vals) {
+ testBinaryFunc(Bool8x16(...v), Bool8x16(...w), Bool8x16.and, andb);
+ }
+}
+
+function testBool8x16or() {
+ function orb(a, b) {
+ return a || b;
+ }
+
+ for (var [v,w] of b8x16vals) {
+ testBinaryFunc(Bool8x16(...v), Bool8x16(...w), Bool8x16.or, orb);
+ }
+}
+
+function testBool8x16xor() {
+ function xorb(a, b) {
+ return a != b;
+ }
+
+ for (var [v,w] of b8x16vals) {
+ testBinaryFunc(Bool8x16(...v), Bool8x16(...w), Bool8x16.xor, xorb);
+ }
+}
+
+var b16x8vals = [
+ [[true, true, true, true, false, false, false, false],
+ [false, true, false, true, false, true, false, true]]
+];
+
+function testBool16x8and() {
+ function andb(a, b) {
+ return a && b;
+ }
+
+ for (var [v,w] of b16x8vals) {
+ testBinaryFunc(Bool16x8(...v), Bool16x8(...w), Bool16x8.and, andb);
+ }
+}
+
+function testBool16x8or() {
+ function orb(a, b) {
+ return a || b;
+ }
+
+ for (var [v,w] of b16x8vals) {
+ testBinaryFunc(Bool16x8(...v), Bool16x8(...w), Bool16x8.or, orb);
+ }
+}
+
+function testBool16x8xor() {
+ function xorb(a, b) {
+ return a != b;
+ }
+
+ for (var [v,w] of b16x8vals) {
+ testBinaryFunc(Bool16x8(...v), Bool16x8(...w), Bool16x8.xor, xorb);
+ }
+}
+
+var b32x4vals = [
+ [[true, true, false, false], [false, true, false, true]]
+];
+
+function testBool32x4and() {
+ function andb(a, b) {
+ return a && b;
+ }
+
+ for (var [v,w] of b32x4vals) {
+ testBinaryFunc(Bool32x4(...v), Bool32x4(...w), Bool32x4.and, andb);
+ }
+}
+
+function testBool32x4or() {
+ function orb(a, b) {
+ return a || b;
+ }
+
+ for (var [v,w] of b32x4vals) {
+ testBinaryFunc(Bool32x4(...v), Bool32x4(...w), Bool32x4.or, orb);
+ }
+}
+
+function testBool32x4xor() {
+ function xorb(a, b) {
+ return a != b;
+ }
+
+ for (var [v,w] of b32x4vals) {
+ testBinaryFunc(Bool32x4(...v), Bool32x4(...w), Bool32x4.xor, xorb);
+ }
+}
+
+var b64x2vals = [
+ [[false, false], [false, true], [true, false], [true, true]]
+];
+
+function testBool64x2and() {
+ function andb(a, b) {
+ return a && b;
+ }
+
+ for (var [v,w] of b64x2vals) {
+ testBinaryFunc(Bool64x2(...v), Bool64x2(...w), Bool64x2.and, andb);
+ }
+}
+
+function testBool64x2or() {
+ function orb(a, b) {
+ return a || b;
+ }
+
+ for (var [v,w] of b64x2vals) {
+ testBinaryFunc(Bool64x2(...v), Bool64x2(...w), Bool64x2.or, orb);
+ }
+}
+
+function testBool64x2xor() {
+ function xorb(a, b) {
+ return a != b;
+ }
+
+ for (var [v,w] of b64x2vals) {
+ testBinaryFunc(Bool64x2(...v), Bool64x2(...w), Bool64x2.xor, xorb);
+ }
+}
+
+function test() {
+ testFloat32x4add();
+ testFloat32x4div();
+ testFloat32x4mul();
+ testFloat32x4sub();
+
+ testInt8x16add();
+ testInt8x16and();
+ testInt8x16mul();
+ testInt8x16or();
+ testInt8x16sub();
+ testInt8x16xor();
+ testInt8x16addSaturate();
+ testInt8x16subSaturate();
+
+ testUint8x16add();
+ testUint8x16and();
+ testUint8x16mul();
+ testUint8x16or();
+ testUint8x16sub();
+ testUint8x16xor();
+ testUint8x16addSaturate();
+ testUint8x16subSaturate();
+
+ testInt16x8add();
+ testInt16x8and();
+ testInt16x8mul();
+ testInt16x8or();
+ testInt16x8sub();
+ testInt16x8xor();
+ testInt16x8addSaturate();
+ testInt16x8subSaturate();
+
+ testUint16x8add();
+ testUint16x8and();
+ testUint16x8mul();
+ testUint16x8or();
+ testUint16x8sub();
+ testUint16x8xor();
+ testUint16x8addSaturate();
+ testUint16x8subSaturate();
+
+ testInt32x4add();
+ testInt32x4and();
+ testInt32x4mul();
+ testInt32x4or();
+ testInt32x4sub();
+ testInt32x4xor();
+
+ testUint32x4add();
+ testUint32x4and();
+ testUint32x4mul();
+ testUint32x4or();
+ testUint32x4sub();
+ testUint32x4xor();
+
+ testBool8x16and();
+ testBool8x16or();
+ testBool8x16xor();
+
+ testBool16x8and();
+ testBool16x8or();
+ testBool16x8xor();
+
+ testBool32x4and();
+ testBool32x4or();
+ testBool32x4xor();
+
+ testBool64x2and();
+ testBool64x2or();
+ testBool64x2xor();
+
+ if (typeof reportCompare === "function") {
+ reportCompare(true, true);
+ }
+}
+
+test();
diff --git a/js/src/tests/ecma_7/SIMD/bug1023145.js b/js/src/tests/ecma_7/SIMD/bug1023145.js
new file mode 100644
index 000000000..45f44afb5
--- /dev/null
+++ b/js/src/tests/ecma_7/SIMD/bug1023145.js
@@ -0,0 +1,14 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+delete Object.prototype.__proto__;
+var Int32x4 = SIMD.Int32x4;
+var ar = Int32x4.array(1);
+var array = new ar([Int32x4(1, 2, 3, 4)]);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_7/SIMD/bug953270.js b/js/src/tests/ecma_7/SIMD/bug953270.js
new file mode 100644
index 000000000..db6a0d7cb
--- /dev/null
+++ b/js/src/tests/ecma_7/SIMD/bug953270.js
@@ -0,0 +1,24 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+// Check that NaN normalization is applied when extracting the x lane
+// out, after bit conversion has occurred.
+
+var Int32x4 = SIMD.Int32x4;
+var a = Int32x4((4294967295), 200, 300, 400);
+var c = SIMD.Float32x4.fromInt32x4Bits(a);
+
+// NaN canonicalization occurs when extracting out x lane:
+assertEq(SIMD.Float32x4.extractLane(c, 0), NaN);
+
+// but underlying bits are faithfully transmitted
+// (though reinterpreted as a signed integer):
+var d = SIMD.Int32x4.fromFloat32x4Bits(c);
+assertEq(SIMD.Int32x4.extractLane(d, 0), -1);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_7/SIMD/check.js b/js/src/tests/ecma_7/SIMD/check.js
new file mode 100644
index 000000000..77ef381be
--- /dev/null
+++ b/js/src/tests/ecma_7/SIMD/check.js
@@ -0,0 +1,214 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+
+function test() {
+
+ var i4 = SIMD.Int32x4(1,2,3,4);
+ var i8 = SIMD.Int16x8(1,2,3,4,5,6,7,8);
+ var i16 = SIMD.Int8x16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16);
+ var u4 = SIMD.Uint32x4(1,2,3,4);
+ var u8 = SIMD.Uint16x8(1,2,3,4,5,6,7,8);
+ var u16 = SIMD.Uint8x16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16);
+ var f4 = SIMD.Float32x4(NaN, -0, Infinity, 13.37);
+ var f2 = SIMD.Float64x2(-0, 13.37);
+ var b2 = SIMD.Bool64x2(true, false);
+ var b4 = SIMD.Bool32x4(true, true, false, false);
+ var b8 = SIMD.Bool16x8(true, true, false, false, true, true, false, false);
+ var b16 = SIMD.Bool8x16(true, true, false, false, true, true, false, false, true, true, false, false, true, true, false, false);
+
+ var ci4 = SIMD.Int32x4.check(i4);
+ assertEqX4(ci4, simdToArray(i4));
+ assertThrowsInstanceOf(() => SIMD.Int32x4.check(f4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int32x4.check(f2), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int32x4.check(i8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int32x4.check(i16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int32x4.check(u4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int32x4.check(u8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int32x4.check(u16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int32x4.check(b2), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int32x4.check(b4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int32x4.check(b8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int32x4.check(b16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int32x4.check("i swear i'm a vector"), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int32x4.check({}), TypeError);
+
+ var ci8 = SIMD.Int16x8.check(i8);
+ assertEqX8(ci8, simdToArray(i8));
+ assertThrowsInstanceOf(() => SIMD.Int16x8.check(i4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int16x8.check(i16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int16x8.check(u4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int16x8.check(u8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int16x8.check(u16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int16x8.check(f4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int16x8.check(f2), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int16x8.check(b2), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int16x8.check(b4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int16x8.check(b8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int16x8.check(b16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int16x8.check("i swear i'm a vector"), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int16x8.check({}), TypeError);
+
+ var ci16 = SIMD.Int8x16.check(i16);
+ assertEqX16(ci16, simdToArray(i16));
+ assertThrowsInstanceOf(() => SIMD.Int8x16.check(i4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int8x16.check(i8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int8x16.check(u4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int8x16.check(u8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int8x16.check(u16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int8x16.check(f4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int8x16.check(f2), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int8x16.check(b2), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int8x16.check(b4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int8x16.check(b8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int8x16.check(b16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int8x16.check("i swear i'm a vector"), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int8x16.check({}), TypeError);
+
+ var cu4 = SIMD.Uint32x4.check(u4);
+ assertEqX4(cu4, simdToArray(u4));
+ assertThrowsInstanceOf(() => SIMD.Uint32x4.check(f4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint32x4.check(f2), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint32x4.check(i4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint32x4.check(i8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint32x4.check(i16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint32x4.check(u8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint32x4.check(u16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint32x4.check(b2), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint32x4.check(b4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint32x4.check(b8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint32x4.check(b16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint32x4.check("i swear i'm a vector"), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint32x4.check({}), TypeError);
+
+ var cu8 = SIMD.Uint16x8.check(u8);
+ assertEqX8(cu8, simdToArray(u8));
+ assertThrowsInstanceOf(() => SIMD.Uint16x8.check(i4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint16x8.check(i8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint16x8.check(i16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint16x8.check(u4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint16x8.check(u16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint16x8.check(f4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint16x8.check(f2), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint16x8.check(b2), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint16x8.check(b4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint16x8.check(b8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint16x8.check(b16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint16x8.check("i swear i'm a vector"), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint16x8.check({}), TypeError);
+
+ var cu16 = SIMD.Uint8x16.check(u16);
+ assertEqX16(cu16, simdToArray(u16));
+ assertThrowsInstanceOf(() => SIMD.Uint8x16.check(i4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint8x16.check(i8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint8x16.check(i16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint8x16.check(u4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint8x16.check(u8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint8x16.check(f4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint8x16.check(f2), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint8x16.check(b2), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint8x16.check(b4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint8x16.check(b8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint8x16.check(b16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint8x16.check("i swear i'm a vector"), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint8x16.check({}), TypeError);
+
+ var cf4 = SIMD.Float32x4.check(f4);
+ assertEqX4(cf4, simdToArray(f4));
+ assertThrowsInstanceOf(() => SIMD.Float32x4.check(i4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Float32x4.check(i8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Float32x4.check(i16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Float32x4.check(u4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Float32x4.check(u8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Float32x4.check(u16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Float32x4.check(f2), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Float32x4.check(b2), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Float32x4.check(b4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Float32x4.check(b8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Float32x4.check(b16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Float32x4.check("i swear i'm a vector"), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Float32x4.check({}), TypeError);
+
+ var cf2 = SIMD.Float64x2.check(f2);
+ assertEqX2(cf2, simdToArray(f2));
+ assertThrowsInstanceOf(() => SIMD.Float64x2.check(f4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Float64x2.check(i4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Float64x2.check(u4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Float64x2.check(u8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Float64x2.check(u16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Float64x2.check(i8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Float64x2.check(i16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Float64x2.check(b2), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Float64x2.check(b4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Float64x2.check(b8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Float64x2.check(b16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Float64x2.check("i swear i'm a vector"), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Float64x2.check({}), TypeError);
+
+ var cb2 = SIMD.Bool64x2.check(b2);
+ assertEqX2(cb2, simdToArray(b2));
+ assertThrowsInstanceOf(() => SIMD.Bool64x2.check(f4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool64x2.check(f2), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool64x2.check(i8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool64x2.check(i16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool64x2.check(u4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool64x2.check(u8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool64x2.check(u16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool64x2.check(b4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool64x2.check(b8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool64x2.check(b16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool64x2.check("i swear i'm a vector"), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool64x2.check({}), TypeError);
+
+ var cb4 = SIMD.Bool32x4.check(b4);
+ assertEqX4(cb4, simdToArray(b4));
+ assertThrowsInstanceOf(() => SIMD.Bool32x4.check(f4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool32x4.check(f2), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool32x4.check(i4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool32x4.check(i8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool32x4.check(i16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool32x4.check(u4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool32x4.check(u8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool32x4.check(u16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool32x4.check(b2), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool32x4.check(b8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool32x4.check(b16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool32x4.check("i swear i'm a vector"), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool32x4.check({}), TypeError);
+
+ var cb8 = SIMD.Bool16x8.check(b8);
+ assertEqX8(cb8, simdToArray(b8));
+ assertThrowsInstanceOf(() => SIMD.Bool16x8.check(f4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool16x8.check(f2), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool16x8.check(i4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool16x8.check(i8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool16x8.check(i16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool16x8.check(u4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool16x8.check(u8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool16x8.check(u16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool16x8.check(b2), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool16x8.check(b4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool16x8.check(b16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool16x8.check("i swear i'm a vector"), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool16x8.check({}), TypeError);
+
+ var cb16 = SIMD.Bool8x16.check(b16);
+ assertEqX16(cb16, simdToArray(b16));
+ assertThrowsInstanceOf(() => SIMD.Bool8x16.check(f4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool8x16.check(f2), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool8x16.check(i4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool8x16.check(i8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool8x16.check(i16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool8x16.check(u4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool8x16.check(u8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool8x16.check(u16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool8x16.check(b2), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool8x16.check(b4), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool8x16.check(b8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool8x16.check("i swear i'm a vector"), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Bool8x16.check({}), TypeError);
+
+ if (typeof reportCompare === "function")
+ reportCompare(true, true);
+}
+
+test();
+
diff --git a/js/src/tests/ecma_7/SIMD/comparisons.js b/js/src/tests/ecma_7/SIMD/comparisons.js
new file mode 100644
index 000000000..2ca54b14e
--- /dev/null
+++ b/js/src/tests/ecma_7/SIMD/comparisons.js
@@ -0,0 +1,349 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var Float32x4 = SIMD.Float32x4;
+var Float64x2 = SIMD.Float64x2;
+var Int8x16 = SIMD.Int8x16;
+var Int16x8 = SIMD.Int16x8;
+var Int32x4 = SIMD.Int32x4;
+var Uint8x16 = SIMD.Uint8x16;
+var Uint16x8 = SIMD.Uint16x8;
+var Uint32x4 = SIMD.Uint32x4;
+var Bool8x16 = SIMD.Bool8x16;
+var Bool16x8 = SIMD.Bool16x8;
+var Bool32x4 = SIMD.Bool32x4;
+var Bool64x2 = SIMD.Bool64x2;
+
+var fround = Math.fround;
+
+
+function testEqualFloat32x4(v, w) {
+ testBinaryCompare(v, w, Float32x4.equal, (x, y) => fround(x) == fround(y), Bool32x4);
+}
+function testNotEqualFloat32x4(v, w) {
+ testBinaryCompare(v, w, Float32x4.notEqual, (x, y) => fround(x) != fround(y), Bool32x4);
+}
+function testLessThanFloat32x4(v, w) {
+ testBinaryCompare(v, w, Float32x4.lessThan, (x, y) => fround(x) < fround(y), Bool32x4);
+}
+function testLessThanOrEqualFloat32x4(v, w) {
+ testBinaryCompare(v, w, Float32x4.lessThanOrEqual, (x, y) => fround(x) <= fround(y), Bool32x4);
+}
+function testGreaterThanFloat32x4(v, w) {
+ testBinaryCompare(v, w, Float32x4.greaterThan, (x, y) => fround(x) > fround(y), Bool32x4);
+}
+function testGreaterThanOrEqualFloat32x4(v, w) {
+ testBinaryCompare(v, w, Float32x4.greaterThanOrEqual, (x, y) => fround(x) >= fround(y), Bool32x4);
+}
+
+function testEqualFloat64x2(v, w) {
+ testBinaryCompare(v, w, Float64x2.equal, (x, y) => x == y, Bool64x2);
+}
+function testNotEqualFloat64x2(v, w) {
+ testBinaryCompare(v, w, Float64x2.notEqual, (x, y) => x != y, Bool64x2);
+}
+function testLessThanFloat64x2(v, w) {
+ testBinaryCompare(v, w, Float64x2.lessThan, (x, y) => x < y, Bool64x2);
+}
+function testLessThanOrEqualFloat64x2(v, w) {
+ testBinaryCompare(v, w, Float64x2.lessThanOrEqual, (x, y) => x <= y, Bool64x2);
+}
+function testGreaterThanFloat64x2(v, w) {
+ testBinaryCompare(v, w, Float64x2.greaterThan, (x, y) => x > y, Bool64x2);
+}
+function testGreaterThanOrEqualFloat64x2(v, w) {
+ testBinaryCompare(v, w, Float64x2.greaterThanOrEqual, (x, y) => x >= y, Bool64x2);
+}
+
+function testEqualInt8x16(v, w) {
+ testBinaryCompare(v, w, Int8x16.equal, (x, y) => x == y, Bool8x16);
+}
+function testNotEqualInt8x16(v, w) {
+ testBinaryCompare(v, w, Int8x16.notEqual, (x, y) => x != y, Bool8x16);
+}
+function testLessThanInt8x16(v, w) {
+ testBinaryCompare(v, w, Int8x16.lessThan, (x, y) => x < y, Bool8x16);
+}
+function testLessThanOrEqualInt8x16(v, w) {
+ testBinaryCompare(v, w, Int8x16.lessThanOrEqual, (x, y) => x <= y, Bool8x16);
+}
+function testGreaterThanInt8x16(v, w) {
+ testBinaryCompare(v, w, Int8x16.greaterThan, (x, y) => x > y, Bool8x16);
+}
+function testGreaterThanOrEqualInt8x16(v, w) {
+ testBinaryCompare(v, w, Int8x16.greaterThanOrEqual, (x, y) => x >= y, Bool8x16);
+}
+
+function testEqualInt16x8(v, w) {
+ testBinaryCompare(v, w, Int16x8.equal, (x, y) => x == y, Bool16x8);
+}
+function testNotEqualInt16x8(v, w) {
+ testBinaryCompare(v, w, Int16x8.notEqual, (x, y) => x != y, Bool16x8);
+}
+function testLessThanInt16x8(v, w) {
+ testBinaryCompare(v, w, Int16x8.lessThan, (x, y) => x < y, Bool16x8);
+}
+function testLessThanOrEqualInt16x8(v, w) {
+ testBinaryCompare(v, w, Int16x8.lessThanOrEqual, (x, y) => x <= y, Bool16x8);
+}
+function testGreaterThanInt16x8(v, w) {
+ testBinaryCompare(v, w, Int16x8.greaterThan, (x, y) => x > y, Bool16x8);
+}
+function testGreaterThanOrEqualInt16x8(v, w) {
+ testBinaryCompare(v, w, Int16x8.greaterThanOrEqual, (x, y) => x >= y, Bool16x8);
+}
+
+function testEqualInt32x4(v, w) {
+ testBinaryCompare(v, w, Int32x4.equal, (x, y) => x == y, Bool32x4);
+}
+function testNotEqualInt32x4(v, w) {
+ testBinaryCompare(v, w, Int32x4.notEqual, (x, y) => x != y, Bool32x4);
+}
+function testLessThanInt32x4(v, w) {
+ testBinaryCompare(v, w, Int32x4.lessThan, (x, y) => x < y, Bool32x4);
+}
+function testLessThanOrEqualInt32x4(v, w) {
+ testBinaryCompare(v, w, Int32x4.lessThanOrEqual, (x, y) => x <= y, Bool32x4);
+}
+function testGreaterThanInt32x4(v, w) {
+ testBinaryCompare(v, w, Int32x4.greaterThan, (x, y) => x > y, Bool32x4);
+}
+function testGreaterThanOrEqualInt32x4(v, w) {
+ testBinaryCompare(v, w, Int32x4.greaterThanOrEqual, (x, y) => x >= y, Bool32x4);
+}
+
+function testEqualUint8x16(v, w) {
+ testBinaryCompare(v, w, Uint8x16.equal, (x, y) => x == y, Bool8x16);
+}
+function testNotEqualUint8x16(v, w) {
+ testBinaryCompare(v, w, Uint8x16.notEqual, (x, y) => x != y, Bool8x16);
+}
+function testLessThanUint8x16(v, w) {
+ testBinaryCompare(v, w, Uint8x16.lessThan, (x, y) => x < y, Bool8x16);
+}
+function testLessThanOrEqualUint8x16(v, w) {
+ testBinaryCompare(v, w, Uint8x16.lessThanOrEqual, (x, y) => x <= y, Bool8x16);
+}
+function testGreaterThanUint8x16(v, w) {
+ testBinaryCompare(v, w, Uint8x16.greaterThan, (x, y) => x > y, Bool8x16);
+}
+function testGreaterThanOrEqualUint8x16(v, w) {
+ testBinaryCompare(v, w, Uint8x16.greaterThanOrEqual, (x, y) => x >= y, Bool8x16);
+}
+
+function testEqualUint16x8(v, w) {
+ testBinaryCompare(v, w, Uint16x8.equal, (x, y) => x == y, Bool16x8);
+}
+function testNotEqualUint16x8(v, w) {
+ testBinaryCompare(v, w, Uint16x8.notEqual, (x, y) => x != y, Bool16x8);
+}
+function testLessThanUint16x8(v, w) {
+ testBinaryCompare(v, w, Uint16x8.lessThan, (x, y) => x < y, Bool16x8);
+}
+function testLessThanOrEqualUint16x8(v, w) {
+ testBinaryCompare(v, w, Uint16x8.lessThanOrEqual, (x, y) => x <= y, Bool16x8);
+}
+function testGreaterThanUint16x8(v, w) {
+ testBinaryCompare(v, w, Uint16x8.greaterThan, (x, y) => x > y, Bool16x8);
+}
+function testGreaterThanOrEqualUint16x8(v, w) {
+ testBinaryCompare(v, w, Uint16x8.greaterThanOrEqual, (x, y) => x >= y, Bool16x8);
+}
+
+function testEqualUint32x4(v, w) {
+ testBinaryCompare(v, w, Uint32x4.equal, (x, y) => x == y, Bool32x4);
+}
+function testNotEqualUint32x4(v, w) {
+ testBinaryCompare(v, w, Uint32x4.notEqual, (x, y) => x != y, Bool32x4);
+}
+function testLessThanUint32x4(v, w) {
+ testBinaryCompare(v, w, Uint32x4.lessThan, (x, y) => x < y, Bool32x4);
+}
+function testLessThanOrEqualUint32x4(v, w) {
+ testBinaryCompare(v, w, Uint32x4.lessThanOrEqual, (x, y) => x <= y, Bool32x4);
+}
+function testGreaterThanUint32x4(v, w) {
+ testBinaryCompare(v, w, Uint32x4.greaterThan, (x, y) => x > y, Bool32x4);
+}
+function testGreaterThanOrEqualUint32x4(v, w) {
+ testBinaryCompare(v, w, Uint32x4.greaterThanOrEqual, (x, y) => x >= y, Bool32x4);
+}
+
+function test() {
+ var Float32x4val = [
+ Float32x4(1, 20, 30, 4),
+ Float32x4(10, 2, 3, 40),
+ Float32x4(9.999, 2.1234, 30.4443, 4),
+ Float32x4(10, 2.1233, 30.4444, 4.0001),
+ Float32x4(NaN, -Infinity, +Infinity, -0),
+ Float32x4(+Infinity, NaN, -0, -Infinity),
+ Float32x4(13.37, 42.42, NaN, 0)
+ ];
+
+ var v, w;
+ for (v of Float32x4val) {
+ for (w of Float32x4val) {
+ testEqualFloat32x4(v, w);
+ testNotEqualFloat32x4(v, w);
+ testLessThanFloat32x4(v, w);
+ testLessThanOrEqualFloat32x4(v, w);
+ testGreaterThanFloat32x4(v, w);
+ testGreaterThanOrEqualFloat32x4(v, w);
+ }
+ }
+
+ var Float64x2val = [
+ Float64x2(1, 20),
+ Float64x2(10, 2),
+ Float64x2(9.999, 2.1234),
+ Float64x2(10, 2.1233),
+ Float64x2(30.4443, 4),
+ Float64x2(30.4444, 4.0001),
+ Float64x2(NaN, -Infinity),
+ Float64x2(+Infinity, NaN),
+ Float64x2(+Infinity, -0),
+ Float64x2(-0, -Infinity),
+ Float64x2(13.37, 42.42),
+ Float64x2(NaN, 0)
+ ];
+
+ for (v of Float64x2val) {
+ for (w of Float64x2val) {
+ testEqualFloat64x2(v, w);
+ testNotEqualFloat64x2(v, w);
+ testLessThanFloat64x2(v, w);
+ testLessThanOrEqualFloat64x2(v, w);
+ testGreaterThanFloat64x2(v, w);
+ testGreaterThanOrEqualFloat64x2(v, w);
+ }
+ }
+
+ var Int8x16val = [
+ Int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16),
+ Int8x16(-1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16),
+ Int8x16(-1, 2, -3, 4, -5, 6, -7, 8, -9, 10, -11, 12, -13, 14, -15, 16),
+ Int8x16(1, -2, 3, -4, 5, -6, 7, -8, 9, -10, 11, -12, 13, -14, 15, -16),
+ Int8x16(INT8_MAX, INT8_MAX, INT8_MIN, INT8_MIN, INT8_MIN + 1, INT8_MAX - 1, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16),
+ Int8x16(INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX - 1, INT8_MIN + 1, 7, 8, 9, 10, 11, 12, 13, 14, 15, -16)
+ ];
+
+ for (v of Int8x16val) {
+ for (w of Int8x16val) {
+ testEqualInt8x16(v, w);
+ testNotEqualInt8x16(v, w);
+ testLessThanInt8x16(v, w);
+ testLessThanOrEqualInt8x16(v, w);
+ testGreaterThanInt8x16(v, w);
+ testGreaterThanOrEqualInt8x16(v, w);
+ }
+ }
+
+ var Int16x8val = [
+ Int16x8(1, 2, 3, 4, 5, 6, 7, 8),
+ Int16x8(-1, -2, -3, -4, -5, -6, -7, -8),
+ Int16x8(-1, 2, -3, 4, -5, 6, -7, 8),
+ Int16x8(1, -2, 3, -4, 5, -6, 7, -8),
+ Int16x8(INT16_MAX, INT16_MAX, INT16_MIN, INT16_MIN, INT16_MIN + 1, INT16_MAX - 1, -7, -8),
+ Int16x8(INT16_MAX, INT16_MIN, INT16_MAX, INT16_MIN, INT16_MAX - 1, INT16_MIN + 1, 7, -8)
+ ];
+
+ for (v of Int16x8val) {
+ for (w of Int16x8val) {
+ testEqualInt16x8(v, w);
+ testNotEqualInt16x8(v, w);
+ testLessThanInt16x8(v, w);
+ testLessThanOrEqualInt16x8(v, w);
+ testGreaterThanInt16x8(v, w);
+ testGreaterThanOrEqualInt16x8(v, w);
+ }
+ }
+
+ var Int32x4val = [
+ Int32x4(1, 2, 3, 4),
+ Int32x4(-1, -2, -3, -4),
+ Int32x4(-1, 2, -3, 4),
+ Int32x4(1, -2, 3, -4),
+ Int32x4(INT32_MAX, INT32_MAX, INT32_MIN, INT32_MIN),
+ Int32x4(INT32_MAX, INT32_MIN, INT32_MAX, INT32_MIN)
+ ];
+
+ for (v of Int32x4val) {
+ for (w of Int32x4val) {
+ testEqualInt32x4(v, w);
+ testNotEqualInt32x4(v, w);
+ testLessThanInt32x4(v, w);
+ testLessThanOrEqualInt32x4(v, w);
+ testGreaterThanInt32x4(v, w);
+ testGreaterThanOrEqualInt32x4(v, w);
+ }
+ }
+
+ var Uint8x16val = [
+ Uint8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16),
+ Uint8x16(-1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16),
+ Uint8x16(-1, 2, -3, 4, -5, 6, -7, 8, -9, 10, -11, 12, -13, 14, -15, 16),
+ Uint8x16(1, -2, 3, -4, 5, -6, 7, -8, 9, -10, 11, -12, 13, -14, 15, -16),
+ Uint8x16(UINT8_MAX, UINT8_MAX, 0, 0, 0 + 1, UINT8_MAX - 1, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16),
+ Uint8x16(UINT8_MAX, 0, UINT8_MAX, 0, UINT8_MAX - 1, 0 + 1, 7, 8, 9, 10, 11, 12, 13, 14, 15, -16)
+ ];
+
+ for (v of Uint8x16val) {
+ for (w of Uint8x16val) {
+ testEqualUint8x16(v, w);
+ testNotEqualUint8x16(v, w);
+ testLessThanUint8x16(v, w);
+ testLessThanOrEqualUint8x16(v, w);
+ testGreaterThanUint8x16(v, w);
+ testGreaterThanOrEqualUint8x16(v, w);
+ }
+ }
+
+ var Uint16x8val = [
+ Uint16x8(1, 2, 3, 4, 5, 6, 7, 8),
+ Uint16x8(-1, -2, -3, -4, -5, -6, -7, -8),
+ Uint16x8(-1, 2, -3, 4, -5, 6, -7, 8),
+ Uint16x8(1, -2, 3, -4, 5, -6, 7, -8),
+ Uint16x8(UINT16_MAX, UINT16_MAX, 0, 0, 0 + 1, UINT16_MAX - 1, -7, -8),
+ Uint16x8(UINT16_MAX, 0, UINT16_MAX, 0, UINT16_MAX - 1, 0 + 1, 7, -8)
+ ];
+
+ for (v of Uint16x8val) {
+ for (w of Uint16x8val) {
+ testEqualUint16x8(v, w);
+ testNotEqualUint16x8(v, w);
+ testLessThanUint16x8(v, w);
+ testLessThanOrEqualUint16x8(v, w);
+ testGreaterThanUint16x8(v, w);
+ testGreaterThanOrEqualUint16x8(v, w);
+ }
+ }
+
+ var Uint32x4val = [
+ Uint32x4(1, 2, 3, 4),
+ Uint32x4(-1, -2, -3, -4),
+ Uint32x4(-1, 2, -3, 4),
+ Uint32x4(1, -2, 3, -4),
+ Uint32x4(UINT32_MAX, UINT32_MAX, 0, 0),
+ Uint32x4(UINT32_MAX, 0, UINT32_MAX, 0)
+ ];
+
+ for (v of Uint32x4val) {
+ for (w of Uint32x4val) {
+ testEqualUint32x4(v, w);
+ testNotEqualUint32x4(v, w);
+ testLessThanUint32x4(v, w);
+ testLessThanOrEqualUint32x4(v, w);
+ testGreaterThanUint32x4(v, w);
+ testGreaterThanOrEqualUint32x4(v, w);
+ }
+ }
+
+ if (typeof reportCompare === "function")
+ reportCompare(true, true);
+}
+
+test();
diff --git a/js/src/tests/ecma_7/SIMD/constructors.js b/js/src/tests/ecma_7/SIMD/constructors.js
new file mode 100644
index 000000000..a10edb343
--- /dev/null
+++ b/js/src/tests/ecma_7/SIMD/constructors.js
@@ -0,0 +1,226 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+
+var Float64x2 = SIMD.Float64x2;
+var Float32x4 = SIMD.Float32x4;
+var Int8x16 = SIMD.Int8x16;
+var Int16x8 = SIMD.Int16x8;
+var Int32x4 = SIMD.Int32x4;
+var Uint8x16 = SIMD.Uint8x16;
+var Uint16x8 = SIMD.Uint16x8;
+var Uint32x4 = SIMD.Uint32x4;
+var Bool8x16 = SIMD.Bool8x16;
+var Bool16x8 = SIMD.Bool16x8;
+var Bool32x4 = SIMD.Bool32x4;
+var Bool64x2 = SIMD.Bool64x2;
+
+function TestInt8x16Ctor() {
+ // Constructors.
+ assertEqX16(Int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]);
+ assertEqX16(Int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0]);
+ assertEqX16(Int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14), [1,2,3,4,5,6,7,8,9,10,11,12,13,14,0,0]);
+ assertEqX16(Int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13), [1,2,3,4,5,6,7,8,9,10,11,12,13,0,0,0]);
+ assertEqX16(Int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), [1,2,3,4,5,6,7,8,9,10,11,12,0,0,0,0]);
+ assertEqX16(Int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), [1,2,3,4,5,6,7,8,9,10,11,0,0,0,0,0]);
+ assertEqX16(Int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), [1,2,3,4,5,6,7,8,9,10,0,0,0,0,0,0]);
+ assertEqX16(Int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9), [1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,0]);
+ assertEqX16(Int8x16(1, 2, 3, 4, 5, 6, 7, 8), [1,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0]);
+ assertEqX16(Int8x16(1, 2, 3, 4, 5, 6, 7), [1,2,3,4,5,6,7,0,0,0,0,0,0,0,0,0]);
+ assertEqX16(Int8x16(1, 2, 3, 4, 5, 6), [1,2,3,4,5,6,0,0,0,0,0,0,0,0,0,0]);
+ assertEqX16(Int8x16(1, 2, 3, 4, 5), [1,2,3,4,5,0,0,0,0,0,0,0,0,0,0,0]);
+ assertEqX16(Int8x16(1, 2, 3, 4), [1,2,3,4,0,0,0,0,0,0,0,0,0,0,0,0]);
+ assertEqX16(Int8x16(1, 2, 3), [1,2,3,0,0,0,0,0,0,0,0,0,0,0,0,0]);
+ assertEqX16(Int8x16(1, 2), [1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);
+ assertEqX16(Int8x16(1), [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);
+ assertEqX16(Int8x16(), [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);
+ assertEqX16(Int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17), [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]);
+ assertEqX16(Int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18), [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]);
+}
+
+function TestInt16x8Ctor() {
+ // Constructors.
+ assertEqX8(Int16x8(1, 2, 3, 4, 5, 6, 7, 8), [1,2,3,4,5,6,7,8]);
+ assertEqX8(Int16x8(1, 2, 3, 4, 5, 6, 7), [1,2,3,4,5,6,7,0]);
+ assertEqX8(Int16x8(1, 2, 3, 4, 5, 6), [1,2,3,4,5,6,0,0]);
+ assertEqX8(Int16x8(1, 2, 3, 4, 5), [1,2,3,4,5,0,0,0]);
+ assertEqX8(Int16x8(1, 2, 3, 4), [1,2,3,4,0,0,0,0]);
+ assertEqX8(Int16x8(1, 2, 3), [1,2,3,0,0,0,0,0]);
+ assertEqX8(Int16x8(1, 2), [1,2,0,0,0,0,0,0]);
+ assertEqX8(Int16x8(1), [1,0,0,0,0,0,0,0]);
+ assertEqX8(Int16x8(), [0,0,0,0,0,0,0,0]);
+ assertEqX8(Int16x8(1, 2, 3, 4, 5, 6, 7, 8, 9), [1,2,3,4,5,6,7,8]);
+ assertEqX8(Int16x8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), [1,2,3,4,5,6,7,8]);
+}
+
+function TestInt32x4Ctor() {
+ // Constructors.
+ assertEqX4(Int32x4(1, 2, 3, 4), [1,2,3,4]);
+ assertEqX4(Int32x4(1, 2, 3), [1,2,3,0]);
+ assertEqX4(Int32x4(1, 2), [1,2,0,0]);
+ assertEqX4(Int32x4(1), [1,0,0,0]);
+ assertEqX4(Int32x4(), [0,0,0,0]);
+ assertEqX4(Int32x4(1, 2, 3, 4, 5), [1,2,3,4]);
+ assertEqX4(Int32x4(1, 2, 3, 4, 5, 6), [1,2,3,4]);
+}
+
+function TestUint8x16Ctor() {
+ // Constructors.
+ assertEqX16(Uint8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]);
+ assertEqX16(Uint8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0]);
+ assertEqX16(Uint8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14), [1,2,3,4,5,6,7,8,9,10,11,12,13,14,0,0]);
+ assertEqX16(Uint8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13), [1,2,3,4,5,6,7,8,9,10,11,12,13,0,0,0]);
+ assertEqX16(Uint8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), [1,2,3,4,5,6,7,8,9,10,11,12,0,0,0,0]);
+ assertEqX16(Uint8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), [1,2,3,4,5,6,7,8,9,10,11,0,0,0,0,0]);
+ assertEqX16(Uint8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), [1,2,3,4,5,6,7,8,9,10,0,0,0,0,0,0]);
+ assertEqX16(Uint8x16(1, 2, 3, 4, 5, 6, 7, 8, 9), [1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,0]);
+ assertEqX16(Uint8x16(1, 2, 3, 4, 5, 6, 7, 8), [1,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0]);
+ assertEqX16(Uint8x16(1, 2, 3, 4, 5, 6, 7), [1,2,3,4,5,6,7,0,0,0,0,0,0,0,0,0]);
+ assertEqX16(Uint8x16(1, 2, 3, 4, 5, 6), [1,2,3,4,5,6,0,0,0,0,0,0,0,0,0,0]);
+ assertEqX16(Uint8x16(1, 2, 3, 4, 5), [1,2,3,4,5,0,0,0,0,0,0,0,0,0,0,0]);
+ assertEqX16(Uint8x16(1, 2, 3, 4), [1,2,3,4,0,0,0,0,0,0,0,0,0,0,0,0]);
+ assertEqX16(Uint8x16(1, 2, 3), [1,2,3,0,0,0,0,0,0,0,0,0,0,0,0,0]);
+ assertEqX16(Uint8x16(1, 2), [1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);
+ assertEqX16(Uint8x16(1), [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);
+ assertEqX16(Uint8x16(), [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);
+ assertEqX16(Uint8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17), [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]);
+ assertEqX16(Uint8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18), [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]);
+}
+
+function TestUint16x8Ctor() {
+ // Constructors.
+ assertEqX8(Uint16x8(1, 2, 3, 4, 5, 6, 7, 8), [1,2,3,4,5,6,7,8]);
+ assertEqX8(Uint16x8(1, 2, 3, 4, 5, 6, 7), [1,2,3,4,5,6,7,0]);
+ assertEqX8(Uint16x8(1, 2, 3, 4, 5, 6), [1,2,3,4,5,6,0,0]);
+ assertEqX8(Uint16x8(1, 2, 3, 4, 5), [1,2,3,4,5,0,0,0]);
+ assertEqX8(Uint16x8(1, 2, 3, 4), [1,2,3,4,0,0,0,0]);
+ assertEqX8(Uint16x8(1, 2, 3), [1,2,3,0,0,0,0,0]);
+ assertEqX8(Uint16x8(1, 2), [1,2,0,0,0,0,0,0]);
+ assertEqX8(Uint16x8(1), [1,0,0,0,0,0,0,0]);
+ assertEqX8(Uint16x8(), [0,0,0,0,0,0,0,0]);
+ assertEqX8(Uint16x8(1, 2, 3, 4, 5, 6, 7, 8, 9), [1,2,3,4,5,6,7,8]);
+ assertEqX8(Uint16x8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), [1,2,3,4,5,6,7,8]);
+}
+
+function TestUint32x4Ctor() {
+ // Constructors.
+ assertEqX4(Uint32x4(1, 2, 3, 4), [1,2,3,4]);
+ assertEqX4(Uint32x4(1, 2, 3), [1,2,3,0]);
+ assertEqX4(Uint32x4(1, 2), [1,2,0,0]);
+ assertEqX4(Uint32x4(1), [1,0,0,0]);
+ assertEqX4(Uint32x4(), [0,0,0,0]);
+ assertEqX4(Uint32x4(1, 2, 3, 4, 5), [1,2,3,4]);
+ assertEqX4(Uint32x4(1, 2, 3, 4, 5, 6), [1,2,3,4]);
+}
+
+function TestFloat32x4Ctor() {
+ assertEqX4(Float32x4(1, 2, 3, 4), [1,2,3,4]);
+ assertEqX4(Float32x4(1, 2, 3), [1,2,3,NaN]);
+ assertEqX4(Float32x4(1, 2), [1,2,NaN,NaN]);
+ assertEqX4(Float32x4(1), [1,NaN,NaN,NaN]);
+ assertEqX4(Float32x4(), [NaN,NaN,NaN,NaN]);
+ assertEqX4(Float32x4(1, 2, 3, 4, 5), [1,2,3,4]);
+ assertEqX4(Float32x4(1, 2, 3, 4, 5, 6), [1,2,3,4]);
+}
+
+function TestFloat64x2Ctor() {
+ assertEqX2(Float64x2(1, 2), [1,2]);
+ assertEqX2(Float64x2(1), [1,NaN]);
+ assertEqX2(Float64x2(), [NaN,NaN]);
+ assertEqX2(Float64x2(1, 2, 3), [1,2]);
+ assertEqX2(Float64x2(1, 2, 3, 4), [1,2]);
+ assertEqX2(Float64x2(1, 2, 3, 4, 5), [1,2]);
+ assertEqX2(Float64x2(1, 2, 3, 4, 5), [1,2]);
+ assertEqX2(Float64x2(1, 2, 3, 4, 5, 6), [1,2]);
+}
+
+function TestBool8x16Ctor() {
+ assertEqX16(Bool8x16(false, false, true, true, false, false, true, true, false, false, true, true, false, false, true, true),
+ [false, false, true, true, false, false, true, true, false, false, true, true, false, false, true, true]);
+ assertEqX16(Bool8x16(false, true, true, false, false, true, true, false, false, true, true, false, false, true, true),
+ [false, true, true, false, false, true, true, false, false, true, true, false, false, true, true, false]);
+ assertEqX16(Bool8x16(true, true, false, false, true, true, false, false, true, true, false, false, true, true),
+ [true, true, false, false, true, true, false, false, true, true, false, false, true, true, false, false]);
+ assertEqX16(Bool8x16(true, false, false, true, true, false, false, true, true, false, false, true, true),
+ [true, false, false, true, true, false, false, true, true, false, false, true, true, false, false, false]);
+ assertEqX16(Bool8x16(false, false, true, true, false, false, true, true, false, false, true, true),
+ [false, false, true, true, false, false, true, true, false, false, true, true, false, false, false, false]);
+ assertEqX16(Bool8x16(false, true, true, false, false, true, true, false, false, true, true),
+ [false, true, true, false, false, true, true, false, false, true, true, false, false, false, false, false]);
+ assertEqX16(Bool8x16(true, true, false, false, true, true, false, false, true, true),
+ [true, true, false, false, true, true, false, false, true, true, false, false, false, false, false, false]);
+ assertEqX16(Bool8x16(true, false, false, true, true, false, false, true, true),
+ [true, false, false, true, true, false, false, true, true, false, false, false, false, false, false, false]);
+ assertEqX16(Bool8x16(false, false, true, true, false, false, true, true),
+ [false, false, true, true, false, false, true, true, false, false, false, false, false, false, false, false]);
+ assertEqX16(Bool8x16(false, true, true, false, false, true, true),
+ [false, true, true, false, false, true, true, false, false, false, false, false, false, false, false, false]);
+ assertEqX16(Bool8x16(true, true, false, false, true, true),
+ [true, true, false, false, true, true, false, false, false, false, false, false, false, false, false, false]);
+ assertEqX16(Bool8x16(true, false, false, true, true),
+ [true, false, false, true, true, false, false, false, false, false, false, false, false, false, false, false]);
+ assertEqX16(Bool8x16(false, false, true, true),
+ [false, false, true, true, false, false, false, false, false, false, false, false, false, false, false, false]);
+ assertEqX16(Bool8x16(false, true, true),
+ [false, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false]);
+ assertEqX16(Bool8x16(true, true),
+ [true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false]);
+ assertEqX16(Bool8x16(true),
+ [true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]);
+ assertEqX16(Bool8x16(),
+ [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]);
+ assertEqX16(Bool8x16(false, false, true, true, false, false, true, true, false, false, true, true, false, false, true, true, false),
+ [false, false, true, true, false, false, true, true, false, false, true, true, false, false, true, true]);
+ assertEqX16(Bool8x16(false, false, true, true, false, false, true, true, false, false, true, true, false, false, true, true, false, true),
+ [false, false, true, true, false, false, true, true, false, false, true, true, false, false, true, true]);
+}
+
+function TestBool16x8Ctor() {
+ assertEqX8(Bool16x8(false, false, true, true, false, false, true, true), [false, false, true, true, false, false, true, true]);
+ assertEqX8(Bool16x8(false, true, true, false, false, true, true), [false, true, true, false, false, true, true, false]);
+ assertEqX8(Bool16x8(true, true, false, false, true, true), [true, true, false, false, true, true, false, false]);
+ assertEqX8(Bool16x8(true, false, false, true, true), [true, false, false, true, true, false, false, false]);
+ assertEqX8(Bool16x8(false, false, true, true), [false, false, true, true, false, false, false, false]);
+ assertEqX8(Bool16x8(false, true, true), [false, true, true, false, false, false, false, false]);
+ assertEqX8(Bool16x8(true, true), [true, true, false, false, false, false, false, false]);
+ assertEqX8(Bool16x8(true), [true, false, false, false, false, false, false, false]);
+ assertEqX8(Bool16x8(), [false, false, false, false, false, false, false, false]);
+ assertEqX8(Bool16x8(false, false, true, true, false, false, true, true, true), [false, false, true, true, false, false, true, true]);
+ assertEqX8(Bool16x8(false, false, true, true, false, false, true, true, true, true), [false, false, true, true, false, false, true, true]);
+}
+
+function TestBool32x4Ctor() {
+ assertEqX4(Bool32x4(false, false, true, true), [false, false, true, true]);
+ assertEqX4(Bool32x4(false, false, true), [false, false, true, false]);
+ assertEqX4(Bool32x4(false, true), [false, true, false, false]);
+ assertEqX4(Bool32x4(true), [true, false, false, false]);
+ assertEqX4(Bool32x4(), [false, false, false, false]);
+ assertEqX4(Bool32x4(false, false, true, true, false), [false, false, true, true]);
+ assertEqX4(Bool32x4(false, false, true, true, false, true), [false, false, true, true]);
+}
+
+function TestBool64x2Ctor() {
+ assertEqX2(Bool64x2(false, true), [false, true]);
+ assertEqX2(Bool64x2(true), [true, false]);
+ assertEqX2(Bool64x2(), [false, false]);
+ assertEqX2(Bool64x2(false, true, true), [false, true]);
+ assertEqX2(Bool64x2(false, true, true, true), [false, true]);
+}
+
+function test() {
+ TestFloat32x4Ctor();
+ TestFloat64x2Ctor();
+ TestInt8x16Ctor();
+ TestInt16x8Ctor();
+ TestInt32x4Ctor();
+ TestUint8x16Ctor();
+ TestUint16x8Ctor();
+ TestUint32x4Ctor();
+ TestBool8x16Ctor();
+ TestBool16x8Ctor();
+ TestBool32x4Ctor();
+ TestBool64x2Ctor();
+ if (typeof reportCompare === "function")
+ reportCompare(true, true);
+}
+
+test();
+
diff --git a/js/src/tests/ecma_7/SIMD/conversions.js b/js/src/tests/ecma_7/SIMD/conversions.js
new file mode 100644
index 000000000..05b2487ac
--- /dev/null
+++ b/js/src/tests/ecma_7/SIMD/conversions.js
@@ -0,0 +1,1261 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+var Float32x4 = SIMD.Float32x4;
+var Float64x2 = SIMD.Float64x2;
+var Int8x16 = SIMD.Int8x16;
+var Int16x8 = SIMD.Int16x8;
+var Int32x4 = SIMD.Int32x4;
+var Uint8x16 = SIMD.Uint8x16;
+var Uint16x8 = SIMD.Uint16x8;
+var Uint32x4 = SIMD.Uint32x4;
+
+function testFloat32x4FromFloat64x2Bits() {
+ var valsExp = [
+ [[2.000000473111868, 512.0001225471497], [1.0, 2.0, 3.0, 4.0]],
+ [[-0, NaN], [0, -0, 0, NaN]],
+ [[Infinity, -Infinity], [0, NaN, 0, NaN]]
+ ];
+
+ for (var [v,w] of valsExp) {
+ assertEqX4(Float32x4.fromFloat64x2Bits(Float64x2(...v)), w);
+ }
+}
+
+function testFloat32x4FromInt8x16Bits() {
+ function expected(v, Buffer) {
+ var i8 = new Int8Array(new Buffer(16));
+ var f32 = new Float32Array(i8.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 16; i++) i8[i] = asArr[i];
+ return [f32[0], f32[1], f32[2], f32[3]];
+ }
+
+ var vals = [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
+ [INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX,
+ INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN]];
+ for (var v of vals) {
+ var i = Int8x16(...v);
+ assertEqX4(Float32x4.fromInt8x16Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX4(Float32x4.fromInt8x16Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testFloat32x4FromUint8x16Bits() {
+ function expected(v, Buffer) {
+ var u8 = new Uint8Array(new Buffer(16));
+ var f32 = new Float32Array(u8.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 16; i++) u8[i] = asArr[i];
+ return [f32[0], f32[1], f32[2], f32[3]];
+ }
+
+ var vals = [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
+ [0, UINT8_MAX, 0, UINT8_MAX, 0, UINT8_MAX, 0, UINT8_MAX,
+ UINT8_MAX, 0, UINT8_MAX, 0, UINT8_MAX, 0, UINT8_MAX, 0]];
+ for (var v of vals) {
+ var i = Uint8x16(...v);
+ assertEqX4(Float32x4.fromUint8x16Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX4(Float32x4.fromUint8x16Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testFloat32x4FromInt16x8Bits() {
+ function expected(v, Buffer) {
+ var i16 = new Int16Array(new Buffer(16));
+ var f32 = new Float32Array(i16.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 8; i++) i16[i] = asArr[i];
+ return [f32[0], f32[1], f32[2], f32[3]];
+ }
+
+ var vals = [[1, 2, 3, 4, 5, 6, 7, 8],
+ [INT16_MIN, INT16_MAX, INT16_MIN, INT16_MAX, INT16_MIN, INT16_MAX, INT16_MIN, INT16_MAX]];
+ for (var v of vals) {
+ var i = Int16x8(...v);
+ assertEqX4(Float32x4.fromInt16x8Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX4(Float32x4.fromInt16x8Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testFloat32x4FromUint16x8Bits() {
+ function expected(v, Buffer) {
+ var u16 = new Uint16Array(new Buffer(16));
+ var f32 = new Float32Array(u16.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 8; i++) u16[i] = asArr[i];
+ return [f32[0], f32[1], f32[2], f32[3]];
+ }
+
+ var vals = [[1, 2, 3, 4, 5, 6, 7, 8],
+ [0, UINT16_MAX, 0, UINT16_MAX, 0, UINT16_MAX, 0, UINT16_MAX]];
+ for (var v of vals) {
+ var i = Uint16x8(...v);
+ assertEqX4(Float32x4.fromUint16x8Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX4(Float32x4.fromUint16x8Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testFloat32x4FromInt32x4() {
+ function expected(v) {
+ return v.map(Math.fround);
+ }
+ var vals = [
+ [1, 2, 3, 4],
+ [INT32_MIN, INT32_MAX, Math.pow(2, 30) - 1, -Math.pow(2, 30)]
+ ];
+
+ for (var v of vals) {
+ assertEqX4(Float32x4.fromInt32x4(Int32x4(...v)), expected(v));
+ }
+
+ // Check that rounding to nearest, even is applied.
+ {
+ var num = makeFloat(0, 150 + 2, 0);
+ var next = makeFloat(0, 150 + 2, 1);
+ assertEq(num + 4, next);
+
+ v = Float32x4.fromInt32x4(Int32x4(num, num + 1, num + 2, num + 3));
+ assertEqX4(v, [num, num, /* even */ num, next]);
+ }
+
+ {
+ var num = makeFloat(0, 150 + 2, 1);
+ var next = makeFloat(0, 150 + 2, 2);
+ assertEq(num + 4, next);
+
+ v = Float32x4.fromInt32x4(Int32x4(num, num + 1, num + 2, num + 3));
+ assertEqX4(v, [num, num, /* even */ next, next]);
+ }
+
+ {
+ var last = makeFloat(0, 157, 0x7fffff);
+
+ assertEq(last, Math.fround(last), "float");
+ assertEq(last < Math.pow(2, 31), true, "less than 2**31");
+ assertEq(last | 0, last, "it should be an integer, as exponent >= 150");
+
+ var diff = (Math.pow(2, 31) - 1) - last;
+ v = Float32x4.fromInt32x4(Int32x4(Math.pow(2, 31) - 1,
+ Math.pow(2, 30) + 1,
+ last + (diff / 2) | 0, // nearest is last
+ last + (diff / 2) + 1 | 0 // nearest is Math.pow(2, 31)
+ ));
+ assertEqX4(v, [Math.pow(2, 31),
+ Math.pow(2, 30),
+ last,
+ Math.pow(2, 31)
+ ]);
+ }
+}
+
+function testFloat32x4FromUint32x4() {
+ function expected(v) {
+ return v.map(Math.fround);
+ }
+ var vals = [
+ [1, 2, 3, 4],
+ [0, UINT32_MAX, Math.pow(2, 30) - 1, Math.pow(2, 31)]
+ ];
+
+ for (var v of vals) {
+ assertEqX4(Float32x4.fromUint32x4(Uint32x4(...v)), expected(v));
+ }
+
+ // Check that rounding to nearest, even is applied.
+ {
+ var num = makeFloat(0, 150 + 2, 0);
+ var next = makeFloat(0, 150 + 2, 1);
+ assertEq(num + 4, next);
+
+ v = Float32x4.fromUint32x4(Uint32x4(num, num + 1, num + 2, num + 3));
+ assertEqX4(v, [num, num, /* even */ num, next]);
+ }
+
+ {
+ var num = makeFloat(0, 150 + 2, 1);
+ var next = makeFloat(0, 150 + 2, 2);
+ assertEq(num + 4, next);
+
+ v = Float32x4.fromUint32x4(Uint32x4(num, num + 1, num + 2, num + 3));
+ assertEqX4(v, [num, num, /* even */ next, next]);
+ }
+
+ {
+ var last = makeFloat(0, 157, 0x7fffff);
+
+ assertEq(last, Math.fround(last), "float");
+ assertEq(last < Math.pow(2, 31), true, "less than 2**31");
+ assertEq(last | 0, last, "it should be an integer, as exponent >= 150");
+
+ var diff = (Math.pow(2, 31) - 1) - last;
+ v = Float32x4.fromUint32x4(Uint32x4(Math.pow(2, 31) - 1,
+ Math.pow(2, 30) + 1,
+ last + (diff / 2) | 0, // nearest is last
+ last + (diff / 2) + 1 | 0 // nearest is Math.pow(2, 31)
+ ));
+ assertEqX4(v, [Math.pow(2, 31),
+ Math.pow(2, 30),
+ last,
+ Math.pow(2, 31)
+ ]);
+ }
+}
+
+function testFloat32x4FromInt32x4Bits() {
+ var valsExp = [
+ [[100, 200, 300, 400], [1.401298464324817e-43, 2.802596928649634e-43, 4.203895392974451e-43, 5.605193857299268e-43]],
+ [[INT32_MIN, INT32_MAX, 0, 0], [-0, NaN, 0, 0]]
+ ];
+
+ for (var [v,w] of valsExp) {
+ assertEqX4(Float32x4.fromInt32x4Bits(Int32x4(...v)), w);
+ }
+}
+
+function testFloat32x4FromUint32x4Bits() {
+ var valsExp = [
+ [[100, 200, 300, 400], [1.401298464324817e-43, 2.802596928649634e-43, 4.203895392974451e-43, 5.605193857299268e-43]],
+ [[INT32_MIN, INT32_MAX, 0, 0], [-0, NaN, 0, 0]]
+ ];
+
+ for (var [v,w] of valsExp) {
+ assertEqX4(Float32x4.fromUint32x4Bits(Uint32x4(...v)), w);
+ }
+}
+
+function testFloat64x2FromFloat32x4Bits() {
+ var valsExp = [
+ [[0, 1.875, 0, 2], [1.0, 2.0]],
+ [[NaN, -0, Infinity, -Infinity], [-1.058925634e-314, -1.404448428688076e+306]]
+ ];
+
+ for (var [v,w] of valsExp) {
+ assertEqX2(Float64x2.fromFloat32x4Bits(Float32x4(...v)), w);
+ }
+}
+
+function testFloat64x2FromInt8x16Bits() {
+ function expected(v, Buffer) {
+ var i8 = new Int8Array(new Buffer(16));
+ var f64 = new Float64Array(i8.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 16; i++) i8[i] = asArr[i];
+ return [f64[0], f64[1]];
+ }
+
+ var vals = [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
+ [INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX,
+ INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN]];
+
+ for (var v of vals) {
+ var f = Int8x16(...v);
+ assertEqX2(Float64x2.fromInt8x16Bits(f), expected(f, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX2(Float64x2.fromInt8x16Bits(f), expected(f, SharedArrayBuffer));
+ }
+}
+
+function testFloat64x2FromUint8x16Bits() {
+ function expected(v, Buffer) {
+ var u8 = new Uint8Array(new Buffer(16));
+ var f64 = new Float64Array(u8.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 16; i++) u8[i] = asArr[i];
+ return [f64[0], f64[1]];
+ }
+
+ var vals = [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
+ [0, UINT8_MAX, 0, UINT8_MAX, 0, UINT8_MAX, 0, UINT8_MAX,
+ UINT8_MAX, 0, UINT8_MAX, 0, UINT8_MAX, 0, UINT8_MAX, 0]];
+
+ for (var v of vals) {
+ var f = Uint8x16(...v);
+ assertEqX2(Float64x2.fromUint8x16Bits(f), expected(f, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX2(Float64x2.fromUint8x16Bits(f), expected(f, SharedArrayBuffer));
+ }
+}
+
+function testFloat64x2FromInt16x8Bits() {
+ function expected(v, Buffer) {
+ var i16 = new Int16Array(new Buffer(16));
+ var f64 = new Float64Array(i16.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 8; i++) i16[i] = asArr[i];
+ return [f64[0], f64[1]];
+ }
+
+ var vals = [[1, 2, 3, 4, 5, 6, 7, 8],
+ [INT16_MIN, INT16_MAX, INT16_MIN, INT16_MAX, INT16_MIN, INT16_MAX, INT16_MIN, INT16_MAX]];
+
+ for (var v of vals) {
+ var f = Int16x8(...v);
+ assertEqX2(Float64x2.fromInt16x8Bits(f), expected(f, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX2(Float64x2.fromInt16x8Bits(f), expected(f, SharedArrayBuffer));
+ }
+}
+
+function testFloat64x2FromUint16x8Bits() {
+ function expected(v, Buffer) {
+ var u16 = new Uint16Array(new Buffer(16));
+ var f64 = new Float64Array(u16.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 8; i++) u16[i] = asArr[i];
+ return [f64[0], f64[1]];
+ }
+
+ var vals = [[1, 2, 3, 4, 5, 6, 7, 8],
+ [0, UINT16_MAX, 0, UINT16_MAX, 0, UINT16_MAX, 0, UINT16_MAX]];
+
+ for (var v of vals) {
+ var f = Uint16x8(...v);
+ assertEqX2(Float64x2.fromUint16x8Bits(f), expected(f, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX2(Float64x2.fromUint16x8Bits(f), expected(f, SharedArrayBuffer));
+ }
+}
+
+function testFloat64x2FromInt32x4Bits() {
+ var valsExp = [
+ [[0x00000000, 0x3ff00000, 0x0000000, 0x40000000], [1.0, 2.0]],
+ [[0xabcdef12, 0x3ff00000, 0x21fedcba, 0x40000000], [1.0000006400213732, 2.0000002532866263]]
+ ];
+
+ for (var [v,w] of valsExp) {
+ assertEqX2(Float64x2.fromInt32x4Bits(Int32x4(...v)), w);
+ }
+}
+
+function testFloat64x2FromUint32x4Bits() {
+ var valsExp = [
+ [[0x00000000, 0x3ff00000, 0x0000000, 0x40000000], [1.0, 2.0]],
+ [[0xabcdef12, 0x3ff00000, 0x21fedcba, 0x40000000], [1.0000006400213732, 2.0000002532866263]]
+ ];
+
+ for (var [v,w] of valsExp) {
+ assertEqX2(Float64x2.fromUint32x4Bits(Uint32x4(...v)), w);
+ }
+}
+
+function testInt32x4FromFloat32x4() {
+ var d = Float32x4(1.1, 2.2, 3.3, 4.6);
+ assertEqX4(Int32x4.fromFloat32x4(d), [1, 2, 3, 4]);
+
+ var d = Float32x4(NaN, 0, 0, 0);
+ assertThrowsInstanceOf(() => SIMD.Int32x4.fromFloat32x4(d), RangeError);
+
+ var d = Float32x4(Infinity, 0, 0, 0);
+ assertThrowsInstanceOf(() => SIMD.Int32x4.fromFloat32x4(d), RangeError);
+
+ var d = Float32x4(-Infinity, 0, 0, 0);
+ assertThrowsInstanceOf(() => SIMD.Int32x4.fromFloat32x4(d), RangeError);
+
+ // Test high boundaries: float(0, 157, 0x7fffff) < INT32_MAX < float(0, 158, 0)
+ var d = Float32x4(makeFloat(0, 127 + 31, 0), 0, 0, 0);
+ assertThrowsInstanceOf(() => SIMD.Int32x4.fromFloat32x4(d), RangeError);
+
+ var lastFloat = makeFloat(0, 127 + 30, 0x7FFFFF);
+ var d = Float32x4(lastFloat, 0, 0, 0);
+ var e = SIMD.Int32x4.fromFloat32x4(d);
+ assertEqX4(e, [lastFloat, 0, 0, 0]);
+
+ // Test low boundaries
+ assertEq(makeFloat(1, 127 + 31, 0), INT32_MIN);
+ var d = Float32x4(makeFloat(1, 127 + 31, 0), 0, 0, 0);
+ var e = SIMD.Int32x4.fromFloat32x4(d);
+ assertEqX4(e, [INT32_MIN, 0, 0, 0]);
+
+ var d = Float32x4(makeFloat(1, 127 + 31, 1), 0, 0, 0);
+ assertThrowsInstanceOf(() => SIMD.Int32x4.fromFloat32x4(d), RangeError);
+}
+
+function testUint32x4FromFloat32x4() {
+ var d = Float32x4(1.1, 2.2, -0.9, 4.6);
+ assertEqX4(Uint32x4.fromFloat32x4(d), [1, 2, 0, 4]);
+
+ var d = Float32x4(NaN, 0, 0, 0);
+ assertThrowsInstanceOf(() => SIMD.Uint32x4.fromFloat32x4(d), RangeError);
+
+ var d = Float32x4(Infinity, 0, 0, 0);
+ assertThrowsInstanceOf(() => SIMD.Uint32x4.fromFloat32x4(d), RangeError);
+
+ var d = Float32x4(-Infinity, 0, 0, 0);
+ assertThrowsInstanceOf(() => SIMD.Uint32x4.fromFloat32x4(d), RangeError);
+
+ // Test high boundaries: float(0, 158, 0x7fffff) < UINT32_MAX < float(0, 159, 0)
+ var d = Float32x4(makeFloat(0, 127 + 32, 0), 0, 0, 0);
+ assertThrowsInstanceOf(() => SIMD.Uint32x4.fromFloat32x4(d), RangeError);
+
+ var lastFloat = makeFloat(0, 127 + 31, 0x7FFFFF);
+ var d = Float32x4(lastFloat, 0, 0, 0);
+ var e = SIMD.Uint32x4.fromFloat32x4(d);
+ assertEqX4(e, [lastFloat, 0, 0, 0]);
+}
+
+function testInt32x4FromFloat32x4Bits() {
+ var valsExp = [
+ [[1, 2, 3, 4], [0x3f800000 | 0, 0x40000000 | 0, 0x40400000 | 0, 0x40800000 | 0]],
+ [[NaN, -0, Infinity, -Infinity], [0x7fc00000 | 0, 0x80000000 | 0, 0x7f800000 | 0, 0xff800000 | 0]]
+ ];
+
+ for (var [v,w] of valsExp) {
+ assertEqX4(Int32x4.fromFloat32x4Bits(Float32x4(...v)), w);
+ }
+}
+
+function testUint32x4FromFloat32x4Bits() {
+ var valsExp = [
+ [[1, 2, 3, 4], [0x3f800000, 0x40000000, 0x40400000, 0x40800000]],
+ [[NaN, -0, Infinity, -Infinity], [0x7fc00000, 0x80000000, 0x7f800000, 0xff800000]]
+ ];
+
+ for (var [v,w] of valsExp) {
+ assertEqX4(Uint32x4.fromFloat32x4Bits(Float32x4(...v)), w);
+ }
+}
+
+function testInt32x4FromFloat64x2Bits() {
+ var valsExp = [
+ [[1.0, 2.0], [0x00000000, 0x3FF00000, 0x00000000, 0x40000000]],
+ [[+Infinity, -Infinity], [0x00000000, 0x7ff00000, 0x00000000, -0x100000]],
+ [[-0, NaN], [0x00000000, -0x80000000, 0x00000000, 0x7ff80000]],
+ [[1.0000006400213732, 2.0000002532866263], [-0x543210ee, 0x3ff00000, 0x21fedcba, 0x40000000]]
+ ];
+
+ for (var [v,w] of valsExp) {
+ assertEqX4(Int32x4.fromFloat64x2Bits(Float64x2(...v)), w);
+ }
+}
+
+function testUint32x4FromFloat64x2Bits() {
+ var valsExp = [
+ [[1.0, 2.0], [0x00000000, 0x3FF00000, 0x00000000, 0x40000000]],
+ [[+Infinity, -Infinity], [0x00000000, 0x7ff00000, 0x00000000, 0xfff00000]],
+ [[-0, NaN], [0x00000000, 0x80000000, 0x00000000, 0x7ff80000]],
+ [[1.0000006400213732, 2.0000002532866263], [0xabcdef12, 0x3ff00000, 0x21fedcba, 0x40000000]]
+ ];
+
+ for (var [v,w] of valsExp) {
+ assertEqX4(Uint32x4.fromFloat64x2Bits(Float64x2(...v)), w);
+ }
+}
+
+function testInt32x4FromInt8x16Bits() {
+ function expected(v, Buffer) {
+ var i8 = new Int8Array(new Buffer(16));
+ var i32 = new Int32Array(i8.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 16; i++) i8[i] = asArr[i];
+ return [i32[0], i32[1], i32[2], i32[3]];
+ }
+
+ var vals = [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
+ [INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX,
+ INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN]];
+
+ for (var v of vals) {
+ var i = Int8x16(...v);
+ assertEqX4(Int32x4.fromInt8x16Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX4(Int32x4.fromInt8x16Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testInt32x4FromUint8x16Bits() {
+ function expected(v, Buffer) {
+ var u8 = new Uint8Array(new Buffer(16));
+ var i32 = new Int32Array(u8.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 16; i++) u8[i] = asArr[i];
+ return [i32[0], i32[1], i32[2], i32[3]];
+ }
+
+ var vals = [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
+ [0, UINT8_MAX, 0, UINT8_MAX, 0, UINT8_MAX, 0, UINT8_MAX,
+ UINT8_MAX, 0, UINT8_MAX, 0, UINT8_MAX, 0, UINT8_MAX, 0]];
+
+ for (var v of vals) {
+ var i = Uint8x16(...v);
+ assertEqX4(Int32x4.fromUint8x16Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX4(Int32x4.fromUint8x16Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testInt32x4FromInt16x8Bits() {
+ function expected(v, Buffer) {
+ var i16 = new Int16Array(new Buffer(16));
+ var i32 = new Int32Array(i16.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 8; i++) i16[i] = asArr[i];
+ return [i32[0], i32[1], i32[2], i32[3]];
+ }
+
+ var vals = [[1, 2, 3, 4, 5, 6, 7, 8],
+ [INT16_MIN, INT16_MAX, INT16_MIN, INT16_MAX, INT16_MIN, INT16_MAX, INT16_MIN, INT16_MAX]];
+
+ for (var v of vals) {
+ var i = Int16x8(...v);
+ assertEqX4(Int32x4.fromInt16x8Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX4(Int32x4.fromInt16x8Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testInt32x4FromUint16x8Bits() {
+ function expected(v, Buffer) {
+ var u16 = new Uint16Array(new Buffer(16));
+ var i32 = new Int32Array(u16.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 8; i++) u16[i] = asArr[i];
+ return [i32[0], i32[1], i32[2], i32[3]];
+ }
+
+ var vals = [[1, 2, 3, 4, 5, 6, 7, 8],
+ [0, UINT16_MAX, 0, UINT16_MAX, 0, UINT16_MAX, 0, UINT16_MAX]];
+
+ for (var v of vals) {
+ var i = Uint16x8(...v);
+ assertEqX4(Int32x4.fromUint16x8Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX4(Int32x4.fromUint16x8Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testInt32x4FromUint32x4Bits() {
+ function expected(v, Buffer) {
+ var u32 = new Uint32Array(new Buffer(16));
+ var i32 = new Int32Array(u32.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 8; i++) u32[i] = asArr[i];
+ return [i32[0], i32[1], i32[2], i32[3]];
+ }
+
+ var vals = [[0, 1, -2, 3], [INT8_MIN, UINT32_MAX, INT32_MIN, INT32_MAX]];
+
+ for (var v of vals) {
+ var i = Uint32x4(...v);
+ assertEqX4(Int32x4.fromUint32x4Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX4(Int32x4.fromUint32x4Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testInt8x16FromFloat32x4Bits() {
+ function expected(v, Buffer) {
+ var f32 = new Float32Array(new Buffer(16));
+ var i8 = new Int8Array(f32.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 4; i++) f32[i] = asArr[i];
+ return [i8[0], i8[1], i8[2], i8[3], i8[4], i8[5], i8[6], i8[7],
+ i8[8], i8[9], i8[10], i8[11], i8[12], i8[13], i8[14], i8[15]];
+ }
+
+ var vals = [[1, -2, 3, -4], [Infinity, -Infinity, NaN, -0]];
+
+ for (var v of vals) {
+ var f = Float32x4(...v);
+ assertEqX16(Int8x16.fromFloat32x4Bits(f), expected(f, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX16(Int8x16.fromFloat32x4Bits(f), expected(f, SharedArrayBuffer));
+ }
+}
+
+function testInt8x16FromFloat64x2Bits() {
+ function expected(v, Buffer) {
+ var f64 = new Float64Array(new Buffer(16));
+ var i8 = new Int8Array(f64.buffer);
+ f64[0] = Float64x2.extractLane(v, 0);
+ f64[1] = Float64x2.extractLane(v, 1);
+ return [i8[0], i8[1], i8[2], i8[3], i8[4], i8[5], i8[6], i8[7],
+ i8[8], i8[9], i8[10], i8[11], i8[12], i8[13], i8[14], i8[15]];
+ }
+ var vals = [[1, -2], [-3, 4], [Infinity, -Infinity], [NaN, -0]];
+
+ for (var v of vals) {
+ var f = Float64x2(...v);
+ assertEqX16(Int8x16.fromFloat64x2Bits(f), expected(f, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX16(Int8x16.fromFloat64x2Bits(f), expected(f, SharedArrayBuffer));
+ }
+}
+
+function testInt8x16FromUint8x16Bits() {
+ function expected(v, Buffer) {
+ var u8 = new Uint8Array(new Buffer(16));
+ var i8 = new Int8Array(u8.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 16; i++) u8[i] = asArr[i];
+ return [i8[0], i8[1], i8[2], i8[3], i8[4], i8[5], i8[6], i8[7],
+ i8[8], i8[9], i8[10], i8[11], i8[12], i8[13], i8[14], i8[15]];
+ }
+
+ var vals = [[0, 1, -2, 3, -4, 5, INT8_MIN, UINT8_MAX, -6, 7, -8, 9, -10, 11, -12, 13]];
+
+ for (var v of vals) {
+ var i = Uint8x16(...v);
+ assertEqX16(Int8x16.fromUint8x16Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX16(Int8x16.fromUint8x16Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testInt8x16FromInt16x8Bits() {
+ function expected(v, Buffer) {
+ var i16 = new Int16Array(new Buffer(16));
+ var i8 = new Int8Array(i16.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 8; i++) i16[i] = asArr[i];
+ return [i8[0], i8[1], i8[2], i8[3], i8[4], i8[5], i8[6], i8[7],
+ i8[8], i8[9], i8[10], i8[11], i8[12], i8[13], i8[14], i8[15]];
+ }
+
+ var vals = [[0, 1, -2, 3, INT8_MIN, INT8_MAX, INT16_MIN, INT16_MAX]];
+ for (var v of vals) {
+ var i = Int16x8(...v);
+ assertEqX16(Int8x16.fromInt16x8Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX16(Int8x16.fromInt16x8Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testInt8x16FromUint16x8Bits() {
+ function expected(v, Buffer) {
+ var u16 = new Uint16Array(new Buffer(16));
+ var i8 = new Int8Array(u16.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 8; i++) u16[i] = asArr[i];
+ return [i8[0], i8[1], i8[2], i8[3], i8[4], i8[5], i8[6], i8[7],
+ i8[8], i8[9], i8[10], i8[11], i8[12], i8[13], i8[14], i8[15]];
+ }
+
+ var vals = [[0, 1, -2, UINT16_MAX, INT8_MIN, INT8_MAX, INT16_MIN, INT16_MAX]];
+ for (var v of vals) {
+ var i = Uint16x8(...v);
+ assertEqX16(Int8x16.fromUint16x8Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX16(Int8x16.fromUint16x8Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testInt8x16FromInt32x4Bits() {
+ function expected(v, Buffer) {
+ var i32 = new Int32Array(new Buffer(16));
+ var i8 = new Int8Array(i32.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 4; i++) i32[i] = asArr[i];
+ return [i8[0], i8[1], i8[2], i8[3], i8[4], i8[5], i8[6], i8[7],
+ i8[8], i8[9], i8[10], i8[11], i8[12], i8[13], i8[14], i8[15]];
+ }
+
+ var vals = [[0, 1, -2, 3], [INT8_MIN, INT8_MAX, INT32_MIN, INT32_MAX]];
+ for (var v of vals) {
+ var i = Int32x4(...v);
+ assertEqX16(Int8x16.fromInt32x4Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX16(Int8x16.fromInt32x4Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testInt8x16FromUint32x4Bits() {
+ function expected(v, Buffer) {
+ var u32 = new Uint32Array(new Buffer(16));
+ var i8 = new Int8Array(u32.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 4; i++) u32[i] = asArr[i];
+ return [i8[0], i8[1], i8[2], i8[3], i8[4], i8[5], i8[6], i8[7],
+ i8[8], i8[9], i8[10], i8[11], i8[12], i8[13], i8[14], i8[15]];
+ }
+
+ var vals = [[0, 1, -2, 3], [INT8_MIN, INT8_MAX, INT32_MIN, INT32_MAX]];
+ for (var v of vals) {
+ var i = Uint32x4(...v);
+ assertEqX16(Int8x16.fromUint32x4Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX16(Int8x16.fromUint32x4Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testInt16x8FromFloat32x4Bits() {
+ function expected(v, Buffer) {
+ var f32 = new Float32Array(new Buffer(16));
+ var i16 = new Int16Array(f32.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 4; i++) f32[i] = asArr[i];
+ return [i16[0], i16[1], i16[2], i16[3], i16[4], i16[5], i16[6], i16[7]];
+ }
+
+ var vals = [[1, -2, 3, -4], [Infinity, -Infinity, NaN, -0]];
+
+ for (var v of vals) {
+ var f = Float32x4(...v);
+ assertEqX8(Int16x8.fromFloat32x4Bits(f), expected(f, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX8(Int16x8.fromFloat32x4Bits(f), expected(f, SharedArrayBuffer));
+ }
+}
+
+function testInt16x8FromFloat64x2Bits() {
+ function expected(v, Buffer) {
+ var f64 = new Float64Array(new Buffer(16));
+ var i16 = new Int16Array(f64.buffer);
+ f64[0] = Float64x2.extractLane(v, 0);
+ f64[1] = Float64x2.extractLane(v, 1);
+ return [i16[0], i16[1], i16[2], i16[3], i16[4], i16[5], i16[6], i16[7]];
+ }
+
+ var vals = [[1, -2], [-3, 4], [Infinity, -Infinity], [NaN, -0]];
+
+ for (var v of vals) {
+ var f = Float64x2(...v);
+ assertEqX8(Int16x8.fromFloat64x2Bits(f), expected(f, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX8(Int16x8.fromFloat64x2Bits(f), expected(f, SharedArrayBuffer));
+ }
+}
+
+function testInt16x8FromInt8x16Bits() {
+ function expected(v, Buffer) {
+ var i8 = new Int8Array(new Buffer(16));
+ var i16 = new Int16Array(i8.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 16; i++) i8[i] = asArr[i];
+ return [i16[0], i16[1], i16[2], i16[3], i16[4], i16[5], i16[6], i16[7]];
+ }
+
+ var vals = [[0, 1, -2, 3, -4, 5, INT8_MIN, INT8_MAX, -6, 7, -8, 9, -10, 11, -12, 13]];
+
+ for (var v of vals) {
+ var i = Int8x16(...v);
+ assertEqX8(Int16x8.fromInt8x16Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX8(Int16x8.fromInt8x16Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testInt16x8FromUint8x16Bits() {
+ function expected(v, Buffer) {
+ var u8 = new Uint8Array(new Buffer(16));
+ var i16 = new Int16Array(u8.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 16; i++) u8[i] = asArr[i];
+ return [i16[0], i16[1], i16[2], i16[3], i16[4], i16[5], i16[6], i16[7]];
+ }
+
+ var vals = [[0, 1, -2, 3, -4, UINT8_MAX, INT8_MIN, INT8_MAX, -6, 7, -8, 9, -10, 11, -12, 13]];
+
+ for (var v of vals) {
+ var i = Uint8x16(...v);
+ assertEqX8(Int16x8.fromUint8x16Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX8(Int16x8.fromUint8x16Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testInt16x8FromUint16x8Bits() {
+ function expected(v, Buffer) {
+ var u16 = new Uint16Array(new Buffer(16));
+ var i16 = new Int16Array(u16.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 8; i++) u16[i] = asArr[i];
+ return [i16[0], i16[1], i16[2], i16[3], i16[4], i16[5], i16[6], i16[7]];
+ }
+
+ var vals = [[1, 2, 3, 4, 5, 6, 7, 8],
+ [0, UINT16_MAX, 0, UINT16_MAX, 0, UINT16_MAX, 0, UINT16_MAX]];
+
+ for (var v of vals) {
+ var i = Uint16x8(...v);
+ assertEqX8(Int16x8.fromUint16x8Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX8(Int16x8.fromUint16x8Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testInt16x8FromInt32x4Bits() {
+ function expected(v, Buffer) {
+ var i32 = new Int32Array(new Buffer(16));
+ var i16 = new Int16Array(i32.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 4; i++) i32[i] = asArr[i];
+ return [i16[0], i16[1], i16[2], i16[3], i16[4], i16[5], i16[6], i16[7]];
+ }
+
+ var vals = [[1, -2, -3, 4], [INT16_MAX, INT16_MIN, INT32_MAX, INT32_MIN]];
+
+ for (var v of vals) {
+ var i = Int32x4(...v);
+ assertEqX8(Int16x8.fromInt32x4Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX8(Int16x8.fromInt32x4Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testInt16x8FromUint32x4Bits() {
+ function expected(v, Buffer) {
+ var u32 = new Uint32Array(new Buffer(16));
+ var i16 = new Int16Array(u32.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 4; i++) u32[i] = asArr[i];
+ return [i16[0], i16[1], i16[2], i16[3], i16[4], i16[5], i16[6], i16[7]];
+ }
+
+ var vals = [[1, -2, -3, 4], [INT16_MAX, INT16_MIN, INT32_MAX, INT32_MIN]];
+
+ for (var v of vals) {
+ var i = Uint32x4(...v);
+ assertEqX8(Int16x8.fromUint32x4Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX8(Int16x8.fromUint32x4Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testUint32x4FromInt8x16Bits() {
+ function expected(v, Buffer) {
+ var i8 = new Int8Array(new Buffer(16));
+ var u32 = new Uint32Array(i8.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 16; i++) i8[i] = asArr[i];
+ return [u32[0], u32[1], u32[2], u32[3]];
+ }
+
+ var vals = [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
+ [INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX,
+ INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN, INT8_MAX, INT8_MIN]];
+
+ for (var v of vals) {
+ var i = Int8x16(...v);
+ assertEqX4(Uint32x4.fromInt8x16Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX4(Uint32x4.fromInt8x16Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testUint32x4FromUint8x16Bits() {
+ function expected(v, Buffer) {
+ var u8 = new Uint8Array(new Buffer(16));
+ var u32 = new Uint32Array(u8.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 16; i++) u8[i] = asArr[i];
+ return [u32[0], u32[1], u32[2], u32[3]];
+ }
+
+ var vals = [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
+ [0, UINT8_MAX, 0, UINT8_MAX, 0, UINT8_MAX, 0, UINT8_MAX,
+ UINT8_MAX, 0, UINT8_MAX, 0, UINT8_MAX, 0, UINT8_MAX, 0]];
+
+ for (var v of vals) {
+ var i = Uint8x16(...v);
+ assertEqX4(Uint32x4.fromUint8x16Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX4(Uint32x4.fromUint8x16Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testUint32x4FromInt16x8Bits() {
+ function expected(v, Buffer) {
+ var i16 = new Int16Array(new Buffer(16));
+ var u32 = new Uint32Array(i16.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 8; i++) i16[i] = asArr[i];
+ return [u32[0], u32[1], u32[2], u32[3]];
+ }
+
+ var vals = [[1, 2, 3, 4, 5, 6, 7, 8],
+ [INT16_MIN, INT16_MAX, INT16_MIN, INT16_MAX, INT16_MIN, INT16_MAX, INT16_MIN, INT16_MAX]];
+
+ for (var v of vals) {
+ var i = Int16x8(...v);
+ assertEqX4(Uint32x4.fromInt16x8Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX4(Uint32x4.fromInt16x8Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testUint32x4FromUint16x8Bits() {
+ function expected(v, Buffer) {
+ var u16 = new Uint16Array(new Buffer(16));
+ var u32 = new Uint32Array(u16.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 8; i++) u16[i] = asArr[i];
+ return [u32[0], u32[1], u32[2], u32[3]];
+ }
+
+ var vals = [[1, 2, 3, 4, 5, 6, 7, 8],
+ [0, UINT16_MAX, 0, UINT16_MAX, 0, UINT16_MAX, 0, UINT16_MAX]];
+
+ for (var v of vals) {
+ var i = Uint16x8(...v);
+ assertEqX4(Uint32x4.fromUint16x8Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX4(Uint32x4.fromUint16x8Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testUint32x4FromInt32x4Bits() {
+ function expected(v, Buffer) {
+ var i32 = new Int32Array(new Buffer(16));
+ var u32 = new Uint32Array(i32.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 8; i++) i32[i] = asArr[i];
+ return [u32[0], u32[1], u32[2], u32[3]];
+ }
+
+ var vals = [[0, 1, -2, 3], [INT8_MIN, UINT32_MAX, INT32_MIN, INT32_MAX]];
+
+ for (var v of vals) {
+ var i = Int32x4(...v);
+ assertEqX4(Uint32x4.fromInt32x4Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX4(Uint32x4.fromInt32x4Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testUint8x16FromFloat32x4Bits() {
+ function expected(v, Buffer) {
+ var f32 = new Float32Array(new Buffer(16));
+ var u8 = new Uint8Array(f32.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 4; i++) f32[i] = asArr[i];
+ return [u8[0], u8[1], u8[2], u8[3], u8[4], u8[5], u8[6], u8[7],
+ u8[8], u8[9], u8[10], u8[11], u8[12], u8[13], u8[14], u8[15]];
+ }
+
+ var vals = [[1, -2, 3, -4], [Infinity, -Infinity, NaN, -0]];
+
+ for (var v of vals) {
+ var f = Float32x4(...v);
+ assertEqX16(Uint8x16.fromFloat32x4Bits(f), expected(f, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX16(Uint8x16.fromFloat32x4Bits(f), expected(f, SharedArrayBuffer));
+ }
+}
+
+function testUint8x16FromFloat64x2Bits() {
+ function expected(v, Buffer) {
+ var f64 = new Float64Array(new Buffer(16));
+ var u8 = new Uint8Array(f64.buffer);
+ f64[0] = Float64x2.extractLane(v, 0);
+ f64[1] = Float64x2.extractLane(v, 1);
+ return [u8[0], u8[1], u8[2], u8[3], u8[4], u8[5], u8[6], u8[7],
+ u8[8], u8[9], u8[10], u8[11], u8[12], u8[13], u8[14], u8[15]];
+ }
+ var vals = [[1, -2], [-3, 4], [Infinity, -Infinity], [NaN, -0]];
+
+ for (var v of vals) {
+ var f = Float64x2(...v);
+ assertEqX16(Uint8x16.fromFloat64x2Bits(f), expected(f, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX16(Uint8x16.fromFloat64x2Bits(f), expected(f, SharedArrayBuffer));
+ }
+}
+
+function testUint8x16FromInt8x16Bits() {
+ function expected(v, Buffer) {
+ var i8 = new Int8Array(new Buffer(16));
+ var u8 = new Uint8Array(i8.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 16; i++) i8[i] = asArr[i];
+ return [u8[0], u8[1], u8[2], u8[3], u8[4], u8[5], u8[6], u8[7],
+ u8[8], u8[9], u8[10], u8[11], u8[12], u8[13], u8[14], u8[15]];
+ }
+
+ var vals = [[0, 1, -2, 3, -4, 5, INT8_MIN, UINT8_MAX, -6, 7, INT8_MAX, 9, -10, 11, -12, 13]];
+
+ for (var v of vals) {
+ var i = Int8x16(...v);
+ assertEqX16(Uint8x16.fromInt8x16Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX16(Uint8x16.fromInt8x16Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testUint8x16FromInt16x8Bits() {
+ function expected(v, Buffer) {
+ var i16 = new Int16Array(new Buffer(16));
+ var u8 = new Uint8Array(i16.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 8; i++) i16[i] = asArr[i];
+ return [u8[0], u8[1], u8[2], u8[3], u8[4], u8[5], u8[6], u8[7],
+ u8[8], u8[9], u8[10], u8[11], u8[12], u8[13], u8[14], u8[15]];
+ }
+
+ var vals = [[0, 1, -2, 3, INT8_MIN, INT8_MAX, INT16_MIN, INT16_MAX]];
+ for (var v of vals) {
+ var i = Int16x8(...v);
+ assertEqX16(Uint8x16.fromInt16x8Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX16(Uint8x16.fromInt16x8Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testUint8x16FromUint16x8Bits() {
+ function expected(v, Buffer) {
+ var u16 = new Uint16Array(new Buffer(16));
+ var u8 = new Uint8Array(u16.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 8; i++) u16[i] = asArr[i];
+ return [u8[0], u8[1], u8[2], u8[3], u8[4], u8[5], u8[6], u8[7],
+ u8[8], u8[9], u8[10], u8[11], u8[12], u8[13], u8[14], u8[15]];
+ }
+
+ var vals = [[0, 1, -2, UINT16_MAX, INT8_MIN, INT8_MAX, INT16_MIN, INT16_MAX]];
+ for (var v of vals) {
+ var i = Uint16x8(...v);
+ assertEqX16(Uint8x16.fromUint16x8Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX16(Uint8x16.fromUint16x8Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testUint8x16FromInt32x4Bits() {
+ function expected(v, Buffer) {
+ var i32 = new Int32Array(new Buffer(16));
+ var u8 = new Uint8Array(i32.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 4; i++) i32[i] = asArr[i];
+ return [u8[0], u8[1], u8[2], u8[3], u8[4], u8[5], u8[6], u8[7],
+ u8[8], u8[9], u8[10], u8[11], u8[12], u8[13], u8[14], u8[15]];
+ }
+
+ var vals = [[0, 1, -2, 3], [INT8_MIN, INT8_MAX, INT32_MIN, INT32_MAX]];
+ for (var v of vals) {
+ var i = Int32x4(...v);
+ assertEqX16(Uint8x16.fromInt32x4Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX16(Uint8x16.fromInt32x4Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testUint8x16FromUint32x4Bits() {
+ function expected(v, Buffer) {
+ var u32 = new Uint32Array(new Buffer(16));
+ var u8 = new Uint8Array(u32.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 4; i++) u32[i] = asArr[i];
+ return [u8[0], u8[1], u8[2], u8[3], u8[4], u8[5], u8[6], u8[7],
+ u8[8], u8[9], u8[10], u8[11], u8[12], u8[13], u8[14], u8[15]];
+ }
+
+ var vals = [[0, 1, -2, 3], [INT8_MIN, INT8_MAX, INT32_MIN, INT32_MAX]];
+ for (var v of vals) {
+ var i = Uint32x4(...v);
+ assertEqX16(Uint8x16.fromUint32x4Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX16(Uint8x16.fromUint32x4Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testUint16x8FromFloat32x4Bits() {
+ function expected(v, Buffer) {
+ var f32 = new Float32Array(new Buffer(16));
+ var u16 = new Uint16Array(f32.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 4; i++) f32[i] = asArr[i];
+ return [u16[0], u16[1], u16[2], u16[3], u16[4], u16[5], u16[6], u16[7]];
+ }
+
+ var vals = [[1, -2, 3, -4], [Infinity, -Infinity, NaN, -0]];
+
+ for (var v of vals) {
+ var f = Float32x4(...v);
+ assertEqX8(Uint16x8.fromFloat32x4Bits(f), expected(f, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX8(Uint16x8.fromFloat32x4Bits(f), expected(f, SharedArrayBuffer));
+ }
+}
+
+function testUint16x8FromFloat64x2Bits() {
+ function expected(v, Buffer) {
+ var f64 = new Float64Array(new Buffer(16));
+ var u16 = new Uint16Array(f64.buffer);
+ f64[0] = Float64x2.extractLane(v, 0);
+ f64[1] = Float64x2.extractLane(v, 1);
+ return [u16[0], u16[1], u16[2], u16[3], u16[4], u16[5], u16[6], u16[7]];
+ }
+
+ var vals = [[1, -2], [-3, 4], [Infinity, -Infinity], [NaN, -0]];
+
+ for (var v of vals) {
+ var f = Float64x2(...v);
+ assertEqX8(Uint16x8.fromFloat64x2Bits(f), expected(f, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX8(Uint16x8.fromFloat64x2Bits(f), expected(f, SharedArrayBuffer));
+ }
+}
+
+function testUint16x8FromInt8x16Bits() {
+ function expected(v, Buffer) {
+ var i8 = new Int8Array(new Buffer(16));
+ var u16 = new Uint16Array(i8.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 16; i++) i8[i] = asArr[i];
+ return [u16[0], u16[1], u16[2], u16[3], u16[4], u16[5], u16[6], u16[7]];
+ }
+
+ var vals = [[0, 1, -2, 3, -4, 5, INT8_MIN, INT8_MAX, -6, 7, -8, 9, -10, 11, -12, 13]];
+
+ for (var v of vals) {
+ var i = Int8x16(...v);
+ assertEqX8(Uint16x8.fromInt8x16Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX8(Uint16x8.fromInt8x16Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testUint16x8FromUint8x16Bits() {
+ function expected(v, Buffer) {
+ var u8 = new Uint8Array(new Buffer(16));
+ var u16 = new Uint16Array(u8.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 16; i++) u8[i] = asArr[i];
+ return [u16[0], u16[1], u16[2], u16[3], u16[4], u16[5], u16[6], u16[7]];
+ }
+
+ var vals = [[0, 1, -2, 3, -4, UINT8_MAX, INT8_MIN, INT8_MAX, -6, 7, -8, 9, -10, 11, -12, 13]];
+
+ for (var v of vals) {
+ var i = Uint8x16(...v);
+ assertEqX8(Uint16x8.fromUint8x16Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX8(Uint16x8.fromUint8x16Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testUint16x8FromInt16x8Bits() {
+ function expected(v, Buffer) {
+ var i16 = new Int16Array(new Buffer(16));
+ var u16 = new Uint16Array(i16.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 8; i++) i16[i] = asArr[i];
+ return [u16[0], u16[1], u16[2], u16[3], u16[4], u16[5], u16[6], u16[7]];
+ }
+
+ var vals = [[1, 2, 3, 4, 5, 6, 7, 8],
+ [INT16_MIN, UINT16_MAX, INT16_MAX, UINT16_MAX, 0, UINT16_MAX, 0, UINT16_MAX]];
+
+ for (var v of vals) {
+ var i = Int16x8(...v);
+ assertEqX8(Uint16x8.fromInt16x8Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX8(Uint16x8.fromInt16x8Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testUint16x8FromInt32x4Bits() {
+ function expected(v, Buffer) {
+ var i32 = new Int32Array(new Buffer(16));
+ var u16 = new Uint16Array(i32.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 4; i++) i32[i] = asArr[i];
+ return [u16[0], u16[1], u16[2], u16[3], u16[4], u16[5], u16[6], u16[7]];
+ }
+
+ var vals = [[1, -2, -3, 4], [INT16_MAX, INT16_MIN, INT32_MAX, INT32_MIN]];
+
+ for (var v of vals) {
+ var i = Int32x4(...v);
+ assertEqX8(Uint16x8.fromInt32x4Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX8(Uint16x8.fromInt32x4Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function testUint16x8FromUint32x4Bits() {
+ function expected(v, Buffer) {
+ var u32 = new Uint32Array(new Buffer(16));
+ var u16 = new Uint16Array(u32.buffer);
+ var asArr = simdToArray(v);
+ for (var i = 0; i < 4; i++) u32[i] = asArr[i];
+ return [u16[0], u16[1], u16[2], u16[3], u16[4], u16[5], u16[6], u16[7]];
+ }
+
+ var vals = [[1, -2, -3, 4], [INT16_MAX, INT16_MIN, INT32_MAX, INT32_MIN]];
+
+ for (var v of vals) {
+ var i = Uint32x4(...v);
+ assertEqX8(Uint16x8.fromUint32x4Bits(i), expected(i, ArrayBuffer));
+ if (typeof SharedArrayBuffer != "undefined")
+ assertEqX8(Uint16x8.fromUint32x4Bits(i), expected(i, SharedArrayBuffer));
+ }
+}
+
+function test() {
+ testFloat32x4FromFloat64x2Bits();
+ testFloat32x4FromInt8x16Bits();
+ testFloat32x4FromInt16x8Bits();
+ testFloat32x4FromInt32x4();
+ testFloat32x4FromInt32x4Bits();
+ testFloat32x4FromUint8x16Bits();
+ testFloat32x4FromUint16x8Bits();
+ testFloat32x4FromUint32x4();
+ testFloat32x4FromUint32x4Bits();
+
+ testFloat64x2FromFloat32x4Bits();
+ testFloat64x2FromInt8x16Bits();
+ testFloat64x2FromInt16x8Bits();
+ testFloat64x2FromInt32x4Bits();
+ testFloat64x2FromUint8x16Bits();
+ testFloat64x2FromUint16x8Bits();
+ testFloat64x2FromUint32x4Bits();
+
+ testInt8x16FromFloat32x4Bits();
+ testInt8x16FromFloat64x2Bits();
+ testInt8x16FromInt16x8Bits();
+ testInt8x16FromInt32x4Bits();
+ testInt8x16FromUint8x16Bits();
+ testInt8x16FromUint16x8Bits();
+ testInt8x16FromUint32x4Bits();
+
+ testInt16x8FromFloat32x4Bits();
+ testInt16x8FromFloat64x2Bits();
+ testInt16x8FromInt8x16Bits();
+ testInt16x8FromInt32x4Bits();
+ testInt16x8FromUint8x16Bits();
+ testInt16x8FromUint16x8Bits();
+ testInt16x8FromUint32x4Bits();
+
+ testInt32x4FromFloat32x4();
+ testInt32x4FromFloat32x4Bits();
+ testInt32x4FromFloat64x2Bits();
+ testInt32x4FromInt8x16Bits();
+ testInt32x4FromInt16x8Bits();
+ testInt32x4FromUint8x16Bits();
+ testInt32x4FromUint16x8Bits();
+ testInt32x4FromUint32x4Bits();
+
+ testUint8x16FromFloat32x4Bits();
+ testUint8x16FromFloat64x2Bits();
+ testUint8x16FromInt8x16Bits();
+ testUint8x16FromInt16x8Bits();
+ testUint8x16FromInt32x4Bits();
+ testUint8x16FromUint16x8Bits();
+ testUint8x16FromUint32x4Bits();
+
+ testUint16x8FromFloat32x4Bits();
+ testUint16x8FromFloat64x2Bits();
+ testUint16x8FromInt8x16Bits();
+ testUint16x8FromInt16x8Bits();
+ testUint16x8FromInt32x4Bits();
+ testUint16x8FromUint8x16Bits();
+ testUint16x8FromUint32x4Bits();
+
+ testUint32x4FromFloat32x4();
+ testUint32x4FromFloat32x4Bits();
+ testUint32x4FromFloat64x2Bits();
+ testUint32x4FromInt8x16Bits();
+ testUint32x4FromInt16x8Bits();
+ testUint32x4FromInt32x4Bits();
+ testUint32x4FromUint8x16Bits();
+ testUint32x4FromUint16x8Bits();
+
+ if (typeof reportCompare === "function") {
+ reportCompare(true, true);
+ }
+}
+
+test();
diff --git a/js/src/tests/ecma_7/SIMD/float64x2-arithmetic.js b/js/src/tests/ecma_7/SIMD/float64x2-arithmetic.js
new file mode 100644
index 000000000..17c51a9e0
--- /dev/null
+++ b/js/src/tests/ecma_7/SIMD/float64x2-arithmetic.js
@@ -0,0 +1,69 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+var Float64x2 = SIMD.Float64x2;
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+function add(a, b) { return a + b; }
+function sub(a, b) { return a - b; }
+function mul(a, b) { return a * b; }
+function div(a, b) { return a / b; }
+function neg(a) { return -a; }
+function reciprocalApproximation(a) { return 1 / a; }
+function reciprocalSqrtApproximation(a) { return 1 / Math.sqrt(a); }
+
+function testAdd(v, w) {
+ return testBinaryFunc(v, w, Float64x2.add, add);
+}
+function testSub(v, w) {
+ return testBinaryFunc(v, w, Float64x2.sub, sub);
+}
+function testMul(v, w) {
+ return testBinaryFunc(v, w, Float64x2.mul, mul);
+}
+function testDiv(v, w) {
+ return testBinaryFunc(v, w, Float64x2.div, div);
+}
+function testAbs(v) {
+ return testUnaryFunc(v, Float64x2.abs, Math.abs);
+}
+function testNeg(v) {
+ return testUnaryFunc(v, Float64x2.neg, neg);
+}
+function testReciprocalApproximation(v) {
+ return testUnaryFunc(v, Float64x2.reciprocalApproximation, reciprocalApproximation);
+}
+function testReciprocalSqrtApproximation(v) {
+ return testUnaryFunc(v, Float64x2.reciprocalSqrtApproximation, reciprocalSqrtApproximation);
+}
+function testSqrt(v) {
+ return testUnaryFunc(v, Float64x2.sqrt, Math.sqrt);
+}
+
+function test() {
+ var v, w;
+ for ([v, w] of [[Float64x2(1, 2), Float64x2(3, 4)],
+ [Float64x2(1.894, 2.8909), Float64x2(100.764, 200.987)],
+ [Float64x2(-1, -2), Float64x2(-14.54, 57)],
+ [Float64x2(+Infinity, -Infinity), Float64x2(NaN, -0)],
+ [Float64x2(Math.pow(2, 31), Math.pow(2, -31)), Float64x2(Math.pow(2, -1047), Math.pow(2, -149))]])
+ {
+ testAdd(v, w);
+ testSub(v, w);
+ testMul(v, w);
+ testDiv(v, w);
+ testAbs(v);
+ testNeg(v);
+ testReciprocalApproximation(v);
+ testSqrt(v);
+ testReciprocalSqrtApproximation(v);
+ }
+
+ if (typeof reportCompare === "function")
+ reportCompare(true, true);
+}
+
+test();
+
diff --git a/js/src/tests/ecma_7/SIMD/load-floats.js b/js/src/tests/ecma_7/SIMD/load-floats.js
new file mode 100644
index 000000000..9ae52dc8c
--- /dev/null
+++ b/js/src/tests/ecma_7/SIMD/load-floats.js
@@ -0,0 +1,19 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var { testLoad } = Helpers;
+
+testLoad('Float32x4', new Float32Array(SIZE_32_ARRAY));
+testLoad('Float64x2', new Float64Array(SIZE_64_ARRAY));
+
+if (typeof SharedArrayBuffer != "undefined") {
+ testLoad('Float32x4', new Float32Array(new SharedArrayBuffer(SIZE_8_ARRAY)));
+ testLoad('Float64x2', new Float64Array(new SharedArrayBuffer(SIZE_8_ARRAY)));
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_7/SIMD/load-int16x8.js b/js/src/tests/ecma_7/SIMD/load-int16x8.js
new file mode 100644
index 000000000..a8b90ca15
--- /dev/null
+++ b/js/src/tests/ecma_7/SIMD/load-int16x8.js
@@ -0,0 +1,17 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var { testLoad } = Helpers;
+
+testLoad('Int16x8', new Int16Array(SIZE_16_ARRAY));
+
+if (typeof SharedArrayBuffer != "undefined") {
+ testLoad('Int16x8', new Int16Array(new SharedArrayBuffer(SIZE_8_ARRAY)));
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_7/SIMD/load-int32x4.js b/js/src/tests/ecma_7/SIMD/load-int32x4.js
new file mode 100644
index 000000000..0719cbc17
--- /dev/null
+++ b/js/src/tests/ecma_7/SIMD/load-int32x4.js
@@ -0,0 +1,18 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var { testLoad } = Helpers;
+
+testLoad('Int32x4', new Int32Array(SIZE_32_ARRAY));
+
+if (typeof SharedArrayBuffer != "undefined") {
+ testLoad('Int32x4', new Int32Array(new SharedArrayBuffer(SIZE_8_ARRAY)));
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
diff --git a/js/src/tests/ecma_7/SIMD/load-int8x16.js b/js/src/tests/ecma_7/SIMD/load-int8x16.js
new file mode 100644
index 000000000..cb6c24285
--- /dev/null
+++ b/js/src/tests/ecma_7/SIMD/load-int8x16.js
@@ -0,0 +1,17 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var { testLoad } = Helpers;
+
+testLoad('Int8x16', new Int8Array(SIZE_8_ARRAY));
+
+if (typeof SharedArrayBuffer != "undefined") {
+ testLoad('Int8x16', new Int8Array(new SharedArrayBuffer(SIZE_8_ARRAY)));
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_7/SIMD/load-sab-buffer-compat.js b/js/src/tests/ecma_7/SIMD/load-sab-buffer-compat.js
new file mode 100644
index 000000000..fe8fac3ed
--- /dev/null
+++ b/js/src/tests/ecma_7/SIMD/load-sab-buffer-compat.js
@@ -0,0 +1,49 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var { MakeComparator } = Helpers;
+
+function testSharedArrayBufferCompat() {
+ var TA = new Float32Array(new SharedArrayBuffer(16*4));
+ for (var i = 0; i < 16; i++)
+ TA[i] = i + 1;
+
+ for (var ta of [
+ new Uint8Array(TA.buffer),
+ new Int8Array(TA.buffer),
+ new Uint16Array(TA.buffer),
+ new Int16Array(TA.buffer),
+ new Uint32Array(TA.buffer),
+ new Int32Array(TA.buffer),
+ new Float32Array(TA.buffer),
+ new Float64Array(TA.buffer)
+ ])
+ {
+ for (var kind of ['Int32x4', 'Uint32x4', 'Float32x4', 'Float64x2']) {
+ var comp = MakeComparator(kind, ta);
+ comp.load(0);
+ comp.load1(0);
+ comp.load2(0);
+ comp.load3(0);
+
+ comp.load(3);
+ comp.load1(3);
+ comp.load2(3);
+ comp.load3(3);
+ }
+
+ assertThrowsInstanceOf(() => SIMD.Int32x4.load(ta, 1024), RangeError);
+ assertThrowsInstanceOf(() => SIMD.Uint32x4.load(ta, 1024), RangeError);
+ assertThrowsInstanceOf(() => SIMD.Float32x4.load(ta, 1024), RangeError);
+ assertThrowsInstanceOf(() => SIMD.Float64x2.load(ta, 1024), RangeError);
+ }
+}
+
+testSharedArrayBufferCompat();
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_7/SIMD/load-unsigned-integers.js b/js/src/tests/ecma_7/SIMD/load-unsigned-integers.js
new file mode 100644
index 000000000..381e7b60a
--- /dev/null
+++ b/js/src/tests/ecma_7/SIMD/load-unsigned-integers.js
@@ -0,0 +1,22 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var { testLoad } = Helpers;
+
+testLoad('Uint8x16', new Uint8Array(SIZE_8_ARRAY));
+testLoad('Uint16x8', new Uint16Array(SIZE_16_ARRAY));
+testLoad('Uint32x4', new Uint32Array(SIZE_32_ARRAY));
+
+if (typeof SharedArrayBuffer != "undefined") {
+ testLoad('Uint8x16', new Uint8Array(new SharedArrayBuffer(SIZE_8_ARRAY)));
+ testLoad('Uint16x8', new Uint16Array(new SharedArrayBuffer(SIZE_8_ARRAY)));
+ testLoad('Uint32x4', new Uint32Array(new SharedArrayBuffer(SIZE_8_ARRAY)));
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
diff --git a/js/src/tests/ecma_7/SIMD/minmax.js b/js/src/tests/ecma_7/SIMD/minmax.js
new file mode 100644
index 000000000..9742b70d1
--- /dev/null
+++ b/js/src/tests/ecma_7/SIMD/minmax.js
@@ -0,0 +1,85 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var Float32x4 = SIMD.Float32x4;
+var Float64x2 = SIMD.Float64x2;
+
+function testMaxFloat32(v, w) {
+ return testBinaryFunc(v, w, Float32x4.max, (x, y) => Math.fround(Math.max(x, y)), 4);
+}
+function testMinFloat32(v, w) {
+ return testBinaryFunc(v, w, Float32x4.min, (x, y) => Math.fround(Math.min(x, y)), 4);
+}
+
+function testMaxFloat64(v, w) {
+ return testBinaryFunc(v, w, Float64x2.max, (x, y) => Math.max(x, y), 2);
+}
+function testMinFloat64(v, w) {
+ return testBinaryFunc(v, w, Float64x2.min, (x, y) => Math.min(x, y), 2);
+}
+
+function maxNum(x, y) {
+ if (x != x)
+ return y;
+ if (y != y)
+ return x;
+ return Math.max(x, y);
+}
+
+function minNum(x, y) {
+ if (x != x)
+ return y;
+ if (y != y)
+ return x;
+ return Math.min(x, y);
+}
+
+function testMaxNumFloat32(v, w) {
+ return testBinaryFunc(v, w, Float32x4.maxNum, maxNum, 4);
+}
+function testMinNumFloat32(v, w) {
+ return testBinaryFunc(v, w, Float32x4.minNum, minNum, 4);
+}
+
+function testMaxNumFloat64(v, w) {
+ return testBinaryFunc(v, w, Float64x2.maxNum, maxNum, 2);
+}
+function testMinNumFloat64(v, w) {
+ return testBinaryFunc(v, w, Float64x2.minNum, minNum, 2);
+}
+
+function test() {
+ var v, w;
+ for ([v, w] of [[Float32x4(1, 20, 30, 4), Float32x4(10, 2, 3, 40)],
+ [Float32x4(9.999, 2.1234, 30.4443, 4), Float32x4(10, 2.1233, 30.4444, 4.0001)],
+ [Float32x4(NaN, -Infinity, +Infinity, -0), Float32x4(13.37, 42.42, NaN, 0)]])
+ {
+ testMinFloat32(v, w);
+ testMaxFloat32(v, w);
+ testMinNumFloat32(v, w);
+ testMaxNumFloat32(v, w);
+ }
+
+ for ([v, w] of [[Float64x2(1, 20), Float64x2(10, 2)],
+ [Float64x2(30, 4), Float64x2(3, 40)],
+ [Float64x2(9.999, 2.1234), Float64x2(10, 2.1233)],
+ [Float64x2(30.4443, 4), Float64x2(30.4444, 4.0001)],
+ [Float64x2(NaN, -Infinity), Float64x2(13.37, 42.42)],
+ [Float64x2(+Infinity, -0), Float64x2(NaN, 0)]])
+ {
+ testMinFloat64(v, w);
+ testMaxFloat64(v, w);
+ testMinNumFloat64(v, w);
+ testMaxNumFloat64(v, w);
+ }
+
+ if (typeof reportCompare === "function")
+ reportCompare(true, true);
+}
+
+test();
+
diff --git a/js/src/tests/ecma_7/SIMD/replaceLane.js b/js/src/tests/ecma_7/SIMD/replaceLane.js
new file mode 100644
index 000000000..b285dc271
--- /dev/null
+++ b/js/src/tests/ecma_7/SIMD/replaceLane.js
@@ -0,0 +1,226 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+var Float32x4 = SIMD.Float32x4;
+var Float64x2 = SIMD.Float64x2;
+var Int8x16 = SIMD.Int8x16;
+var Int16x8 = SIMD.Int16x8;
+var Int32x4 = SIMD.Int32x4;
+var Uint8x16 = SIMD.Uint8x16;
+var Uint16x8 = SIMD.Uint16x8;
+var Uint32x4 = SIMD.Uint32x4;
+var Bool8x16 = SIMD.Bool8x16;
+var Bool16x8 = SIMD.Bool16x8;
+var Bool32x4 = SIMD.Bool32x4;
+var Bool64x2 = SIMD.Bool64x2;
+
+function replaceLaneN(laneIndex, arr, value) {
+ var copy = arr.slice();
+ assertEq(laneIndex <= arr.length, true);
+ copy[laneIndex] = value;
+ return copy;
+}
+
+var replaceLane0 = replaceLaneN.bind(null, 0);
+var replaceLane1 = replaceLaneN.bind(null, 1);
+var replaceLane2 = replaceLaneN.bind(null, 2);
+var replaceLane3 = replaceLaneN.bind(null, 3);
+var replaceLane4 = replaceLaneN.bind(null, 4);
+var replaceLane5 = replaceLaneN.bind(null, 5);
+var replaceLane6 = replaceLaneN.bind(null, 6);
+var replaceLane7 = replaceLaneN.bind(null, 7);
+var replaceLane8 = replaceLaneN.bind(null, 8);
+var replaceLane9 = replaceLaneN.bind(null, 9);
+var replaceLane10 = replaceLaneN.bind(null, 10);
+var replaceLane11 = replaceLaneN.bind(null, 11);
+var replaceLane12 = replaceLaneN.bind(null, 12);
+var replaceLane13 = replaceLaneN.bind(null, 13);
+var replaceLane14 = replaceLaneN.bind(null, 14);
+var replaceLane15 = replaceLaneN.bind(null, 15);
+
+function testReplaceLane(vec, scalar, simdFunc, func) {
+ var varr = simdToArray(vec);
+ var observed = simdToArray(simdFunc(vec, scalar));
+ var expected = func(varr, scalar);
+ for (var i = 0; i < observed.length; i++)
+ assertEq(observed[i], expected[i]);
+}
+
+function test() {
+ function testType(type, inputs) {
+ var length = simdToArray(inputs[0][0]).length;
+ for (var [vec, s] of inputs) {
+ testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 0, y), replaceLane0);
+ testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 1, y), replaceLane1);
+ if (length <= 2)
+ continue;
+ testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 2, y), replaceLane2);
+ testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 3, y), replaceLane3);
+ if (length <= 4)
+ continue;
+ testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 4, y), replaceLane4);
+ testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 5, y), replaceLane5);
+ testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 6, y), replaceLane6);
+ testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 7, y), replaceLane7);
+ if (length <= 8)
+ continue;
+ testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 8, y), replaceLane8);
+ testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 9, y), replaceLane9);
+ testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 10, y), replaceLane10);
+ testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 11, y), replaceLane11);
+ testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 12, y), replaceLane12);
+ testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 13, y), replaceLane13);
+ testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 14, y), replaceLane14);
+ testReplaceLane(vec, s, (x,y) => SIMD[type].replaceLane(x, 15, y), replaceLane15);
+ }
+ }
+
+ function TestError(){};
+ var good = {valueOf: () => 42};
+ var bad = {valueOf: () => {throw new TestError(); }};
+
+ var Float32x4inputs = [
+ [Float32x4(1, 2, 3, 4), 5],
+ [Float32x4(1.87, 2.08, 3.84, 4.17), Math.fround(13.37)],
+ [Float32x4(NaN, -0, Infinity, -Infinity), 0]
+ ];
+ testType('Float32x4', Float32x4inputs);
+
+ var v = Float32x4inputs[1][0];
+ assertEqX4(Float32x4.replaceLane(v, 0), replaceLane0(simdToArray(v), NaN));
+ assertEqX4(Float32x4.replaceLane(v, 0, good), replaceLane0(simdToArray(v), good | 0));
+ assertThrowsInstanceOf(() => Float32x4.replaceLane(v, 0, bad), TestError);
+ assertThrowsInstanceOf(() => Float32x4.replaceLane(v, 4, good), RangeError);
+ assertThrowsInstanceOf(() => Float32x4.replaceLane(v, 1.1, good), RangeError);
+
+ var Float64x2inputs = [
+ [Float64x2(1, 2), 5],
+ [Float64x2(1.87, 2.08), Math.fround(13.37)],
+ [Float64x2(NaN, -0), 0]
+ ];
+ testType('Float64x2', Float64x2inputs);
+
+ var v = Float64x2inputs[1][0];
+ assertEqX2(Float64x2.replaceLane(v, 0), replaceLane0(simdToArray(v), NaN));
+ assertEqX2(Float64x2.replaceLane(v, 0, good), replaceLane0(simdToArray(v), good | 0));
+ assertThrowsInstanceOf(() => Float64x2.replaceLane(v, 0, bad), TestError);
+ assertThrowsInstanceOf(() => Float64x2.replaceLane(v, 2, good), RangeError);
+ assertThrowsInstanceOf(() => Float64x2.replaceLane(v, 1.1, good), RangeError);
+
+ var Int8x16inputs = [[Int8x16(0, 1, 2, 3, 4, 5, 6, 7, -1, -2, -3, -4, -5, -6, INT8_MIN, INT8_MAX), 17]];
+ testType('Int8x16', Int8x16inputs);
+
+ var v = Int8x16inputs[0][0];
+ assertEqX16(Int8x16.replaceLane(v, 0), replaceLane0(simdToArray(v), 0));
+ assertEqX16(Int8x16.replaceLane(v, 0, good), replaceLane0(simdToArray(v), good | 0));
+ assertThrowsInstanceOf(() => Int8x16.replaceLane(v, 0, bad), TestError);
+ assertThrowsInstanceOf(() => Int8x16.replaceLane(v, 16, good), RangeError);
+ assertThrowsInstanceOf(() => Int8x16.replaceLane(v, 1.1, good), RangeError);
+
+ var Int16x8inputs = [[Int16x8(0, 1, 2, 3, -1, -2, INT16_MIN, INT16_MAX), 9]];
+ testType('Int16x8', Int16x8inputs);
+
+ var v = Int16x8inputs[0][0];
+ assertEqX8(Int16x8.replaceLane(v, 0), replaceLane0(simdToArray(v), 0));
+ assertEqX8(Int16x8.replaceLane(v, 0, good), replaceLane0(simdToArray(v), good | 0));
+ assertThrowsInstanceOf(() => Int16x8.replaceLane(v, 0, bad), TestError);
+ assertThrowsInstanceOf(() => Int16x8.replaceLane(v, 8, good), RangeError);
+ assertThrowsInstanceOf(() => Int16x8.replaceLane(v, 1.1, good), RangeError);
+
+ var Int32x4inputs = [
+ [Int32x4(1, 2, 3, 4), 5],
+ [Int32x4(INT32_MIN, INT32_MAX, 3, 4), INT32_MIN],
+ ];
+ testType('Int32x4', Int32x4inputs);
+
+ var v = Int32x4inputs[1][0];
+ assertEqX4(Int32x4.replaceLane(v, 0), replaceLane0(simdToArray(v), 0));
+ assertEqX4(Int32x4.replaceLane(v, 0, good), replaceLane0(simdToArray(v), good | 0));
+ assertThrowsInstanceOf(() => Int32x4.replaceLane(v, 0, bad), TestError);
+ assertThrowsInstanceOf(() => Int32x4.replaceLane(v, 4, good), RangeError);
+ assertThrowsInstanceOf(() => Int32x4.replaceLane(v, 1.1, good), RangeError);
+
+ var Uint8x16inputs = [[Uint8x16(0, 1, 2, 3, 4, 5, 6, 7, -1, -2, -3, -4, -5, -6, INT8_MIN, UINT8_MAX), 17]];
+ testType('Uint8x16', Uint8x16inputs);
+
+ var v = Uint8x16inputs[0][0];
+ assertEqX16(Uint8x16.replaceLane(v, 0), replaceLane0(simdToArray(v), 0));
+ assertEqX16(Uint8x16.replaceLane(v, 0, good), replaceLane0(simdToArray(v), good | 0));
+ assertThrowsInstanceOf(() => Uint8x16.replaceLane(v, 0, bad), TestError);
+ assertThrowsInstanceOf(() => Uint8x16.replaceLane(v, 16, good), RangeError);
+ assertThrowsInstanceOf(() => Uint8x16.replaceLane(v, 1.1, good), RangeError);
+
+ var Uint16x8inputs = [[Uint16x8(0, 1, 2, 3, -1, -2, INT16_MIN, UINT16_MAX), 9]];
+ testType('Uint16x8', Uint16x8inputs);
+
+ var v = Uint16x8inputs[0][0];
+ assertEqX8(Uint16x8.replaceLane(v, 0), replaceLane0(simdToArray(v), 0));
+ assertEqX8(Uint16x8.replaceLane(v, 0, good), replaceLane0(simdToArray(v), good | 0));
+ assertThrowsInstanceOf(() => Uint16x8.replaceLane(v, 0, bad), TestError);
+ assertThrowsInstanceOf(() => Uint16x8.replaceLane(v, 8, good), RangeError);
+ assertThrowsInstanceOf(() => Uint16x8.replaceLane(v, 1.1, good), RangeError);
+
+ var Uint32x4inputs = [
+ [Uint32x4(1, 2, 3, 4), 5],
+ [Uint32x4(INT32_MIN, UINT32_MAX, INT32_MAX, 4), UINT32_MAX],
+ ];
+ testType('Uint32x4', Uint32x4inputs);
+
+ var v = Uint32x4inputs[1][0];
+ assertEqX4(Uint32x4.replaceLane(v, 0), replaceLane0(simdToArray(v), 0));
+ assertEqX4(Uint32x4.replaceLane(v, 0, good), replaceLane0(simdToArray(v), good | 0));
+ assertThrowsInstanceOf(() => Uint32x4.replaceLane(v, 0, bad), TestError);
+ assertThrowsInstanceOf(() => Uint32x4.replaceLane(v, 4, good), RangeError);
+ assertThrowsInstanceOf(() => Uint32x4.replaceLane(v, 1.1, good), RangeError);
+
+ var Bool64x2inputs = [
+ [Bool64x2(true, true), false],
+ ];
+ testType('Bool64x2', Bool64x2inputs);
+
+ var v = Bool64x2inputs[0][0];
+ assertEqX2(Bool64x2.replaceLane(v, 0), replaceLane0(simdToArray(v), false));
+ assertEqX2(Bool64x2.replaceLane(v, 0, true), replaceLane0(simdToArray(v), true));
+ assertEqX2(Bool64x2.replaceLane(v, 0, bad), replaceLane0(simdToArray(v), true));
+ assertThrowsInstanceOf(() => Bool64x2.replaceLane(v, 4, true), RangeError);
+ assertThrowsInstanceOf(() => Bool64x2.replaceLane(v, 1.1, false), RangeError);
+
+ var Bool32x4inputs = [
+ [Bool32x4(true, true, true, true), false],
+ ];
+ testType('Bool32x4', Bool32x4inputs);
+
+ var v = Bool32x4inputs[0][0];
+ assertEqX4(Bool32x4.replaceLane(v, 0), replaceLane0(simdToArray(v), false));
+ assertEqX4(Bool32x4.replaceLane(v, 0, true), replaceLane0(simdToArray(v), true));
+ assertEqX4(Bool32x4.replaceLane(v, 0, bad), replaceLane0(simdToArray(v), true));
+ assertThrowsInstanceOf(() => Bool32x4.replaceLane(v, 4, true), RangeError);
+ assertThrowsInstanceOf(() => Bool32x4.replaceLane(v, 1.1, false), RangeError);
+
+ var Bool16x8inputs = [
+ [Bool16x8(true, true, true, true, true, true, true, true), false],
+ ];
+
+ testType('Bool16x8', Bool16x8inputs);
+ var v = Bool16x8inputs[0][0];
+ assertEqX8(Bool16x8.replaceLane(v, 0), replaceLane0(simdToArray(v), false));
+ assertEqX8(Bool16x8.replaceLane(v, 0, true), replaceLane0(simdToArray(v), true));
+ assertEqX8(Bool16x8.replaceLane(v, 0, bad), replaceLane0(simdToArray(v), true));
+ assertThrowsInstanceOf(() => Bool16x8.replaceLane(v, 16, true), RangeError);
+ assertThrowsInstanceOf(() => Bool16x8.replaceLane(v, 1.1, false), RangeError);
+
+ var Bool8x16inputs = [
+ [Bool8x16(true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true), false],
+ ];
+
+ testType('Bool8x16', Bool8x16inputs);
+ var v = Bool8x16inputs[0][0];
+ assertEqX16(Bool8x16.replaceLane(v, 0), replaceLane0(simdToArray(v), false));
+ assertEqX16(Bool8x16.replaceLane(v, 0, true), replaceLane0(simdToArray(v), true));
+ assertEqX16(Bool8x16.replaceLane(v, 0, bad), replaceLane0(simdToArray(v), true));
+ assertThrowsInstanceOf(() => Bool8x16.replaceLane(v, 16, true), RangeError);
+ assertThrowsInstanceOf(() => Bool8x16.replaceLane(v, 1.1, false), RangeError);
+
+ if (typeof reportCompare === "function")
+ reportCompare(true, true);
+}
+
+test();
diff --git a/js/src/tests/ecma_7/SIMD/select-bitselect.js b/js/src/tests/ecma_7/SIMD/select-bitselect.js
new file mode 100644
index 000000000..61fcd1a3f
--- /dev/null
+++ b/js/src/tests/ecma_7/SIMD/select-bitselect.js
@@ -0,0 +1,133 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var Float32x4 = SIMD.Float32x4;
+var Float64x2 = SIMD.Float64x2;
+var Int8x16 = SIMD.Int8x16;
+var Int16x8 = SIMD.Int16x8;
+var Int32x4 = SIMD.Int32x4;
+var Uint8x16 = SIMD.Uint8x16;
+var Uint16x8 = SIMD.Uint16x8;
+var Uint32x4 = SIMD.Uint32x4;
+var Bool8x16 = SIMD.Bool8x16;
+var Bool16x8 = SIMD.Bool16x8;
+var Bool32x4 = SIMD.Bool32x4;
+var Bool64x2 = SIMD.Bool64x2;
+
+function getMask(i, maskLength) {
+ var args = [];
+ for (var j = 0; j < maskLength; j++)
+ args.push((i >> j) & 1);
+ if (maskLength == 2)
+ return Bool64x2(...args);
+ else if (maskLength == 4)
+ return Bool32x4(...args);
+ else if (maskLength == 8)
+ return Bool16x8(...args);
+ else if (maskLength == 16)
+ return Bool8x16(...args);
+ else
+ throw new Error("Invalid mask length.");
+}
+
+function select(mask, ifTrue, ifFalse) {
+ var m = simdToArray(mask);
+ var tv = simdToArray(ifTrue);
+ var fv = simdToArray(ifFalse);
+ return m.map(function(v, i) {
+ return (v ? tv : fv)[i];
+ });
+}
+
+/**
+ * Tests type.select on all input pairs, for all possible masks. As the mask
+ * has 4 lanes (for Int32x4) and 2 possible values (true or false), there are 16 possible
+ * masks. For Int8x16, the mask has 16 lanes and 2 possible values, so there are 256
+ * possible masks. For Int16x8, the mask has 8 lanes and 2 possible values, so there
+ * are 64 possible masks.
+ */
+function testSelect(type, inputs) {
+ var x, y;
+ var maskLength = simdLengthType(type);
+ for (var i = 0; i < Math.pow(maskLength, 2); i++) {
+ var mask = getMask(i, maskLength);
+ for ([x, y] of inputs)
+ assertEqVec(type.select(mask, x, y), select(mask, x, y));
+ }
+}
+
+function test() {
+ var inputs = [
+ [Int8x16(0,4,9,16,25,36,49,64,81,121,-4,-9,-16,-25,-36,-49), Int8x16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)],
+ [Int8x16(-1, 2, INT8_MAX, INT8_MIN, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16),
+ Int8x16(INT8_MAX, -4, INT8_MIN, 42, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)]
+ ];
+
+ testSelect(Int8x16, inputs);
+
+ inputs = [
+ [Int16x8(0,4,9,16,25,36,49,64), Int16x8(1,2,3,4,5,6,7,8)],
+ [Int16x8(-1, 2, INT16_MAX, INT16_MIN, 5, 6, 7, 8),
+ Int16x8(INT16_MAX, -4, INT16_MIN, 42, 5, 6, 7, 8)]
+ ];
+
+ testSelect(Int16x8, inputs);
+
+ inputs = [
+ [Int32x4(0,4,9,16), Int32x4(1,2,3,4)],
+ [Int32x4(-1, 2, INT32_MAX, INT32_MIN), Int32x4(INT32_MAX, -4, INT32_MIN, 42)]
+ ];
+
+ testSelect(Int32x4, inputs);
+
+ inputs = [
+ [Uint8x16(0,4,9,16,25,36,49,64,81,121,-4,-9,-16,-25,-36,-49), Uint8x16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)],
+ [Uint8x16(-1, 2, INT8_MAX, INT8_MIN, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16),
+ Uint8x16(INT8_MAX, -4, INT8_MIN, 42, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)]
+ ];
+
+ testSelect(Uint8x16, inputs);
+
+ inputs = [
+ [Uint16x8(0,4,9,16,25,36,49,64), Uint16x8(1,2,3,4,5,6,7,8)],
+ [Uint16x8(-1, 2, INT16_MAX, INT16_MIN, 5, 6, 7, 8),
+ Uint16x8(INT16_MAX, -4, INT16_MIN, 42, 5, 6, 7, 8)]
+ ];
+
+ testSelect(Uint16x8, inputs);
+
+ inputs = [
+ [Uint32x4(0,4,9,16), Uint32x4(1,2,3,4)],
+ [Uint32x4(-1, 2, INT32_MAX, INT32_MIN), Uint32x4(INT32_MAX, -4, INT32_MIN, 42)]
+ ];
+
+ testSelect(Uint32x4, inputs);
+
+ inputs = [
+ [Float32x4(0.125,4.25,9.75,16.125), Float32x4(1.5,2.75,3.25,4.5)],
+ [Float32x4(-1.5,-0,NaN,-Infinity), Float32x4(1,-2,13.37,3.13)],
+ [Float32x4(1.5,2.75,NaN,Infinity), Float32x4(-NaN,-Infinity,9.75,16.125)]
+ ];
+
+ testSelect(Float32x4, inputs);
+
+ inputs = [
+ [Float64x2(0.125,4.25), Float64x2(9.75,16.125)],
+ [Float64x2(1.5,2.75), Float64x2(3.25,4.5)],
+ [Float64x2(-1.5,-0), Float64x2(NaN,-Infinity)],
+ [Float64x2(1,-2), Float64x2(13.37,3.13)],
+ [Float64x2(1.5,2.75), Float64x2(NaN,Infinity)],
+ [Float64x2(-NaN,-Infinity), Float64x2(9.75,16.125)]
+ ];
+
+ testSelect(Float64x2, inputs);
+
+ if (typeof reportCompare === "function")
+ reportCompare(true, true);
+}
+
+test();
diff --git a/js/src/tests/ecma_7/SIMD/shell.js b/js/src/tests/ecma_7/SIMD/shell.js
new file mode 100644
index 000000000..943965390
--- /dev/null
+++ b/js/src/tests/ecma_7/SIMD/shell.js
@@ -0,0 +1,580 @@
+function makeFloat(sign, exp, mantissa) {
+ assertEq(sign, sign & 0x1);
+ assertEq(exp, exp & 0xFF);
+ assertEq(mantissa, mantissa & 0x7FFFFF);
+
+ var i32 = new Int32Array(1);
+ var f32 = new Float32Array(i32.buffer);
+
+ i32[0] = (sign << 31) | (exp << 23) | mantissa;
+ return f32[0];
+}
+
+function makeDouble(sign, exp, mantissa) {
+ assertEq(sign, sign & 0x1);
+ assertEq(exp, exp & 0x7FF);
+
+ // Can't use bitwise operations on mantissa, as it might be a double
+ assertEq(mantissa <= 0xfffffffffffff, true);
+ var highBits = (mantissa / Math.pow(2, 32)) | 0;
+ var lowBits = mantissa - highBits * Math.pow(2, 32);
+
+ var i32 = new Int32Array(2);
+ var f64 = new Float64Array(i32.buffer);
+
+ // Note that this assumes little-endian order, which is the case on tier-1
+ // platforms.
+ i32[0] = lowBits;
+ i32[1] = (sign << 31) | (exp << 20) | highBits;
+ return f64[0];
+}
+
+function GetType(v) {
+ switch (Object.getPrototypeOf(v)) {
+ case SIMD.Int8x16.prototype: return SIMD.Int8x16;
+ case SIMD.Int16x8.prototype: return SIMD.Int16x8;
+ case SIMD.Int32x4.prototype: return SIMD.Int32x4;
+ case SIMD.Uint8x16.prototype: return SIMD.Uint8x16;
+ case SIMD.Uint16x8.prototype: return SIMD.Uint16x8;
+ case SIMD.Uint32x4.prototype: return SIMD.Uint32x4;
+ case SIMD.Float32x4.prototype: return SIMD.Float32x4;
+ case SIMD.Float64x2.prototype: return SIMD.Float64x2;
+ case SIMD.Bool8x16.prototype: return SIMD.Bool8x16;
+ case SIMD.Bool16x8.prototype: return SIMD.Bool16x8;
+ case SIMD.Bool32x4.prototype: return SIMD.Bool32x4;
+ case SIMD.Bool64x2.prototype: return SIMD.Bool64x2;
+ }
+}
+
+function assertEqFloat64x2(v, arr) {
+ try {
+ assertEq(SIMD.Float64x2.extractLane(v, 0), arr[0]);
+ assertEq(SIMD.Float64x2.extractLane(v, 1), arr[1]);
+ } catch (e) {
+ print("stack trace:", e.stack);
+ throw e;
+ }
+}
+
+function assertEqBool64x2(v, arr) {
+ try {
+ assertEq(SIMD.Bool64x2.extractLane(v, 0), arr[0]);
+ assertEq(SIMD.Bool64x2.extractLane(v, 1), arr[1]);
+ } catch (e) {
+ print("stack trace:", e.stack);
+ throw e;
+ }
+}
+
+function assertEqX2(v, arr) {
+ var Type = GetType(v);
+ if (Type === SIMD.Float64x2) assertEqFloat64x2(v, arr);
+ else if (Type === SIMD.Bool64x2) assertEqBool64x2(v, arr);
+ else throw new TypeError("Unknown SIMD kind.");
+}
+
+function assertEqInt32x4(v, arr) {
+ try {
+ for (var i = 0; i < 4; i++)
+ assertEq(SIMD.Int32x4.extractLane(v, i), arr[i]);
+ } catch (e) {
+ print("stack trace:", e.stack);
+ throw e;
+ }
+}
+
+function assertEqUint32x4(v, arr) {
+ try {
+ for (var i = 0; i < 4; i++)
+ assertEq(SIMD.Uint32x4.extractLane(v, i), arr[i]);
+ } catch (e) {
+ print("stack trace:", e.stack);
+ throw e;
+ }
+}
+
+function assertEqFloat32x4(v, arr) {
+ try {
+ for (var i = 0; i < 4; i++)
+ assertEq(SIMD.Float32x4.extractLane(v, i), arr[i]);
+ } catch (e) {
+ print("stack trace:", e.stack);
+ throw e;
+ }
+}
+
+function assertEqBool32x4(v, arr) {
+ try {
+ for (var i = 0; i < 4; i++)
+ assertEq(SIMD.Bool32x4.extractLane(v, i), arr[i]);
+ } catch (e) {
+ print("stack trace:", e.stack);
+ throw e;
+ }
+}
+
+function assertEqX4(v, arr) {
+ var Type = GetType(v);
+ if (Type === SIMD.Int32x4) assertEqInt32x4(v, arr);
+ else if (Type === SIMD.Uint32x4) assertEqUint32x4(v, arr);
+ else if (Type === SIMD.Float32x4) assertEqFloat32x4(v, arr);
+ else if (Type === SIMD.Bool32x4) assertEqBool32x4(v, arr);
+ else throw new TypeError("Unknown SIMD kind.");
+}
+
+function assertEqInt16x8(v, arr) {
+ try {
+ for (var i = 0; i < 8; i++)
+ assertEq(SIMD.Int16x8.extractLane(v, i), arr[i]);
+ } catch (e) {
+ print("stack trace:", e.stack);
+ throw e;
+ }
+}
+
+function assertEqUint16x8(v, arr) {
+ try {
+ for (var i = 0; i < 8; i++)
+ assertEq(SIMD.Uint16x8.extractLane(v, i), arr[i]);
+ } catch (e) {
+ print("stack trace:", e.stack);
+ throw e;
+ }
+}
+
+function assertEqBool16x8(v, arr) {
+ try {
+ for (var i = 0; i < 8; i++){
+ assertEq(SIMD.Bool16x8.extractLane(v, i), arr[i]);
+ }
+ } catch (e) {
+ print("stack trace:", e.stack);
+ throw e;
+ }
+}
+
+function assertEqX8(v, arr) {
+ var Type = GetType(v);
+ if (Type === SIMD.Int16x8) assertEqInt16x8(v, arr);
+ else if (Type === SIMD.Uint16x8) assertEqUint16x8(v, arr);
+ else if (Type === SIMD.Bool16x8) assertEqBool16x8(v, arr);
+ else throw new TypeError("Unknown x8 vector.");
+}
+
+function assertEqInt8x16(v, arr) {
+ try {
+ for (var i = 0; i < 16; i++)
+ assertEq(SIMD.Int8x16.extractLane(v, i), arr[i]);
+ } catch (e) {
+ print("stack trace:", e.stack);
+ throw e;
+ }
+}
+
+function assertEqUint8x16(v, arr) {
+ try {
+ for (var i = 0; i < 16; i++)
+ assertEq(SIMD.Uint8x16.extractLane(v, i), arr[i]);
+ } catch (e) {
+ print("stack trace:", e.stack);
+ throw e;
+ }
+}
+
+function assertEqBool8x16(v, arr) {
+ try {
+ for (var i = 0; i < 16; i++)
+ assertEq(SIMD.Bool8x16.extractLane(v, i), arr[i]);
+ } catch (e) {
+ print("stack trace:", e.stack);
+ throw e;
+ }
+}
+
+function assertEqX16(v, arr) {
+ var Type = GetType(v);
+ if (Type === SIMD.Int8x16) assertEqInt8x16(v, arr);
+ else if (Type === SIMD.Uint8x16) assertEqUint8x16(v, arr);
+ else if (Type === SIMD.Bool8x16) assertEqBool8x16(v, arr);
+ else throw new TypeError("Unknown x16 vector.");
+}
+
+function simdLength(v) {
+ var pt = Object.getPrototypeOf(v);
+ if (pt == SIMD.Int8x16.prototype || pt == SIMD.Uint8x16.prototype ||
+ pt === SIMD.Bool8x16.prototype)
+ return 16;
+ if (pt == SIMD.Int16x8.prototype || pt == SIMD.Uint16x8.prototype ||
+ pt === SIMD.Bool16x8.prototype)
+ return 8;
+ if (pt === SIMD.Int32x4.prototype || pt === SIMD.Uint32x4.prototype ||
+ pt === SIMD.Float32x4.prototype || pt === SIMD.Bool32x4.prototype)
+ return 4;
+ if (pt === SIMD.Float64x2.prototype || pt == SIMD.Bool64x2.prototype)
+ return 2;
+ throw new TypeError("Unknown SIMD kind.");
+}
+
+function simdLengthType(t) {
+ if (t == SIMD.Int8x16 || t == SIMD.Uint8x16 || t == SIMD.Bool8x16)
+ return 16;
+ else if (t == SIMD.Int16x8 || t == SIMD.Uint16x8 || t == SIMD.Bool16x8)
+ return 8;
+ else if (t == SIMD.Int32x4 || t == SIMD.Uint32x4 || t == SIMD.Float32x4 || t == SIMD.Bool32x4)
+ return 4;
+ else if (t == SIMD.Float64x2 || t == SIMD.Bool64x2)
+ return 2;
+ else
+ throw new TypeError("Unknown SIMD kind.");
+}
+
+function getAssertFuncFromLength(l) {
+ if (l == 2)
+ return assertEqX2;
+ else if (l == 4)
+ return assertEqX4;
+ else if (l == 8)
+ return assertEqX8;
+ else if (l == 16)
+ return assertEqX16;
+ else
+ throw new TypeError("Unknown SIMD kind.");
+}
+
+function assertEqVec(v, arr) {
+ var Type = GetType(v);
+ if (Type === SIMD.Int8x16) assertEqInt8x16(v, arr);
+ else if (Type === SIMD.Int16x8) assertEqInt16x8(v, arr);
+ else if (Type === SIMD.Int32x4) assertEqInt32x4(v, arr);
+ else if (Type === SIMD.Uint8x16) assertEqUint8x16(v, arr);
+ else if (Type === SIMD.Uint16x8) assertEqUint16x8(v, arr);
+ else if (Type === SIMD.Uint32x4) assertEqUint32x4(v, arr);
+ else if (Type === SIMD.Float32x4) assertEqFloat32x4(v, arr);
+ else if (Type === SIMD.Float64x2) assertEqFloat64x2(v, arr);
+ else if (Type === SIMD.Bool8x16) assertEqBool8x16(v, arr);
+ else if (Type === SIMD.Bool16x8) assertEqBool16x8(v, arr);
+ else if (Type === SIMD.Bool32x4) assertEqBool32x4(v, arr);
+ else if (Type === SIMD.Bool64x2) assertEqBool64x2(v, arr);
+ else throw new TypeError("Unknown SIMD Kind");
+}
+
+function simdToArray(v) {
+ var Type = GetType(v);
+
+ function indexes(n) {
+ var arr = [];
+ for (var i = 0; i < n; i++) arr.push(i);
+ return arr;
+ }
+
+ if (Type === SIMD.Bool8x16) {
+ return indexes(16).map((i) => SIMD.Bool8x16.extractLane(v, i));
+ }
+
+ if (Type === SIMD.Bool16x8) {
+ return indexes(8).map((i) => SIMD.Bool16x8.extractLane(v, i));
+ }
+
+ if (Type === SIMD.Bool32x4) {
+ return indexes(4).map((i) => SIMD.Bool32x4.extractLane(v, i));
+ }
+
+ if (Type === SIMD.Bool64x2) {
+ return indexes(2).map((i) => SIMD.Bool64x2.extractLane(v, i));
+ }
+
+ if (Type === SIMD.Int8x16) {
+ return indexes(16).map((i) => SIMD.Int8x16.extractLane(v, i));
+ }
+
+ if (Type === SIMD.Int16x8) {
+ return indexes(8).map((i) => SIMD.Int16x8.extractLane(v, i));
+ }
+
+ if (Type === SIMD.Int32x4) {
+ return indexes(4).map((i) => SIMD.Int32x4.extractLane(v, i));
+ }
+
+ if (Type === SIMD.Uint8x16) {
+ return indexes(16).map((i) => SIMD.Uint8x16.extractLane(v, i));
+ }
+
+ if (Type === SIMD.Uint16x8) {
+ return indexes(8).map((i) => SIMD.Uint16x8.extractLane(v, i));
+ }
+
+ if (Type === SIMD.Uint32x4) {
+ return indexes(4).map((i) => SIMD.Uint32x4.extractLane(v, i));
+ }
+
+ if (Type === SIMD.Float32x4) {
+ return indexes(4).map((i) => SIMD.Float32x4.extractLane(v, i));
+ }
+
+ if (Type === SIMD.Float64x2) {
+ return indexes(2).map((i) => SIMD.Float64x2.extractLane(v, i));
+ }
+
+ throw new TypeError("Unknown SIMD Kind");
+}
+
+const INT8_MAX = Math.pow(2, 7) -1;
+const INT8_MIN = -Math.pow(2, 7);
+assertEq((INT8_MAX + 1) << 24 >> 24, INT8_MIN);
+const INT16_MAX = Math.pow(2, 15) - 1;
+const INT16_MIN = -Math.pow(2, 15);
+assertEq((INT16_MAX + 1) << 16 >> 16, INT16_MIN);
+const INT32_MAX = Math.pow(2, 31) - 1;
+const INT32_MIN = -Math.pow(2, 31);
+assertEq(INT32_MAX + 1 | 0, INT32_MIN);
+
+const UINT8_MAX = Math.pow(2, 8) - 1;
+const UINT16_MAX = Math.pow(2, 16) - 1;
+const UINT32_MAX = Math.pow(2, 32) - 1;
+
+function testUnaryFunc(v, simdFunc, func) {
+ var varr = simdToArray(v);
+
+ var observed = simdToArray(simdFunc(v));
+ var expected = varr.map(function(v, i) { return func(varr[i]); });
+
+ for (var i = 0; i < observed.length; i++)
+ assertEq(observed[i], expected[i]);
+}
+
+function testBinaryFunc(v, w, simdFunc, func) {
+ var varr = simdToArray(v);
+ var warr = simdToArray(w);
+
+ var observed = simdToArray(simdFunc(v, w));
+ var expected = varr.map(function(v, i) { return func(varr[i], warr[i]); });
+
+ for (var i = 0; i < observed.length; i++)
+ assertEq(observed[i], expected[i]);
+}
+
+function testBinaryCompare(v, w, simdFunc, func, outType) {
+ var varr = simdToArray(v);
+ var warr = simdToArray(w);
+
+ var inLanes = simdLength(v);
+ var observed = simdToArray(simdFunc(v, w));
+ var outTypeLen = simdLengthType(outType);
+ assertEq(observed.length, outTypeLen);
+ for (var i = 0; i < outTypeLen; i++) {
+ var j = ((i * inLanes) / outTypeLen) | 0;
+ assertEq(observed[i], func(varr[j], warr[j]));
+ }
+}
+
+function testBinaryScalarFunc(v, scalar, simdFunc, func) {
+ var varr = simdToArray(v);
+
+ var observed = simdToArray(simdFunc(v, scalar));
+ var expected = varr.map(function(v, i) { return func(varr[i], scalar); });
+
+ for (var i = 0; i < observed.length; i++)
+ assertEq(observed[i], expected[i]);
+}
+
+// Our array for Int32x4 and Float32x4 will have 16 elements
+const SIZE_8_ARRAY = 64;
+const SIZE_16_ARRAY = 32;
+const SIZE_32_ARRAY = 16;
+const SIZE_64_ARRAY = 8;
+
+const SIZE_BYTES = SIZE_32_ARRAY * 4;
+
+function MakeComparator(kind, arr, shared) {
+ var bpe = arr.BYTES_PER_ELEMENT;
+ var uint8 = (bpe != 1) ? new Uint8Array(arr.buffer) : arr;
+
+ // Size in bytes of a single element in the SIMD vector.
+ var sizeOfLaneElem;
+ // Typed array constructor corresponding to the SIMD kind.
+ var typedArrayCtor;
+ switch (kind) {
+ case 'Int8x16':
+ sizeOfLaneElem = 1;
+ typedArrayCtor = Int8Array;
+ break;
+ case 'Int16x8':
+ sizeOfLaneElem = 2;
+ typedArrayCtor = Int16Array;
+ break;
+ case 'Int32x4':
+ sizeOfLaneElem = 4;
+ typedArrayCtor = Int32Array;
+ break;
+ case 'Uint8x16':
+ sizeOfLaneElem = 1;
+ typedArrayCtor = Uint8Array;
+ break;
+ case 'Uint16x8':
+ sizeOfLaneElem = 2;
+ typedArrayCtor = Uint16Array;
+ break;
+ case 'Uint32x4':
+ sizeOfLaneElem = 4;
+ typedArrayCtor = Uint32Array;
+ break;
+ case 'Float32x4':
+ sizeOfLaneElem = 4;
+ typedArrayCtor = Float32Array;
+ break;
+ case 'Float64x2':
+ sizeOfLaneElem = 8;
+ typedArrayCtor = Float64Array;
+ break;
+ default:
+ assertEq(true, false, "unknown SIMD kind");
+ }
+ var lanes = 16 / sizeOfLaneElem;
+ // Reads (numElemToRead * sizeOfLaneElem) bytes in arr, and reinterprets
+ // these bytes as a typed array equivalent to the typed SIMD vector.
+ var slice = function(start, numElemToRead) {
+ // Read enough bytes
+ var startBytes = start * bpe;
+ var endBytes = startBytes + numElemToRead * sizeOfLaneElem;
+ var asArray = Array.prototype.slice.call(uint8, startBytes, endBytes);
+
+ // If length is less than SIZE_BYTES bytes, fill with 0.
+ // This is needed for load1, load2, load3 which do only partial
+ // reads.
+ for (var i = asArray.length; i < SIZE_BYTES; i++) asArray[i] = 0;
+ assertEq(asArray.length, SIZE_BYTES);
+
+ return new typedArrayCtor(new Uint8Array(asArray).buffer);
+ }
+
+ var assertFunc = getAssertFuncFromLength(lanes);
+ var type = SIMD[kind];
+ return {
+ load1: function(index) {
+ if (lanes >= 8) // Int8x16 and Int16x8 only support load, no load1/load2/etc.
+ return
+ var v = type.load1(arr, index);
+ assertFunc(v, slice(index, 1));
+ },
+
+ load2: function(index) {
+ if (lanes !== 4)
+ return;
+ var v = type.load2(arr, index);
+ assertFunc(v, slice(index, 2));
+ },
+
+ load3: function(index) {
+ if (lanes !== 4)
+ return;
+ var v = type.load3(arr, index);
+ assertFunc(v, slice(index, 3));
+ },
+
+ load: function(index) {
+ var v = type.load(arr, index);
+ assertFunc(v, slice(index, lanes));
+ }
+ }
+}
+
+function testLoad(kind, TA) {
+ var lanes = TA.length / 4;
+ for (var i = TA.length; i--;)
+ TA[i] = i;
+
+ for (var ta of [
+ new Uint8Array(TA.buffer),
+ new Int8Array(TA.buffer),
+ new Uint16Array(TA.buffer),
+ new Int16Array(TA.buffer),
+ new Uint32Array(TA.buffer),
+ new Int32Array(TA.buffer),
+ new Float32Array(TA.buffer),
+ new Float64Array(TA.buffer)
+ ])
+ {
+ // Invalid args
+ assertThrowsInstanceOf(() => SIMD[kind].load(), TypeError);
+ assertThrowsInstanceOf(() => SIMD[kind].load(ta), TypeError);
+ assertThrowsInstanceOf(() => SIMD[kind].load("hello", 0), TypeError);
+ // Indexes must be integers, there is no rounding.
+ assertThrowsInstanceOf(() => SIMD[kind].load(ta, 1.5), RangeError);
+ assertThrowsInstanceOf(() => SIMD[kind].load(ta, -1), RangeError);
+ assertThrowsInstanceOf(() => SIMD[kind].load(ta, "hello"), RangeError);
+ assertThrowsInstanceOf(() => SIMD[kind].load(ta, NaN), RangeError);
+ // Try to trip up the bounds checking. Int32 is enough for everybody.
+ assertThrowsInstanceOf(() => SIMD[kind].load(ta, 0x100000000), RangeError);
+ assertThrowsInstanceOf(() => SIMD[kind].load(ta, 0x80000000), RangeError);
+ assertThrowsInstanceOf(() => SIMD[kind].load(ta, 0x40000000), RangeError);
+ assertThrowsInstanceOf(() => SIMD[kind].load(ta, 0x20000000), RangeError);
+ assertThrowsInstanceOf(() => SIMD[kind].load(ta, (1<<30) * (1<<23) - 1), RangeError);
+ assertThrowsInstanceOf(() => SIMD[kind].load(ta, (1<<30) * (1<<23)), RangeError);
+
+ // Valid and invalid reads
+ var C = MakeComparator(kind, ta);
+ var bpe = ta.BYTES_PER_ELEMENT;
+
+ var lastValidArgLoad1 = (SIZE_BYTES - (16 / lanes)) / bpe | 0;
+ var lastValidArgLoad2 = (SIZE_BYTES - 8) / bpe | 0;
+ var lastValidArgLoad3 = (SIZE_BYTES - 12) / bpe | 0;
+ var lastValidArgLoad = (SIZE_BYTES - 16) / bpe | 0;
+
+ C.load(0);
+ C.load(1);
+ C.load(2);
+ C.load(3);
+ C.load(lastValidArgLoad);
+
+ C.load1(0);
+ C.load1(1);
+ C.load1(2);
+ C.load1(3);
+ C.load1(lastValidArgLoad1);
+
+ C.load2(0);
+ C.load2(1);
+ C.load2(2);
+ C.load2(3);
+ C.load2(lastValidArgLoad2);
+
+ C.load3(0);
+ C.load3(1);
+ C.load3(2);
+ C.load3(3);
+ C.load3(lastValidArgLoad3);
+
+ assertThrowsInstanceOf(() => SIMD[kind].load(ta, lastValidArgLoad + 1), RangeError);
+ if (lanes <= 4) {
+ assertThrowsInstanceOf(() => SIMD[kind].load1(ta, lastValidArgLoad1 + 1), RangeError);
+ }
+ if (lanes == 4) {
+ assertThrowsInstanceOf(() => SIMD[kind].load2(ta, lastValidArgLoad2 + 1), RangeError);
+ assertThrowsInstanceOf(() => SIMD[kind].load3(ta, lastValidArgLoad3 + 1), RangeError);
+ }
+
+ // Indexes are coerced with ToNumber. Try some strings that
+ // CanonicalNumericIndexString() would reject.
+ C.load("1.0e0");
+ C.load(" 2");
+ }
+
+ if (lanes == 4) {
+ // Test ToNumber behavior.
+ var obj = {
+ valueOf: function() { return 12 }
+ }
+ var v = SIMD[kind].load(TA, obj);
+ assertEqX4(v, [12, 13, 14, 15]);
+ }
+
+ var obj = {
+ valueOf: function() { throw new TypeError("i ain't a number"); }
+ }
+ assertThrowsInstanceOf(() => SIMD[kind].load(TA, obj), TypeError);
+}
+
+var Helpers = {
+ testLoad,
+ MakeComparator
+};
diff --git a/js/src/tests/ecma_7/SIMD/shifts.js b/js/src/tests/ecma_7/SIMD/shifts.js
new file mode 100644
index 000000000..1d81f7483
--- /dev/null
+++ b/js/src/tests/ecma_7/SIMD/shifts.js
@@ -0,0 +1,202 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var Int8x16 = SIMD.Int8x16;
+var Int16x8 = SIMD.Int16x8;
+var Int32x4 = SIMD.Int32x4;
+var Uint8x16 = SIMD.Uint8x16;
+var Uint16x8 = SIMD.Uint16x8;
+var Uint32x4 = SIMD.Uint32x4;
+
+// Int8 shifts.
+function lsh8(a, b) {
+ return (a << (b & 7)) << 24 >> 24;
+}
+function rsha8(a, b) {
+ return (a >> (b & 7)) << 24 >> 24;
+}
+function rshl8(a, b) {
+ return (a >>> (b & 7)) << 24 >> 24;
+}
+
+// Int16 shifts.
+function lsh16(a, b) {
+ return (a << (b & 15)) << 16 >> 16;
+}
+function rsha16(a, b) {
+ return (a >> (b & 15)) << 16 >> 16;
+}
+function rshl16(a, b) {
+ return (a >>> (b & 15)) << 16 >> 16;
+}
+
+// Int32 shifts.
+function lsh32(a, b) {
+ return (a << (b & 31)) | 0;
+}
+function rsha32(a, b) {
+ return (a >> (b & 31)) | 0;
+}
+function rshl32(a, b) {
+ return (a >>> (b & 31)) | 0;
+}
+
+// Uint8 shifts.
+function ulsh8(a, b) {
+ return (a << (b & 7)) << 24 >>> 24;
+}
+function ursha8(a, b) {
+ return ((a << 24 >> 24) >> (b & 7)) << 24 >>> 24;
+}
+function urshl8(a, b) {
+ return (a >>> (b & 7)) << 24 >>> 24;
+}
+
+// Uint16 shifts.
+function ulsh16(a, b) {
+ return (a << (b & 15)) << 16 >>> 16;
+}
+function ursha16(a, b) {
+ return ((a << 16 >> 16) >> (b & 15)) << 16 >>> 16;
+}
+function urshl16(a, b) {
+ return (a >>> (b & 15)) << 16 >>> 16;
+}
+
+// Uint32 shifts.
+function ulsh32(a, b) {
+ return (a << (b & 31)) >>> 0;
+}
+function ursha32(a, b) {
+ return ((a | 0) >> (b & 31)) >>> 0;
+}
+function urshl32(a, b) {
+ return (a >>> (b & 31)) >>> 0;
+}
+
+function test() {
+ function TestError() {};
+
+ var good = {valueOf: () => 21};
+ var bad = {valueOf: () => {throw new TestError(); }};
+
+ for (var v of [
+ Int8x16(-1, 2, -3, 4, -5, 6, -7, 8, -9, 10, -11, 12, -13, 14, -15, 16),
+ Int8x16(INT8_MAX, INT8_MIN, INT8_MAX - 1, INT8_MIN + 1)
+ ])
+ {
+ for (var bits = -2; bits < 12; bits++) {
+ testBinaryScalarFunc(v, bits, Int8x16.shiftLeftByScalar, lsh8);
+ testBinaryScalarFunc(v, bits, Int8x16.shiftRightByScalar, rsha8);
+ }
+ // Test that the shift count is coerced to an int32.
+ testBinaryScalarFunc(v, undefined, Int8x16.shiftLeftByScalar, lsh8);
+ testBinaryScalarFunc(v, 3.5, Int8x16.shiftLeftByScalar, lsh8);
+ testBinaryScalarFunc(v, good, Int8x16.shiftLeftByScalar, lsh8);
+ }
+ for (var v of [
+ Int16x8(-1, 2, -3, 4, -5, 6, -7, 8),
+ Int16x8(INT16_MAX, INT16_MIN, INT16_MAX - 1, INT16_MIN + 1)
+ ])
+ {
+ for (var bits = -2; bits < 20; bits++) {
+ testBinaryScalarFunc(v, bits, Int16x8.shiftLeftByScalar, lsh16);
+ testBinaryScalarFunc(v, bits, Int16x8.shiftRightByScalar, rsha16);
+ }
+ // Test that the shift count is coerced to an int32.
+ testBinaryScalarFunc(v, undefined, Int16x8.shiftLeftByScalar, lsh16);
+ testBinaryScalarFunc(v, 3.5, Int16x8.shiftLeftByScalar, lsh16);
+ testBinaryScalarFunc(v, good, Int16x8.shiftLeftByScalar, lsh16);
+ }
+ for (var v of [
+ Int32x4(-1, 2, -3, 4),
+ Int32x4(INT32_MAX, INT32_MIN, INT32_MAX - 1, INT32_MIN + 1)
+ ])
+ {
+ for (var bits = -2; bits < 36; bits++) {
+ testBinaryScalarFunc(v, bits, Int32x4.shiftLeftByScalar, lsh32);
+ testBinaryScalarFunc(v, bits, Int32x4.shiftRightByScalar, rsha32);
+ }
+ // Test that the shift count is coerced to an int32.
+ testBinaryScalarFunc(v, undefined, Int32x4.shiftLeftByScalar, lsh32);
+ testBinaryScalarFunc(v, 3.5, Int32x4.shiftLeftByScalar, lsh32);
+ testBinaryScalarFunc(v, good, Int32x4.shiftLeftByScalar, lsh32);
+ }
+
+ for (var v of [
+ Uint8x16(-1, 2, -3, 4, -5, 6, -7, 8, -9, 10, -11, 12, -13, 14, -15, 16),
+ Uint8x16(INT8_MAX, INT8_MIN, INT8_MAX - 1, INT8_MIN + 1, UINT8_MAX, UINT8_MAX - 1)
+ ])
+ {
+ for (var bits = -2; bits < 12; bits++) {
+ testBinaryScalarFunc(v, bits, Uint8x16.shiftLeftByScalar, ulsh8);
+ testBinaryScalarFunc(v, bits, Uint8x16.shiftRightByScalar, urshl8);
+ }
+ // Test that the shift count is coerced to an int32.
+ testBinaryScalarFunc(v, undefined, Uint8x16.shiftLeftByScalar, ulsh8);
+ testBinaryScalarFunc(v, 3.5, Uint8x16.shiftLeftByScalar, ulsh8);
+ testBinaryScalarFunc(v, good, Uint8x16.shiftLeftByScalar, ulsh8);
+ }
+ for (var v of [
+ Uint16x8(-1, 2, -3, 4, -5, 6, -7, 8),
+ Uint16x8(INT16_MAX, INT16_MIN, INT16_MAX - 1, INT16_MIN + 1, UINT16_MAX, UINT16_MAX - 1)
+ ])
+ {
+ for (var bits = -2; bits < 20; bits++) {
+ testBinaryScalarFunc(v, bits, Uint16x8.shiftLeftByScalar, ulsh16);
+ testBinaryScalarFunc(v, bits, Uint16x8.shiftRightByScalar, urshl16);
+ }
+ // Test that the shift count is coerced to an int32.
+ testBinaryScalarFunc(v, undefined, Uint16x8.shiftLeftByScalar, ulsh16);
+ testBinaryScalarFunc(v, 3.5, Uint16x8.shiftLeftByScalar, ulsh16);
+ testBinaryScalarFunc(v, good, Uint16x8.shiftLeftByScalar, ulsh16);
+ }
+ for (var v of [
+ Uint32x4(-1, 2, -3, 4),
+ Uint32x4(UINT32_MAX, UINT32_MAX - 1, 0, 1),
+ Uint32x4(INT32_MAX, INT32_MIN, INT32_MAX - 1, INT32_MIN + 1)
+ ])
+ {
+ for (var bits = -2; bits < 36; bits++) {
+ testBinaryScalarFunc(v, bits, Uint32x4.shiftLeftByScalar, ulsh32);
+ testBinaryScalarFunc(v, bits, Uint32x4.shiftRightByScalar, urshl32);
+ }
+ // Test that the shift count is coerced to an int32.
+ testBinaryScalarFunc(v, undefined, Uint32x4.shiftLeftByScalar, ulsh32);
+ testBinaryScalarFunc(v, 3.5, Uint32x4.shiftLeftByScalar, ulsh32);
+ testBinaryScalarFunc(v, good, Uint32x4.shiftLeftByScalar, ulsh32);
+ }
+
+ var v = SIMD.Int8x16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16);
+ assertThrowsInstanceOf(() => SIMD.Int8x16.shiftLeftByScalar(v, bad), TestError);
+ assertThrowsInstanceOf(() => SIMD.Int8x16.shiftRightByScalar(v, bad), TestError);
+
+ var v = SIMD.Int16x8(1,2,3,4,5,6,7,8);
+ assertThrowsInstanceOf(() => SIMD.Int16x8.shiftLeftByScalar(v, bad), TestError);
+ assertThrowsInstanceOf(() => SIMD.Int16x8.shiftRightByScalar(v, bad), TestError);
+
+ var v = SIMD.Int32x4(1,2,3,4);
+ assertThrowsInstanceOf(() => SIMD.Int32x4.shiftLeftByScalar(v, bad), TestError);
+ assertThrowsInstanceOf(() => SIMD.Int32x4.shiftRightByScalar(v, bad), TestError);
+
+ var v = SIMD.Uint8x16(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16);
+ assertThrowsInstanceOf(() => SIMD.Uint8x16.shiftLeftByScalar(v, bad), TestError);
+ assertThrowsInstanceOf(() => SIMD.Uint8x16.shiftRightByScalar(v, bad), TestError);
+
+ var v = SIMD.Uint16x8(1,2,3,4,5,6,7,8);
+ assertThrowsInstanceOf(() => SIMD.Uint16x8.shiftLeftByScalar(v, bad), TestError);
+ assertThrowsInstanceOf(() => SIMD.Uint16x8.shiftRightByScalar(v, bad), TestError);
+
+ var v = SIMD.Uint32x4(1,2,3,4);
+ assertThrowsInstanceOf(() => SIMD.Uint32x4.shiftLeftByScalar(v, bad), TestError);
+ assertThrowsInstanceOf(() => SIMD.Uint32x4.shiftRightByScalar(v, bad), TestError);
+
+ if (typeof reportCompare === "function")
+ reportCompare(true, true);
+}
+
+test();
diff --git a/js/src/tests/ecma_7/SIMD/splat.js b/js/src/tests/ecma_7/SIMD/splat.js
new file mode 100644
index 000000000..1ab7ec98c
--- /dev/null
+++ b/js/src/tests/ecma_7/SIMD/splat.js
@@ -0,0 +1,97 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+
+var Float64x2 = SIMD.Float64x2;
+var Float32x4 = SIMD.Float32x4;
+var Int8x16 = SIMD.Int8x16;
+var Int16x8 = SIMD.Int16x8;
+var Int32x4 = SIMD.Int32x4;
+var Uint8x16 = SIMD.Uint8x16;
+var Uint16x8 = SIMD.Uint16x8;
+var Uint32x4 = SIMD.Uint32x4;
+var Bool8x16 = SIMD.Bool8x16;
+var Bool16x8 = SIMD.Bool16x8;
+var Bool32x4 = SIMD.Bool32x4;
+
+function TestSplatX16(type, inputs, coerceFunc) {
+ for (var x of inputs) {
+ assertEqX16(SIMD[type].splat(x), [x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x].map(coerceFunc));
+ }
+}
+
+function TestSplatX8(type, inputs, coerceFunc) {
+ for (var x of inputs) {
+ assertEqX8(SIMD[type].splat(x), [x, x, x, x, x, x, x, x].map(coerceFunc));
+ }
+}
+
+function TestSplatX4(type, inputs, coerceFunc) {
+ for (var x of inputs) {
+ assertEqX4(SIMD[type].splat(x), [x, x, x, x].map(coerceFunc));
+ }
+}
+
+function TestSplatX2(type, inputs, coerceFunc) {
+ for (var x of inputs) {
+ assertEqX2(SIMD[type].splat(x), [x, x].map(coerceFunc));
+ }
+}
+
+function test() {
+ function TestError(){};
+
+ var good = {valueOf: () => 19.89};
+ var bad = {valueOf: () => { throw new TestError(); }};
+
+ TestSplatX16('Int8x16', [0, 1, 2, -1, -2, 3, -3, 4, -4, 5, -5, 6, INT8_MIN, INT8_MAX, INT8_MIN - 1, INT8_MAX + 1], (x) => x << 24 >> 24);
+ assertEqX16(Int8x16.splat(), [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
+ assertThrowsInstanceOf(() => SIMD.Int8x16.splat(bad), TestError);
+
+ TestSplatX8('Int16x8', [0, 1, 2, -1, INT16_MIN, INT16_MAX, INT16_MIN - 1, INT16_MAX + 1], (x) => x << 16 >> 16);
+ assertEqX8(Int16x8.splat(), [0, 0, 0, 0, 0, 0, 0, 0]);
+ assertThrowsInstanceOf(() => SIMD.Int16x8.splat(bad), TestError);
+
+ TestSplatX4('Int32x4', [0, undefined, 3.5, 42, -1337, INT32_MAX, INT32_MAX + 1, good], (x) => x | 0);
+ assertEqX4(SIMD.Int32x4.splat(), [0, 0, 0, 0]);
+ assertThrowsInstanceOf(() => SIMD.Int32x4.splat(bad), TestError);
+
+ TestSplatX16('Uint8x16', [0, 1, 2, -1, -2, 3, -3, 4, -4, 5, -5, 6, INT8_MIN, INT8_MAX, INT8_MIN - 1, INT8_MAX + 1], (x) => x << 24 >>> 24);
+ assertEqX16(Uint8x16.splat(), [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
+ assertThrowsInstanceOf(() => SIMD.Uint8x16.splat(bad), TestError);
+
+ TestSplatX8('Uint16x8', [0, 1, 2, -1, INT16_MIN, INT16_MAX, INT16_MIN - 1, INT16_MAX + 1], (x) => x << 16 >>> 16);
+ assertEqX8(Uint16x8.splat(), [0, 0, 0, 0, 0, 0, 0, 0]);
+ assertThrowsInstanceOf(() => SIMD.Uint16x8.splat(bad), TestError);
+
+ TestSplatX4('Uint32x4', [0, undefined, 3.5, 42, INT32_MAX, INT32_MIN, UINT32_MAX, UINT32_MAX + 1, good], (x) => x >>> 0);
+ assertEqX4(SIMD.Uint32x4.splat(), [0, 0, 0, 0]);
+ assertThrowsInstanceOf(() => SIMD.Uint32x4.splat(bad), TestError);
+
+ TestSplatX4('Float32x4', [0, undefined, 3.5, 42, -13.37, Infinity, NaN, -0, good], (x) => Math.fround(x));
+ assertEqX4(SIMD.Float32x4.splat(), [NaN, NaN, NaN, NaN]);
+ assertThrowsInstanceOf(() => SIMD.Float32x4.splat(bad), TestError);
+
+ TestSplatX2('Float64x2', [0, undefined, 3.5, 42, -13.37, Infinity, NaN, -0, good], (x) => +x);
+ assertEqX2(SIMD.Float64x2.splat(), [NaN, NaN]);
+ assertThrowsInstanceOf(() => SIMD.Float64x2.splat(bad), TestError);
+
+ TestSplatX16('Bool8x16', [true, false], (x) => !!x);
+ assertEqX16(Bool8x16.splat(), [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]);
+ assertEqX16(Bool8x16.splat(bad), [true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true]);
+
+ TestSplatX8('Bool16x8', [true, false], (x) => !!x);
+ assertEqX8(Bool16x8.splat(), [false, false, false, false, false, false, false, false]);
+ assertEqX8(Bool16x8.splat(bad), [true, true, true, true, true, true, true, true]);
+
+ TestSplatX4('Bool32x4', [true, false], (x) => !!x);
+ assertEqX4(SIMD.Bool32x4.splat(), [false, false, false, false]);
+ assertEqX4(SIMD.Bool32x4.splat(bad), [true, true, true, true]);
+
+ TestSplatX2('Bool64x2', [true, false], (x) => !!x);
+ assertEqX2(SIMD.Bool64x2.splat(), [false, false]);
+ assertEqX2(SIMD.Bool64x2.splat(bad), [true, true]);
+
+ if (typeof reportCompare === "function")
+ reportCompare(true, true);
+}
+
+test();
diff --git a/js/src/tests/ecma_7/SIMD/store.js b/js/src/tests/ecma_7/SIMD/store.js
new file mode 100644
index 000000000..ef3c2249e
--- /dev/null
+++ b/js/src/tests/ecma_7/SIMD/store.js
@@ -0,0 +1,264 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+// As SIMD.*.store is entirely symmetric to SIMD.*.load, this file just
+// contains basic tests to store on one single TypedArray kind, while load is
+// exhaustively tested. See load.js for more details.
+
+const POISON = 42;
+
+function reset(ta) {
+ for (var i = 0; i < ta.length; i++)
+ ta[i] = POISON + i;
+}
+
+function assertChanged(ta, from, expected) {
+ var i = 0;
+ for (; i < from; i++)
+ assertEq(ta[i], POISON + i);
+ for (; i < from + expected.length; i++)
+ assertEq(ta[i], expected[i - from]);
+ for (; i < ta.length; i++)
+ assertEq(ta[i], POISON + i);
+}
+
+function testStore(ta, kind, i, v) {
+ var asArr = simdToArray(v);
+
+ reset(ta);
+ SIMD[kind].store(ta, i, v);
+ assertChanged(ta, i, asArr);
+
+ var length = asArr.length;
+ if (length >= 8) // Int8x16 and Int16x8 only support store, and not store1/store2/etc.
+ return;
+
+ reset(ta);
+ SIMD[kind].store1(ta, i, v);
+ assertChanged(ta, i, [asArr[0]]);
+ if (length > 2) {
+ reset(ta);
+ SIMD[kind].store2(ta, i, v);
+ assertChanged(ta, i, [asArr[0], asArr[1]]);
+
+ reset(ta);
+ SIMD[kind].store3(ta, i, v);
+ assertChanged(ta, i, [asArr[0], asArr[1], asArr[2]]);
+ }
+}
+
+function testStoreInt8x16(Buffer) {
+ var I8 = new Int8Array(new Buffer(32));
+
+ var v = SIMD.Int8x16(0, 1, INT8_MAX, INT8_MIN, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
+ testStore(I8, 'Int8x16', 0, v);
+ testStore(I8, 'Int8x16', 1, v);
+ testStore(I8, 'Int8x16', 2, v);
+ testStore(I8, 'Int8x16', 16, v);
+
+ assertThrowsInstanceOf(() => SIMD.Int8x16.store(I8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int8x16.store(I8, 0), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int16x8.store(I8, 0, v), TypeError);
+}
+
+function testStoreInt16x8(Buffer) {
+ var I16 = new Int16Array(new Buffer(64));
+
+ var v = SIMD.Int16x8(0, 1, INT16_MAX, INT16_MIN, 4, 5, 6, 7);
+ testStore(I16, 'Int16x8', 0, v);
+ testStore(I16, 'Int16x8', 1, v);
+ testStore(I16, 'Int16x8', 2, v);
+ testStore(I16, 'Int16x8', 24, v);
+
+ assertThrowsInstanceOf(() => SIMD.Int16x8.store(I16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int16x8.store(I16, 0), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int8x16.store(I16, 0, v), TypeError);
+}
+
+function testStoreInt32x4(Buffer) {
+ var I32 = new Int32Array(new Buffer(64));
+
+ var v = SIMD.Int32x4(0, 1, Math.pow(2,31) - 1, -Math.pow(2, 31));
+ testStore(I32, 'Int32x4', 0, v);
+ testStore(I32, 'Int32x4', 1, v);
+ testStore(I32, 'Int32x4', 2, v);
+ testStore(I32, 'Int32x4', 12, v);
+
+ assertThrowsInstanceOf(() => SIMD.Int32x4.store(I32), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int32x4.store(I32, 0), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Float32x4.store(I32, 0, v), TypeError);
+}
+
+function testStoreUint8x16(Buffer) {
+ var I8 = new Uint8Array(new Buffer(32));
+
+ var v = SIMD.Uint8x16(0, 1, INT8_MAX, INT8_MIN, UINT8_MAX, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
+ testStore(I8, 'Uint8x16', 0, v);
+ testStore(I8, 'Uint8x16', 1, v);
+ testStore(I8, 'Uint8x16', 2, v);
+ testStore(I8, 'Uint8x16', 16, v);
+
+ assertThrowsInstanceOf(() => SIMD.Uint8x16.store(I8), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint8x16.store(I8, 0), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint16x8.store(I8, 0, v), TypeError);
+}
+
+function testStoreUint16x8(Buffer) {
+ var I16 = new Uint16Array(new Buffer(64));
+
+ var v = SIMD.Uint16x8(0, 1, INT16_MAX, INT16_MIN, 4, 5, 6, 7);
+ testStore(I16, 'Uint16x8', 0, v);
+ testStore(I16, 'Uint16x8', 1, v);
+ testStore(I16, 'Uint16x8', 2, v);
+ testStore(I16, 'Uint16x8', 24, v);
+
+ assertThrowsInstanceOf(() => SIMD.Uint16x8.store(I16), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint16x8.store(I16, 0), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint8x16.store(I16, 0, v), TypeError);
+}
+
+function testStoreUint32x4(Buffer) {
+ var I32 = new Uint32Array(new Buffer(64));
+
+ var v = SIMD.Uint32x4(0, 1, Math.pow(2,31) - 1, -Math.pow(2, 31));
+ testStore(I32, 'Uint32x4', 0, v);
+ testStore(I32, 'Uint32x4', 1, v);
+ testStore(I32, 'Uint32x4', 2, v);
+ testStore(I32, 'Uint32x4', 12, v);
+
+ assertThrowsInstanceOf(() => SIMD.Uint32x4.store(I32), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Uint32x4.store(I32, 0), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Float32x4.store(I32, 0, v), TypeError);
+}
+
+function testStoreFloat32x4(Buffer) {
+ var F32 = new Float32Array(new Buffer(64));
+
+ var v = SIMD.Float32x4(1,2,3,4);
+ testStore(F32, 'Float32x4', 0, v);
+ testStore(F32, 'Float32x4', 1, v);
+ testStore(F32, 'Float32x4', 2, v);
+ testStore(F32, 'Float32x4', 12, v);
+
+ var v = SIMD.Float32x4(NaN, -0, -Infinity, 5e-324);
+ testStore(F32, 'Float32x4', 0, v);
+ testStore(F32, 'Float32x4', 1, v);
+ testStore(F32, 'Float32x4', 2, v);
+ testStore(F32, 'Float32x4', 12, v);
+
+ assertThrowsInstanceOf(() => SIMD.Float32x4.store(F32), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Float32x4.store(F32, 0), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Int32x4.store(F32, 0, v), TypeError);
+}
+
+function testStoreFloat64x2(Buffer) {
+ var F64 = new Float64Array(new Buffer(128));
+
+ var v = SIMD.Float64x2(1, 2);
+ testStore(F64, 'Float64x2', 0, v);
+ testStore(F64, 'Float64x2', 1, v);
+ testStore(F64, 'Float64x2', 14, v);
+
+ var v = SIMD.Float64x2(NaN, -0);
+ testStore(F64, 'Float64x2', 0, v);
+ testStore(F64, 'Float64x2', 1, v);
+ testStore(F64, 'Float64x2', 14, v);
+
+ var v = SIMD.Float64x2(-Infinity, +Infinity);
+ testStore(F64, 'Float64x2', 0, v);
+ testStore(F64, 'Float64x2', 1, v);
+ testStore(F64, 'Float64x2', 14, v);
+
+ assertThrowsInstanceOf(() => SIMD.Float64x2.store(F64), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Float64x2.store(F64, 0), TypeError);
+ assertThrowsInstanceOf(() => SIMD.Float32x4.store(F64, 0, v), TypeError);
+}
+
+function testSharedArrayBufferCompat() {
+ var I32 = new Int32Array(new SharedArrayBuffer(16*4));
+ var TA = I32;
+
+ var I8 = new Int8Array(TA.buffer);
+ var I16 = new Int16Array(TA.buffer);
+ var F32 = new Float32Array(TA.buffer);
+ var F64 = new Float64Array(TA.buffer);
+
+ var Int8x16 = SIMD.Int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
+ var Int16x8 = SIMD.Int16x8(1, 2, 3, 4, 5, 6, 7, 8);
+ var Int32x4 = SIMD.Int32x4(1, 2, 3, 4);
+ var Uint8x16 = SIMD.Uint8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
+ var Uint16x8 = SIMD.Uint16x8(1, 2, 3, 4, 5, 6, 7, 8);
+ var Uint32x4 = SIMD.Uint32x4(1, 2, 3, 4);
+ var Float32x4 = SIMD.Float32x4(1, 2, 3, 4);
+ var Float64x2 = SIMD.Float64x2(1, 2);
+
+ for (var ta of [
+ new Uint8Array(TA.buffer),
+ new Int8Array(TA.buffer),
+ new Uint16Array(TA.buffer),
+ new Int16Array(TA.buffer),
+ new Uint32Array(TA.buffer),
+ new Int32Array(TA.buffer),
+ new Float32Array(TA.buffer),
+ new Float64Array(TA.buffer)
+ ])
+ {
+ SIMD.Int8x16.store(ta, 0, Int8x16);
+ for (var i = 0; i < 16; i++) assertEq(I8[i], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16][i]);
+
+ SIMD.Int16x8.store(ta, 0, Int16x8);
+ for (var i = 0; i < 8; i++) assertEq(I16[i], [1, 2, 3, 4, 5, 6, 7, 8][i]);
+
+ SIMD.Int32x4.store(ta, 0, Int32x4);
+ for (var i = 0; i < 4; i++) assertEq(I32[i], [1, 2, 3, 4][i]);
+
+ SIMD.Uint8x16.store(ta, 0, Uint8x16);
+ for (var i = 0; i < 16; i++) assertEq(I8[i], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16][i]);
+
+ SIMD.Uint16x8.store(ta, 0, Uint16x8);
+ for (var i = 0; i < 8; i++) assertEq(I16[i], [1, 2, 3, 4, 5, 6, 7, 8][i]);
+
+ SIMD.Uint32x4.store(ta, 0, Uint32x4);
+ for (var i = 0; i < 4; i++) assertEq(I32[i], [1, 2, 3, 4][i]);
+
+ SIMD.Float32x4.store(ta, 0, Float32x4);
+ for (var i = 0; i < 4; i++) assertEq(F32[i], [1, 2, 3, 4][i]);
+
+ SIMD.Float64x2.store(ta, 0, Float64x2);
+ for (var i = 0; i < 2; i++) assertEq(F64[i], [1, 2][i]);
+
+ assertThrowsInstanceOf(() => SIMD.Int8x16.store(ta, 1024, Int8x16), RangeError);
+ assertThrowsInstanceOf(() => SIMD.Int16x8.store(ta, 1024, Int16x8), RangeError);
+ assertThrowsInstanceOf(() => SIMD.Int32x4.store(ta, 1024, Int32x4), RangeError);
+ assertThrowsInstanceOf(() => SIMD.Float32x4.store(ta, 1024, Float32x4), RangeError);
+ assertThrowsInstanceOf(() => SIMD.Float64x2.store(ta, 1024, Float64x2), RangeError);
+ }
+}
+
+testStoreInt8x16(ArrayBuffer);
+testStoreInt16x8(ArrayBuffer);
+testStoreInt32x4(ArrayBuffer);
+testStoreUint8x16(ArrayBuffer);
+testStoreUint16x8(ArrayBuffer);
+testStoreUint32x4(ArrayBuffer);
+testStoreFloat32x4(ArrayBuffer);
+testStoreFloat64x2(ArrayBuffer);
+
+if (typeof SharedArrayBuffer != "undefined") {
+ testStoreInt8x16(SharedArrayBuffer);
+ testStoreInt16x8(SharedArrayBuffer);
+ testStoreInt32x4(SharedArrayBuffer);
+ testStoreUint8x16(SharedArrayBuffer);
+ testStoreUint16x8(SharedArrayBuffer);
+ testStoreUint32x4(SharedArrayBuffer);
+ testStoreFloat32x4(SharedArrayBuffer);
+ testStoreFloat64x2(SharedArrayBuffer);
+ testSharedArrayBufferCompat();
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_7/SIMD/swizzle-shuffle.js b/js/src/tests/ecma_7/SIMD/swizzle-shuffle.js
new file mode 100644
index 000000000..7af98e2a7
--- /dev/null
+++ b/js/src/tests/ecma_7/SIMD/swizzle-shuffle.js
@@ -0,0 +1,507 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var Float32x4 = SIMD.Float32x4;
+var Float64x2 = SIMD.Float64x2;
+var Int8x16 = SIMD.Int8x16;
+var Int16x8 = SIMD.Int16x8;
+var Int32x4 = SIMD.Int32x4;
+var Uint8x16 = SIMD.Uint8x16;
+var Uint16x8 = SIMD.Uint16x8;
+var Uint32x4 = SIMD.Uint32x4;
+
+function swizzle2(arr, x, y) {
+ return [arr[x], arr[y]];
+}
+
+function swizzle4(arr, x, y, z, w) {
+ return [arr[x], arr[y], arr[z], arr[w]];
+}
+
+function swizzle8(arr, s0, s1, s2, s3, s4, s5, s6, s7) {
+ return [arr[s0], arr[s1], arr[s2], arr[s3], arr[s4], arr[s5], arr[s6], arr[s7]];
+}
+
+function swizzle16(arr, s0, s1, s2, s3, s4, s5, s6, s7,
+ s8, s9, s10, s11, s12, s13, s14, s15) {
+ return [arr[s0], arr[s1], arr[s2], arr[s3], arr[s4], arr[s5], arr[s6], arr[s7],
+ arr[s8], arr[s9], arr[s10], arr[s11], arr[s12], arr[s13], arr[s14], arr[s15]];
+}
+
+function getNumberOfLanesFromType(type) {
+ switch (type) {
+ case Int8x16:
+ case Uint8x16:
+ return 16;
+ case Int16x8:
+ case Uint16x8:
+ return 8;
+ case Float32x4:
+ case Int32x4:
+ case Uint32x4:
+ return 4;
+ case Float64x2:
+ return 2;
+ }
+ throw new TypeError("Unknown SIMD type.");
+}
+
+function testSwizzleForType(type) {
+ var lanes = getNumberOfLanesFromType(type);
+ var v;
+ switch (lanes) {
+ case 2:
+ v = type(1, 2);
+ break;
+ case 4:
+ v = type(1, 2, 3, 4);
+ break;
+ case 8:
+ v = type(1, 2, 3, 4, 5, 6, 7, 8);
+ break;
+ case 16:
+ v = type(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
+ break;
+ }
+
+ assertThrowsInstanceOf(() => type.swizzle() , TypeError);
+ assertThrowsInstanceOf(() => type.swizzle(v, 0) , TypeError);
+ assertThrowsInstanceOf(() => type.swizzle(v, 0, 1, 2) , TypeError);
+ assertThrowsInstanceOf(() => type.swizzle(0, 1, 2, 3, v) , TypeError);
+
+ // Test all possible swizzles.
+ if (lanes == 2) {
+ var x, y;
+ for (var i = 0; i < Math.pow(2, 2); i++) {
+ [x, y] = [x & 1, (y >> 1) & 1];
+ assertEqVec(type.swizzle(v, x, y), swizzle2(simdToArray(v), x, y));
+ }
+ } else if (lanes == 4) {
+ var x, y, z, w;
+ for (var i = 0; i < Math.pow(4, 4); i++) {
+ [x, y, z, w] = [i & 3, (i >> 2) & 3, (i >> 4) & 3, (i >> 6) & 3];
+ assertEqVec(type.swizzle(v, x, y, z, w), swizzle4(simdToArray(v), x, y, z, w));
+ }
+ } else if (lanes == 8) {
+ var vals = [[1, 2, 1, 2, 1, 2, 1, 2], [1, 1, 1, 1, 1, 1, 1, 1], [0, 1, 2, 3, 4, 5, 6, 7],
+ [7, 6, 5, 4, 3, 2, 1, 0], [5, 3, 2, 6, 1, 7, 4, 0]];
+ for (var t of vals) {
+ assertEqVec(type.swizzle(v, ...t), swizzle8(simdToArray(v), ...t));
+ }
+ } else {
+ assertEq(lanes, 16);
+
+ var vals = [[11, 2, 11, 2, 11, 2, 11, 2, 11, 2, 11, 2, 11, 2, 11, 2],
+ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
+ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
+ [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0],
+ [5, 14, 3, 2, 6, 9, 1, 10, 7, 11, 4, 0, 13, 15, 8, 12]];
+ for (var t of vals) {
+ assertEqVec(type.swizzle(v, ...t), swizzle16(simdToArray(v), ...t));
+ }
+ }
+
+ // Test that we throw if an lane argument doesn't coerce to an integer in bounds.
+ if (lanes == 2) {
+ assertThrowsInstanceOf(() => type.swizzle(v, 0, 0.5), RangeError);
+ assertThrowsInstanceOf(() => type.swizzle(v, 0, {}), RangeError);
+ assertThrowsInstanceOf(() => type.swizzle(v, 0, {valueOf: function(){return 42}}), RangeError);
+ assertThrowsInstanceOf(() => type.swizzle(v, 0, "one"), RangeError);
+ assertThrowsInstanceOf(() => type.swizzle(v, 0, undefined), RangeError);
+
+ type.swizzle(v, 0, "00.0");
+ type.swizzle(v, 0, null);
+ type.swizzle(v, 0, false);
+ type.swizzle(v, 0, true);
+
+ // In bounds is [0, 1]
+ assertThrowsInstanceOf(() => type.swizzle(v, 0, -1), RangeError);
+ assertThrowsInstanceOf(() => type.swizzle(v, 0, 2), RangeError);
+ } else if (lanes == 4) {
+ assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0.5), RangeError);
+ assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, {}), RangeError);
+ assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, {valueOf: function(){return 42}}), RangeError);
+ assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, "one"), RangeError);
+ assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, undefined), RangeError);
+
+ type.swizzle(v, 0, 0, 0, "00.0");
+ type.swizzle(v, 0, 0, 0, null);
+ type.swizzle(v, 0, 0, 0, false);
+ type.swizzle(v, 0, 0, 0, true);
+
+ // In bounds is [0, 3]
+ assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, -1), RangeError);
+ assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 4), RangeError);
+ } else if (lanes == 8) {
+ assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0.5), RangeError);
+ assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, {}), RangeError);
+ assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, {valueOf: function(){return 42}}), RangeError);
+ assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, "one"), RangeError);
+ assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, undefined), RangeError);
+
+ type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, "00.0");
+ type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, null);
+ type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, false);
+ type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, true);
+
+ // In bounds is [0, 7]
+ assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, -1), RangeError);
+ assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 8), RangeError);
+ } else {
+ assertEq(lanes, 16);
+
+ assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5), RangeError);
+ assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}), RangeError);
+ assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {valueOf: function(){return 42}}), RangeError);
+ assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "one"), RangeError);
+ assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, undefined), RangeError);
+
+ type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "00.0");
+ type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, null);
+ type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, false);
+ type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true);
+
+ // In bounds is [0, 15]
+ assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1), RangeError);
+ assertThrowsInstanceOf(() => type.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16), RangeError);
+ }
+}
+
+function testSwizzleInt8x16() {
+ var v = Int16x8(1, 2, 3, 4, 5, 6, 7, 8);
+
+ assertThrowsInstanceOf(function() {
+ Int8x16.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ }, TypeError);
+
+ testSwizzleForType(Int8x16);
+}
+
+function testSwizzleInt16x8() {
+ var v = Int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
+
+ assertThrowsInstanceOf(function() {
+ Int16x8.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0);
+ }, TypeError);
+
+ testSwizzleForType(Int16x8);
+}
+
+function testSwizzleInt32x4() {
+ var v = Int32x4(1, 2, 3, 4);
+
+ assertThrowsInstanceOf(function() {
+ Float32x4.swizzle(v, 0, 0, 0, 0);
+ }, TypeError);
+
+ testSwizzleForType(Int32x4);
+}
+
+function testSwizzleUint8x16() {
+ var v = Uint16x8(1, 2, 3, 4, 5, 6, 7, 8);
+
+ assertThrowsInstanceOf(function() {
+ Uint8x16.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ }, TypeError);
+
+ testSwizzleForType(Uint8x16);
+}
+
+function testSwizzleUint16x8() {
+ var v = Uint8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
+
+ assertThrowsInstanceOf(function() {
+ Uint16x8.swizzle(v, 0, 0, 0, 0, 0, 0, 0, 0);
+ }, TypeError);
+
+ testSwizzleForType(Uint16x8);
+}
+
+function testSwizzleUint32x4() {
+ var v = Uint32x4(1, 2, 3, 4);
+
+ assertThrowsInstanceOf(function() {
+ Float32x4.swizzle(v, 0, 0, 0, 0);
+ }, TypeError);
+
+ testSwizzleForType(Uint32x4);
+}
+
+function testSwizzleFloat32x4() {
+ var v = Float32x4(1, 2, 3, 4);
+
+ assertThrowsInstanceOf(function() {
+ Int32x4.swizzle(v, 0, 0, 0, 0);
+ }, TypeError);
+
+ testSwizzleForType(Float32x4);
+}
+
+function testSwizzleFloat64x2() {
+ var v = Float64x2(1, 2);
+
+ assertThrowsInstanceOf(function() {
+ Float32x4.swizzle(v, 0, 0, 0, 0);
+ }, TypeError);
+
+ testSwizzleForType(Float64x2);
+}
+
+function shuffle2(lhsa, rhsa, x, y) {
+ return [(x < 2 ? lhsa : rhsa)[x % 2],
+ (y < 2 ? lhsa : rhsa)[y % 2]];
+}
+function shuffle4(lhsa, rhsa, x, y, z, w) {
+ return [(x < 4 ? lhsa : rhsa)[x % 4],
+ (y < 4 ? lhsa : rhsa)[y % 4],
+ (z < 4 ? lhsa : rhsa)[z % 4],
+ (w < 4 ? lhsa : rhsa)[w % 4]];
+}
+
+function shuffle8(lhsa, rhsa, s0, s1, s2, s3, s4, s5, s6, s7, s8) {
+ return [(s0 < 8 ? lhsa : rhsa)[s0 % 8],
+ (s1 < 8 ? lhsa : rhsa)[s1 % 8],
+ (s2 < 8 ? lhsa : rhsa)[s2 % 8],
+ (s3 < 8 ? lhsa : rhsa)[s3 % 8],
+ (s4 < 8 ? lhsa : rhsa)[s4 % 8],
+ (s5 < 8 ? lhsa : rhsa)[s5 % 8],
+ (s6 < 8 ? lhsa : rhsa)[s6 % 8],
+ (s7 < 8 ? lhsa : rhsa)[s7 % 8]];
+}
+
+function shuffle16(lhsa, rhsa, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15) {
+ return [(s0 < 16 ? lhsa : rhsa)[s0 % 16],
+ (s1 < 16 ? lhsa : rhsa)[s1 % 16],
+ (s2 < 16 ? lhsa : rhsa)[s2 % 16],
+ (s3 < 16 ? lhsa : rhsa)[s3 % 16],
+ (s4 < 16 ? lhsa : rhsa)[s4 % 16],
+ (s5 < 16 ? lhsa : rhsa)[s5 % 16],
+ (s6 < 16 ? lhsa : rhsa)[s6 % 16],
+ (s7 < 16 ? lhsa : rhsa)[s7 % 16],
+ (s8 < 16 ? lhsa : rhsa)[s8 % 16],
+ (s9 < 16 ? lhsa : rhsa)[s9 % 16],
+ (s10 < 16 ? lhsa : rhsa)[s10 % 16],
+ (s11 < 16 ? lhsa : rhsa)[s11 % 16],
+ (s12 < 16 ? lhsa : rhsa)[s12 % 16],
+ (s13 < 16 ? lhsa : rhsa)[s13 % 16],
+ (s14 < 16 ? lhsa : rhsa)[s14 % 16],
+ (s15 < 16 ? lhsa : rhsa)[s15 % 16]];
+}
+
+function testShuffleForType(type) {
+ var lanes = getNumberOfLanesFromType(type);
+ var lhs, rhs;
+ if (lanes == 2) {
+ lhs = type(1, 2);
+ rhs = type(3, 4);
+ } else if (lanes == 4) {
+ lhs = type(1, 2, 3, 4);
+ rhs = type(5, 6, 7, 8);
+ } else if (lanes == 8) {
+ lhs = type(1, 2, 3, 4, 5, 6, 7, 8);
+ rhs = type(9, 10, 11, 12, 13, 14, 15, 16);
+ } else {
+ assertEq(lanes, 16);
+
+ lhs = type(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
+ rhs = type(17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32);
+ }
+
+ assertThrowsInstanceOf(() => type.shuffle(lhs) , TypeError);
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs) , TypeError);
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0) , TypeError);
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 1, 2) , TypeError);
+ assertThrowsInstanceOf(() => type.shuffle(lhs, 0, 1, 2, 7, rhs) , TypeError);
+
+ // Test all possible shuffles.
+ var x, y, z, w;
+ if (lanes == 2) {
+ var x, y;
+ for (var i = 0; i < Math.pow(4, 2); i++) {
+ [x, y] = [i & 3, (i >> 3) & 3];
+ assertEqVec(type.shuffle(lhs, rhs, x, y),
+ shuffle2(simdToArray(lhs), simdToArray(rhs), x, y));
+ }
+ } else if (lanes == 4) {
+ var x, y, z, w;
+ for (var i = 0; i < Math.pow(8, 4); i++) {
+ [x, y, z, w] = [i & 7, (i >> 3) & 7, (i >> 6) & 7, (i >> 9) & 7];
+ assertEqVec(type.shuffle(lhs, rhs, x, y, z, w),
+ shuffle4(simdToArray(lhs), simdToArray(rhs), x, y, z, w));
+ }
+ } else if (lanes == 8) {
+ var s0, s1, s2, s3, s4, s5, s6, s7;
+ var vals = [[15, 8, 15, 8, 15, 8, 15, 8], [9, 7, 9, 7, 9, 7, 9, 7],
+ [7, 3, 8, 9, 2, 15, 14, 6], [2, 2, 2, 2, 2, 2, 2, 2],
+ [8, 8, 8, 8, 8, 8, 8, 8], [11, 11, 11, 11, 11, 11, 11, 11]];
+ for (var t of vals) {
+ [s0, s1, s2, s3, s4, s5, s6, s7] = t;
+ assertEqVec(type.shuffle(lhs, rhs, s0, s1, s2, s3, s4, s5, s6, s7),
+ shuffle8(simdToArray(lhs), simdToArray(rhs), s0, s1, s2, s3, s4, s5, s6, s7));
+ }
+ } else {
+ assertEq(lanes, 16);
+
+ var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15;
+ var vals = [[30, 16, 30, 16, 30, 16, 30, 16, 30, 16, 30, 16, 30, 16, 30, 16],
+ [19, 17, 19, 17, 19, 17, 19, 17, 19, 17, 19, 17, 19, 17, 19, 17],
+ [7, 3, 8, 18, 9, 21, 2, 15, 14, 6, 16, 22, 29, 31, 30, 1],
+ [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
+ [16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16],
+ [21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21]];
+ for (var t of vals) {
+ [s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15] = t;
+ assertEqVec(type.shuffle(lhs, rhs, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15),
+ shuffle16(simdToArray(lhs), simdToArray(rhs), s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15));
+ }
+ }
+
+ // Test that we throw if an lane argument isn't an int32 or isn't in bounds.
+ if (lanes == 2) {
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0.5), RangeError);
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, {}), RangeError);
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, {valueOf: function(){return 42}}), RangeError);
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, "one"), RangeError);
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, undefined), RangeError);
+
+ // In bounds is [0, 3]
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, -1), RangeError);
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 4), RangeError);
+ } else if (lanes == 4) {
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0.5), RangeError);
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, {}), RangeError);
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, {valueOf: function(){return 42}}), RangeError);
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, "one"), RangeError);
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, undefined), RangeError);
+
+ // In bounds is [0, 7]
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, -1), RangeError);
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 8), RangeError);
+ } else if (lanes == 8) {
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0.5), RangeError);
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, {}), RangeError);
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, {valueOf: function(){return 42}}), RangeError);
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, "one"), RangeError);
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, undefined), RangeError);
+
+ // In bounds is [0, 15]
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, -1), RangeError);
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 16), RangeError);
+ } else {
+ assertEq(lanes, 16);
+
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5), RangeError);
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}), RangeError);
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {valueOf: function(){return 42}}), RangeError);
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "one"), RangeError);
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, undefined), RangeError);
+
+ // In bounds is [0, 31]
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1), RangeError);
+ assertThrowsInstanceOf(() => type.shuffle(lhs, rhs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32), RangeError);
+ }
+}
+
+function testShuffleInt8x16() {
+ var v = Int16x8(1, 2, 3, 4, 5, 6, 7, 8);
+
+ assertThrowsInstanceOf(function() {
+ Int8x16.shuffle(v, v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ }, TypeError);
+
+ testShuffleForType(Int8x16);
+}
+
+function testShuffleInt16x8() {
+ var v = Int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
+
+ assertThrowsInstanceOf(function() {
+ Int16x8.shuffle(v, v, 0, 0, 0, 0, 0, 0, 0, 0);
+ }, TypeError);
+
+ testShuffleForType(Int16x8);
+}
+
+function testShuffleInt32x4() {
+ var v = Int32x4(1, 2, 3, 4);
+
+ assertThrowsInstanceOf(function() {
+ Float32x4.shuffle(v, v, 0, 0, 0, 0);
+ }, TypeError);
+
+ testShuffleForType(Int32x4);
+}
+
+function testShuffleUint8x16() {
+ var v = Uint16x8(1, 2, 3, 4, 5, 6, 7, 8);
+
+ assertThrowsInstanceOf(function() {
+ Uint8x16.shuffle(v, v, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ }, TypeError);
+
+ testShuffleForType(Uint8x16);
+}
+
+function testShuffleUint16x8() {
+ var v = Uint8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
+
+ assertThrowsInstanceOf(function() {
+ Uint16x8.shuffle(v, v, 0, 0, 0, 0, 0, 0, 0, 0);
+ }, TypeError);
+
+ testShuffleForType(Uint16x8);
+}
+
+function testShuffleUint32x4() {
+ var v = Uint32x4(1, 2, 3, 4);
+
+ assertThrowsInstanceOf(function() {
+ Float32x4.shuffle(v, v, 0, 0, 0, 0);
+ }, TypeError);
+
+ testShuffleForType(Uint32x4);
+}
+
+function testShuffleFloat32x4() {
+ var v = Float32x4(1, 2, 3, 4);
+
+ assertThrowsInstanceOf(function() {
+ Int32x4.shuffle(v, v, 0, 0, 0, 0);
+ }, TypeError);
+
+ testShuffleForType(Float32x4);
+}
+
+function testShuffleFloat64x2() {
+ var v = Float64x2(1, 2);
+
+ assertThrowsInstanceOf(function() {
+ Float32x4.shuffle(v, v, 0, 0, 0, 0);
+ }, TypeError);
+
+ testShuffleForType(Float64x2);
+}
+
+testSwizzleInt8x16();
+testSwizzleInt16x8();
+testSwizzleInt32x4();
+testSwizzleUint8x16();
+testSwizzleUint16x8();
+testSwizzleUint32x4();
+testSwizzleFloat32x4();
+testSwizzleFloat64x2();
+testShuffleInt8x16();
+testShuffleInt16x8();
+testShuffleInt32x4();
+testShuffleUint8x16();
+testShuffleUint16x8();
+testShuffleUint32x4();
+testShuffleFloat32x4();
+testShuffleFloat64x2();
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_7/SIMD/toString.js b/js/src/tests/ecma_7/SIMD/toString.js
new file mode 100644
index 000000000..0f8bb7a9b
--- /dev/null
+++ b/js/src/tests/ecma_7/SIMD/toString.js
@@ -0,0 +1,90 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+
+function test() {
+ var Float32x4 = SIMD.Float32x4;
+ var f = Float32x4(11, 22, NaN, -44);
+ assertEq(f.toString(), "SIMD.Float32x4(11, 22, NaN, -44)");
+
+ // Polyfill check should show that we already have a toString.
+ assertEq(Float32x4.prototype.hasOwnProperty("toString"), true);
+
+ // This toString method type checks its argument.
+ var ts = Float32x4.prototype.toString;
+ assertThrowsInstanceOf(() => ts.call(5), TypeError);
+ assertThrowsInstanceOf(() => ts.call({}), TypeError);
+
+ // Can't convert SIMD objects to numbers.
+ assertThrowsInstanceOf(() => +f, TypeError);
+ assertThrowsInstanceOf(() => f.valueOf(), TypeError);
+
+ var Float64x2 = SIMD.Float64x2;
+ var f = Float64x2(11, 22);
+ assertEq(f.toString(), "SIMD.Float64x2(11, 22)");
+ assertThrowsInstanceOf(() => +f, TypeError);
+ assertThrowsInstanceOf(() => f.valueOf(), TypeError);
+
+ var Int8x16 = SIMD.Int8x16;
+ var f = Int8x16(11, 22, 33, 44, -11, -22, -33, -44, 1, 2, 3, 4, -1, -2, -3, -4);
+ assertEq(f.toString(), "SIMD.Int8x16(11, 22, 33, 44, -11, -22, -33, -44, 1, 2, 3, 4, -1, -2, -3, -4)");
+ assertThrowsInstanceOf(() => +f, TypeError);
+ assertThrowsInstanceOf(() => f.valueOf(), TypeError);
+
+ var Int16x8 = SIMD.Int16x8;
+ var f = Int16x8(11, 22, 33, 44, -11, -22, -33, -44);
+ assertEq(f.toString(), "SIMD.Int16x8(11, 22, 33, 44, -11, -22, -33, -44)");
+ assertThrowsInstanceOf(() => +f, TypeError);
+ assertThrowsInstanceOf(() => f.valueOf(), TypeError);
+
+ var Int32x4 = SIMD.Int32x4;
+ var f = Int32x4(11, 22, 33, 44);
+ assertEq(f.toString(), "SIMD.Int32x4(11, 22, 33, 44)");
+ assertThrowsInstanceOf(() => +f, TypeError);
+ assertThrowsInstanceOf(() => f.valueOf(), TypeError);
+
+ var Uint8x16 = SIMD.Uint8x16;
+ var f = Uint8x16(11, 22, 33, 44, 245, 234, 223, 212, 1, 2, 3, 4, 255, 254, 0, 250);
+ assertEq(f.toString(), "SIMD.Uint8x16(11, 22, 33, 44, 245, 234, 223, 212, 1, 2, 3, 4, 255, 254, 0, 250)");
+ assertThrowsInstanceOf(() => +f, TypeError);
+ assertThrowsInstanceOf(() => f.valueOf(), TypeError);
+
+ var Uint16x8 = SIMD.Uint16x8;
+ var f = Uint16x8(11, 22, 33, 44, 65535, 65534, 65533, 65532);
+ assertEq(f.toString(), "SIMD.Uint16x8(11, 22, 33, 44, 65535, 65534, 65533, 65532)");
+ assertThrowsInstanceOf(() => +f, TypeError);
+ assertThrowsInstanceOf(() => f.valueOf(), TypeError);
+
+ var Uint32x4 = SIMD.Uint32x4;
+ var f = Uint32x4(11, 22, 4294967295, 4294967294);
+ assertEq(f.toString(), "SIMD.Uint32x4(11, 22, 4294967295, 4294967294)");
+ assertThrowsInstanceOf(() => +f, TypeError);
+ assertThrowsInstanceOf(() => f.valueOf(), TypeError);
+
+ var Bool8x16 = SIMD.Bool8x16;
+ var f = Bool8x16(true, true, false, false, false, true, true, false, true, true, true, true, false, false, false, false);
+ assertEq(f.toString(), "SIMD.Bool8x16(true, true, false, false, false, true, true, false, true, true, true, true, false, false, false, false)");
+ assertThrowsInstanceOf(() => +f, TypeError);
+ assertThrowsInstanceOf(() => f.valueOf(), TypeError);
+
+ var Bool16x8 = SIMD.Bool16x8;
+ var f = Bool16x8(true, true, false, false, true, false, false, true);
+ assertEq(f.toString(), "SIMD.Bool16x8(true, true, false, false, true, false, false, true)");
+ assertThrowsInstanceOf(() => +f, TypeError);
+ assertThrowsInstanceOf(() => f.valueOf(), TypeError);
+
+ var Bool32x4 = SIMD.Bool32x4;
+ var f = Bool32x4(true, true, false, false);
+ assertEq(f.toString(), "SIMD.Bool32x4(true, true, false, false)");
+ assertThrowsInstanceOf(() => +f, TypeError);
+ assertThrowsInstanceOf(() => f.valueOf(), TypeError);
+
+ var Bool64x2 = SIMD.Bool64x2;
+ var f = Bool64x2(true, false);
+ assertEq(f.toString(), "SIMD.Bool64x2(true, false)");
+ assertThrowsInstanceOf(() => +f, TypeError);
+ assertThrowsInstanceOf(() => f.valueOf(), TypeError);
+
+ if (typeof reportCompare === "function")
+ reportCompare(true, true);
+}
+
+test();
diff --git a/js/src/tests/ecma_7/SIMD/typedobjects.js b/js/src/tests/ecma_7/SIMD/typedobjects.js
new file mode 100644
index 000000000..e4886cf4e
--- /dev/null
+++ b/js/src/tests/ecma_7/SIMD/typedobjects.js
@@ -0,0 +1,1077 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+var Float32x4 = SIMD.Float32x4;
+var Float64x2 = SIMD.Float64x2;
+var Int8x16 = SIMD.Int8x16;
+var Int16x8 = SIMD.Int16x8;
+var Int32x4 = SIMD.Int32x4;
+var Uint8x16 = SIMD.Uint8x16;
+var Uint16x8 = SIMD.Uint16x8;
+var Uint32x4 = SIMD.Uint32x4;
+var Bool8x16 = SIMD.Bool8x16;
+var Bool16x8 = SIMD.Bool16x8;
+var Bool32x4 = SIMD.Bool32x4;
+var Bool64x2 = SIMD.Bool64x2;
+
+var {StructType, Handle} = TypedObject;
+var {float32, float64, int8, int16, int32, uint8} = TypedObject;
+
+function testFloat32x4Alignment() {
+ assertEq(Float32x4.byteLength, 16);
+ assertEq(Float32x4.byteAlignment, 16);
+
+ var Compound = new StructType({c: uint8, d: uint8, f: Float32x4});
+ assertEq(Compound.fieldOffsets.c, 0);
+ assertEq(Compound.fieldOffsets.d, 1);
+ assertEq(Compound.fieldOffsets.f, 16);
+}
+
+function testFloat32x4Getters() {
+ var f = Float32x4(11, 22, 33, 44);
+ assertEq(Float32x4.extractLane(f, 0), 11);
+ assertEq(Float32x4.extractLane(f, 1), 22);
+ assertEq(Float32x4.extractLane(f, 2), 33);
+ assertEq(Float32x4.extractLane(f, 3), 44);
+
+ assertThrowsInstanceOf(() => Float32x4.extractLane(f, 4), RangeError);
+ assertThrowsInstanceOf(() => Float32x4.extractLane(f, -1), RangeError);
+ assertThrowsInstanceOf(() => Float32x4.extractLane(f, 0.5), RangeError);
+ assertThrowsInstanceOf(() => Float32x4.extractLane(f, {}), RangeError);
+ assertThrowsInstanceOf(() => Float32x4.extractLane(Int32x4(1,2,3,4), 0), TypeError);
+ assertThrowsInstanceOf(() => Float32x4.extractLane(1, 0), TypeError);
+ assertThrowsInstanceOf(() => Float32x4.extractLane(f, f), TypeError);
+}
+
+function testFloat32x4Handles() {
+ var Array = Float32x4.array(3);
+ var array = new Array([Float32x4(1, 2, 3, 4),
+ Float32x4(5, 6, 7, 8),
+ Float32x4(9, 10, 11, 12)]);
+
+ // Test that trying to create handle into the interior of a
+ // Float32x4 fails.
+ assertThrowsInstanceOf(function() {
+ var h = float32.handle(array, 1, 0);
+ }, TypeError, "Creating a float32 handle to elem via ctor");
+
+ assertThrowsInstanceOf(function() {
+ var h = float32.handle();
+ Handle.move(h, array, 1, 0);
+ }, TypeError, "Creating a float32 handle to elem via move");
+}
+
+function testFloat32x4Reify() {
+ var Array = Float32x4.array(3);
+ var array = new Array([Float32x4(1, 2, 3, 4),
+ Float32x4(5, 6, 7, 8),
+ Float32x4(9, 10, 11, 12)]);
+
+ // Test that reading array[1] produces a *copy* of Float32x4, not an
+ // alias into the array.
+
+ var f = array[1];
+ assertEq(Float32x4.extractLane(f, 3), 8);
+ assertEq(Float32x4.extractLane(array[1], 3), 8);
+ array[1] = Float32x4(15, 16, 17, 18);
+ assertEq(Float32x4.extractLane(f, 3), 8);
+ assertEq(Float32x4.extractLane(array[1], 3), 18);
+}
+
+function testFloat32x4Setters() {
+ var Array = Float32x4.array(3);
+ var array = new Array([Float32x4(1, 2, 3, 4),
+ Float32x4(5, 6, 7, 8),
+ Float32x4(9, 10, 11, 12)]);
+ assertEq(Float32x4.extractLane(array[1], 3), 8);
+
+ // Test that we are allowed to write Float32x4 values into array,
+ // but not other things.
+
+ array[1] = Float32x4(15, 16, 17, 18);
+ assertEq(Float32x4.extractLane(array[1], 3), 18);
+
+ assertThrowsInstanceOf(function() {
+ array[1] = {x: 15, y: 16, z: 17, w: 18};
+ }, TypeError, "Setting Float32x4 from an object");
+
+ assertThrowsInstanceOf(function() {
+ array[1] = [15, 16, 17, 18];
+ }, TypeError, "Setting Float32x4 from an array");
+
+ assertThrowsInstanceOf(function() {
+ array[1] = 22;
+ }, TypeError, "Setting Float32x4 from a number");
+}
+
+function testFloat64x2Alignment() {
+ assertEq(Float64x2.byteLength, 16);
+ assertEq(Float64x2.byteAlignment, 16);
+
+ var Compound = new StructType({c: uint8, d: uint8, f: Float64x2});
+ assertEq(Compound.fieldOffsets.c, 0);
+ assertEq(Compound.fieldOffsets.d, 1);
+ assertEq(Compound.fieldOffsets.f, 16);
+}
+
+function testFloat64x2Getters() {
+ // Create a Float64x2 and check that the getters work:
+ var f = Float64x2(11, 22);
+ assertEq(Float64x2.extractLane(f, 0), 11);
+ assertEq(Float64x2.extractLane(f, 1), 22);
+
+ assertThrowsInstanceOf(() => Float64x2.extractLane(f, 2), RangeError);
+ assertThrowsInstanceOf(() => Float64x2.extractLane(f, -1), RangeError);
+ assertThrowsInstanceOf(() => Float64x2.extractLane(f, 0.5), RangeError);
+ assertThrowsInstanceOf(() => Float64x2.extractLane(f, {}), RangeError);
+ assertThrowsInstanceOf(() => Float64x2.extractLane(Float32x4(1,2,3,4), 0), TypeError);
+ assertThrowsInstanceOf(() => Float64x2.extractLane(1, 0), TypeError);
+ assertThrowsInstanceOf(() => Float64x2.extractLane(f, f), TypeError);
+}
+
+function testFloat64x2Handles() {
+ var Array = Float64x2.array(3);
+ var array = new Array([Float64x2(1, 2),
+ Float64x2(3, 4),
+ Float64x2(5, 6)]);
+
+ // Test that trying to create handle into the interior of a
+ // Float64x2 fails.
+ assertThrowsInstanceOf(function() {
+ var h = float64.handle(array, 1, 0);
+ }, TypeError, "Creating a float64 handle to elem via ctor");
+
+ assertThrowsInstanceOf(function() {
+ var h = float64.handle();
+ Handle.move(h, array, 1, 0);
+ }, TypeError, "Creating a float64 handle to elem via move");
+}
+
+function testFloat64x2Reify() {
+ var Array = Float64x2.array(3);
+ var array = new Array([Float64x2(1, 2),
+ Float64x2(3, 4),
+ Float64x2(5, 6)]);
+
+ // Test that reading array[1] produces a *copy* of Float64x2, not an
+ // alias into the array.
+
+ var f = array[1];
+ assertEq(Float64x2.extractLane(f, 1), 4);
+ assertEq(Float64x2.extractLane(array[1], 1), 4);
+ array[1] = Float64x2(7, 8);
+ assertEq(Float64x2.extractLane(f, 1), 4);
+ assertEq(Float64x2.extractLane(array[1], 1), 8);
+}
+
+function testFloat64x2Setters() {
+ var Array = Float64x2.array(3);
+ var array = new Array([Float64x2(1, 2),
+ Float64x2(3, 4),
+ Float64x2(5, 6)]);
+ assertEq(Float64x2.extractLane(array[1], 1), 4);
+
+ // Test that we are allowed to write Float64x2 values into array,
+ // but not other things.
+
+ array[1] = Float64x2(7, 8);
+ assertEq(Float64x2.extractLane(array[1], 1), 8);
+
+ assertThrowsInstanceOf(function() {
+ array[1] = {x: 7, y: 8 };
+ }, TypeError, "Setting Float64x2 from an object");
+
+ assertThrowsInstanceOf(function() {
+ array[1] = [ 7, 8 ];
+ }, TypeError, "Setting Float64x2 from an array");
+
+ assertThrowsInstanceOf(function() {
+ array[1] = 9;
+ }, TypeError, "Setting Float64x2 from a number");
+}
+
+function testInt8x16Alignment() {
+ assertEq(Int8x16.byteLength, 16);
+ assertEq(Int8x16.byteAlignment, 16);
+
+ var Compound = new StructType({c: uint8, d: uint8, f: Int8x16});
+ assertEq(Compound.fieldOffsets.c, 0);
+ assertEq(Compound.fieldOffsets.d, 1);
+ assertEq(Compound.fieldOffsets.f, 16);
+}
+
+function testInt8x16Getters() {
+ // Create a Int8x16 and check that the getters work:
+ var f = Int8x16(11, 22, 33, 44, 55, 66, 77, 88, 99, 10, 20, 30, 40, 50, 60, 70);
+ assertEq(Int8x16.extractLane(f, 0), 11);
+ assertEq(Int8x16.extractLane(f, 1), 22);
+ assertEq(Int8x16.extractLane(f, 2), 33);
+ assertEq(Int8x16.extractLane(f, 3), 44);
+ assertEq(Int8x16.extractLane(f, 4), 55);
+ assertEq(Int8x16.extractLane(f, 5), 66);
+ assertEq(Int8x16.extractLane(f, 6), 77);
+ assertEq(Int8x16.extractLane(f, 7), 88);
+ assertEq(Int8x16.extractLane(f, 8), 99);
+ assertEq(Int8x16.extractLane(f, 9), 10);
+ assertEq(Int8x16.extractLane(f, 10), 20);
+ assertEq(Int8x16.extractLane(f, 11), 30);
+ assertEq(Int8x16.extractLane(f, 12), 40);
+ assertEq(Int8x16.extractLane(f, 13), 50);
+ assertEq(Int8x16.extractLane(f, 14), 60);
+ assertEq(Int8x16.extractLane(f, 15), 70);
+
+ assertThrowsInstanceOf(() => Int8x16.extractLane(f, 16), RangeError);
+ assertThrowsInstanceOf(() => Int8x16.extractLane(f, -1), RangeError);
+ assertThrowsInstanceOf(() => Int8x16.extractLane(f, 0.5), RangeError);
+ assertThrowsInstanceOf(() => Int8x16.extractLane(f, {}), RangeError);
+ assertThrowsInstanceOf(() => Int8x16.extractLane(Int32x4(1,2,3,4), 0), TypeError);
+ assertThrowsInstanceOf(() => Int8x16.extractLane(1, 0), TypeError);
+ assertThrowsInstanceOf(() => Int8x16.extractLane(f, f), TypeError);
+}
+
+function testInt8x16Handles() {
+ var Array = Int8x16.array(3);
+ var array = new Array([Int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16),
+ Int8x16(17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32),
+ Int8x16(33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48)]);
+
+ // Test that trying to create handle into the interior of a
+ // Int8x16 fails.
+ assertThrowsInstanceOf(function() {
+ var h = int8.handle(array, 1, 0);
+ }, TypeError, "Creating a int8 handle to elem via ctor");
+
+ assertThrowsInstanceOf(function() {
+ var h = int8.handle();
+ Handle.move(h, array, 1, 0);
+ }, TypeError, "Creating a int8 handle to elem via move");
+}
+
+function testInt8x16Reify() {
+ var Array = Int8x16.array(3);
+ var array = new Array([Int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16),
+ Int8x16(17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32),
+ Int8x16(33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48)]);
+
+ // Test that reading array[1] produces a *copy* of Int8x16, not an
+ // alias into the array.
+
+ var f = array[1];
+
+ var sj1 = Int8x16.extractLane(f, 3);
+
+ assertEq(sj1, 20);
+ assertEq(Int8x16.extractLane(array[1], 3), 20);
+ array[1] = Int8x16(49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64);
+ assertEq(Int8x16.extractLane(f, 3), 20);
+ assertEq(Int8x16.extractLane(array[1], 3), 52);
+}
+
+function testInt8x16Setters() {
+ var Array = Int8x16.array(3);
+ var array = new Array([Int8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16),
+ Int8x16(17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32),
+ Int8x16(33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48)]);
+ assertEq(Int8x16.extractLane(array[1], 3), 20);
+
+ // Test that we are allowed to write Int8x16 values into array,
+ // but not other things.
+
+ array[1] = Int8x16(49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64);
+ assertEq(Int8x16.extractLane(array[1], 3), 52);
+
+ assertThrowsInstanceOf(function() {
+ array[1] = {s0: 49, s1: 50, s2: 51, s3: 52, s4: 53, s5: 54, s6: 55, s7: 56,
+ s8: 57, s9: 58, s10: 59, s11: 60, s12: 61, s13: 62, s14: 63, s15: 64};
+ }, TypeError, "Setting Int8x16 from an object");
+
+ assertThrowsInstanceOf(function() {
+ array[1] = [49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64];
+ }, TypeError, "Setting Int8x16 from an array");
+
+ assertThrowsInstanceOf(function() {
+ array[1] = 52;
+ }, TypeError, "Setting Int8x16 from a number");
+}
+
+function testInt16x8Alignment() {
+ assertEq(Int16x8.byteLength, 16);
+ assertEq(Int16x8.byteAlignment, 16);
+
+ var Compound = new StructType({c: uint8, d: uint8, f: Int16x8});
+ assertEq(Compound.fieldOffsets.c, 0);
+ assertEq(Compound.fieldOffsets.d, 1);
+ assertEq(Compound.fieldOffsets.f, 16);
+}
+
+function testInt16x8Getters() {
+ // Create a Int16x8 and check that the getters work:
+ var f = Int16x8(11, 22, 33, 44, 55, 66, 77, 88);
+ assertEq(Int16x8.extractLane(f, 0), 11);
+ assertEq(Int16x8.extractLane(f, 1), 22);
+ assertEq(Int16x8.extractLane(f, 2), 33);
+ assertEq(Int16x8.extractLane(f, 3), 44);
+ assertEq(Int16x8.extractLane(f, 4), 55);
+ assertEq(Int16x8.extractLane(f, 5), 66);
+ assertEq(Int16x8.extractLane(f, 6), 77);
+ assertEq(Int16x8.extractLane(f, 7), 88);
+
+ assertThrowsInstanceOf(() => Int16x8.extractLane(f, 8), RangeError);
+ assertThrowsInstanceOf(() => Int16x8.extractLane(f, -1), RangeError);
+ assertThrowsInstanceOf(() => Int16x8.extractLane(f, 0.5), RangeError);
+ assertThrowsInstanceOf(() => Int16x8.extractLane(f, {}), RangeError);
+ assertThrowsInstanceOf(() => Int16x8.extractLane(Int32x4(1,2,3,4), 0), TypeError);
+ assertThrowsInstanceOf(() => Int16x8.extractLane(1, 0), TypeError);
+ assertThrowsInstanceOf(() => Int16x8.extractLane(f, f), TypeError);
+}
+
+function testInt16x8Handles() {
+ var Array = Int16x8.array(3);
+ var array = new Array([Int16x8(1, 2, 3, 4, 5, 6, 7, 8),
+ Int16x8(9, 10, 11, 12, 13, 14, 15, 16),
+ Int16x8(17, 18, 19, 20, 21, 22, 23, 24)]);
+
+ // Test that trying to create handle into the interior of a
+ // Int16x8 fails.
+ assertThrowsInstanceOf(function() {
+ var h = int16.handle(array, 1, 0);
+ }, TypeError, "Creating a int16 handle to elem via ctor");
+
+ assertThrowsInstanceOf(function() {
+ var h = int16.handle();
+ Handle.move(h, array, 1, 0);
+ }, TypeError, "Creating a int16 handle to elem via move");
+}
+
+function testInt16x8Reify() {
+ var Array = Int16x8.array(3);
+ var array = new Array([Int16x8(1, 2, 3, 4, 5, 6, 7, 8),
+ Int16x8(9, 10, 11, 12, 13, 14, 15, 16),
+ Int16x8(17, 18, 19, 20, 21, 22, 23, 24)]);
+
+ // Test that reading array[1] produces a *copy* of Int16x8, not an
+ // alias into the array.
+
+ var f = array[1];
+ assertEq(Int16x8.extractLane(f, 3), 12);
+ assertEq(Int16x8.extractLane(array[1], 3), 12);
+ array[1] = Int16x8(25, 26, 27, 28, 29, 30, 31, 32);
+ assertEq(Int16x8.extractLane(f, 3), 12);
+ assertEq(Int16x8.extractLane(array[1], 3), 28);
+}
+
+function testInt16x8Setters() {
+ var Array = Int16x8.array(3);
+ var array = new Array([Int16x8(1, 2, 3, 4, 5, 6, 7, 8),
+ Int16x8(9, 10, 11, 12, 13, 14, 15, 16),
+ Int16x8(17, 18, 19, 20, 21, 22, 23, 24)]);
+ assertEq(Int16x8.extractLane(array[1], 3), 12);
+
+ // Test that we are allowed to write Int16x8 values into array,
+ // but not other things.
+
+ array[1] = Int16x8(25, 26, 27, 28, 29, 30, 31, 32);
+ assertEq(Int16x8.extractLane(array[1], 3), 28);
+
+ assertThrowsInstanceOf(function() {
+ array[1] = {s0: 25, s1: 26, s2: 27, s3: 28, s4: 29, s5: 30, s6: 31, s7: 32};
+ }, TypeError, "Setting Int16x8 from an object");
+
+ assertThrowsInstanceOf(function() {
+ array[1] = [25, 26, 27, 28, 29, 30, 31, 32];
+ }, TypeError, "Setting Int16x8 from an array");
+
+ assertThrowsInstanceOf(function() {
+ array[1] = 28;
+ }, TypeError, "Setting Int16x8 from a number");
+}
+
+function testInt32x4Alignment() {
+ assertEq(Int32x4.byteLength, 16);
+ assertEq(Int32x4.byteAlignment, 16);
+
+ var Compound = new StructType({c: uint8, d: uint8, f: Int32x4});
+ assertEq(Compound.fieldOffsets.c, 0);
+ assertEq(Compound.fieldOffsets.d, 1);
+ assertEq(Compound.fieldOffsets.f, 16);
+}
+
+function testInt32x4Getters() {
+ // Create a Int32x4 and check that the getters work:
+ var f = Int32x4(11, 22, 33, 44);
+ assertEq(Int32x4.extractLane(f, 0), 11);
+ assertEq(Int32x4.extractLane(f, 1), 22);
+ assertEq(Int32x4.extractLane(f, 2), 33);
+ assertEq(Int32x4.extractLane(f, 3), 44);
+
+ assertThrowsInstanceOf(() => Int32x4.extractLane(f, 4), RangeError);
+ assertThrowsInstanceOf(() => Int32x4.extractLane(f, -1), RangeError);
+ assertThrowsInstanceOf(() => Int32x4.extractLane(f, 0.5), RangeError);
+ assertThrowsInstanceOf(() => Int32x4.extractLane(f, {}), RangeError);
+ assertThrowsInstanceOf(() => Int32x4.extractLane(Float32x4(1,2,3,4), 0), TypeError);
+ assertThrowsInstanceOf(() => Int32x4.extractLane(1, 0), TypeError);
+ assertThrowsInstanceOf(() => Int32x4.extractLane(f, f), TypeError);
+}
+
+function testInt32x4Handles() {
+ var Array = Int32x4.array(3);
+ var array = new Array([Int32x4(1, 2, 3, 4),
+ Int32x4(5, 6, 7, 8),
+ Int32x4(9, 10, 11, 12)]);
+
+ // Test that trying to create handle into the interior of a
+ // Int32x4 fails.
+ assertThrowsInstanceOf(function() {
+ var h = int32.handle(array, 1, 0);
+ }, TypeError, "Creating a int32 handle to elem via ctor");
+
+ assertThrowsInstanceOf(function() {
+ var h = int32.handle();
+ Handle.move(h, array, 1, 0);
+ }, TypeError, "Creating a int32 handle to elem via move");
+}
+
+function testInt32x4Reify() {
+ var Array = Int32x4.array(3);
+ var array = new Array([Int32x4(1, 2, 3, 4),
+ Int32x4(5, 6, 7, 8),
+ Int32x4(9, 10, 11, 12)]);
+
+ // Test that reading array[1] produces a *copy* of Int32x4, not an
+ // alias into the array.
+
+ var f = array[1];
+ assertEq(Int32x4.extractLane(f, 3), 8);
+ assertEq(Int32x4.extractLane(array[1], 3), 8);
+ array[1] = Int32x4(15, 16, 17, 18);
+ assertEq(Int32x4.extractLane(f, 3), 8);
+ assertEq(Int32x4.extractLane(array[1], 3), 18);
+}
+
+function testInt32x4Setters() {
+ var Array = Int32x4.array(3);
+ var array = new Array([Int32x4(1, 2, 3, 4),
+ Int32x4(5, 6, 7, 8),
+ Int32x4(9, 10, 11, 12)]);
+ assertEq(Int32x4.extractLane(array[1], 3), 8);
+
+ // Test that we are allowed to write Int32x4 values into array,
+ // but not other things.
+ array[1] = Int32x4(15, 16, 17, 18);
+ assertEq(Int32x4.extractLane(array[1], 3), 18);
+
+ assertThrowsInstanceOf(function() {
+ array[1] = {x: 15, y: 16, z: 17, w: 18};
+ }, TypeError, "Setting Int32x4 from an object");
+
+ assertThrowsInstanceOf(function() {
+ array[1] = [15, 16, 17, 18];
+ }, TypeError, "Setting Int32x4 from an array");
+
+ assertThrowsInstanceOf(function() {
+ array[1] = 22;
+ }, TypeError, "Setting Int32x4 from a number");
+}
+
+function testUint8x16Alignment() {
+ assertEq(Uint8x16.byteLength, 16);
+ assertEq(Uint8x16.byteAlignment, 16);
+
+ var Compound = new StructType({c: uint8, d: uint8, f: Uint8x16});
+ assertEq(Compound.fieldOffsets.c, 0);
+ assertEq(Compound.fieldOffsets.d, 1);
+ assertEq(Compound.fieldOffsets.f, 16);
+}
+
+function testUint8x16Getters() {
+ // Create a Uint8x16 and check that the getters work:
+ var f = Uint8x16(11, 22, 33, 44, 55, 66, 77, 88, 99, 10, 20, 30, 40, 50, 60, 70);
+ assertEq(Uint8x16.extractLane(f, 0), 11);
+ assertEq(Uint8x16.extractLane(f, 1), 22);
+ assertEq(Uint8x16.extractLane(f, 2), 33);
+ assertEq(Uint8x16.extractLane(f, 3), 44);
+ assertEq(Uint8x16.extractLane(f, 4), 55);
+ assertEq(Uint8x16.extractLane(f, 5), 66);
+ assertEq(Uint8x16.extractLane(f, 6), 77);
+ assertEq(Uint8x16.extractLane(f, 7), 88);
+ assertEq(Uint8x16.extractLane(f, 8), 99);
+ assertEq(Uint8x16.extractLane(f, 9), 10);
+ assertEq(Uint8x16.extractLane(f, 10), 20);
+ assertEq(Uint8x16.extractLane(f, 11), 30);
+ assertEq(Uint8x16.extractLane(f, 12), 40);
+ assertEq(Uint8x16.extractLane(f, 13), 50);
+ assertEq(Uint8x16.extractLane(f, 14), 60);
+ assertEq(Uint8x16.extractLane(f, 15), 70);
+
+ assertThrowsInstanceOf(() => Uint8x16.extractLane(f, 16), RangeError);
+ assertThrowsInstanceOf(() => Uint8x16.extractLane(f, -1), RangeError);
+ assertThrowsInstanceOf(() => Uint8x16.extractLane(f, 0.5), RangeError);
+ assertThrowsInstanceOf(() => Uint8x16.extractLane(f, {}), RangeError);
+ assertThrowsInstanceOf(() => Uint8x16.extractLane(Uint32x4(1,2,3,4), 0), TypeError);
+ assertThrowsInstanceOf(() => Uint8x16.extractLane(1, 0), TypeError);
+ assertThrowsInstanceOf(() => Uint8x16.extractLane(f, f), TypeError);
+}
+
+function testUint8x16Handles() {
+ var Array = Uint8x16.array(3);
+ var array = new Array([Uint8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16),
+ Uint8x16(17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32),
+ Uint8x16(33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48)]);
+
+ // Test that trying to create handle into the interior of a
+ // Uint8x16 fails.
+ assertThrowsInstanceOf(function() {
+ var h = int8.handle(array, 1, 0);
+ }, TypeError, "Creating a int8 handle to elem via ctor");
+
+ assertThrowsInstanceOf(function() {
+ var h = int8.handle();
+ Handle.move(h, array, 1, 0);
+ }, TypeError, "Creating a int8 handle to elem via move");
+}
+
+function testUint8x16Reify() {
+ var Array = Uint8x16.array(3);
+ var array = new Array([Uint8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16),
+ Uint8x16(17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32),
+ Uint8x16(33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48)]);
+
+ // Test that reading array[1] produces a *copy* of Uint8x16, not an
+ // alias into the array.
+
+ var f = array[1];
+
+ var sj1 = Uint8x16.extractLane(f, 3);
+
+ assertEq(sj1, 20);
+ assertEq(Uint8x16.extractLane(array[1], 3), 20);
+ array[1] = Uint8x16(49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64);
+ assertEq(Uint8x16.extractLane(f, 3), 20);
+ assertEq(Uint8x16.extractLane(array[1], 3), 52);
+}
+
+function testUint8x16Setters() {
+ var Array = Uint8x16.array(3);
+ var array = new Array([Uint8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16),
+ Uint8x16(17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32),
+ Uint8x16(33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48)]);
+ assertEq(Uint8x16.extractLane(array[1], 3), 20);
+
+ // Test that we are allowed to write Uint8x16 values into array,
+ // but not other things.
+
+ array[1] = Uint8x16(49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64);
+ assertEq(Uint8x16.extractLane(array[1], 3), 52);
+
+ assertThrowsInstanceOf(function() {
+ array[1] = {s0: 49, s1: 50, s2: 51, s3: 52, s4: 53, s5: 54, s6: 55, s7: 56,
+ s8: 57, s9: 58, s10: 59, s11: 60, s12: 61, s13: 62, s14: 63, s15: 64};
+ }, TypeError, "Setting Uint8x16 from an object");
+
+ assertThrowsInstanceOf(function() {
+ array[1] = [49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64];
+ }, TypeError, "Setting Uint8x16 from an array");
+
+ assertThrowsInstanceOf(function() {
+ array[1] = 52;
+ }, TypeError, "Setting Uint8x16 from a number");
+}
+
+function testUint16x8Alignment() {
+ assertEq(Uint16x8.byteLength, 16);
+ assertEq(Uint16x8.byteAlignment, 16);
+
+ var Compound = new StructType({c: uint8, d: uint8, f: Uint16x8});
+ assertEq(Compound.fieldOffsets.c, 0);
+ assertEq(Compound.fieldOffsets.d, 1);
+ assertEq(Compound.fieldOffsets.f, 16);
+}
+
+function testUint16x8Getters() {
+ // Create a Uint16x8 and check that the getters work:
+ var f = Uint16x8(11, 22, 33, 44, 55, 66, 77, 88);
+ assertEq(Uint16x8.extractLane(f, 0), 11);
+ assertEq(Uint16x8.extractLane(f, 1), 22);
+ assertEq(Uint16x8.extractLane(f, 2), 33);
+ assertEq(Uint16x8.extractLane(f, 3), 44);
+ assertEq(Uint16x8.extractLane(f, 4), 55);
+ assertEq(Uint16x8.extractLane(f, 5), 66);
+ assertEq(Uint16x8.extractLane(f, 6), 77);
+ assertEq(Uint16x8.extractLane(f, 7), 88);
+
+ assertThrowsInstanceOf(() => Uint16x8.extractLane(f, 8), RangeError);
+ assertThrowsInstanceOf(() => Uint16x8.extractLane(f, -1), RangeError);
+ assertThrowsInstanceOf(() => Uint16x8.extractLane(f, 0.5), RangeError);
+ assertThrowsInstanceOf(() => Uint16x8.extractLane(f, {}), RangeError);
+ assertThrowsInstanceOf(() => Uint16x8.extractLane(Uint32x4(1,2,3,4), 0), TypeError);
+ assertThrowsInstanceOf(() => Uint16x8.extractLane(1, 0), TypeError);
+ assertThrowsInstanceOf(() => Uint16x8.extractLane(f, f), TypeError);
+}
+
+function testUint16x8Handles() {
+ var Array = Uint16x8.array(3);
+ var array = new Array([Uint16x8(1, 2, 3, 4, 5, 6, 7, 8),
+ Uint16x8(9, 10, 11, 12, 13, 14, 15, 16),
+ Uint16x8(17, 18, 19, 20, 21, 22, 23, 24)]);
+
+ // Test that trying to create handle into the interior of a
+ // Uint16x8 fails.
+ assertThrowsInstanceOf(function() {
+ var h = int16.handle(array, 1, 0);
+ }, TypeError, "Creating a int16 handle to elem via ctor");
+
+ assertThrowsInstanceOf(function() {
+ var h = int16.handle();
+ Handle.move(h, array, 1, 0);
+ }, TypeError, "Creating a int16 handle to elem via move");
+}
+
+function testUint16x8Reify() {
+ var Array = Uint16x8.array(3);
+ var array = new Array([Uint16x8(1, 2, 3, 4, 5, 6, 7, 8),
+ Uint16x8(9, 10, 11, 12, 13, 14, 15, 16),
+ Uint16x8(17, 18, 19, 20, 21, 22, 23, 24)]);
+
+ // Test that reading array[1] produces a *copy* of Uint16x8, not an
+ // alias into the array.
+
+ var f = array[1];
+ assertEq(Uint16x8.extractLane(f, 3), 12);
+ assertEq(Uint16x8.extractLane(array[1], 3), 12);
+ array[1] = Uint16x8(25, 26, 27, 28, 29, 30, 31, 32);
+ assertEq(Uint16x8.extractLane(f, 3), 12);
+ assertEq(Uint16x8.extractLane(array[1], 3), 28);
+}
+
+function testUint16x8Setters() {
+ var Array = Uint16x8.array(3);
+ var array = new Array([Uint16x8(1, 2, 3, 4, 5, 6, 7, 8),
+ Uint16x8(9, 10, 11, 12, 13, 14, 15, 16),
+ Uint16x8(17, 18, 19, 20, 21, 22, 23, 24)]);
+ assertEq(Uint16x8.extractLane(array[1], 3), 12);
+
+ // Test that we are allowed to write Uint16x8 values into array,
+ // but not other things.
+
+ array[1] = Uint16x8(25, 26, 27, 28, 29, 30, 31, 32);
+ assertEq(Uint16x8.extractLane(array[1], 3), 28);
+
+ assertThrowsInstanceOf(function() {
+ array[1] = {s0: 25, s1: 26, s2: 27, s3: 28, s4: 29, s5: 30, s6: 31, s7: 32};
+ }, TypeError, "Setting Uint16x8 from an object");
+
+ assertThrowsInstanceOf(function() {
+ array[1] = [25, 26, 27, 28, 29, 30, 31, 32];
+ }, TypeError, "Setting Uint16x8 from an array");
+
+ assertThrowsInstanceOf(function() {
+ array[1] = 28;
+ }, TypeError, "Setting Uint16x8 from a number");
+}
+
+function testUint32x4Alignment() {
+ assertEq(Uint32x4.byteLength, 16);
+ assertEq(Uint32x4.byteAlignment, 16);
+
+ var Compound = new StructType({c: uint8, d: uint8, f: Uint32x4});
+ assertEq(Compound.fieldOffsets.c, 0);
+ assertEq(Compound.fieldOffsets.d, 1);
+ assertEq(Compound.fieldOffsets.f, 16);
+}
+
+function testUint32x4Getters() {
+ // Create a Uint32x4 and check that the getters work:
+ var f = Uint32x4(11, 22, 33, 44);
+ assertEq(Uint32x4.extractLane(f, 0), 11);
+ assertEq(Uint32x4.extractLane(f, 1), 22);
+ assertEq(Uint32x4.extractLane(f, 2), 33);
+ assertEq(Uint32x4.extractLane(f, 3), 44);
+
+ assertThrowsInstanceOf(() => Uint32x4.extractLane(f, 4), RangeError);
+ assertThrowsInstanceOf(() => Uint32x4.extractLane(f, -1), RangeError);
+ assertThrowsInstanceOf(() => Uint32x4.extractLane(f, 0.5), RangeError);
+ assertThrowsInstanceOf(() => Uint32x4.extractLane(f, {}), RangeError);
+ assertThrowsInstanceOf(() => Uint32x4.extractLane(Float32x4(1,2,3,4), 0), TypeError);
+ assertThrowsInstanceOf(() => Uint32x4.extractLane(1, 0), TypeError);
+ assertThrowsInstanceOf(() => Uint32x4.extractLane(f, f), TypeError);
+}
+
+function testUint32x4Handles() {
+ var Array = Uint32x4.array(3);
+ var array = new Array([Uint32x4(1, 2, 3, 4),
+ Uint32x4(5, 6, 7, 8),
+ Uint32x4(9, 10, 11, 12)]);
+
+ // Test that trying to create handle into the interior of a
+ // Uint32x4 fails.
+ assertThrowsInstanceOf(function() {
+ var h = int32.handle(array, 1, 0);
+ }, TypeError, "Creating a int32 handle to elem via ctor");
+
+ assertThrowsInstanceOf(function() {
+ var h = int32.handle();
+ Handle.move(h, array, 1, 0);
+ }, TypeError, "Creating a int32 handle to elem via move");
+}
+
+function testUint32x4Reify() {
+ var Array = Uint32x4.array(3);
+ var array = new Array([Uint32x4(1, 2, 3, 4),
+ Uint32x4(5, 6, 7, 8),
+ Uint32x4(9, 10, 11, 12)]);
+
+ // Test that reading array[1] produces a *copy* of Uint32x4, not an
+ // alias into the array.
+
+ var f = array[1];
+ assertEq(Uint32x4.extractLane(f, 3), 8);
+ assertEq(Uint32x4.extractLane(array[1], 3), 8);
+ array[1] = Uint32x4(15, 16, 17, 18);
+ assertEq(Uint32x4.extractLane(f, 3), 8);
+ assertEq(Uint32x4.extractLane(array[1], 3), 18);
+}
+
+function testUint32x4Setters() {
+ var Array = Uint32x4.array(3);
+ var array = new Array([Uint32x4(1, 2, 3, 4),
+ Uint32x4(5, 6, 7, 8),
+ Uint32x4(9, 10, 11, 12)]);
+ assertEq(Uint32x4.extractLane(array[1], 3), 8);
+
+ // Test that we are allowed to write Uint32x4 values into array,
+ // but not other things.
+ array[1] = Uint32x4(15, 16, 17, 18);
+ assertEq(Uint32x4.extractLane(array[1], 3), 18);
+
+ assertThrowsInstanceOf(function() {
+ array[1] = {x: 15, y: 16, z: 17, w: 18};
+ }, TypeError, "Setting Uint32x4 from an object");
+
+ assertThrowsInstanceOf(function() {
+ array[1] = [15, 16, 17, 18];
+ }, TypeError, "Setting Uint32x4 from an array");
+
+ assertThrowsInstanceOf(function() {
+ array[1] = 22;
+ }, TypeError, "Setting Uint32x4 from a number");
+}
+
+function testBool8x16Getters() {
+ // Create a Bool8x16 and check that the getters work:
+ var f = Bool8x16(true, false, true, false, true, false, true, false, true, true, false, false, true, true, false, false);
+ assertEq(Bool8x16.extractLane(f, 0), true);
+ assertEq(Bool8x16.extractLane(f, 1), false);
+ assertEq(Bool8x16.extractLane(f, 2), true);
+ assertEq(Bool8x16.extractLane(f, 3), false);
+ assertEq(Bool8x16.extractLane(f, 4), true);
+ assertEq(Bool8x16.extractLane(f, 5), false);
+ assertEq(Bool8x16.extractLane(f, 6), true);
+ assertEq(Bool8x16.extractLane(f, 7), false);
+ assertEq(Bool8x16.extractLane(f, 8), true);
+ assertEq(Bool8x16.extractLane(f, 9), true);
+ assertEq(Bool8x16.extractLane(f, 10), false);
+ assertEq(Bool8x16.extractLane(f, 11), false);
+ assertEq(Bool8x16.extractLane(f, 12), true);
+ assertEq(Bool8x16.extractLane(f, 13), true);
+ assertEq(Bool8x16.extractLane(f, 14), false);
+ assertEq(Bool8x16.extractLane(f, 15), false);
+
+ assertThrowsInstanceOf(() => Bool8x16.extractLane(f, 16), RangeError);
+ assertThrowsInstanceOf(() => Bool8x16.extractLane(f, -1), RangeError);
+ assertThrowsInstanceOf(() => Bool8x16.extractLane(f, 0.5), RangeError);
+ assertThrowsInstanceOf(() => Bool8x16.extractLane(f, {}), RangeError);
+ assertThrowsInstanceOf(() => Bool8x16.extractLane(Float32x4(1, 2, 3, 4), 0), TypeError);
+ assertThrowsInstanceOf(() => Bool8x16.extractLane(1, 0), TypeError);
+ assertThrowsInstanceOf(() => Bool8x16.extractLane(f, f), TypeError);
+}
+
+function testBool8x16Reify() {
+ var Array = Bool8x16.array(3);
+ var array = new Array([Bool8x16(true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false),
+ Bool8x16(false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true),
+ Bool8x16(true, true, true, true, false, false, false, false, true, true, true, true, false, false, false, false)]);
+
+ // Test that reading array[1] produces a *copy* of Bool8x16, not an
+ // alias into the array.
+
+ var f = array[1];
+ assertEq(Bool8x16.extractLane(f, 2), false);
+ assertEq(Bool8x16.extractLane(array[1], 2), false);
+ assertEq(Bool8x16.extractLane(f, 3), true);
+ assertEq(Bool8x16.extractLane(array[1], 3), true);
+ array[1] = Bool8x16(true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false);
+ assertEq(Bool8x16.extractLane(f, 3), true);
+ assertEq(Bool8x16.extractLane(array[1], 3), false);
+}
+
+function testBool8x16Setters() {
+ var Array = Bool8x16.array(3);
+ var array = new Array([Bool8x16(true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false),
+ Bool8x16(false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true),
+ Bool8x16(true, true, true, true, false, false, false, false, true, true, true, true, false, false, false, false)]);
+
+ assertEq(Bool8x16.extractLane(array[1], 3), true);
+ // Test that we are allowed to write Bool8x16 values into array,
+ // but not other things.
+ array[1] = Bool8x16(true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false);
+ assertEq(Bool8x16.extractLane(array[1], 3), false);
+ assertThrowsInstanceOf(function() {
+ array[1] = {s0: true, s1: true, s2: true, s3: true, s4: true, s5: true, s6: true, s7: true,
+ s8: false, s9: false, s10: false, s11: false, s12: false, s13: false, s14: false, s15: false};
+ }, TypeError, "Setting Bool8x16 from an object");
+ assertThrowsInstanceOf(function() {
+ array[1] = [true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false];
+ }, TypeError, "Setting Bool8x16 from an array");
+ assertThrowsInstanceOf(function() {
+ array[1] = false;
+ }, TypeError, "Setting Bool8x16 from a boolean");
+}
+
+function testBool16x8Getters() {
+ // Create a Bool8x16 and check that the getters work:
+ var f = Bool16x8(true, false, true, false, true, true, false, false);
+ assertEq(Bool16x8.extractLane(f, 0), true);
+ assertEq(Bool16x8.extractLane(f, 1), false);
+ assertEq(Bool16x8.extractLane(f, 2), true);
+ assertEq(Bool16x8.extractLane(f, 3), false);
+ assertEq(Bool16x8.extractLane(f, 4), true);
+ assertEq(Bool16x8.extractLane(f, 5), true);
+ assertEq(Bool16x8.extractLane(f, 6), false);
+ assertEq(Bool16x8.extractLane(f, 7), false);
+
+ assertThrowsInstanceOf(() => Bool16x8.extractLane(f, 8), RangeError);
+ assertThrowsInstanceOf(() => Bool16x8.extractLane(f, -1), RangeError);
+ assertThrowsInstanceOf(() => Bool16x8.extractLane(f, 0.5), RangeError);
+ assertThrowsInstanceOf(() => Bool16x8.extractLane(f, {}), RangeError);
+ assertThrowsInstanceOf(() => Bool16x8.extractLane(Float32x4(1, 2, 3, 4), 0), TypeError);
+ assertThrowsInstanceOf(() => Bool16x8.extractLane(1, 0), TypeError);
+ assertThrowsInstanceOf(() => Bool16x8.extractLane(f, f), TypeError);
+}
+
+function testBool16x8Reify() {
+ var Array = Bool16x8.array(3);
+ var array = new Array([Bool16x8(true, false, true, false, true, false, true, false),
+ Bool16x8(false, true, false, true, false, true, false, true),
+ Bool16x8(true, true, true, false, true, true, true, false)]);
+ // Test that reading array[1] produces a *copy* of Bool16x8, not an
+ // alias into the array.
+ var f = array[1];
+ assertEq(Bool16x8.extractLane(f, 2), false);
+ assertEq(Bool16x8.extractLane(array[1], 2), false);
+ assertEq(Bool16x8.extractLane(f, 3), true);
+ assertEq(Bool16x8.extractLane(array[1], 3), true);
+ array[1] = Bool16x8(true, false, true, false, true, false, true, false);
+ assertEq(Bool16x8.extractLane(f, 3), true);
+ assertEq(Bool16x8.extractLane(array[1], 3), false);
+}
+
+function testBool16x8Setters() {
+ var Array = Bool16x8.array(3);
+ var array = new Array([Bool16x8(true, false, true, false, true, false, true, false),
+ Bool16x8(false, true, false, true, false, true, false, true),
+ Bool16x8(true, true, true, false, true, true, true, false)]);
+
+
+ assertEq(Bool16x8.extractLane(array[1], 3), true);
+ // Test that we are allowed to write Bool16x8 values into array,
+ // but not other things.
+ array[1] = Bool16x8(true, false, true, false, true, false, true, false);
+ assertEq(Bool16x8.extractLane(array[1], 3), false);
+ assertThrowsInstanceOf(function() {
+ array[1] = {s0: false, s1: true, s2: false, s3: true, s4: false, s5: true, s6: false, s7: true};
+ }, TypeError, "Setting Bool16x8 from an object");
+ assertThrowsInstanceOf(function() {
+ array[1] = [true, false, false, true, true, true, false, false];
+ }, TypeError, "Setting Bool16x8 from an array");
+ assertThrowsInstanceOf(function() {
+ array[1] = false;
+ }, TypeError, "Setting Bool16x8 from a boolean");
+}
+
+function testBool32x4Getters() {
+ // Create a Bool32x4 and check that the getters work:
+ var f = Bool32x4(true, false, false, true);
+ assertEq(Bool32x4.extractLane(f, 0), true);
+ assertEq(Bool32x4.extractLane(f, 1), false);
+ assertEq(Bool32x4.extractLane(f, 2), false);
+ assertEq(Bool32x4.extractLane(f, 3), true);
+ assertThrowsInstanceOf(() => Bool32x4.extractLane(f, 4), RangeError);
+ assertThrowsInstanceOf(() => Bool32x4.extractLane(f, -1), RangeError);
+ assertThrowsInstanceOf(() => Bool32x4.extractLane(f, 0.5), RangeError);
+ assertThrowsInstanceOf(() => Bool32x4.extractLane(f, {}), RangeError);
+ assertThrowsInstanceOf(() => Bool32x4.extractLane(Float32x4(1, 2, 3, 4), 0), TypeError);
+ assertThrowsInstanceOf(() => Bool32x4.extractLane(1, 0), TypeError);
+ assertThrowsInstanceOf(() => Bool32x4.extractLane(f, f), TypeError);
+}
+
+function testBool32x4Reify() {
+ var Array = Bool32x4.array(3);
+ var array = new Array([Bool32x4(true, false, false, true),
+ Bool32x4(true, false, true, false),
+ Bool32x4(true, true, true, false)]);
+
+ // Test that reading array[1] produces a *copy* of Bool32x4, not an
+ // alias into the array.
+
+ var f = array[1];
+ assertEq(Bool32x4.extractLane(f, 2), true);
+ assertEq(Bool32x4.extractLane(array[1], 2), true);
+ assertEq(Bool32x4.extractLane(f, 3), false);
+ assertEq(Bool32x4.extractLane(array[1], 3), false);
+ array[1] = Bool32x4(false, true, false, true);
+ assertEq(Bool32x4.extractLane(f, 3), false);
+ assertEq(Bool32x4.extractLane(array[1], 3), true);
+}
+
+function testBool32x4Setters() {
+ var Array = Bool32x4.array(3);
+ var array = new Array([Bool32x4(true, false, false, true),
+ Bool32x4(true, false, true, false),
+ Bool32x4(true, true, true, false)]);
+
+
+ assertEq(Bool32x4.extractLane(array[1], 3), false);
+ // Test that we are allowed to write Bool32x4 values into array,
+ // but not other things.
+ array[1] = Bool32x4(false, true, false, true);
+ assertEq(Bool32x4.extractLane(array[1], 3), true);
+ assertThrowsInstanceOf(function() {
+ array[1] = {x: false, y: true, z: false, w: true};
+ }, TypeError, "Setting Bool32x4 from an object");
+ assertThrowsInstanceOf(function() {
+ array[1] = [true, false, false, true];
+ }, TypeError, "Setting Bool32x4 from an array");
+ assertThrowsInstanceOf(function() {
+ array[1] = false;
+ }, TypeError, "Setting Bool32x4 from a number");
+}
+
+function testBool64x2Getters() {
+ // Create a Bool64x2 and check that the getters work:
+ var f = Bool64x2(true, false);
+ assertEq(Bool64x2.extractLane(f, 0), true);
+ assertEq(Bool64x2.extractLane(f, 1), false);
+
+ assertThrowsInstanceOf(() => Bool64x2.extractLane(f, 2), RangeError);
+ assertThrowsInstanceOf(() => Bool64x2.extractLane(f, -1), RangeError);
+ assertThrowsInstanceOf(() => Bool64x2.extractLane(f, 0.5), RangeError);
+ assertThrowsInstanceOf(() => Bool64x2.extractLane(f, {}), RangeError);
+ assertThrowsInstanceOf(() => Bool64x2.extractLane(Bool32x4(1,2,3,4), 0), TypeError);
+ assertThrowsInstanceOf(() => Bool64x2.extractLane(1, 0), TypeError);
+ assertThrowsInstanceOf(() => Bool64x2.extractLane(f, f), TypeError);
+}
+
+function testBool64x2Reify() {
+ var Array = Bool64x2.array(3);
+ var array = new Array([Bool64x2(true, false),
+ Bool64x2(false, true),
+ Bool64x2(true, true)]);
+
+ // Test that reading array[1] produces a *copy* of Bool64x2, not an
+ // alias into the array.
+
+ var f = array[1];
+ assertEq(Bool64x2.extractLane(f, 1), true);
+ assertEq(Bool64x2.extractLane(array[1], 1), true);
+ array[1] = Bool64x2(false, false);
+ assertEq(Bool64x2.extractLane(f, 1), true);
+ assertEq(Bool64x2.extractLane(array[1], 1), false);
+}
+
+function testBool64x2Setters() {
+ var Array = Bool64x2.array(3);
+ var array = new Array([Bool64x2(true, false),
+ Bool64x2(false, true),
+ Bool64x2(true, true)]);
+ assertEq(Bool64x2.extractLane(array[1], 1), true);
+
+ // Test that we are allowed to write Bool64x2 values into array,
+ // but not other things.
+
+ array[1] = Bool64x2(false, false);
+ assertEq(Bool64x2.extractLane(array[1], 1), false);
+
+ assertThrowsInstanceOf(function() {
+ array[1] = {x: false, y: false };
+ }, TypeError, "Setting Bool64x2 from an object");
+
+ assertThrowsInstanceOf(function() {
+ array[1] = [ false, false ];
+ }, TypeError, "Setting Bool64x2 from an array");
+
+ assertThrowsInstanceOf(function() {
+ array[1] = 9;
+ }, TypeError, "Setting Bool64x2 from a number");
+}
+
+
+function test() {
+
+ testFloat32x4Alignment();
+ testFloat32x4Getters();
+ testFloat32x4Handles();
+ testFloat32x4Reify();
+ testFloat32x4Setters();
+
+ testFloat64x2Alignment();
+ testFloat64x2Getters();
+ testFloat64x2Handles();
+ testFloat64x2Reify();
+ testFloat64x2Setters();
+
+ testInt8x16Alignment();
+ testInt8x16Getters();
+ testInt8x16Handles();
+ testInt8x16Reify();
+ testInt8x16Setters();
+
+ testInt16x8Alignment();
+ testInt16x8Getters();
+ testInt16x8Handles();
+ testInt16x8Reify();
+ testInt16x8Setters();
+
+ testInt32x4Alignment();
+ testInt32x4Getters();
+ testInt32x4Handles();
+ testInt32x4Reify();
+ testInt32x4Setters();
+
+ testUint8x16Alignment();
+ testUint8x16Getters();
+ testUint8x16Handles();
+ testUint8x16Reify();
+ testUint8x16Setters();
+
+ testUint16x8Alignment();
+ testUint16x8Getters();
+ testUint16x8Handles();
+ testUint16x8Reify();
+ testUint16x8Setters();
+
+ testUint32x4Alignment();
+ testUint32x4Getters();
+ testUint32x4Handles();
+ testUint32x4Reify();
+ testUint32x4Setters();
+
+ testBool8x16Getters();
+ testBool8x16Reify();
+ testBool8x16Setters();
+
+ testBool16x8Getters();
+ testBool16x8Reify();
+ testBool16x8Setters();
+
+ testBool32x4Getters();
+ testBool32x4Reify();
+ testBool32x4Setters();
+
+ testBool64x2Getters();
+ testBool64x2Reify();
+ testBool64x2Setters();
+
+ if (typeof reportCompare === "function") {
+ reportCompare(true, true);
+ }
+}
+
+test();
diff --git a/js/src/tests/ecma_7/SIMD/unary-operations.js b/js/src/tests/ecma_7/SIMD/unary-operations.js
new file mode 100644
index 000000000..b04d23874
--- /dev/null
+++ b/js/src/tests/ecma_7/SIMD/unary-operations.js
@@ -0,0 +1,410 @@
+// |reftest| skip-if(!this.hasOwnProperty("SIMD"))
+var Float32x4 = SIMD.Float32x4;
+var Int8x16 = SIMD.Int8x16;
+var Int16x8 = SIMD.Int16x8;
+var Int32x4 = SIMD.Int32x4;
+var Uint8x16 = SIMD.Uint8x16;
+var Uint16x8 = SIMD.Uint16x8;
+var Uint32x4 = SIMD.Uint32x4;
+var Bool8x16 = SIMD.Bool8x16;
+var Bool16x8 = SIMD.Bool16x8;
+var Bool32x4 = SIMD.Bool32x4;
+var Bool64x2 = SIMD.Bool64x2;
+
+function testFloat32x4abs() {
+ function absf(a) {
+ return Math.abs(Math.fround(a));
+ }
+
+ var vals = [
+ [-1, 2, -3, 4],
+ [-1.63, 2.46, -3.17, 4.94],
+ [NaN, -0, Infinity, -Infinity]
+ ];
+ for (var v of vals) {
+ assertEqX4(Float32x4.abs(Float32x4(...v)), v.map(absf));
+ }
+}
+
+function testFloat32x4neg() {
+ function negf(a) {
+ return -1 * Math.fround(a);
+ }
+
+ var vals = [
+ [1, 2, 3, 4],
+ [0.999, -0.001, 3.78, 4.05],
+ [NaN, -0, Infinity, -Infinity]
+ ];
+ for (var v of vals) {
+ assertEqX4(Float32x4.neg(Float32x4(...v)), v.map(negf));
+ }
+}
+
+function testFloat32x4reciprocalApproximation() {
+ function reciprocalf(a) {
+ return Math.fround(1 / Math.fround(a));
+ }
+
+ var vals = [
+ [[1, 0.5, 0.25, 0.125], [1, 2, 4, 8]],
+ [[1.6, 0.8, 0.4, 0.2], [1.6, 0.8, 0.4, 0.2].map(reciprocalf)],
+ [[NaN, -0, Infinity, -Infinity], [NaN, -Infinity, 0, -0]]
+ ];
+
+ for (var [v,w] of vals) {
+ assertEqX4(Float32x4.reciprocalApproximation(Float32x4(...v)), w);
+ }
+}
+
+function testFloat32x4reciprocalSqrtApproximation() {
+ function reciprocalsqrtf(a) {
+ assertEq(Math.fround(a), a);
+ return Math.fround(1 / Math.fround(Math.sqrt(a)));
+ }
+
+ var vals = [
+ [[1, 1, 0.25, 0.25], [1, 1, 2, 2]],
+ [[25, 16, 6.25, 1.5625], [25, 16, 6.25, 1.5625].map(reciprocalsqrtf)],
+ [[NaN, -0, Infinity, -Infinity], [NaN, -0, Infinity, -Infinity].map(reciprocalsqrtf)],
+ [[Math.pow(2, 32), Math.pow(2, -32), +0, Math.pow(2, -148)],
+ [Math.pow(2, -16), Math.pow(2, 16), Infinity, Math.pow(2, 74)]]
+ ];
+
+ for (var [v,w] of vals) {
+ assertEqX4(Float32x4.reciprocalSqrtApproximation(Float32x4(...v)), w);
+ }
+}
+
+function testFloat32x4sqrt() {
+ function sqrtf(a) {
+ return Math.fround(Math.sqrt(Math.fround(a)));
+ }
+
+ var vals = [
+ [[1, 4, 9, 16], [1, 2, 3, 4]],
+ [[2.7225, 7.3441, 9.4249, -1], [2.7225, 7.3441, 9.4249, -1].map(sqrtf)],
+ [[NaN, -0, Infinity, -Infinity], [NaN, -0, Infinity, NaN]]
+ ];
+
+ for (var [v,w] of vals) {
+ assertEqX4(Float32x4.sqrt(Float32x4(...v)), w);
+ }
+}
+
+function testInt8x16neg() {
+ var vals = [
+ [[1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4, -5, INT8_MAX, INT8_MIN, 0],
+ [-1, -2, -3, -4, -5, -6, -7, -8, 1, 2, 3, 4, 5, -INT8_MAX, INT8_MIN, 0]]
+ ];
+ for (var [v,w] of vals) {
+ assertEqX16(Int8x16.neg(Int8x16(...v)), w);
+ }
+}
+
+function testInt8x16not() {
+ var vals = [
+ [[1, 2, 3, 4, 5, 6, 7, -1, -2, -3, -4, -5, -6, 0, INT8_MIN, INT8_MAX],
+ [1, 2, 3, 4, 5, 6, 7, -1, -2, -3, -4, -5, -6, 0, INT8_MIN, INT8_MAX].map((x) => ~x << 24 >> 24)]
+ ];
+ for (var [v,w] of vals) {
+ assertEqX16(Int8x16.not(Int8x16(...v)), w);
+ }
+}
+
+function testInt16x8neg() {
+ var vals = [
+ [[1, 2, 3, -1, -2, 0, INT16_MIN, INT16_MAX],
+ [-1, -2, -3, 1, 2, 0, INT16_MIN, -INT16_MAX]]
+ ];
+ for (var [v,w] of vals) {
+ assertEqX8(Int16x8.neg(Int16x8(...v)), w);
+ }
+}
+
+function testInt16x8not() {
+ var vals = [
+ [[1, 2, 3, -1, -2, 0, INT16_MIN, INT16_MAX],
+ [1, 2, 3, -1, -2, 0, INT16_MIN, INT16_MAX].map((x) => ~x << 16 >> 16)]
+ ];
+ for (var [v,w] of vals) {
+ assertEqX8(Int16x8.not(Int16x8(...v)), w);
+ }
+}
+
+function testInt32x4neg() {
+ var valsExp = [
+ [[1, 2, 3, 4], [-1, -2, -3, -4]],
+ [[INT32_MAX, INT32_MIN, -0, 0], [-INT32_MAX | 0, -INT32_MIN | 0, 0, 0]]
+ ];
+ for (var [v,w] of valsExp) {
+ assertEqX4(Int32x4.neg(Int32x4(...v)), w);
+ }
+}
+
+function testInt32x4not() {
+ var valsExp = [
+ [[1, 2, 3, 4], [-2, -3, -4, -5]],
+ [[INT32_MAX, INT32_MIN, 0, 0], [~INT32_MAX | 0, ~INT32_MIN | 0, ~0 | 0, ~0 | 0]]
+ ];
+ for (var [v,w] of valsExp) {
+ assertEqX4(Int32x4.not(Int32x4(...v)), w);
+ }
+}
+
+function testUint8x16neg() {
+ var vals = [
+ [[ 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, UINT8_MAX, INT8_MAX, 0, 0],
+ [255, 254, 253, 252, 251, 250, 249, 0, 1, 2, 3, 4, 1, INT8_MAX+2, 0, 0]]
+ ];
+ for (var [v,w] of vals) {
+ assertEqX16(Uint8x16.neg(Uint8x16(...v)), w);
+ }
+}
+
+function testUint8x16not() {
+ var vals = [
+ [[1, 2, 3, 4, 5, 6, 7, -1, -2, -3, -4, -5, -6, 0, INT8_MIN, INT8_MAX],
+ [1, 2, 3, 4, 5, 6, 7, -1, -2, -3, -4, -5, -6, 0, INT8_MIN, INT8_MAX].map((x) => ~x << 24 >>> 24)]
+ ];
+ for (var [v,w] of vals) {
+ assertEqX16(Uint8x16.not(Uint8x16(...v)), w);
+ }
+}
+
+function testUint16x8neg() {
+ var vals = [
+ [[1, 2, UINT16_MAX, -1, -2, 0, INT16_MIN, INT16_MAX],
+ [1, 2, UINT16_MAX, -1, -2, 0, INT16_MIN, INT16_MAX].map((x) => -x << 16 >>> 16)]
+ ];
+ for (var [v,w] of vals) {
+ assertEqX8(Uint16x8.neg(Uint16x8(...v)), w);
+ }
+}
+
+function testUint16x8not() {
+ var vals = [
+ [[1, 2, UINT16_MAX, -1, -2, 0, INT16_MIN, INT16_MAX],
+ [1, 2, UINT16_MAX, -1, -2, 0, INT16_MIN, INT16_MAX].map((x) => ~x << 16 >>> 16)]
+ ];
+ for (var [v,w] of vals) {
+ assertEqX8(Uint16x8.not(Uint16x8(...v)), w);
+ }
+}
+
+function testUint32x4neg() {
+ var valsExp = [
+ [[1, 2, 3, 4], [-1 >>> 0, -2 >>> 0, -3 >>> 0, -4 >>> 0]],
+ [[INT32_MAX, INT32_MIN, -0, 0], [-INT32_MAX >>> 0, -INT32_MIN >>> 0, 0, 0]]
+ ];
+ for (var [v,w] of valsExp) {
+ assertEqX4(Uint32x4.neg(Uint32x4(...v)), w);
+ }
+}
+
+function testUint32x4not() {
+ var valsExp = [
+ [[1, 2, 3, 4], [~1 >>> 0, ~2 >>> 0, ~3 >>> 0, ~4 >>> 0]],
+ [[INT32_MAX, INT32_MIN, UINT32_MAX, 0], [~INT32_MAX >>> 0, ~INT32_MIN >>> 0, 0, ~0 >>> 0]]
+ ];
+ for (var [v,w] of valsExp) {
+ assertEqX4(Uint32x4.not(Uint32x4(...v)), w);
+ }
+}
+
+function testBool8x16not() {
+ var valsExp = [
+ [[true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false],
+ [false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true]],
+ [[true, true, false, false, true, true, false, false, true, true, false, false, true, true, false, false],
+ [false, false, true, true, false, false, true, true, false, false, true, true, false, false, true, true]]
+ ];
+ for (var [v,w] of valsExp) {
+ assertEqX16(Bool8x16.not(Bool8x16(...v)), w);
+ }
+}
+
+function testBool8x16allTrue() {
+ var valsExp = [
+ [[false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false], false],
+ [[true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true], true],
+ [[false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true], false],
+ [[true, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true], false],
+ [[true, false, true, true, true, true, true, true, true, true, true, true, true, true, false, true], false],
+ [[true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false], false],
+ ];
+ for (var [v,w] of valsExp) {
+ assertEq(Bool8x16.allTrue(Bool8x16(...v)), w);
+ }
+}
+
+function testBool8x16anyTrue() {
+ var valsExp = [
+ [[false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false], false],
+ [[true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true], true],
+ [[false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true], true],
+ [[true, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true], true],
+ [[true, false, true, true, true, true, true, true, true, true, true, true, true, true, false, true], true],
+ [[true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false], true],
+ ];
+ for (var [v,w] of valsExp) {
+ assertEq(Bool8x16.anyTrue(Bool8x16(...v)), w);
+ }
+}
+
+function testBool16x8not() {
+ var valsExp = [
+ [[true, false, true, false, true, false, true, false], [false, true, false, true, false, true, false, true]],
+ [[true, true, false, false, true, true, false, false], [false, false, true, true, false, false, true, true]]
+ ];
+ for (var [v,w] of valsExp) {
+ assertEqX8(Bool16x8.not(Bool16x8(...v)), w);
+ }
+}
+
+function testBool16x8allTrue() {
+ var valsExp = [
+ [[false, false, false, false, false, false, false, false], false],
+ [[true, true, true, true, true, true, true, true], true],
+ [[false, true, true, true, true, true, true, true], false],
+ [[true, false, true, true, true, true, true, true], false],
+ [[true, true, true, true, true, true, false, true], false],
+ [[true, true, true, true, true, true, true, false], false],
+ ];
+ for (var [v,w] of valsExp) {
+ assertEq(Bool16x8.allTrue(Bool16x8(...v)), w);
+ }
+}
+
+function testBool16x8anyTrue() {
+ var valsExp = [
+ [[false, false, false, false, false, false, false, false], false],
+ [[true, true, true, true, true, true, true, true], true],
+ [[false, false, false, false, false, false, false, true], true],
+ [[false, false, false, false, false, false, true, false], true],
+ [[false, true, false, false, false, false, false, true], true],
+ [[true, false, false, false, false, false, false, false], true],
+ ];
+ for (var [v,w] of valsExp) {
+ assertEq(Bool16x8.anyTrue(Bool16x8(...v)), w);
+ }
+}
+
+function testBool32x4not() {
+ var valsExp = [
+ [[true, false, true, false], [false, true, false, true]],
+ [[true, true, false, false], [false, false, true, true]]
+ ];
+ for (var [v,w] of valsExp) {
+ assertEqX4(Bool32x4.not(Bool32x4(...v)), w);
+ }
+}
+
+function testBool32x4allTrue() {
+ var valsExp = [
+ [[false, false, false, false], false],
+ [[true, false, true, false], false],
+ [[true, true, true, true], true],
+ [[true, true, false, false], false]
+ ];
+ for (var [v,w] of valsExp) {
+ assertEq(Bool32x4.allTrue(Bool32x4(...v)), w);
+ }
+}
+
+function testBool32x4anyTrue() {
+ var valsExp = [
+ [[false, false, false, false], false],
+ [[true, false, true, false], true],
+ [[true, true, true, true], true],
+ [[true, true, false, false], true]
+ ];
+ for (var [v,w] of valsExp) {
+ assertEq(Bool32x4.anyTrue(Bool32x4(...v)), w);
+ }
+}
+
+function testBool64x2not() {
+ var valsExp = [
+ [[false, false], [true, true]],
+ [[false, true], [true, false]],
+ [[true, false], [false, true]],
+ [[true, true], [false, false]]
+ ];
+ for (var [v,w] of valsExp) {
+ assertEqX2(Bool64x2.not(Bool64x2(...v)), w);
+ }
+}
+
+function testBool64x2allTrue() {
+ var valsExp = [
+ [[false, false], false],
+ [[false, true], false],
+ [[true, false], false],
+ [[true, true], true]
+ ];
+ for (var [v,w] of valsExp) {
+ assertEq(Bool64x2.allTrue(Bool64x2(...v)), w);
+ }
+}
+
+function testBool64x2anyTrue() {
+ var valsExp = [
+ [[false, false], false],
+ [[false, true], true],
+ [[true, false], true],
+ [[true, true], true]
+ ];
+ for (var [v,w] of valsExp) {
+ assertEq(Bool64x2.anyTrue(Bool64x2(...v)), w);
+ }
+}
+
+function test() {
+ testFloat32x4abs();
+ testFloat32x4neg();
+ testFloat32x4reciprocalApproximation();
+ testFloat32x4reciprocalSqrtApproximation();
+ testFloat32x4sqrt();
+
+ testInt8x16neg();
+ testInt8x16not();
+
+ testInt16x8neg();
+ testInt16x8not();
+
+ testInt32x4neg();
+ testInt32x4not();
+
+ testUint8x16neg();
+ testUint8x16not();
+
+ testUint16x8neg();
+ testUint16x8not();
+
+ testUint32x4neg();
+ testUint32x4not();
+
+ testBool8x16not();
+ testBool8x16allTrue();
+ testBool8x16anyTrue();
+
+ testBool16x8not();
+ testBool16x8allTrue();
+ testBool16x8anyTrue();
+
+ testBool32x4not();
+ testBool32x4allTrue();
+ testBool32x4anyTrue();
+
+ testBool64x2not();
+ testBool64x2allTrue();
+ testBool64x2anyTrue();
+
+
+ if (typeof reportCompare === "function") {
+ reportCompare(true, true);
+ }
+}
+
+test();
diff --git a/js/src/tests/ecma_7/String/shell.js b/js/src/tests/ecma_7/String/shell.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/js/src/tests/ecma_7/String/shell.js
diff --git a/js/src/tests/ecma_7/String/string-pad-start-end.js b/js/src/tests/ecma_7/String/string-pad-start-end.js
new file mode 100644
index 000000000..d784c83e0
--- /dev/null
+++ b/js/src/tests/ecma_7/String/string-pad-start-end.js
@@ -0,0 +1,99 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+// `this` must be object coercable.
+
+for (let badThis of [null, undefined]) {
+ assertThrowsInstanceOf(() => {
+ String.prototype.padStart.call(badThis, 42, "oups");
+ }, TypeError);
+
+ assertThrowsInstanceOf(() => {
+ String.prototype.padEnd.call(badThis, 42, "oups");
+ }, TypeError);
+}
+
+let proxy = new Proxy({}, {
+get(t, name) {
+ if (name === Symbol.toPrimitive || name === "toString") return;
+ if (name === "valueOf") return () => 42;
+ throw "This should not be reachable";
+}
+});
+
+assertEq("42bloop", String.prototype.padEnd.call(proxy, 7, "bloopie"));
+
+// maxLength must convert to an integer
+
+assertEq("lame", "lame".padStart(0, "foo"));
+assertEq("lame", "lame".padStart(0.1119, "foo"));
+assertEq("lame", "lame".padStart(-0, "foo"));
+assertEq("lame", "lame".padStart(NaN, "foo"));
+assertEq("lame", "lame".padStart(-1, "foo"));
+assertEq("lame", "lame".padStart({toString: () => 0}, "foo"));
+
+assertEq("lame", "lame".padEnd(0, "foo"));
+assertEq("lame", "lame".padEnd(0.1119, "foo"));
+assertEq("lame", "lame".padEnd(-0, "foo"));
+assertEq("lame", "lame".padEnd(NaN, "foo"));
+assertEq("lame", "lame".padEnd(-1, "foo"));
+assertEq("lame", "lame".padEnd({toString: () => 0}, "foo"));
+
+assertThrowsInstanceOf(() => {
+ "lame".padStart(Symbol("9900"), 0);
+}, TypeError);
+
+assertThrowsInstanceOf(() => {
+ "lame".padEnd(Symbol("9900"), 0);
+}, TypeError);
+
+// The fill argument must be string coercable.
+
+assertEq("nulln.", ".".padStart(6, null));
+assertEq(".nulln", ".".padEnd(6, null));
+
+assertEq("[obje.", ".".padStart(6, {}));
+assertEq(".[obje", ".".padEnd(6, {}));
+
+assertEq("1,2,3.", ".".padStart(6, [1, 2, 3]));
+assertEq(".1,2,3", ".".padEnd(6, [1, 2, 3]));
+
+assertEq("aaaaa.", ".".padStart(6, {toString: () => "a"}));
+assertEq(".aaaaa", ".".padEnd(6, {toString: () => "a"}));
+
+// undefined is converted to " "
+
+assertEq(" .", ".".padStart(6, undefined));
+assertEq(". ", ".".padEnd(6, undefined));
+
+assertEq(" .", ".".padStart(6));
+assertEq(". ", ".".padEnd(6));
+
+// The empty string has no effect
+
+assertEq("Tilda", "Tilda".padStart(100000, ""));
+assertEq("Tilda", "Tilda".padEnd(100000, ""));
+
+assertEq("Tilda", "Tilda".padStart(100000, {toString: () => ""}));
+assertEq("Tilda", "Tilda".padEnd(100000, {toString: () => ""}));
+
+// Test repetition against a bruteforce implementation
+
+let filler = "space";
+let truncatedFiller = "";
+for (let i = 0; i < 2500; i++) {
+ truncatedFiller += filler[i % filler.length];
+ assertEq(truncatedFiller + "goto", "goto".padStart(5 + i, filler));
+ assertEq("goto" + truncatedFiller, "goto".padEnd(5 + i, filler));
+}
+
+// [Argument] Length
+
+assertEq(1, String.prototype.padStart.length)
+assertEq(1, String.prototype.padEnd.length)
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
diff --git a/js/src/tests/ecma_7/Syntax/browser.js b/js/src/tests/ecma_7/Syntax/browser.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/js/src/tests/ecma_7/Syntax/browser.js
diff --git a/js/src/tests/ecma_7/Syntax/non-simple-with-strict-directive.js b/js/src/tests/ecma_7/Syntax/non-simple-with-strict-directive.js
new file mode 100644
index 000000000..a0e536687
--- /dev/null
+++ b/js/src/tests/ecma_7/Syntax/non-simple-with-strict-directive.js
@@ -0,0 +1,140 @@
+/* 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/. */
+
+const testCases = [
+ // Array destructuring.
+ "[]",
+ "[a]",
+ "x, [a]",
+ "[a], x",
+
+ // Array destructuring with defaults.
+ "[a = 0]",
+ "x, [a = 0]",
+ "[a = 0], x",
+
+ // Array destructuring with rest binding identifier.
+ "[...a]",
+ "x, [...a]",
+ "[...a], x",
+
+ // Array destructuring with rest binding pattern.
+ "[...[a]]",
+ "x, [...[a]]",
+ "[...[a]], x",
+
+ // Object destructuring.
+ "{}",
+ "{p: o}",
+ "x, {p: o}",
+ "{p: o}, x",
+
+ // Object destructuring with defaults.
+ "{p: o = 0}",
+ "x, {p: o = 0}",
+ "{p: o = 0}, x",
+
+ // Object destructuring with shorthand identifier form.
+ "{o}",
+ "x, {o}",
+ "{o}, x",
+
+ // Object destructuring with CoverInitName.
+ "{o = 0}",
+ "x, {o = 0}",
+ "{o = 0}, x",
+
+ // Default parameter.
+ "d = 0",
+ "x, d = 0",
+ "d = 0, x",
+
+ // Rest parameter.
+ "...rest",
+ "x, ...rest",
+
+ // Rest parameter with array destructuring.
+ "...[]",
+ "...[a]",
+ "x, ...[]",
+ "x, ...[a]",
+
+ // Rest parameter with object destructuring.
+ "...{}",
+ "...{p: o}",
+ "x, ...{}",
+ "x, ...{p: o}",
+
+ // All non-simple cases combined.
+ "x, d = 123, [a], {p: 0}, ...rest",
+];
+
+const GeneratorFunction = function*(){}.constructor;
+
+const functionDefinitions = [
+ // FunctionDeclaration
+ parameters => `function f(${parameters}) { "use strict"; }`,
+
+ // FunctionExpression
+ parameters => `void function(${parameters}) { "use strict"; };`,
+ parameters => `void function f(${parameters}) { "use strict"; };`,
+
+ // Function constructor
+ parameters => `Function('${parameters}', '"use strict";')`,
+
+ // GeneratorDeclaration
+ parameters => `function* g(${parameters}) { "use strict"; }`,
+
+ // GeneratorExpression
+ parameters => `void function*(${parameters}) { "use strict"; };`,
+ parameters => `void function* g(${parameters}) { "use strict"; };`,
+
+ // GeneratorFunction constructor
+ parameters => `GeneratorFunction('${parameters}', '"use strict";')`,
+
+ // MethodDefinition
+ parameters => `({ m(${parameters}) { "use strict"; } });`,
+ parameters => `(class { m(${parameters}) { "use strict"; } });`,
+ parameters => `class C { m(${parameters}) { "use strict"; } }`,
+
+ // MethodDefinition (constructors)
+ parameters => `(class { constructor(${parameters}) { "use strict"; } });`,
+ parameters => `class C { constructor(${parameters}) { "use strict"; } }`,
+
+ // MethodDefinition (getter)
+ parameters => `({ get m(${parameters}) { "use strict"; } });`,
+ parameters => `(class { get m(${parameters}) { "use strict"; } });`,
+ parameters => `class C { get m(${parameters}) { "use strict"; } }`,
+
+ // MethodDefinition (setter)
+ parameters => `({ set m(${parameters}) { "use strict"; } });`,
+ parameters => `(class { set m(${parameters}) { "use strict"; } });`,
+ parameters => `class C { set m(${parameters}) { "use strict"; } }`,
+
+ // GeneratorMethod
+ parameters => `({ *m(${parameters}) { "use strict"; } });`,
+ parameters => `(class { *m(${parameters}) { "use strict"; } });`,
+ parameters => `class C { *m(${parameters}) { "use strict"; } }`,
+
+ // ArrowFunction
+ parameters => `(${parameters}) => { "use strict"; };`,
+];
+
+for (let nonSimpleParameters of testCases) {
+ for (let def of functionDefinitions) {
+ // Non-strict script code.
+ assertThrowsInstanceOf(() => eval(`
+ ${def(nonSimpleParameters)}
+ `), SyntaxError, def(nonSimpleParameters));
+
+ // Strict script code.
+ assertThrowsInstanceOf(() => eval(`
+ "use strict";
+ ${def(nonSimpleParameters)}
+ `), SyntaxError, `"use strict"; ${def(nonSimpleParameters)}`);
+ }
+}
+
+if (typeof reportCompare === 'function')
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_7/Syntax/shell.js b/js/src/tests/ecma_7/Syntax/shell.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/js/src/tests/ecma_7/Syntax/shell.js
diff --git a/js/src/tests/ecma_7/TypedArray/browser.js b/js/src/tests/ecma_7/TypedArray/browser.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedArray/browser.js
diff --git a/js/src/tests/ecma_7/TypedArray/filter-validation.js b/js/src/tests/ecma_7/TypedArray/filter-validation.js
new file mode 100644
index 000000000..450b4fa2c
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedArray/filter-validation.js
@@ -0,0 +1,185 @@
+/* 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/. */
+
+// Summary: Ensure typed array validation is called for TypedArray.prototype.filter.
+
+const otherGlobal = typeof newGlobal === "function" ? newGlobal() : undefined;
+const typedArrayLengths = [0, 1, 1024];
+
+function createTestCases(TAConstructor, constructor, constructorCrossRealm) {
+ let testCases = [];
+ testCases.push({
+ species: constructor,
+ method: TAConstructor.prototype.filter,
+ error: TypeError,
+ });
+ if (otherGlobal) {
+ testCases.push({
+ species: constructorCrossRealm,
+ method: TAConstructor.prototype.filter,
+ error: TypeError,
+ });
+ testCases.push({
+ species: constructor,
+ method: otherGlobal[TAConstructor.name].prototype.filter,
+ error: otherGlobal.TypeError,
+ });
+ }
+ return testCases;
+}
+
+// Throws TypeError when the returned value is not a typed array.
+for (const TAConstructor of anyTypedArrayConstructors) {
+ let callCount = 0, expectedCallCount = 0;
+ function NoTypedArrayConstructor(...args) {
+ let a = [];
+ callCount += 1;
+ return a;
+ }
+ function NoTypedArrayConstructorCrossRealm(...args) {
+ let a = new otherGlobal.Array();
+ callCount += 1;
+ return a;
+ }
+ let testCases = createTestCases(TAConstructor, NoTypedArrayConstructor, NoTypedArrayConstructorCrossRealm);
+
+ for (let {species, method, error} of testCases) {
+ for (let length of typedArrayLengths) {
+ let ta = new TAConstructor(length);
+ ta.constructor = {[Symbol.species]: species};
+ assertThrowsInstanceOf(() => method.call(ta, () => true), error);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+
+ for (let {species, method, error} of testCases) {
+ for (let length of typedArrayLengths) {
+ let ta = new TAConstructor(length);
+ ta.constructor = {[Symbol.species]: species};
+ assertThrowsInstanceOf(() => method.call(ta, () => false), error);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+}
+
+// Throws TypeError exception when returned array is too small.
+for (const TAConstructor of anyTypedArrayConstructors) {
+ let callCount = 0, expectedCallCount = 0;
+ function TooSmallConstructor(length) {
+ let a = new TAConstructor(Math.max(length - 1, 0));
+ callCount += 1;
+ return a;
+ }
+ function TooSmallConstructorCrossRealm(length) {
+ let a = new otherGlobal[TAConstructor.name](Math.max(length - 1, 0));
+ callCount += 1;
+ return a;
+ }
+ let testCases = createTestCases(TAConstructor, TooSmallConstructor, TooSmallConstructorCrossRealm);
+
+ for (let {species, method, error} of testCases) {
+ for (let length of typedArrayLengths) {
+ let ta = new TAConstructor(length);
+ ta.constructor = {[Symbol.species]: species};
+
+ // Passes when the length is zero.
+ if (length === 0) {
+ let result = method.call(ta, () => true);
+ assertEq(result.length, 0);
+ } else {
+ assertThrowsInstanceOf(() => method.call(ta, () => true), error);
+ }
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+
+ for (let {species, method, error} of testCases) {
+ for (let length of typedArrayLengths) {
+ let ta = new TAConstructor(length);
+ ta.constructor = {[Symbol.species]: species};
+ let result = method.call(ta, () => false);
+ assertEq(result.length, 0);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+}
+
+// No exception when array is larger than requested.
+for (const TAConstructor of anyTypedArrayConstructors) {
+ const extraLength = 1;
+
+ let callCount = 0, expectedCallCount = 0;
+ function TooLargeConstructor(length) {
+ let a = new TAConstructor(length + extraLength);
+ callCount += 1;
+ return a;
+ }
+ function TooLargeConstructorCrossRealm(length) {
+ let a = new otherGlobal[TAConstructor.name](length + extraLength);
+ callCount += 1;
+ return a;
+ }
+ let testCases = createTestCases(TAConstructor, TooLargeConstructor, TooLargeConstructorCrossRealm);
+
+ for (let {species, method, error} of testCases) {
+ for (let length of typedArrayLengths) {
+ let ta = new TAConstructor(length);
+ ta.constructor = {[Symbol.species]: species};
+ let result = method.call(ta, () => true);
+ assertEq(result.length, length + extraLength);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+
+ for (let {species, method, error} of testCases) {
+ for (let length of typedArrayLengths) {
+ let ta = new TAConstructor(length);
+ ta.constructor = {[Symbol.species]: species};
+ let result = method.call(ta, () => false);
+ assertEq(result.length, extraLength);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+}
+
+// Throws TypeError exception when returned array is detached.
+if (typeof detachArrayBuffer === "function") {
+ for (const TAConstructor of typedArrayConstructors) {
+ let callCount = 0, expectedCallCount = 0;
+ function DetachConstructor(...args) {
+ let a = new TAConstructor(...args);
+ detachArrayBuffer(a.buffer);
+ callCount += 1;
+ return a;
+ }
+ function DetachConstructorCrossRealm(...args) {
+ let a = new otherGlobal[TAConstructor.name](...args);
+ otherGlobal.detachArrayBuffer(a.buffer);
+ callCount += 1;
+ return a;
+ }
+ let testCases = createTestCases(TAConstructor, DetachConstructor, DetachConstructorCrossRealm);
+
+ for (let {species, method, error} of testCases) {
+ for (let length of typedArrayLengths) {
+ let ta = new TAConstructor(length);
+ ta.constructor = {[Symbol.species]: species};
+ assertThrowsInstanceOf(() => method.call(ta, () => true), error);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+
+ for (let {species, method, error} of testCases) {
+ for (let length of typedArrayLengths) {
+ let ta = new TAConstructor(length);
+ ta.constructor = {[Symbol.species]: species};
+ assertThrowsInstanceOf(() => method.call(ta, () => false), error);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_7/TypedArray/from-iterable-validation.js b/js/src/tests/ecma_7/TypedArray/from-iterable-validation.js
new file mode 100644
index 000000000..50d46bb81
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedArray/from-iterable-validation.js
@@ -0,0 +1,140 @@
+/* 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/. */
+
+// Summary: Ensure typed array validation is called for TypedArray.from.
+
+const otherGlobal = typeof newGlobal === "function" ? newGlobal() : undefined;
+const typedArrayArgs = [[], [123], [123, ...Array(1023).fill(0)]];
+
+function createTestCases(TAConstructor, constructor, constructorCrossRealm) {
+ let testCases = [];
+ testCases.push({
+ species: constructor,
+ method: TAConstructor.from,
+ error: TypeError,
+ });
+ if (otherGlobal) {
+ testCases.push({
+ species: constructorCrossRealm,
+ method: TAConstructor.from,
+ error: TypeError,
+ });
+ testCases.push({
+ species: constructor,
+ method: otherGlobal[TAConstructor.name].from,
+ error: otherGlobal.TypeError,
+ });
+ }
+ return testCases;
+}
+
+// Throws TypeError when the returned value is not a typed array.
+for (const TAConstructor of anyTypedArrayConstructors) {
+ let callCount = 0, expectedCallCount = 0;
+ function NoTypedArrayConstructor(...args) {
+ let a = [];
+ callCount += 1;
+ return a;
+ }
+ function NoTypedArrayConstructorCrossRealm(...args) {
+ let a = new otherGlobal.Array();
+ callCount += 1;
+ return a;
+ }
+ let testCases = createTestCases(TAConstructor, NoTypedArrayConstructor, NoTypedArrayConstructorCrossRealm);
+
+ for (let {species, method, error} of testCases) {
+ for (let args of typedArrayArgs) {
+ assertThrowsInstanceOf(() => method.call(species, args), error);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+}
+
+// Throws TypeError exception when returned array is too small.
+for (const TAConstructor of anyTypedArrayConstructors) {
+ let callCount = 0, expectedCallCount = 0;
+ function TooSmallConstructor(length) {
+ let a = new TAConstructor(Math.max(length - 1, 0));
+ callCount += 1;
+ return a;
+ }
+ function TooSmallConstructorCrossRealm(length) {
+ let a = new otherGlobal[TAConstructor.name](Math.max(length - 1, 0));
+ callCount += 1;
+ return a;
+ }
+ let testCases = createTestCases(TAConstructor, TooSmallConstructor, TooSmallConstructorCrossRealm);
+
+ for (let {species, method, error} of testCases) {
+ for (let args of typedArrayArgs) {
+ // Passes when the length is zero.
+ if (args.length === 0) {
+ let result = method.call(species, args);
+ assertEq(result.length, 0);
+ } else {
+ assertThrowsInstanceOf(() => method.call(species, args), error);
+ }
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+}
+
+// No exception when array is larger than requested.
+for (const TAConstructor of anyTypedArrayConstructors) {
+ const extraLength = 1;
+
+ let callCount = 0, expectedCallCount = 0;
+ function TooLargeConstructor(length) {
+ let a = new TAConstructor(length + extraLength);
+ callCount += 1;
+ return a;
+ }
+ function TooLargeConstructorCrossRealm(length) {
+ let a = new otherGlobal[TAConstructor.name](length + extraLength);
+ callCount += 1;
+ return a;
+ }
+ let testCases = createTestCases(TAConstructor, TooLargeConstructor, TooLargeConstructorCrossRealm);
+
+ for (let {species, method, error} of testCases) {
+ for (let args of typedArrayArgs) {
+ let result = method.call(species, args);
+ assertEq(result.length, args.length + extraLength);
+ assertEq(result[0], (args.length === 0 ? 0 : 123));
+ assertEq(result[args.length + extraLength - 1], 0);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+}
+
+// Throws TypeError exception when returned array is detached.
+if (typeof detachArrayBuffer === "function") {
+ for (const TAConstructor of typedArrayConstructors) {
+ let callCount = 0, expectedCallCount = 0;
+ function DetachConstructor(...args) {
+ let a = new TAConstructor(...args);
+ detachArrayBuffer(a.buffer);
+ callCount += 1;
+ return a;
+ }
+ function DetachConstructorCrossRealm(...args) {
+ let a = new otherGlobal[TAConstructor.name](...args);
+ otherGlobal.detachArrayBuffer(a.buffer);
+ callCount += 1;
+ return a;
+ }
+ let testCases = createTestCases(TAConstructor, DetachConstructor, DetachConstructorCrossRealm);
+
+ for (let {species, method, error} of testCases) {
+ for (let args of typedArrayArgs) {
+ assertThrowsInstanceOf(() => method.call(species, args), error);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_7/TypedArray/from-non-iterable-validation.js b/js/src/tests/ecma_7/TypedArray/from-non-iterable-validation.js
new file mode 100644
index 000000000..3276426b2
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedArray/from-non-iterable-validation.js
@@ -0,0 +1,140 @@
+/* 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/. */
+
+// Summary: Ensure typed array validation is called for TypedArray.from.
+
+const otherGlobal = typeof newGlobal === "function" ? newGlobal() : undefined;
+const typedArrayArgs = [{length: 0}, {length: 1, 0: 123}, {length: 1024, 0: 123}];
+
+function createTestCases(TAConstructor, constructor, constructorCrossRealm) {
+ let testCases = [];
+ testCases.push({
+ species: constructor,
+ method: TAConstructor.from,
+ error: TypeError,
+ });
+ if (otherGlobal) {
+ testCases.push({
+ species: constructorCrossRealm,
+ method: TAConstructor.from,
+ error: TypeError,
+ });
+ testCases.push({
+ species: constructor,
+ method: otherGlobal[TAConstructor.name].from,
+ error: otherGlobal.TypeError,
+ });
+ }
+ return testCases;
+}
+
+// Throws TypeError when the returned value is not a typed array.
+for (const TAConstructor of anyTypedArrayConstructors) {
+ let callCount = 0, expectedCallCount = 0;
+ function NoTypedArrayConstructor(...args) {
+ let a = [];
+ callCount += 1;
+ return a;
+ }
+ function NoTypedArrayConstructorCrossRealm(...args) {
+ let a = new otherGlobal.Array();
+ callCount += 1;
+ return a;
+ }
+ let testCases = createTestCases(TAConstructor, NoTypedArrayConstructor, NoTypedArrayConstructorCrossRealm);
+
+ for (let {species, method, error} of testCases) {
+ for (let args of typedArrayArgs) {
+ assertThrowsInstanceOf(() => method.call(species, args), error);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+}
+
+// Throws TypeError exception when returned array is too small.
+for (const TAConstructor of anyTypedArrayConstructors) {
+ let callCount = 0, expectedCallCount = 0;
+ function TooSmallConstructor(length) {
+ let a = new TAConstructor(Math.max(length - 1, 0));
+ callCount += 1;
+ return a;
+ }
+ function TooSmallConstructorCrossRealm(length) {
+ let a = new otherGlobal[TAConstructor.name](Math.max(length - 1, 0));
+ callCount += 1;
+ return a;
+ }
+ let testCases = createTestCases(TAConstructor, TooSmallConstructor, TooSmallConstructorCrossRealm);
+
+ for (let {species, method, error} of testCases) {
+ for (let args of typedArrayArgs) {
+ // Passes when the length is zero.
+ if (args.length === 0) {
+ let result = method.call(species, args);
+ assertEq(result.length, 0);
+ } else {
+ assertThrowsInstanceOf(() => method.call(species, args), error);
+ }
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+}
+
+// No exception when array is larger than requested.
+for (const TAConstructor of anyTypedArrayConstructors) {
+ const extraLength = 1;
+
+ let callCount = 0, expectedCallCount = 0;
+ function TooLargeConstructor(length) {
+ let a = new TAConstructor(length + extraLength);
+ callCount += 1;
+ return a;
+ }
+ function TooLargeConstructorCrossRealm(length) {
+ let a = new otherGlobal[TAConstructor.name](length + extraLength);
+ callCount += 1;
+ return a;
+ }
+ let testCases = createTestCases(TAConstructor, TooLargeConstructor, TooLargeConstructorCrossRealm);
+
+ for (let {species, method, error} of testCases) {
+ for (let args of typedArrayArgs) {
+ let result = method.call(species, args);
+ assertEq(result.length, args.length + extraLength);
+ assertEq(result[0], (args.length === 0 ? 0 : 123));
+ assertEq(result[args.length + extraLength - 1], 0);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+}
+
+// Throws TypeError exception when returned array is detached.
+if (typeof detachArrayBuffer === "function") {
+ for (const TAConstructor of typedArrayConstructors) {
+ let callCount = 0, expectedCallCount = 0;
+ function DetachConstructor(...args) {
+ let a = new TAConstructor(...args);
+ detachArrayBuffer(a.buffer);
+ callCount += 1;
+ return a;
+ }
+ function DetachConstructorCrossRealm(...args) {
+ let a = new otherGlobal[TAConstructor.name](...args);
+ otherGlobal.detachArrayBuffer(a.buffer);
+ callCount += 1;
+ return a;
+ }
+ let testCases = createTestCases(TAConstructor, DetachConstructor, DetachConstructorCrossRealm);
+
+ for (let {species, method, error} of testCases) {
+ for (let args of typedArrayArgs) {
+ assertThrowsInstanceOf(() => method.call(species, args), error);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_7/TypedArray/map-validation.js b/js/src/tests/ecma_7/TypedArray/map-validation.js
new file mode 100644
index 000000000..1694ef50c
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedArray/map-validation.js
@@ -0,0 +1,149 @@
+/* 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/. */
+
+// Summary: Ensure typed array validation is called for TypedArray.prototype.map.
+
+const otherGlobal = typeof newGlobal === "function" ? newGlobal() : undefined;
+const typedArrayLengths = [0, 1, 1024];
+
+function createTestCases(TAConstructor, constructor, constructorCrossRealm) {
+ let testCases = [];
+ testCases.push({
+ species: constructor,
+ method: TAConstructor.prototype.map,
+ error: TypeError,
+ });
+ if (otherGlobal) {
+ testCases.push({
+ species: constructorCrossRealm,
+ method: TAConstructor.prototype.map,
+ error: TypeError,
+ });
+ testCases.push({
+ species: constructor,
+ method: otherGlobal[TAConstructor.name].prototype.map,
+ error: otherGlobal.TypeError,
+ });
+ }
+ return testCases;
+}
+
+// Throws TypeError when the returned value is not a typed array.
+for (const TAConstructor of anyTypedArrayConstructors) {
+ let callCount = 0, expectedCallCount = 0;
+ function NoTypedArrayConstructor(...args) {
+ let a = [];
+ callCount += 1;
+ return a;
+ }
+ function NoTypedArrayConstructorCrossRealm(...args) {
+ let a = new otherGlobal.Array();
+ callCount += 1;
+ return a;
+ }
+ let testCases = createTestCases(TAConstructor, NoTypedArrayConstructor, NoTypedArrayConstructorCrossRealm);
+
+ for (let {species, method, error} of testCases) {
+ for (let length of typedArrayLengths) {
+ let ta = new TAConstructor(length);
+ ta.constructor = {[Symbol.species]: species};
+ assertThrowsInstanceOf(() => method.call(ta, () => 123), error);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+}
+
+// Throws TypeError exception when returned array is too small.
+for (const TAConstructor of anyTypedArrayConstructors) {
+ let callCount = 0, expectedCallCount = 0;
+ function TooSmallConstructor(length) {
+ let a = new TAConstructor(Math.max(length - 1, 0));
+ callCount += 1;
+ return a;
+ }
+ function TooSmallConstructorCrossRealm(length) {
+ let a = new otherGlobal[TAConstructor.name](Math.max(length - 1, 0));
+ callCount += 1;
+ return a;
+ }
+ let testCases = createTestCases(TAConstructor, TooSmallConstructor, TooSmallConstructorCrossRealm);
+
+ for (let {species, method, error} of testCases) {
+ for (let length of typedArrayLengths) {
+ let ta = new TAConstructor(length);
+ ta.constructor = {[Symbol.species]: species};
+
+ // Passes when the length is zero.
+ if (length === 0) {
+ let result = method.call(ta, () => 123);
+ assertEq(result.length, 0);
+ } else {
+ assertThrowsInstanceOf(() => method.call(ta, () => 123), error);
+ }
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+}
+
+// No exception when array is larger than requested.
+for (const TAConstructor of anyTypedArrayConstructors) {
+ const extraLength = 1;
+
+ let callCount = 0, expectedCallCount = 0;
+ function TooLargeConstructor(length) {
+ let a = new TAConstructor(length + extraLength);
+ callCount += 1;
+ return a;
+ }
+ function TooLargeConstructorCrossRealm(length) {
+ let a = new otherGlobal[TAConstructor.name](length + extraLength);
+ callCount += 1;
+ return a;
+ }
+ let testCases = createTestCases(TAConstructor, TooLargeConstructor, TooLargeConstructorCrossRealm);
+
+ for (let {species, method, error} of testCases) {
+ for (let length of typedArrayLengths) {
+ let ta = new TAConstructor(length);
+ ta.constructor = {[Symbol.species]: species};
+ let result = method.call(ta, () => 123);
+ assertEq(result.length, length + extraLength);
+ assertEq(result[0], (length === 0 ? 0 : 123));
+ assertEq(result[length + extraLength - 1], 0);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+}
+
+// Throws TypeError exception when returned array is detached.
+if (typeof detachArrayBuffer === "function") {
+ for (const TAConstructor of typedArrayConstructors) {
+ let callCount = 0, expectedCallCount = 0;
+ function DetachConstructor(...args) {
+ let a = new TAConstructor(...args);
+ detachArrayBuffer(a.buffer);
+ callCount += 1;
+ return a;
+ }
+ function DetachConstructorCrossRealm(...args) {
+ let a = new otherGlobal[TAConstructor.name](...args);
+ otherGlobal.detachArrayBuffer(a.buffer);
+ callCount += 1;
+ return a;
+ }
+ let testCases = createTestCases(TAConstructor, DetachConstructor, DetachConstructorCrossRealm);
+
+ for (let {species, method, error} of testCases) {
+ for (let length of typedArrayLengths) {
+ let ta = new TAConstructor(length);
+ ta.constructor = {[Symbol.species]: species};
+ assertThrowsInstanceOf(() => method.call(ta, () => 123), error);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_7/TypedArray/of-validation.js b/js/src/tests/ecma_7/TypedArray/of-validation.js
new file mode 100644
index 000000000..e7ab90519
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedArray/of-validation.js
@@ -0,0 +1,140 @@
+/* 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/. */
+
+// Summary: Ensure typed array validation is called for TypedArray.of.
+
+const otherGlobal = typeof newGlobal === "function" ? newGlobal() : undefined;
+const typedArrayArgs = [[], [123], [123, ...Array(1023).fill(0)]];
+
+function createTestCases(TAConstructor, constructor, constructorCrossRealm) {
+ let testCases = [];
+ testCases.push({
+ species: constructor,
+ method: TAConstructor.of,
+ error: TypeError,
+ });
+ if (otherGlobal) {
+ testCases.push({
+ species: constructorCrossRealm,
+ method: TAConstructor.of,
+ error: TypeError,
+ });
+ testCases.push({
+ species: constructor,
+ method: otherGlobal[TAConstructor.name].of,
+ error: otherGlobal.TypeError,
+ });
+ }
+ return testCases;
+}
+
+// Throws TypeError when the returned value is not a typed array.
+for (const TAConstructor of anyTypedArrayConstructors) {
+ let callCount = 0, expectedCallCount = 0;
+ function NoTypedArrayConstructor(...args) {
+ let a = [];
+ callCount += 1;
+ return a;
+ }
+ function NoTypedArrayConstructorCrossRealm(...args) {
+ let a = new otherGlobal.Array();
+ callCount += 1;
+ return a;
+ }
+ let testCases = createTestCases(TAConstructor, NoTypedArrayConstructor, NoTypedArrayConstructorCrossRealm);
+
+ for (let {species, method, error} of testCases) {
+ for (let args of typedArrayArgs) {
+ assertThrowsInstanceOf(() => method.call(species, ...args), error);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+}
+
+// Throws TypeError exception when returned array is too small.
+for (const TAConstructor of anyTypedArrayConstructors) {
+ let callCount = 0, expectedCallCount = 0;
+ function TooSmallConstructor(length) {
+ let a = new TAConstructor(Math.max(length - 1, 0));
+ callCount += 1;
+ return a;
+ }
+ function TooSmallConstructorCrossRealm(length) {
+ let a = new otherGlobal[TAConstructor.name](Math.max(length - 1, 0));
+ callCount += 1;
+ return a;
+ }
+ let testCases = createTestCases(TAConstructor, TooSmallConstructor, TooSmallConstructorCrossRealm);
+
+ for (let {species, method, error} of testCases) {
+ for (let args of typedArrayArgs) {
+ // Passes when the length is zero.
+ if (args.length === 0) {
+ let result = method.call(species, ...args);
+ assertEq(result.length, 0);
+ } else {
+ assertThrowsInstanceOf(() => method.call(species, ...args), error);
+ }
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+}
+
+// No exception when array is larger than requested.
+for (const TAConstructor of anyTypedArrayConstructors) {
+ const extraLength = 1;
+
+ let callCount = 0, expectedCallCount = 0;
+ function TooLargeConstructor(length) {
+ let a = new TAConstructor(length + extraLength);
+ callCount += 1;
+ return a;
+ }
+ function TooLargeConstructorCrossRealm(length) {
+ let a = new otherGlobal[TAConstructor.name](length + extraLength);
+ callCount += 1;
+ return a;
+ }
+ let testCases = createTestCases(TAConstructor, TooLargeConstructor, TooLargeConstructorCrossRealm);
+
+ for (let {species, method, error} of testCases) {
+ for (let args of typedArrayArgs) {
+ let result = method.call(species, ...args);
+ assertEq(result.length, args.length + extraLength);
+ assertEq(result[0], (args.length === 0 ? 0 : 123));
+ assertEq(result[args.length + extraLength - 1], 0);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+}
+
+// Throws TypeError exception when returned array is detached.
+if (typeof detachArrayBuffer === "function") {
+ for (const TAConstructor of typedArrayConstructors) {
+ let callCount = 0, expectedCallCount = 0;
+ function DetachConstructor(...args) {
+ let a = new TAConstructor(...args);
+ detachArrayBuffer(a.buffer);
+ callCount += 1;
+ return a;
+ }
+ function DetachConstructorCrossRealm(...args) {
+ let a = new otherGlobal[TAConstructor.name](...args);
+ otherGlobal.detachArrayBuffer(a.buffer);
+ callCount += 1;
+ return a;
+ }
+ let testCases = createTestCases(TAConstructor, DetachConstructor, DetachConstructorCrossRealm);
+
+ for (let {species, method, error} of testCases) {
+ for (let args of typedArrayArgs) {
+ assertThrowsInstanceOf(() => method.call(species, ...args), error);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_7/TypedArray/shell.js b/js/src/tests/ecma_7/TypedArray/shell.js
new file mode 100644
index 000000000..2fb0ab8f1
--- /dev/null
+++ b/js/src/tests/ecma_7/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_7/TypedArray/slice-validation.js b/js/src/tests/ecma_7/TypedArray/slice-validation.js
new file mode 100644
index 000000000..95954aafc
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedArray/slice-validation.js
@@ -0,0 +1,187 @@
+/* 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/. */
+
+// Summary: Ensure typed array validation is called for TypedArray.prototype.slice.
+
+const otherGlobal = typeof newGlobal === "function" ? newGlobal() : undefined;
+const typedArrayLengths = [0, 1, 1024];
+
+function createTestCases(TAConstructor, constructor, constructorCrossRealm) {
+ let testCases = [];
+ testCases.push({
+ species: constructor,
+ method: TAConstructor.prototype.slice,
+ error: TypeError,
+ });
+ if (otherGlobal) {
+ testCases.push({
+ species: constructorCrossRealm,
+ method: TAConstructor.prototype.slice,
+ error: TypeError,
+ });
+ testCases.push({
+ species: constructor,
+ method: otherGlobal[TAConstructor.name].prototype.slice,
+ // Note: slice uses CallTypedArrayMethodIfWrapped, which results
+ // in throwing a TypeError from the wrong Realm.
+ error: TypeError,
+ });
+ }
+ return testCases;
+}
+
+// Throws TypeError when the returned value is not a typed array.
+for (const TAConstructor of anyTypedArrayConstructors) {
+ let callCount = 0, expectedCallCount = 0;
+ function NoTypedArrayConstructor(...args) {
+ let a = [];
+ callCount += 1;
+ return a;
+ }
+ function NoTypedArrayConstructorCrossRealm(...args) {
+ let a = new otherGlobal.Array();
+ callCount += 1;
+ return a;
+ }
+ let testCases = createTestCases(TAConstructor, NoTypedArrayConstructor, NoTypedArrayConstructorCrossRealm);
+
+ for (let {species, method, error} of testCases) {
+ for (let length of typedArrayLengths) {
+ let ta = new TAConstructor(length);
+ ta.constructor = {[Symbol.species]: species};
+ assertThrowsInstanceOf(() => method.call(ta, 0), error);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+
+ for (let {species, method, error} of testCases) {
+ for (let length of typedArrayLengths) {
+ let ta = new TAConstructor(length);
+ ta.constructor = {[Symbol.species]: species};
+ assertThrowsInstanceOf(() => method.call(ta, 0, 0), error);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+}
+
+// Throws TypeError exception when returned array is too small.
+for (const TAConstructor of anyTypedArrayConstructors) {
+ let callCount = 0, expectedCallCount = 0;
+ function TooSmallConstructor(length) {
+ let a = new TAConstructor(Math.max(length - 1, 0));
+ callCount += 1;
+ return a;
+ }
+ function TooSmallConstructorCrossRealm(length) {
+ let a = new otherGlobal[TAConstructor.name](Math.max(length - 1, 0));
+ callCount += 1;
+ return a;
+ }
+ let testCases = createTestCases(TAConstructor, TooSmallConstructor, TooSmallConstructorCrossRealm);
+
+ for (let {species, method, error} of testCases) {
+ for (let length of typedArrayLengths) {
+ let ta = new TAConstructor(length);
+ ta.constructor = {[Symbol.species]: species};
+
+ // Passes when the length is zero.
+ if (length === 0) {
+ let result = method.call(ta, 0);
+ assertEq(result.length, 0);
+ } else {
+ assertThrowsInstanceOf(() => method.call(ta, 0), error);
+ }
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+
+ for (let {species, method, error} of testCases) {
+ for (let length of typedArrayLengths) {
+ let ta = new TAConstructor(length);
+ ta.constructor = {[Symbol.species]: species};
+ let result = method.call(ta, 0, 0);
+ assertEq(result.length, 0);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+}
+
+// No exception when array is larger than requested.
+for (const TAConstructor of anyTypedArrayConstructors) {
+ const extraLength = 1;
+
+ let callCount = 0, expectedCallCount = 0;
+ function TooLargeConstructor(length) {
+ let a = new TAConstructor(length + extraLength);
+ callCount += 1;
+ return a;
+ }
+ function TooLargeConstructorCrossRealm(length) {
+ let a = new otherGlobal[TAConstructor.name](length + extraLength);
+ callCount += 1;
+ return a;
+ }
+ let testCases = createTestCases(TAConstructor, TooLargeConstructor, TooLargeConstructorCrossRealm);
+
+ for (let {species, method, error} of testCases) {
+ for (let length of typedArrayLengths) {
+ let ta = new TAConstructor(length);
+ ta.constructor = {[Symbol.species]: species};
+ let result = method.call(ta, 0);
+ assertEq(result.length, length + extraLength);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+
+ for (let {species, method, error} of testCases) {
+ for (let length of typedArrayLengths) {
+ let ta = new TAConstructor(length);
+ ta.constructor = {[Symbol.species]: species};
+ let result = method.call(ta, 0, 0);
+ assertEq(result.length, extraLength);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+}
+
+// Throws TypeError exception when returned array is detached.
+if (typeof detachArrayBuffer === "function") {
+ for (const TAConstructor of typedArrayConstructors) {
+ let callCount = 0, expectedCallCount = 0;
+ function DetachConstructor(...args) {
+ let a = new TAConstructor(...args);
+ detachArrayBuffer(a.buffer);
+ callCount += 1;
+ return a;
+ }
+ function DetachConstructorCrossRealm(...args) {
+ let a = new otherGlobal[TAConstructor.name](...args);
+ otherGlobal.detachArrayBuffer(a.buffer);
+ callCount += 1;
+ return a;
+ }
+ let testCases = createTestCases(TAConstructor, DetachConstructor, DetachConstructorCrossRealm);
+
+ for (let {species, method, error} of testCases) {
+ for (let length of typedArrayLengths) {
+ let ta = new TAConstructor(length);
+ ta.constructor = {[Symbol.species]: species};
+ assertThrowsInstanceOf(() => method.call(ta, 0), error);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+
+ for (let {species, method, error} of testCases) {
+ for (let length of typedArrayLengths) {
+ let ta = new TAConstructor(length);
+ ta.constructor = {[Symbol.species]: species};
+ assertThrowsInstanceOf(() => method.call(ta, 0, 0), error);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_7/TypedArray/subarray-validation.js b/js/src/tests/ecma_7/TypedArray/subarray-validation.js
new file mode 100644
index 000000000..e81f194fb
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedArray/subarray-validation.js
@@ -0,0 +1,110 @@
+/* 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/. */
+
+// Summary: Ensure typed array validation is called for TypedArray.prototype.subarray.
+
+const otherGlobal = typeof newGlobal === "function" ? newGlobal() : undefined;
+const typedArrayLengths = [0, 1, 1024];
+
+function createTestCases(TAConstructor, constructor, constructorCrossRealm) {
+ let testCases = [];
+ testCases.push({
+ species: constructor,
+ method: TAConstructor.prototype.subarray,
+ error: TypeError,
+ });
+ if (otherGlobal) {
+ testCases.push({
+ species: constructorCrossRealm,
+ method: TAConstructor.prototype.subarray,
+ error: TypeError,
+ });
+ testCases.push({
+ species: constructor,
+ method: otherGlobal[TAConstructor.name].prototype.subarray,
+ // Note: subarray uses CallTypedArrayMethodIfWrapped, which results
+ // in throwing a TypeError from the wrong Realm.
+ error: TypeError,
+ });
+ }
+ return testCases;
+}
+
+// Throws TypeError when the returned value is not a typed array.
+for (const TAConstructor of anyTypedArrayConstructors) {
+ let callCount = 0, expectedCallCount = 0;
+ function NoTypedArrayConstructor(...args) {
+ let a = [];
+ callCount += 1;
+ return a;
+ }
+ function NoTypedArrayConstructorCrossRealm(...args) {
+ let a = new otherGlobal.Array();
+ callCount += 1;
+ return a;
+ }
+ let testCases = createTestCases(TAConstructor, NoTypedArrayConstructor, NoTypedArrayConstructorCrossRealm);
+
+ for (let {species, method, error} of testCases) {
+ for (let length of typedArrayLengths) {
+ let ta = new TAConstructor(length);
+ ta.constructor = {[Symbol.species]: species};
+ assertThrowsInstanceOf(() => method.call(ta, 0), error);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+
+ for (let {species, method, error} of testCases) {
+ for (let length of typedArrayLengths) {
+ let ta = new TAConstructor(length);
+ ta.constructor = {[Symbol.species]: species};
+ assertThrowsInstanceOf(() => method.call(ta, 0, 0), error);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+}
+
+// Throws TypeError exception when returned array is detached.
+if (typeof detachArrayBuffer === "function") {
+ for (const TAConstructor of typedArrayConstructors) {
+ let callCount = 0, expectedCallCount = 0;
+ function DetachConstructor(...args) {
+ let a = new TAConstructor(...args);
+ detachArrayBuffer(a.buffer);
+ callCount += 1;
+ return a;
+ }
+ function DetachConstructorCrossRealm(...args) {
+ let a = new otherGlobal[TAConstructor.name](...args);
+ // Note: TypedArray |a| is (currently) created in this global, not
+ // |otherGlobal|, because a typed array and its buffer must
+ // use the same compartment.
+ detachArrayBuffer(a.buffer);
+ callCount += 1;
+ return a;
+ }
+ let testCases = createTestCases(TAConstructor, DetachConstructor, DetachConstructorCrossRealm);
+
+ for (let {species, method, error} of testCases) {
+ for (let length of typedArrayLengths) {
+ let ta = new TAConstructor(length);
+ ta.constructor = {[Symbol.species]: species};
+ assertThrowsInstanceOf(() => method.call(ta, 0), error);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+
+ for (let {species, method, error} of testCases) {
+ for (let length of typedArrayLengths) {
+ let ta = new TAConstructor(length);
+ ta.constructor = {[Symbol.species]: species};
+ assertThrowsInstanceOf(() => method.call(ta, 0, 0), error);
+ assertEq(callCount, ++expectedCallCount);
+ }
+ }
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_7/TypedObject/architecture.js b/js/src/tests/ecma_7/TypedObject/architecture.js
new file mode 100644
index 000000000..4ebaaa9c3
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/architecture.js
@@ -0,0 +1,55 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+
+var BUGNUMBER = 578700;
+var summary = 'Binary Data class diagram';
+
+function assertNotEq(a, b) {
+ var ok = false;
+ try {
+ assertEq(a, b);
+ } catch(exc) {
+ ok = true;
+ }
+
+ if (!ok)
+ throw new TypeError("Assertion failed: assertNotEq(" + a + " " + b + ")");
+}
+
+function assertThrows(f) {
+ var ok = false;
+ try {
+ f();
+ } catch (exc) {
+ ok = true;
+ }
+ if (!ok)
+ throw new TypeError("Assertion failed: " + f + " did not throw as expected");
+}
+
+function runTests() {
+ print(BUGNUMBER + ": " + summary);
+
+ var ArrayType = TypedObject.ArrayType;
+ var StructType = TypedObject.StructType;
+
+ assertEq(ArrayType instanceof Function, true);
+ assertEq(ArrayType.prototype instanceof Function, true);
+
+ assertEq(ArrayType.__proto__, Function.__proto__);
+ assertEq(ArrayType.prototype.__proto__, Function.__proto__);
+
+ assertEq(StructType instanceof Function, true);
+ assertEq(StructType.prototype instanceof Function, true);
+
+ assertEq(Object.getPrototypeOf(StructType),
+ Object.getPrototypeOf(Function));
+ assertEq(Object.getPrototypeOf(StructType.prototype),
+ Object.getPrototypeOf(Function));
+
+ if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+ print("Tests complete");
+}
+
+runTests();
diff --git a/js/src/tests/ecma_7/TypedObject/arraybuffer_isview.js b/js/src/tests/ecma_7/TypedObject/arraybuffer_isview.js
new file mode 100644
index 000000000..2035eab30
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/arraybuffer_isview.js
@@ -0,0 +1,33 @@
+var BUGNUMBER = 896105;
+var summary = 'ArrayBuffer.isView';
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+function runTests() {
+ assertEq(ArrayBuffer.isView(), false);
+ assertEq(ArrayBuffer.isView(undefined), false);
+ assertEq(ArrayBuffer.isView(null), false);
+ assertEq(ArrayBuffer.isView("primitive"), false);
+ assertEq(ArrayBuffer.isView({}), false);
+ assertEq(ArrayBuffer.isView([]), false);
+ assertEq(ArrayBuffer.isView(new ArrayBuffer(10)), false);
+ assertEq(ArrayBuffer.isView(new Int8Array(10)), true);
+ assertEq(ArrayBuffer.isView(new Int8Array(10).subarray(0, 3)), true);
+ if (typeof SharedArrayBuffer != "undefined") {
+ assertEq(ArrayBuffer.isView(new SharedArrayBuffer(10)), false);
+ assertEq(ArrayBuffer.isView(new Int8Array(new SharedArrayBuffer(10))), true);
+ // In the next case subarray should return an ArrayBuffer, so this is
+ // similar to the subarray test above.
+ assertEq(ArrayBuffer.isView(new Int8Array(new SharedArrayBuffer(10)).subarray(0, 3)),
+ true);
+ }
+
+ if (typeof reportCompare !== 'undefined')
+ reportCompare(true, true);
+ print("Tests complete");
+}
+
+runTests();
diff --git a/js/src/tests/ecma_7/TypedObject/arrayequiv.js b/js/src/tests/ecma_7/TypedObject/arrayequiv.js
new file mode 100644
index 000000000..e6a89586d
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/arrayequiv.js
@@ -0,0 +1,59 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 922216;
+var summary = 'TypedObjects Equivalent ArrayTypes';
+
+var ArrayType = TypedObject.ArrayType;
+var StructType = TypedObject.StructType;
+var uint8 = TypedObject.uint8;
+var uint16 = TypedObject.uint16;
+var uint32 = TypedObject.uint32;
+var uint8Clamped = TypedObject.uint8Clamped;
+var int8 = TypedObject.int8;
+var int16 = TypedObject.int16;
+var int32 = TypedObject.int32;
+var float32 = TypedObject.float32;
+var float64 = TypedObject.float64;
+
+function assertEquivalent(t1, t2) {
+ assertEq(true, t1.equivalent(t2));
+ assertEq(true, t2.equivalent(t1));
+}
+
+function assertNotEquivalent(t1, t2) {
+ assertEq(false, t1.equivalent(t2));
+ assertEq(false, t2.equivalent(t1));
+}
+
+function runTests() {
+ print(BUGNUMBER + ": " + summary);
+
+ // Create a line:
+ var PixelType1 = new StructType({x: uint8, y: uint8});
+ var PixelsType1 = PixelType1.array(22);
+
+ // Sanity checks about type equivalence:
+ assertEquivalent(PixelType1, PixelType1);
+ assertEquivalent(PixelsType1, PixelsType1);
+ assertNotEquivalent(PixelType1, PixelsType1);
+
+ // Define the same two types again. Equivalent.
+ var PixelType2 = new StructType({x: uint8, y: uint8});
+ var PixelsType2 = PixelType2.array(22);
+ assertEquivalent(PixelType1, PixelType2);
+ assertEquivalent(PixelsType1, PixelsType2);
+
+ // Define the pixel type with field order reversed. Not equivalent.
+ var PixelType3 = new StructType({y: uint8, x: uint8});
+ var PixelsType3 = PixelType3.array(22);
+ assertNotEquivalent(PixelType1, PixelType3);
+ assertNotEquivalent(PixelsType1, PixelsType3);
+
+ // Define the pixels type with different number of elements. Not equivalent.
+ var PixelsType3 = PixelType1.array(23);
+ assertNotEquivalent(PixelsType1, PixelsType3);
+
+ reportCompare(true, true);
+ print("Tests complete");
+}
+
+runTests();
diff --git a/js/src/tests/ecma_7/TypedObject/arrayofstructs.js b/js/src/tests/ecma_7/TypedObject/arrayofstructs.js
new file mode 100644
index 000000000..e437bd7ab
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/arrayofstructs.js
@@ -0,0 +1,29 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 578700;
+var summary = 'TypedObjects StructType prototype chains';
+
+var ArrayType = TypedObject.ArrayType;
+var StructType = TypedObject.StructType;
+var float32 = TypedObject.float32;
+
+function runTests() {
+ var Point = new ArrayType(float32, 3);
+ var Line = new StructType({from: Point, to: Point});
+ var Lines = new ArrayType(Line, 3);
+
+ var lines = new Lines([
+ {from: [1, 2, 3], to: [4, 5, 6]},
+ {from: [7, 8, 9], to: [10, 11, 12]},
+ {from: [13, 14, 15], to: [16, 17, 18]}
+ ]);
+
+ assertEq(lines[1].to[1], 11);
+ assertEqArray(lines[2].from, [13, 14, 15]);
+
+ reportCompare(true, true);
+ print("Tests complete");
+}
+
+runTests();
+
+
diff --git a/js/src/tests/ecma_7/TypedObject/arraytype.js b/js/src/tests/ecma_7/TypedObject/arraytype.js
new file mode 100644
index 000000000..78f4494dd
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/arraytype.js
@@ -0,0 +1,136 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 578700;
+var summary = 'TypedObjects ArrayType implementation';
+
+function assertThrows(f) {
+ var ok = false;
+ try {
+ f();
+ } catch (exc) {
+ ok = true;
+ }
+ if (!ok)
+ throw new TypeError("Assertion failed: " + f + " did not throw as expected");
+}
+
+var ArrayType = TypedObject.ArrayType;
+var uint8 = TypedObject.uint8;
+var float32 = TypedObject.float32;
+var uint32 = TypedObject.uint32;
+
+function runTests() {
+ print(BUGNUMBER + ": " + summary);
+
+ assertEq(typeof ArrayType.prototype.prototype.forEach == "function", true);
+
+ assertThrows(() => ArrayType(uint8, 10));
+ assertThrows(() => new ArrayType());
+ assertThrows(() => new ArrayType(""));
+ assertThrows(() => new ArrayType(5));
+ assertThrows(() => new ArrayType(uint8).dimension(-1));
+ var A = new ArrayType(uint8, 10);
+ //assertEq(A.__proto__.__proto__, ArrayType.prototype);
+ assertEq(A.length, 10);
+ assertEq(A.elementType, uint8);
+ assertEq(A.byteLength, 10);
+ assertEq(A.toSource(), "new ArrayType(uint8, 10)");
+
+ //assertEq(A.prototype.__proto__.__proto__, ArrayType.prototype.prototype);
+
+ var a = new A();
+ assertEq(a.__proto__, A.prototype);
+ assertEq(a.length, 10);
+
+ assertThrows(() => a.length = 2);
+
+ for (var i = 0; i < a.length; i++)
+ a[i] = i*2;
+
+ for (var i = 0; i < a.length; i++)
+ assertEq(a[i], i*2);
+
+ a.forEach(function(val, i) {
+ assertEq(val, i*2);
+ assertEq(arguments[2], a);
+ });
+
+ // Range.
+ assertThrows(() => a[i] = 5);
+
+ assertEq(a[a.length], undefined);
+
+ // constructor takes initial value
+ var b = new A(a);
+ for (var i = 0; i < a.length; i++)
+ assertEq(b[i], i*2);
+
+
+ var b = new A([0, 1, 0, 1, 0, 1, 0, 1, 0, 1]);
+ for (var i = 0; i < b.length; i++)
+ assertEq(b[i], i%2);
+
+ assertThrows(() => new A(5));
+ assertThrows(() => new A(/fail/));
+ // Length different
+ assertThrows(() => new A([0, 1, 0, 1, 0, 1, 0, 1, 0]));
+
+ var Vec3 = new ArrayType(float32, 3);
+ var Sprite = new ArrayType(Vec3, 3); // say for position, velocity, and direction
+ assertEq(Sprite.elementType, Vec3);
+ assertEq(Sprite.elementType.elementType, float32);
+
+
+ var mario = new Sprite();
+ // setting using binary data
+ mario[0] = new Vec3([1, 0, 0]);
+ // setting using JS array conversion
+ mario[1] = [1, 1.414, 3.14];
+
+ assertEq(mario[0].length, 3);
+ assertEq(mario[0][0], 1);
+ assertEq(mario[0][1], 0);
+ assertEq(mario[0][2], 0);
+
+ assertThrows(() => mario[1] = 5);
+ mario[1][1] = {};
+ assertEq(Number.isNaN(mario[1][1]), true);
+
+ // ok this is just for kicks
+ var AllSprites = new ArrayType(Sprite, 65536);
+ var as = new AllSprites();
+ assertEq(as.length, 65536);
+
+ var indexPropDesc = Object.getOwnPropertyDescriptor(as, '0');
+ assertEq(typeof indexPropDesc == "undefined", false);
+ assertEq(indexPropDesc.configurable, false);
+ assertEq(indexPropDesc.enumerable, true);
+ assertEq(indexPropDesc.writable, true);
+
+ var lengthPropDesc = Object.getOwnPropertyDescriptor(as, 'length');
+ assertEq(typeof lengthPropDesc == "undefined", false);
+ assertEq(lengthPropDesc.configurable, false);
+ assertEq(lengthPropDesc.enumerable, false);
+ assertEq(lengthPropDesc.writable, false);
+
+ var counter = 0;
+ for (var nm in as) {
+ assertEq(+nm, counter++);
+ }
+ assertEq(counter, as.length);
+
+ assertThrows(() => Object.defineProperty(o, "foo", { value: "bar" }));
+
+ // check if a reference acts the way it should
+ var AA = uint8.array(5, 5);
+ var aa = new AA();
+ var aa0 = aa[0];
+ aa[0] = [0,1,2,3,4];
+ for (var i = 0; i < aa0.length; i++)
+ assertEq(aa0[i], i);
+
+ if (typeof reportCompare === "function")
+ reportCompare(true, true);
+ print("Tests complete");
+}
+
+runTests();
diff --git a/js/src/tests/ecma_7/TypedObject/arrayzerolen.js b/js/src/tests/ecma_7/TypedObject/arrayzerolen.js
new file mode 100644
index 000000000..c8cdf2f54
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/arrayzerolen.js
@@ -0,0 +1,17 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 926401;
+var summary = 'TypedObjects ArrayType implementation';
+
+// Test creation of zero-length array
+
+function runTest() {
+ var T = TypedObject;
+ var Color = new T.StructType({'r': T.uint8, 'g': T.uint8, 'b': T.uint8});
+ var Rainbow = Color.array(0);
+ var theOneISawWasJustBlack = new Rainbow([]);
+ if (typeof reportCompare === "function")
+ reportCompare(true, true);
+ print("Tests complete");
+}
+
+runTest();
diff --git a/js/src/tests/ecma_7/TypedObject/atopbuffer.js b/js/src/tests/ecma_7/TypedObject/atopbuffer.js
new file mode 100644
index 000000000..6385edd9c
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/atopbuffer.js
@@ -0,0 +1,27 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 898356;
+
+var {StructType, uint32, Object, Any, storage, objectType} = TypedObject;
+
+function main() { // once a C programmer, always a C programmer.
+ print(BUGNUMBER + ": " + summary);
+
+ var Uints = new StructType({f: uint32, g: uint32});
+
+ var anArray = new Uint32Array(2);
+ anArray[0] = 22;
+ anArray[1] = 44;
+
+ var uints = new Uints(anArray.buffer);
+ assertEq(storage(uints).buffer, anArray.buffer);
+ assertEq(uints.f, 22);
+ assertEq(uints.g, 44);
+
+ uints.f++;
+ assertEq(anArray[0], 23);
+
+ reportCompare(true, true);
+ print("Tests complete");
+}
+
+main();
diff --git a/js/src/tests/ecma_7/TypedObject/atopbufferwithoffset.js b/js/src/tests/ecma_7/TypedObject/atopbufferwithoffset.js
new file mode 100644
index 000000000..a4e3af08c
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/atopbufferwithoffset.js
@@ -0,0 +1,51 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 898356;
+
+var {StructType, uint32, Object, Any, storage, objectType} = TypedObject;
+
+function main() { // once a C programmer, always a C programmer.
+ print(BUGNUMBER + ": " + summary);
+
+ var Uints = new StructType({f: uint32, g: uint32});
+
+ var anArray = new Uint32Array(4);
+ anArray[1] = 22;
+ anArray[2] = 44;
+
+ var uints = new Uints(anArray.buffer, 4);
+ assertEq(storage(uints).buffer, anArray.buffer);
+ assertEq(uints.f, 22);
+ assertEq(uints.g, 44);
+ uints.f++;
+ assertEq(anArray[1], 23);
+
+ // No misaligned byte offsets or offsets that would stretch past the end:
+ assertThrows(() => new Uints(anArray.buffer, -4)); // negative
+ assertThrows(() => new Uints(anArray.buffer, -3)); // negative
+ assertThrows(() => new Uints(anArray.buffer, -2)); // negative
+ assertThrows(() => new Uints(anArray.buffer, -1)); // negative
+ new Uints(anArray.buffer, 0); // ok
+ assertThrows(() => new Uints(anArray.buffer, 1)); // misaligned
+ assertThrows(() => new Uints(anArray.buffer, 2)); // misaligned
+ assertThrows(() => new Uints(anArray.buffer, 3)); // misaligned
+ new Uints(anArray.buffer, 4); // ok
+ assertThrows(() => new Uints(anArray.buffer, 5)); // misaligned
+ assertThrows(() => new Uints(anArray.buffer, 6)); // misaligned
+ assertThrows(() => new Uints(anArray.buffer, 7)); // misaligned
+ new Uints(anArray.buffer, 8); // ok
+ assertThrows(() => new Uints(anArray.buffer, 9)); // misaligned
+ assertThrows(() => new Uints(anArray.buffer, 10)); // misaligned
+ assertThrows(() => new Uints(anArray.buffer, 11)); // misaligned
+ assertThrows(() => new Uints(anArray.buffer, 12)); // would extend past end
+ assertThrows(() => new Uints(anArray.buffer, 13)); // misaligned
+ assertThrows(() => new Uints(anArray.buffer, 14)); // misaligned
+ assertThrows(() => new Uints(anArray.buffer, 15)); // misaligned
+ assertThrows(() => new Uints(anArray.buffer, 16)); // would extend past end
+ assertThrows(() => new Uints(anArray.buffer, 17)); // misaligned
+ assertThrows(() => new Uints(anArray.buffer, 4294967292)); // overflows int
+
+ reportCompare(true, true);
+ print("Tests complete");
+}
+
+main();
diff --git a/js/src/tests/ecma_7/TypedObject/map-neutered-midway.js b/js/src/tests/ecma_7/TypedObject/map-neutered-midway.js
new file mode 100644
index 000000000..2e3892d7a
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/map-neutered-midway.js
@@ -0,0 +1,43 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject")||!xulRuntime.shell) -- needs TypedObject, detachArrayBuffer()
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var BUGNUMBER = 991981;
+var summary =
+ "Behavior of mapping from an array whose buffer is detached midway through " +
+ "mapping";
+
+function mapOneDimArrayOfUint8()
+{
+ var FourByteArray = TypedObject.uint8.array(4);
+ var FourByteArrayArray = FourByteArray.array(4);
+
+ var buf = new ArrayBuffer(16);
+ var arr = new FourByteArrayArray(buf);
+
+ var count = 0;
+ assertThrowsInstanceOf(function()
+ {
+ arr.map(function(v)
+ {
+ if (count++ > 0)
+ detachArrayBuffer(buf);
+ return new FourByteArray();
+ });
+ }, TypeError, "mapping of a detached object worked?");
+}
+
+function runTests()
+{
+ print(BUGNUMBER + ": " + summary);
+
+ mapOneDimArrayOfUint8();
+
+ if (typeof reportCompare === "function")
+ reportCompare(true, true);
+ print("Tests complete");
+}
+
+runTests();
diff --git a/js/src/tests/ecma_7/TypedObject/memory.js b/js/src/tests/ecma_7/TypedObject/memory.js
new file mode 100644
index 000000000..242124177
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/memory.js
@@ -0,0 +1,97 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 578700;
+var summary = 'TypedObjects memory check';
+
+function spin() {
+ for (var i = 0; i < 10000; i++)
+ ;
+}
+
+var ArrayType = TypedObject.ArrayType;
+var StructType = TypedObject.StructType;
+var uint8 = TypedObject.uint8;
+var uint16 = TypedObject.uint16;
+var uint32 = TypedObject.uint32;
+var uint8Clamped = TypedObject.uint8Clamped;
+var int8 = TypedObject.int8;
+var int16 = TypedObject.int16;
+var int32 = TypedObject.int32;
+var float32 = TypedObject.float32;
+var float64 = TypedObject.float64;
+
+
+function runTests() {
+ print(BUGNUMBER + ": " + summary);
+
+ var AA = uint8.array(5, 5);
+ var aa = new AA();
+ var aa0 = aa[0];
+ aa[0] = [0,1,2,3,4];
+
+ aa = null;
+
+ gc();
+ spin();
+
+ for (var i = 0; i < aa0.length; i++)
+ assertEq(aa0[i], i);
+
+ var AAA = AA.array(5);
+ var aaa = new AAA();
+ var a0 = aaa[0][0];
+
+ for (var i = 0; i < a0.length; i++)
+ assertEq(a0[i], 0);
+
+ aaa[0] = [[0,1,2,3,4], [0,1,2,3,4], [0,1,2,3,4], [0,1,2,3,4], [0,1,2,3,4]];
+
+ aaa = null;
+
+ gc();
+ spin();
+ for (var i = 0; i < a0.length; i++)
+ assertEq(a0[i], i);
+
+ var Color = new StructType({'r': uint8, 'g': uint8, 'b': uint8});
+ var Rainbow = Color.array(7);
+
+ var theOneISawWasJustBlack = new Rainbow([
+ {'r': 0, 'g': 0, 'b': 0},
+ {'r': 0, 'g': 0, 'b': 0},
+ {'r': 0, 'g': 0, 'b': 0},
+ {'r': 0, 'g': 0, 'b': 0},
+ {'r': 0, 'g': 0, 'b': 0},
+ {'r': 0, 'g': 0, 'b': 0},
+ {'r': 0, 'g': 0, 'b': 0}]);
+
+ var middleBand = theOneISawWasJustBlack[3];
+ theOneISawWasJustBlack = null;
+ gc();
+ spin();
+ assertEq(middleBand['r'] == 0 && middleBand['g'] == 0 && middleBand['b'] == 0, true);
+ middleBand.r = 255;
+ middleBand.g = 207;
+ middleBand.b = 142;
+ assertEq(middleBand['r'] == 255 && middleBand['g'] == 207 && middleBand['b'] == 142, true);
+
+ var scopedType = function() {
+ var Point = new StructType({'x': int32, 'y': int32});
+ var aPoint = new Point();
+ aPoint.x = 4;
+ aPoint.y = 5;
+ return aPoint;
+ }
+
+ var point = scopedType();
+ gc();
+ spin();
+ gc();
+ assertEq(point.constructor.fieldTypes.x, int32);
+ assertEq(point.constructor.fieldTypes.y, int32);
+
+ if (typeof reportCompare === "function")
+ reportCompare(true, true);
+ print("Tests complete");
+}
+
+runTests();
diff --git a/js/src/tests/ecma_7/TypedObject/method_build.js b/js/src/tests/ecma_7/TypedObject/method_build.js
new file mode 100644
index 000000000..c23f629c1
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/method_build.js
@@ -0,0 +1,141 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 939715;
+var summary = 'method type.build';
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var ArrayType = TypedObject.ArrayType;
+var StructType = TypedObject.StructType;
+var uint8 = TypedObject.uint8;
+var uint16 = TypedObject.uint16;
+var uint32 = TypedObject.uint32;
+var uint8Clamped = TypedObject.uint8Clamped;
+var int8 = TypedObject.int8;
+var int16 = TypedObject.int16;
+var int32 = TypedObject.int32;
+var float32 = TypedObject.float32;
+var float64 = TypedObject.float64;
+
+function oneDimensionalArrayOfUints() {
+ var grain = uint32;
+ var type = grain.array(4);
+ var r1 = type.build(x => x * 2);
+ assertTypedEqual(type, r1, new type([0, 2, 4, 6]));
+}
+
+function oneDimensionalArrayOfStructs() {
+ var grain = new StructType({f: uint32});
+ var type = grain.array(4);
+ var r1 = type.build(x => new grain({f: x * 2}));
+ var r2 = type.build((x, out) => { out.f = x * 2; });
+ assertTypedEqual(type, r1, new type([{f:0}, {f:2},
+ {f:4}, {f:6}]));
+ assertTypedEqual(type, r1, r2);
+}
+
+// At an attempt at readability, the tests below all try to build up
+// numbers where there is a one-to-one mapping between input dimension
+// and base-10 digit in the output.
+//
+// (Note that leading zeros must be elided in the expected-values to
+// avoid inadvertantly interpreting the numbers as octal constants.)
+
+function twoDimensionalArrayOfStructsWithDepth2() {
+ var grain = new StructType({f: uint32});
+ var type = grain.array(2, 2);
+
+ var r1 = type.build(2, (x, y) => {
+ return new grain({f: x * 10 + y});
+ });
+
+ var r2 = type.build(2, (x, y, out) => {
+ out.f = x * 10 + y;
+ });
+
+ assertTypedEqual(type, r1, new type([[{f: 0}, {f: 1}],
+ [{f:10}, {f:11}]]));
+ assertTypedEqual(type, r1, r2);
+}
+
+function twoDimensionalArrayOfStructsWithDepth1() {
+ var grain = new StructType({f: uint32}).array(2);
+ var type = grain.array(2);
+
+ var r1 = type.build((x) => {
+ return new grain([{f: x * 10},
+ {f: x * 10 + 1}]);
+ });
+
+ var r2 = type.build(1, (x, out) => {
+ out[0].f = x * 10 + 0;
+ out[1].f = x * 10 + 1;
+ });
+
+ assertTypedEqual(type, r1, new type([[{f: 0}, {f: 1}],
+ [{f:10}, {f:11}]]));
+ assertTypedEqual(type, r1, r2);
+}
+
+function threeDimensionalArrayOfUintsWithDepth3() {
+ var grain = uint32;
+ var type = grain.array(2).array(2).array(2);
+ var r1 = type.build(3, (x,y,z) => x * 100 + y * 10 + z);
+ assertTypedEqual(type, r1, new type([[[ 0, 1], [ 10, 11]],
+ [[100, 101], [110, 111]]]));
+}
+
+function threeDimensionalArrayOfUintsWithDepth2() {
+ var grain = uint32.array(2);
+ var type = grain.array(2).array(2);
+ var r1 = type.build(2, (x,y) => [x * 100 + y * 10 + 0, x * 100 + y * 10 + 1]);
+ var r1b = type.build(2, (x,y) => grain.build(z => x * 100 + y * 10 + z));
+ var r1c = type.build(2, (x,y) => grain.build(1, z => x * 100 + y * 10 + z));
+
+ var r2 = type.build(2, (x,y, out) => { out[0] = x * 100 + y * 10 + 0;
+ out[1] = x * 100 + y * 10 + 1;
+ });
+ assertTypedEqual(type, r1, new type([[[ 0, 1], [ 10, 11]],
+ [[100, 101], [110, 111]]]));
+ assertTypedEqual(type, r1, r1b);
+ assertTypedEqual(type, r1, r1c);
+ assertTypedEqual(type, r1, r2);
+}
+
+function threeDimensionalArrayOfUintsWithDepth1() {
+ var grain = uint32.array(2).array(2);
+ var type = grain.array(2);
+ var r1 = type.build(1, (x) => grain.build(y => [x * 100 + y * 10 + 0, x * 100 + y * 10 + 1]));
+ var r1b = type.build(1, (x) => grain.build(1, y => [x * 100 + y * 10 + 0, x * 100 + y * 10 + 1]));
+ var r1c = type.build(1, (x) => grain.build(2, (y,z) => x * 100 + y * 10 + z));
+ var r2 = type.build(1, (x, out) => { out[0][0] = x * 100 + 0 * 10 + 0;
+ out[0][1] = x * 100 + 0 * 10 + 1;
+ out[1][0] = x * 100 + 1 * 10 + 0;
+ out[1][1] = x * 100 + 1 * 10 + 1;
+ });
+ assertTypedEqual(type, r1, new type([[[ 0, 1], [ 10, 11]],
+ [[100, 101], [110, 111]]]));
+ assertTypedEqual(type, r1, r1b);
+ assertTypedEqual(type, r1, r1c);
+ assertTypedEqual(type, r1, r2);
+}
+
+function runTests() {
+ print(BUGNUMBER + ": " + summary);
+
+ oneDimensionalArrayOfUints();
+ oneDimensionalArrayOfStructs();
+ twoDimensionalArrayOfStructsWithDepth2();
+ twoDimensionalArrayOfStructsWithDepth1();
+ threeDimensionalArrayOfUintsWithDepth3();
+ threeDimensionalArrayOfUintsWithDepth2();
+ threeDimensionalArrayOfUintsWithDepth1();
+
+ if (typeof reportCompare === "function")
+ reportCompare(true, true);
+ print("Tests complete");
+}
+
+runTests();
diff --git a/js/src/tests/ecma_7/TypedObject/method_filter.js b/js/src/tests/ecma_7/TypedObject/method_filter.js
new file mode 100644
index 000000000..37cd445a2
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/method_filter.js
@@ -0,0 +1,47 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 939715;
+var summary = 'method instance.filter';
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var ArrayType = TypedObject.ArrayType;
+var StructType = TypedObject.StructType;
+var uint8 = TypedObject.uint8;
+var uint16 = TypedObject.uint16;
+var uint32 = TypedObject.uint32;
+var uint8Clamped = TypedObject.uint8Clamped;
+var int8 = TypedObject.int8;
+var int16 = TypedObject.int16;
+var int32 = TypedObject.int32;
+var float32 = TypedObject.float32;
+var float64 = TypedObject.float64;
+
+var objectType = TypedObject.objectType;
+
+function filterOdds() {
+ var length = 100;
+ var Uint32s = new ArrayType(uint32, 100);
+ var uint32s = new Uint32s();
+ for (var i = 0; i < length; i++)
+ uint32s[i] = i;
+
+ var odds = uint32s.filter(i => (i % 2) != 0);
+ assertEq(50, odds.length);
+ for (var i = 0, j = 1; j < length; i++, j += 2)
+ assertEq(odds[i], j);
+}
+
+function runTests() {
+ print(BUGNUMBER + ": " + summary);
+
+ filterOdds();
+
+ if (typeof reportCompare === "function")
+ reportCompare(true, true);
+ print("Tests complete");
+}
+
+runTests();
diff --git a/js/src/tests/ecma_7/TypedObject/method_from.js b/js/src/tests/ecma_7/TypedObject/method_from.js
new file mode 100644
index 000000000..81980837c
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/method_from.js
@@ -0,0 +1,238 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 939715;
+var summary = 'method type.from';
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var ArrayType = TypedObject.ArrayType;
+var StructType = TypedObject.StructType;
+var uint8 = TypedObject.uint8;
+var uint16 = TypedObject.uint16;
+var uint32 = TypedObject.uint32;
+var uint8Clamped = TypedObject.uint8Clamped;
+var int8 = TypedObject.int8;
+var int16 = TypedObject.int16;
+var int32 = TypedObject.int32;
+var float32 = TypedObject.float32;
+var float64 = TypedObject.float64;
+
+// Test name format:
+
+// from<N>DimArrayOf<G1>sTo<G2>s where <N> is a positive integer (or its
+// equivalent word in English) and <G1> and <G2> are both grain types
+// (potentially an array themselves.)
+
+function fromOneDimArrayOfUint8ToUint32s() {
+ var intype = uint8.array(4);
+ var type = uint32.array(4);
+ var i1 = intype.build(i => i);
+ var r1 = type.from(i1, j => j*2);
+ var r2 = type.from(i1, 1, j => j*2);
+ assertTypedEqual(type, r1, new type([0, 2, 4, 6]));
+ assertTypedEqual(type, r1, r2);
+}
+
+function fromOneDimArrayOfUint32ToUint8s() {
+ var intype = uint32.array(4);
+ var type = uint8.array(4);
+ var i1 = intype.build(i => i);
+ var r1 = type.from(i1, j => j*200);
+ var r2 = type.from(i1, 1, j => j*200);
+ assertTypedEqual(type, r1, new type([0, 200, 400 % 256, 600 % 256]));
+ assertTypedEqual(type, r1, r2);
+}
+
+function fromTwoDimArrayOfUint8ToUint32s() {
+ var intype = uint8.array(4).array(4);
+ var rowtype = uint32.array(4);
+ var type = rowtype.array(4);
+ var i1 = new type([[10, 11, 12, 13],
+ [20, 21, 22, 23],
+ [30, 31, 32, 33],
+ [40, 41, 42, 43]]);
+
+ var r1 = type.from(i1, 2, x => x*2);
+ var r2 = type.from(i1, 1, a => rowtype.from(a, 1, x => x*2));
+ var r3 = type.from(i1, 1, (a, j, c, out) => { out[0] = a[0]*2;
+ out[1] = a[1]*2;
+ out[2] = a[2]*2;
+ out[3] = a[3]*2; });
+ assertTypedEqual(type, r1, new type([[20, 22, 24, 26],
+ [40, 42, 44, 46],
+ [60, 62, 64, 66],
+ [80, 82, 84, 86]]));
+ assertTypedEqual(type, r1, r2);
+ assertTypedEqual(type, r1, r3);
+}
+
+function fromTwoDimArrayOfUint32ToUint8s() {
+ var intype = uint32.array(4).array(4);
+ var rowtype = uint8.array(4);
+ var type = rowtype.array(4);
+ var i1 = new type([[10, 11, 12, 13],
+ [20, 21, 22, 23],
+ [30, 31, 32, 33],
+ [40, 41, 42, 43]]);
+
+ var r1 = type.from(i1, 2, x => x*2);
+ var r2 = type.from(i1, 1, a => rowtype.from(a, 1, x => x*2));
+ var r3 = type.from(i1, 1, (a, j, c, out) => { out[0] = a[0]*2;
+ out[1] = a[1]*2;
+ out[2] = a[2]*2;
+ out[3] = a[3]*2; });
+ assertTypedEqual(type, r1, new type([[20, 22, 24, 26],
+ [40, 42, 44, 46],
+ [60, 62, 64, 66],
+ [80, 82, 84, 86]]));
+ assertTypedEqual(type, r1, r2);
+ assertTypedEqual(type, r1, r3);
+}
+
+function fromOneDimArrayOfArrayOfUint8ToUint32s() {
+ var intype = uint8.array(4).array(4);
+ var type = uint32.array(4);
+ var i1 = new intype([[0xdd, 0xcc, 0xbb, 0xaa],
+ [0x09, 0x08, 0x07, 0x06],
+ [0x15, 0x14, 0x13, 0x12],
+ [0x23, 0x32, 0x41, 0x50]]);
+
+ function combine(a,b,c,d) { return a << 24 | b << 16 | c << 8 | d; }
+
+ var r1 = type.from(i1, x => combine(x[0], x[1], x[2], x[3]));
+ assertTypedEqual(type, r1, new type([0xddccbbaa,
+ 0x09080706,
+ 0x15141312,
+ 0x23324150]));
+}
+
+function fromOneDimArrayOfUint32ToArrayOfUint8s() {
+ var intype = uint32.array(4);
+ var type = uint8.array(4).array(4);
+ var i1 = new intype([0xddccbbaa,
+ 0x09080706,
+ 0x15141312,
+ 0x23324150]);
+
+ function divide(a) { return [a >> 24 & 0xFF, a >> 16 & 0xFF, a >> 8 & 0xFF, a & 0xFF]; }
+
+ var r1 = type.from(i1, x => divide(x));
+ var r2 = type.from(i1, 1, (x, i, c, out) => {
+ var [a,b,c,d] = divide(x);
+ out[0] = a; out[1] = b; out[2] = c; out[3] = d;
+ });
+ assertTypedEqual(type, r1, new type([[0xdd, 0xcc, 0xbb, 0xaa],
+ [0x09, 0x08, 0x07, 0x06],
+ [0x15, 0x14, 0x13, 0x12],
+ [0x23, 0x32, 0x41, 0x50]]));
+ assertTypedEqual(type, r1, r2);
+}
+
+var Grain = new StructType({f: uint32});
+function wrapG(v) { return new Grain({f: v}); }
+function doubleG(g) { return new Grain({f: g.f * 2}); }
+function tenG(x, y) { return new Grain({f: x * 10 + y}); }
+
+function fromOneDimArrayOfStructsToStructs() {
+ var type = Grain.array(4);
+ var i1 = type.build(wrapG);
+ var r1 = type.from(i1, doubleG);
+ var r2 = type.from(i1, 1, doubleG);
+ var r3 = type.from(i1, 1, (g, j, c, out) => { out.f = g.f * 2; });
+ assertTypedEqual(type, r1, new type([{f:0}, {f:2},
+ {f:4}, {f:6}]));
+ assertTypedEqual(type, r1, r2);
+ assertTypedEqual(type, r1, r3);
+}
+
+function fromTwoDimArrayOfStructsToStructs() {
+ var rowtype = Grain.array(2);
+ var type = rowtype.array(2);
+ var i1 = type.build(2, tenG);
+ var r1 = type.from(i1, 2, doubleG);
+ var r2 = type.from(i1, 1, (m) => rowtype.from(m, 1, doubleG));
+ var r3 = type.from(i1, 1,
+ (m, j, c, out) => { out[0].f = m[0].f * 2; out[1].f = m[1].f * 2; });
+ assertTypedEqual(type, r1, new type([[{f:00}, {f:02}],
+ [{f:20}, {f:22}]]));
+ assertTypedEqual(type, r1, r2);
+ assertTypedEqual(type, r1, r3);
+}
+
+function fromOneDimArrayOfStructsToArrayOfStructs() {
+ var Line = Grain.array(2);
+ var Box = Line.array(2);
+ var i1 = Line.build(wrapG);
+ var r1 = Box.from(i1, (g) => Line.build((y) => tenG(g.f, y)));
+ var r2 = Box.from(i1, (g) => Line.from(i1, (y) => tenG(g.f, y.f)));
+ var r3 = Box.from(i1,
+ (g, j, c, out) => { out[0] = tenG(g.f, 0); out[1] = tenG(g.f, 1); });
+ assertTypedEqual(Box, r1, new Box([[{f:00}, {f:01}],
+ [{f:10}, {f:11}]]));
+ assertTypedEqual(Box, r1, r2);
+ assertTypedEqual(Box, r1, r3);
+}
+
+function Array_build(n, f) {
+ var a = new Array(n);
+ for ( var i=0 ; i < n ; i++ )
+ a[i] = f(i);
+ return a;
+}
+
+function fromUntypedArrayToUint32s() {
+ var type = uint32.array(4);
+ var i1 = Array_build(4, i => i);
+ var r1 = type.from(i1, j => j*2);
+ var r2 = type.from(i1, 1, j => j*2);
+ assertTypedEqual(type, r1, new type([0, 2, 4, 6]));
+ assertTypedEqual(type, r1, r2);
+}
+
+function fromUntypedArrayToUint8s() {
+ var type = uint8.array(4);
+ var i1 = Array_build(4, i => i);
+ var r1 = type.from(i1, j => j*200);
+ var r2 = type.from(i1, 1, j => j*200);
+ assertTypedEqual(type, r1, new type([0, 200, 400 % 256, 600 % 256]));
+ assertTypedEqual(type, r1, r2);
+}
+
+function fromNonArrayTypedObjects() {
+ var type = TypedObject.uint32.array(4);
+ var myStruct = new StructType({x: uint32});
+ var r1 = type.from(new myStruct({x: 42}), j => j);
+ assertTypedEqual(type, r1, new type([0,0,0,0]));
+
+ var r2 = type.from(SIMD.Int32x4(0,0,0,0), j => j);
+ assertTypedEqual(type, r1, new type([0,0,0,0]));
+}
+
+function runTests() {
+ print(BUGNUMBER + ": " + summary);
+
+ fromOneDimArrayOfUint8ToUint32s();
+ fromOneDimArrayOfUint32ToUint8s();
+
+ fromTwoDimArrayOfUint8ToUint32s();
+ fromTwoDimArrayOfUint32ToUint8s();
+
+ fromOneDimArrayOfArrayOfUint8ToUint32s();
+ fromOneDimArrayOfUint32ToArrayOfUint8s();
+
+ fromOneDimArrayOfStructsToStructs();
+ fromTwoDimArrayOfStructsToStructs();
+
+ fromOneDimArrayOfStructsToArrayOfStructs();
+
+ fromUntypedArrayToUint32s();
+ fromUntypedArrayToUint8s();
+
+ if (typeof reportCompare === "function")
+ reportCompare(true, true);
+ print("Tests complete");
+}
+
+runTests();
diff --git a/js/src/tests/ecma_7/TypedObject/method_map.js b/js/src/tests/ecma_7/TypedObject/method_map.js
new file mode 100644
index 000000000..e5bf9b3ee
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/method_map.js
@@ -0,0 +1,136 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 939715;
+var summary = 'method instance.map';
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var ArrayType = TypedObject.ArrayType;
+var StructType = TypedObject.StructType;
+var uint8 = TypedObject.uint8;
+var uint16 = TypedObject.uint16;
+var uint32 = TypedObject.uint32;
+var uint8Clamped = TypedObject.uint8Clamped;
+var int8 = TypedObject.int8;
+var int16 = TypedObject.int16;
+var int32 = TypedObject.int32;
+var float32 = TypedObject.float32;
+var float64 = TypedObject.float64;
+
+// Test name format:
+
+// map<N>DimArrayOf<G1>sTo<G2>s where <N> is a positive integer (or its
+// equivalent word in English) and <G1> and <G2> are both grain types
+// (potentially an array themselves.)
+
+function mapOneDimArrayOfUint8() {
+ var type = uint8.array(4);
+ var i1 = type.build(i => i);
+ var r1 = i1.map(j => j*200);
+ var r2 = i1.map(1, j => j*200);
+ assertTypedEqual(type, r1, new type([0, 200, 400 % 256, 600 % 256]));
+ assertTypedEqual(type, r1, r2);
+}
+
+function mapOneDimArrayOfUint32() {
+ var type = uint32.array(4);
+ var i1 = type.build(i => i);
+ var r1 = i1.map(j => j*200);
+ var r2 = i1.map(1, j => j*200);
+ assertTypedEqual(type, r1, new type([0, 200, 400, 600]));
+ assertTypedEqual(type, r1, r2);
+}
+
+function mapTwoDimArrayOfUint8() {
+ var type = uint8.array(4).array(4);
+ var i1 = new type([[10, 11, 12, 13],
+ [20, 21, 22, 23],
+ [30, 31, 32, 33],
+ [40, 41, 42, 43]]);
+
+ var r1 = i1.map(2, x => x*2);
+ var r2 = i1.map(1, a => a.map(1, x => x*2));
+ var r3 = i1.map(1, (a, j, c, out) => { out[0] = a[0]*2;
+ out[1] = a[1]*2;
+ out[2] = a[2]*2;
+ out[3] = a[3]*2; });
+ assertTypedEqual(type, r1, new type([[20, 22, 24, 26],
+ [40, 42, 44, 46],
+ [60, 62, 64, 66],
+ [80, 82, 84, 86]]));
+ assertTypedEqual(type, r1, r2);
+ assertTypedEqual(type, r1, r3);
+}
+
+function mapTwoDimArrayOfUint32() {
+ var type = uint32.array(4).array(4);
+ var i1 = new type([[10, 11, 12, 13],
+ [20, 21, 22, 23],
+ [30, 31, 32, 33],
+ [40, 41, 42, 43]]);
+
+ var r1 = i1.map(2, x => x*2);
+ var r2 = i1.map(1, a => a.map(1, x => x*2));
+ var r3 = i1.map(1, (a, j, c, out) => { out[0] = a[0]*2;
+ out[1] = a[1]*2;
+ out[2] = a[2]*2;
+ out[3] = a[3]*2; });
+ assertTypedEqual(type, r1, new type([[20, 22, 24, 26],
+ [40, 42, 44, 46],
+ [60, 62, 64, 66],
+ [80, 82, 84, 86]]));
+ assertTypedEqual(type, r1, r2);
+ assertTypedEqual(type, r1, r3);
+}
+
+var Grain = new StructType({f: uint32});
+function wrapG(v) { return new Grain({f: v}); }
+function doubleG(g) { return new Grain({f: g.f * 2}); }
+function tenG(x, y) { return new Grain({f: x * 10 + y}); }
+
+function mapOneDimArrayOfStructs() {
+ var type = Grain.array(4);
+ var i1 = type.build(wrapG);
+ var r1 = i1.map(doubleG);
+ var r2 = i1.map(1, doubleG);
+ var r3 = i1.map(1, (g, j, c, out) => { out.f = g.f * 2; });
+ assertTypedEqual(type, r1, new type([{f:0}, {f:2},
+ {f:4}, {f:6}]));
+ assertTypedEqual(type, r1, r2);
+ assertTypedEqual(type, r1, r3);
+}
+
+function mapTwoDimArrayOfStructs() {
+ var rowtype = Grain.array(2);
+ var type = rowtype.array(2);
+ var i1 = type.build(2, tenG);
+ var r1 = i1.map(2, doubleG);
+ var r2 = i1.map(1, (m) => m.map(1, doubleG));
+ var r3 = i1.map(1, (m, j, c, out) => { out[0].f = m[0].f * 2;
+ out[1].f = m[1].f * 2; });
+ assertTypedEqual(type, r1, new type([[{f:00}, {f:02}],
+ [{f:20}, {f:22}]]));
+ assertTypedEqual(type, r1, r2);
+ assertTypedEqual(type, r1, r3);
+}
+
+function runTests() {
+ print(BUGNUMBER + ": " + summary);
+
+ mapOneDimArrayOfUint8();
+ mapOneDimArrayOfUint32();
+
+ mapTwoDimArrayOfUint8();
+ mapTwoDimArrayOfUint32();
+
+ mapOneDimArrayOfStructs();
+ mapTwoDimArrayOfStructs();
+
+ if (typeof reportCompare === "function")
+ reportCompare(true, true);
+ print("Tests complete");
+}
+
+runTests();
diff --git a/js/src/tests/ecma_7/TypedObject/method_reduce.js b/js/src/tests/ecma_7/TypedObject/method_reduce.js
new file mode 100644
index 000000000..7e710d62e
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/method_reduce.js
@@ -0,0 +1,91 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 939715;
+var summary = 'method instance.reduce';
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var ArrayType = TypedObject.ArrayType;
+var StructType = TypedObject.StructType;
+var uint8 = TypedObject.uint8;
+var uint16 = TypedObject.uint16;
+var uint32 = TypedObject.uint32;
+var uint8Clamped = TypedObject.uint8Clamped;
+var int8 = TypedObject.int8;
+var int16 = TypedObject.int16;
+var int32 = TypedObject.int32;
+var float32 = TypedObject.float32;
+var float64 = TypedObject.float64;
+
+function reduceUint8s() {
+ var uint8Array = uint8.array(5);
+ var array = new uint8Array([128, 129, 130, 131, 132]);
+
+ var sum = array.reduce((a, b) => a + b);
+ assertEq(sum, (128+129+130+131+132) % 256);
+
+ var f64Array = float64.array(5);
+ var floats = new f64Array([128.0, 129.0, 130.0, 131.0, 132.0]);
+
+ // (Note that floating point add is not associative in general;
+ // we should double-check that the result below is robust.)
+ var fsum = floats.reduce((a, b) => a + b);
+ assertEq(fsum, 128.0+129.0+130.0+131.0+132.0);
+}
+
+function reduceVectors() {
+ var VectorType = uint32.array(3);
+ var VectorsType = VectorType.array(3);
+ var array = new VectorsType([[1, 2, 3],
+ [4, 5, 6],
+ [7, 8, 9]]);
+
+ var sum = array.reduce(vectorAdd);
+ assertTypedEqual(VectorType,
+ sum,
+ new VectorType([1+4+7,
+ 2+5+8,
+ 3+6+9]));
+
+ // The mutated accumulator does not alias the input.
+ assertTypedEqual(VectorsType,
+ array,
+ new VectorsType([[1, 2, 3],
+ [4, 5, 6],
+ [7, 8, 9]]));
+
+ var sum = array.reduce(vectorAddFunctional);
+ assertTypedEqual(VectorType,
+ sum,
+ new VectorType([1+4+7,
+ 2+5+8,
+ 3+6+9]));
+
+ function vectorAdd(l, r) {
+ assertEq(l.length, r.length);
+ for (var i = 0; i < l.length; i++)
+ l[i] += r[i];
+ return l;
+ }
+
+ function vectorAddFunctional(l, r) {
+ assertEq(l.length, r.length);
+ return VectorType.build(1, i => l[i] + r[i]);
+ }
+
+}
+
+function runTests() {
+ print(BUGNUMBER + ": " + summary);
+
+ reduceUint8s();
+ reduceVectors();
+
+ if (typeof reportCompare === "function")
+ reportCompare(true, true);
+ print("Tests complete");
+}
+
+runTests();
diff --git a/js/src/tests/ecma_7/TypedObject/numerictypes.js b/js/src/tests/ecma_7/TypedObject/numerictypes.js
new file mode 100644
index 000000000..9df58f346
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/numerictypes.js
@@ -0,0 +1,189 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 578700;
+var summary = 'TypedObjects numeric types';
+var actual = '';
+var expect = '';
+
+var ArrayType = TypedObject.ArrayType;
+var StructType = TypedObject.StructType;
+var uint8 = TypedObject.uint8;
+var uint16 = TypedObject.uint16;
+var uint32 = TypedObject.uint32;
+var uint8Clamped = TypedObject.uint8Clamped;
+var int8 = TypedObject.int8;
+var int16 = TypedObject.int16;
+var int32 = TypedObject.int32;
+var float32 = TypedObject.float32;
+var float64 = TypedObject.float64;
+
+function runTests()
+{
+ printBugNumber(BUGNUMBER);
+ printStatus(summary);
+
+ var TestPassCount = 0;
+ var TestFailCount = 0;
+ var TestTodoCount = 0;
+
+ var TODO = 1;
+
+ function check(fun, todo) {
+ var thrown = null;
+ var success = false;
+ try {
+ success = fun();
+ } catch (x) {
+ thrown = x;
+ }
+
+ if (thrown)
+ success = false;
+
+ if (todo) {
+ TestTodoCount++;
+
+ if (success) {
+ var ex = new Error;
+ print ("=== TODO but PASSED? ===");
+ print (ex.stack);
+ print ("========================");
+ }
+
+ return;
+ }
+
+ if (success) {
+ TestPassCount++;
+ } else {
+ TestFailCount++;
+
+ var ex = new Error;
+ print ("=== FAILED ===");
+ print (ex.stack);
+ if (thrown) {
+ print (" threw exception:");
+ print (thrown);
+ }
+ print ("==============");
+ }
+ }
+
+ function checkThrows(fun, todo) {
+ var thrown = false;
+ try {
+ fun();
+ } catch (x) {
+ thrown = true;
+ }
+
+ check(() => thrown, todo);
+ }
+
+ var types = [uint8, uint16, uint32, int8, int16, int32];
+ var strings = ["uint8", "uint16", "uint32", "int8", "int16", "int32"];
+ for (var i = 0; i < types.length; i++) {
+ var type = types[i];
+
+ check(() => type(true) === 1);
+ check(() => type(false) === 0);
+ check(() => type(+Infinity) === 0);
+ check(() => type(-Infinity) === 0);
+ check(() => type(NaN) === 0);
+ check(() => type.toSource() === strings[i]);
+ check(() => type(null) == 0);
+ check(() => type(undefined) == 0);
+ check(() => type([]) == 0);
+ check(() => type({}) == 0);
+ check(() => type(/abcd/) == 0);
+
+ checkThrows(() => new type());
+ checkThrows(() => type());
+ }
+
+ var floatTypes = [float32, float64];
+ var floatStrings = ["float32", "float64"];
+ for (var i = 0; i < floatTypes.length; i++) {
+ var type = floatTypes[i];
+
+ check(() => type(true) === 1);
+ check(() => type(false) === 0);
+ check(() => type(+Infinity) === Infinity);
+ check(() => type(-Infinity) === -Infinity);
+ check(() => Number.isNaN(type(NaN)));
+ check(() => type.toSource() === floatStrings[i]);
+ check(() => type(null) == 0);
+ check(() => Number.isNaN(type(undefined)));
+ check(() => type([]) == 0);
+ check(() => Number.isNaN(type({})));
+ check(() => Number.isNaN(type(/abcd/)));
+
+ checkThrows(() => new type());
+ checkThrows(() => type());
+ }
+
+ ///// test ranges and creation
+ /// uint8
+ // valid
+ check(() => uint8(0) == 0);
+ check(() => uint8(-0) == 0);
+ check(() => uint8(129) == 129);
+ check(() => uint8(255) == 255);
+
+ // overflow is allowed for explicit conversions
+ check(() => uint8(-1) == 255);
+ check(() => uint8(-255) == 1);
+ check(() => uint8(256) == 0);
+ check(() => uint8(2345678) == 206);
+ check(() => uint8(3.14) == 3);
+ check(() => uint8(342.56) == 86);
+ check(() => uint8(-342.56) == 170);
+
+ /// uint8clamped
+ // valid
+ check(() => uint8Clamped(0) == 0);
+ check(() => uint8Clamped(-0) == 0);
+ check(() => uint8Clamped(129) == 129);
+ check(() => uint8Clamped(-30) == 0);
+ check(() => uint8Clamped(254.5) == 254);
+ check(() => uint8Clamped(257) == 255);
+ check(() => uint8Clamped(513) == 255);
+ check(() => uint8Clamped(60000) == 255);
+
+ // strings
+ check(() => uint8("0") == 0);
+ check(() => uint8("255") == 255);
+ check(() => uint8("256") == 0);
+ check(() => uint8("0x0f") == 15);
+ check(() => uint8("0x00") == 0);
+ check(() => uint8("0xff") == 255);
+ check(() => uint8("0x1ff") == 255);
+ // in JS, string literals with leading zeroes are interpreted as decimal
+ check(() => uint8("-0777") == 247);
+ check(() => uint8("-0xff") == 0);
+
+ /// uint16
+ // valid
+ check(() => uint16(65535) == 65535);
+
+ // overflow is allowed for explicit conversions
+ check(() => uint16(-1) == 65535);
+ check(() => uint16(-65535) == 1);
+ check(() => uint16(-65536) == 0);
+ check(() => uint16(65536) == 0);
+
+ // strings
+ check(() => uint16("0x1234") == 0x1234);
+ check(() => uint16("0x00") == 0);
+ check(() => uint16("0xffff") == 65535);
+ check(() => uint16("-0xffff") == 0);
+ check(() => uint16("0xffffff") == 0xffff);
+
+ // wrong types
+ check(() => uint16(3.14) == 3); // c-like casts in explicit conversion
+
+ print("done");
+
+ reportCompare(0, TestFailCount, "TypedObjects numeric type tests");
+}
+
+runTests();
diff --git a/js/src/tests/ecma_7/TypedObject/objecttype.js b/js/src/tests/ecma_7/TypedObject/objecttype.js
new file mode 100644
index 000000000..3f0f3747f
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/objecttype.js
@@ -0,0 +1,38 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 917454;
+var summary = 'objecttype';
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var T = TypedObject;
+
+function runTests() {
+ var Point = T.float32.array(3);
+ var Line = new T.StructType({from: Point, to: Point});
+ var Lines = Line.array(3);
+
+ var lines = new Lines([
+ {from: [1, 2, 3], to: [4, 5, 6]},
+ {from: [7, 8, 9], to: [10, 11, 12]},
+ {from: [13, 14, 15], to: [16, 17, 18]}
+ ]);
+
+ assertEq(T.objectType(lines), Lines);
+ assertEq(T.objectType(lines[0]), Line);
+ assertEq(T.objectType(lines[0].from[0]), T.float64);
+ assertEq(T.objectType(""), T.String);
+ assertEq(T.objectType({}), T.Object);
+ assertEq(T.objectType([]), T.Object);
+ assertEq(T.objectType(function() { }), T.Object);
+ assertEq(T.objectType(undefined), T.Any);
+
+ reportCompare(true, true);
+ print("Tests complete");
+}
+
+runTests();
+
+
diff --git a/js/src/tests/ecma_7/TypedObject/redimension.js b/js/src/tests/ecma_7/TypedObject/redimension.js
new file mode 100644
index 000000000..c061f5a2b
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/redimension.js
@@ -0,0 +1,57 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 922172;
+var summary = 'redimension method';
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var T = TypedObject;
+
+function runTests() {
+ var counter;
+
+ // create an array of 40 bytes with some initial data
+ var Bytes40 = T.uint8.array(40);
+ var bytes40 = new Bytes40();
+ for (var i = 0, counter = 0; i < 40; i++)
+ bytes40[i] = counter++;
+
+ // redimension to an array of 10x4 bytes, check data is unchanged
+ var Bytes10times4 = T.uint8.array(10, 4);
+ var bytes10times4 = bytes40.redimension(Bytes10times4);
+ counter = 0;
+ for (var i = 0; i < 10; i++)
+ for (var j = 0; j < 4; j++)
+ assertEq(counter++, bytes10times4[i][j]);
+
+ // redimension to an array of 2x5x2x2, check data is unchanged
+ var Bytes2times5times2times2 = T.uint8.array(2, 5, 2, 2);
+ var bytes2times5times2times2 = bytes10times4.redimension(Bytes2times5times2times2);
+ counter = 0;
+ for (var i = 0; i < 2; i++)
+ for (var j = 0; j < 5; j++)
+ for (var k = 0; k < 2; k++)
+ for (var l = 0; l < 2; l++)
+ assertEq(counter++, bytes2times5times2times2[i][j][k][l]);
+
+ // test what happens if number of elements does not match
+ assertThrowsInstanceOf(() => {
+ var Bytes10times5 = T.uint8.array(10, 5);
+ bytes40.redimension(Bytes10times5);
+ }, TypeError);
+
+ // test what happens if inner type does not match, even if size is the same
+ assertThrowsInstanceOf(() => {
+ var Words40 = T.uint8Clamped.array(40);
+ bytes40.redimension(Words40);
+ }, TypeError);
+
+ reportCompare(true, true);
+ print("Tests complete");
+}
+
+runTests();
+
+
diff --git a/js/src/tests/ecma_7/TypedObject/referencetypealiasing.js b/js/src/tests/ecma_7/TypedObject/referencetypealiasing.js
new file mode 100644
index 000000000..66e6e16a8
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/referencetypealiasing.js
@@ -0,0 +1,33 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 898359;
+var summary = 'TypedObjects reference type aliasing';
+var actual = '';
+var expect = '';
+
+var ArrayType = TypedObject.ArrayType;
+var StructType = TypedObject.StructType;
+var Any = TypedObject.Any;
+var Object = TypedObject.Object;
+var string = TypedObject.string;
+
+function runTests()
+{
+ printBugNumber(BUGNUMBER);
+ printStatus(summary);
+
+ var MyType = new StructType({f: Object});
+
+ // Test aliasing
+ var myInstance = new MyType({f: {a: 22}});
+ var anotherInstance = new MyType({f: myInstance.f});
+ assertEq(myInstance.f.a, 22);
+ assertEq(myInstance.f.a, anotherInstance.f.a);
+
+ myInstance.f.a += 1;
+ assertEq(myInstance.f.a, 23);
+ assertEq(myInstance.f.a, anotherInstance.f.a);
+
+ reportCompare(true, true, "TypedObjects reference type aliasing tests");
+}
+
+runTests();
diff --git a/js/src/tests/ecma_7/TypedObject/referencetypecoercions.js b/js/src/tests/ecma_7/TypedObject/referencetypecoercions.js
new file mode 100644
index 000000000..0a62b07fd
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/referencetypecoercions.js
@@ -0,0 +1,70 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 898359;
+var summary = 'TypedObjects reference type coercions';
+var actual = '';
+var expect = '';
+
+var ArrayType = TypedObject.ArrayType;
+var StructType = TypedObject.StructType;
+var Any = TypedObject.Any;
+var Object = TypedObject.Object;
+var string = TypedObject.string;
+
+function TestValues(type, values) {
+ for (var i = 0; i < values.length; i++) {
+ compare(type(values[i].input), values[i]);
+ }
+
+ var Struct = new StructType({f: type});
+ for (var i = 0; i < values.length; i++) {
+ var struct = new Struct({f: values[i].input});
+ compare(struct.f, values[i]);
+ }
+
+ for (var i = 0; i < values.length; i++) {
+ var struct = new Struct();
+ struct.f = values[i].input;
+ compare(struct.f, values[i]);
+ }
+
+ var Array = new ArrayType(type, 1);
+ for (var i = 0; i < values.length; i++) {
+ var array = new Array();
+ array[0] = values[i].input;
+ compare(array[0], values[i]);
+ }
+
+ function compare(v, spec) {
+ if (spec.source)
+ v = v.toSource();
+ assertEq(v, spec.output);
+ }
+}
+
+function runTests()
+{
+ printBugNumber(BUGNUMBER);
+ printStatus(summary);
+
+ var x = {};
+
+ TestValues(Any, [{input: undefined, output: undefined},
+ {input: x, output: x},
+ {input: 22.22, output: 22.22},
+ {input: true, output: true}]);
+
+ TestValues(string, [{input: undefined, output: "undefined"},
+ {input: x, output: x.toString()},
+ {input: 22.22, output: "22.22"},
+ {input: true, output: "true"}]);
+
+ assertThrows(() => Object(undefined));
+
+ TestValues(Object, [{input: x, output: x},
+ {input: 22.22, source: true, output: "(new Number(22.22))"},
+ {input: true, source: true, output: "(new Boolean(true))"}]);
+
+ reportCompare(true, true, "TypedObjects reference type tests");
+}
+
+runTests();
diff --git a/js/src/tests/ecma_7/TypedObject/referencetypemultiple.js b/js/src/tests/ecma_7/TypedObject/referencetypemultiple.js
new file mode 100644
index 000000000..f5fc54891
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/referencetypemultiple.js
@@ -0,0 +1,22 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 898359;
+var summary = 'TypedObjects reference type coercions';
+var actual = '';
+var expect = '';
+
+var ArrayType = TypedObject.ArrayType;
+var StructType = TypedObject.StructType;
+var Any = TypedObject.Any;
+var Object = TypedObject.Object;
+var string = TypedObject.string;
+
+
+function runTests()
+{
+ var S = new StructType({f: Any, g: Any});
+ var s = new S({f: "Hello", g: "Hello"});
+ assertEq(s.f, s.g);
+ reportCompare(true, true, "TypedObjects trace tests");
+}
+
+runTests();
diff --git a/js/src/tests/ecma_7/TypedObject/referencetypetrace.js b/js/src/tests/ecma_7/TypedObject/referencetypetrace.js
new file mode 100644
index 000000000..02246c1d2
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/referencetypetrace.js
@@ -0,0 +1,80 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject")||!this.hasOwnProperty("hasChild"))
+var BUGNUMBER = 898359;
+var summary = 'TypedObjects reference type trace';
+var actual = '';
+var expect = '';
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var ArrayType = TypedObject.ArrayType;
+var StructType = TypedObject.StructType;
+var Any = TypedObject.Any;
+var Object = TypedObject.Object;
+var string = TypedObject.string;
+
+function TestStructFields(RefType) {
+ var rabbit = {};
+ var S1 = new StructType({f: RefType});
+ var s1 = new S1({f: rabbit});
+ assertEq(hasChild(s1, rabbit), true);
+ s1.f = null;
+ assertEq(hasChild(s1, rabbit), false);
+}
+
+function TestArrayElements(RefType) {
+ var rabbit = {};
+ var S1 = new ArrayType(RefType, 1);
+ var s1 = new S1([rabbit]);
+ assertEq(hasChild(s1, rabbit), true);
+ s1[0] = null;
+ assertEq(hasChild(s1, rabbit), false);
+}
+
+function TestStructInArray(RefType) {
+ var rabbit = {};
+ var S2 = new StructType({f: RefType, g: RefType});
+ var S1 = new ArrayType(S2, 1);
+ var s1 = new S1([{f: rabbit, g: {}}]);
+ assertEq(hasChild(s1, rabbit), true);
+ s1[0].f = null;
+ assertEq(hasChild(s1, rabbit), false);
+}
+
+function TestStringInStruct() {
+ // Rather subtle hair-pullingly maddening testing phenomena: If you
+ // just use a constant string here, it's always reachable via the
+ // atoms table. Same is true of "Hello" + "1" (an earlier
+ // attempt) due to parser constant folding. So we have to make a
+ // rabbit that's not constant foldable. But don't just use
+ // Math.random(), since small integers are atoms already.
+ var rabbit = "Hello" + Math.random();
+ var S1 = new StructType({f: string});
+ var s1 = new S1({f: rabbit});
+ assertEq(hasChild(s1, rabbit), true);
+ s1.f = "World";
+ assertEq(hasChild(s1, rabbit), false);
+}
+
+function runTests()
+{
+ printBugNumber(BUGNUMBER);
+ printStatus(summary);
+
+ TestStructFields(Object);
+ TestStructFields(Any);
+
+ TestArrayElements(Object);
+ TestArrayElements(Any);
+
+ TestStructInArray(Object);
+ TestStructInArray(Any);
+
+ TestStringInStruct();
+
+ reportCompare(true, true, "TypedObjects trace tests");
+}
+
+runTests();
diff --git a/js/src/tests/ecma_7/TypedObject/referencetypeuninit.js b/js/src/tests/ecma_7/TypedObject/referencetypeuninit.js
new file mode 100644
index 000000000..86e8d7a6d
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/referencetypeuninit.js
@@ -0,0 +1,30 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 898359;
+var summary = 'TypedObjects reference type default values';
+var actual = '';
+var expect = '';
+
+var ArrayType = TypedObject.ArrayType;
+var StructType = TypedObject.StructType;
+var Any = TypedObject.Any;
+var Object = TypedObject.Object;
+var string = TypedObject.string;
+
+function runTests()
+{
+ printBugNumber(BUGNUMBER);
+ printStatus(summary);
+
+ var S = new StructType({any: Any,
+ object: Object,
+ string: string});
+ var s = new S();
+
+ assertEq(s.any, undefined);
+ assertEq(s.object, null);
+ assertEq(s.string, "");
+
+ reportCompare(true, true, "TypedObjects ref type uninit");
+}
+
+runTests();
diff --git a/js/src/tests/ecma_7/TypedObject/scalar_types.js b/js/src/tests/ecma_7/TypedObject/scalar_types.js
new file mode 100644
index 000000000..5d5ea5c02
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/scalar_types.js
@@ -0,0 +1,68 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+
+var BUGNUMBER = 578700;
+var summary = 'Byte-sized type conversion';
+
+var T = TypedObject;
+
+function check(results, ctor) {
+ print("ctor = ", ctor.toSource());
+
+ // check applying the ctor directly
+ for (var i = 0; i < results.length; i++)
+ assertEq(results[i][0], ctor(results[i][1]));
+
+ // check writing and reading from a struct
+ var S = new T.StructType({f: ctor});
+ for (var i = 0; i < results.length; i++) {
+ var s = new S({f: results[i][1]});
+ assertEq(results[i][0], s.f);
+ }
+}
+
+function runTests() {
+ print(BUGNUMBER + ": " + summary);
+
+ var int8results = [
+ [22, 22],
+ [-128, 128],
+ [-1, 255],
+ [-128, -128],
+ [127, -129],
+ [0x75, 0x7575],
+ [-123, 0x7585]
+ ];
+ check(int8results, T.int8);
+
+ var uint8results = [
+ [22, 22],
+ [128, 128],
+ [255, 255],
+ [0, 256],
+ [128, -128],
+ [127, -129],
+ [129, 129],
+ [0x75, 0x7575],
+ [0x85, 0x7585]
+ ];
+ check(uint8results, T.uint8);
+
+ var uint8clampedresults = [
+ [22, 22],
+ [128, 128],
+ [255, 255],
+ [0, -128],
+ [0, -129],
+ [129, 129],
+ [255, 0x7575],
+ [255, 0x7585]
+ ];
+ check(uint8clampedresults, T.uint8Clamped);
+
+ if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+ print("Tests complete");
+}
+
+runTests();
diff --git a/js/src/tests/ecma_7/TypedObject/shell.js b/js/src/tests/ecma_7/TypedObject/shell.js
new file mode 100644
index 000000000..a0471778d
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/shell.js
@@ -0,0 +1,29 @@
+// Checks that |a_orig| and |b_orig| are:
+// 1. Both instances of |type|, and
+// 2. Are structurally equivalent (as dictated by the structure of |type|).
+function assertTypedEqual(type, a_orig, b_orig) {
+ try {
+ recur(type, a_orig, b_orig);
+ } catch (e) {
+ print("failure during "+
+ "assertTypedEqual("+type.toSource()+", "+a_orig.toSource()+", "+b_orig.toSource()+")");
+ throw e;
+ }
+
+ function recur(type, a, b) {
+ if (type instanceof ArrayType) {
+ assertEq(a.length, type.length);
+ assertEq(b.length, type.length);
+ for (var i = 0; i < type.length; i++)
+ recur(type.elementType, a[i], b[i]);
+ } else if (type instanceof StructType) {
+ var fieldNames = Object.getOwnPropertyNames(type.fieldTypes);
+ for (var i = 0; i < fieldNames.length; i++) {
+ var fieldName = fieldNames[i];
+ recur(type.fieldTypes[fieldName], a[fieldName], b[fieldName]);
+ }
+ } else {
+ assertEq(a, b);
+ }
+ }
+}
diff --git a/js/src/tests/ecma_7/TypedObject/simpleequiv.js b/js/src/tests/ecma_7/TypedObject/simpleequiv.js
new file mode 100644
index 000000000..144315262
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/simpleequiv.js
@@ -0,0 +1,25 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 922216;
+var summary = 'TypedObjects Equivalent Numeric Types';
+
+var T = TypedObject;
+
+function runTests() {
+ print(BUGNUMBER + ": " + summary);
+
+ var simpleTypes = [
+ T.int8, T.int16, T.int32,
+ T.uint8, T.uint16, T.uint32,
+ T.float32, T.float64,
+ T.Object, T.Any, T.string
+ ];
+
+ for (var i = 0; i < simpleTypes.length; i++)
+ for (var j = 0; j < simpleTypes.length; j++)
+ assertEq(i == j, simpleTypes[i].equivalent(simpleTypes[j]));
+
+ reportCompare(true, true);
+ print("Tests complete");
+}
+
+runTests();
diff --git a/js/src/tests/ecma_7/TypedObject/size_and_alignment.js b/js/src/tests/ecma_7/TypedObject/size_and_alignment.js
new file mode 100644
index 000000000..c01dc9572
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/size_and_alignment.js
@@ -0,0 +1,61 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 578700;
+var summary = 'Size and Alignment of TypedObjects types';
+var actual = '';
+var expect = '';
+
+
+var ArrayType = TypedObject.ArrayType;
+var StructType = TypedObject.StructType;
+var uint8 = TypedObject.uint8;
+var uint16 = TypedObject.uint16;
+var uint32 = TypedObject.uint32;
+var uint8Clamped = TypedObject.uint8Clamped;
+var int8 = TypedObject.int8;
+var int16 = TypedObject.int16;
+var int32 = TypedObject.int32;
+var float32 = TypedObject.float32;
+var float64 = TypedObject.float64;
+
+
+function runTests() {
+ printBugNumber(BUGNUMBER);
+ printStatus(summary);
+
+ var typesAndAlignments = [
+ {type: uint8, size: 1, alignment: 1},
+ {type: uint8Clamped, size: 1, alignment: 1},
+ {type: uint16, size: 2, alignment: 2},
+ {type: uint32, size: 4, alignment: 4},
+
+ {type: int8, size: 1, alignment: 1},
+ {type: int16, size: 2, alignment: 2},
+ {type: int32, size: 4, alignment: 4},
+
+ {type: float32, size: 4, alignment: 4},
+ {type: float64, size: 8, alignment: 8},
+
+ {type: new StructType({a: uint8, b: uint16, c: uint8}), size: 6, alignment: 2},
+
+ {type: new StructType({a: uint8, b: uint8, c: uint16}), size: 4, alignment: 2},
+
+ {type: new ArrayType(uint8, 32), size: 32, alignment: 1},
+ {type: new ArrayType(uint16, 16), size: 32, alignment: 2},
+ {type: new ArrayType(uint32, 8), size: 32, alignment: 4},
+ ];
+
+ for (var i = 0; i < typesAndAlignments.length; i++) {
+ var test = typesAndAlignments[i];
+ print("Type:", test.type.toSource(),
+ "Size:", test.type.byteLength,
+ "Alignment:", test.type.byteAlignment);
+ assertEq(test.type.byteLength, test.size);
+ assertEq(test.type.byteAlignment, test.alignment);
+ }
+
+ if (typeof reportCompare === "function")
+ reportCompare(true, true);
+ print("Tests complete");
+}
+
+runTests();
diff --git a/js/src/tests/ecma_7/TypedObject/storageopaque.js b/js/src/tests/ecma_7/TypedObject/storageopaque.js
new file mode 100644
index 000000000..b90bd9b10
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/storageopaque.js
@@ -0,0 +1,33 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 898356;
+
+var {StructType, uint32, Object, Any, storage, objectType} = TypedObject;
+
+function main() { // once a C programmer, always a C programmer.
+ print(BUGNUMBER + ": " + summary);
+
+ var Uints = new StructType({f: uint32, g: uint32});
+ var uints = new Uints({f: 0, g: 1});
+ assertEq(storage(uints) != null, true);
+
+ var Objects = new StructType({f: Object, g: Object});
+ var objects = new Objects({f: 0, g: 1});
+ assertEq(storage(objects), null);
+
+ var Anys = new StructType({f: Any, g: Any});
+ var anys = new Anys({f: 0, g: 1});
+ assertEq(storage(anys), null);
+
+ // Note: test that `mixed.g`, when derived from an opaque buffer,
+ // remains opaque.
+ var Mixed = new StructType({f: Object, g: Uints});
+ var mixed = new Mixed({f: 0, g: {f: 22, g: 44}});
+ assertEq(storage(mixed), null);
+ assertEq(objectType(mixed.g), Uints);
+ assertEq(storage(mixed.g), null);
+
+ reportCompare(true, true);
+ print("Tests complete");
+}
+
+main();
diff --git a/js/src/tests/ecma_7/TypedObject/structequiv.js b/js/src/tests/ecma_7/TypedObject/structequiv.js
new file mode 100644
index 000000000..6881e3ba3
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/structequiv.js
@@ -0,0 +1,61 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 922216;
+var summary = 'TypedObjects Equivalent StructTypes';
+
+var ArrayType = TypedObject.ArrayType;
+var StructType = TypedObject.StructType;
+var uint8 = TypedObject.uint8;
+var uint16 = TypedObject.uint16;
+var uint32 = TypedObject.uint32;
+var uint8Clamped = TypedObject.uint8Clamped;
+var int8 = TypedObject.int8;
+var int16 = TypedObject.int16;
+var int32 = TypedObject.int32;
+var float32 = TypedObject.float32;
+var float64 = TypedObject.float64;
+
+function assertEquivalent(t1, t2) {
+ assertEq(true, t1.equivalent(t2));
+ assertEq(true, t2.equivalent(t1));
+}
+
+function assertNotEquivalent(t1, t2) {
+ assertEq(false, t1.equivalent(t2));
+ assertEq(false, t2.equivalent(t1));
+}
+
+function runTests() {
+ print(BUGNUMBER + ": " + summary);
+
+ // Create a line:
+ var PixelType1 = new StructType({x: uint8, y: uint8});
+ var LineType1 = new StructType({from: PixelType1, to: PixelType1});
+
+ // Sanity checks about type equivalence:
+ assertEquivalent(PixelType1, PixelType1);
+ assertEquivalent(LineType1, LineType1);
+ assertNotEquivalent(PixelType1, LineType1);
+
+ // Define the same two types again. Equivalent.
+ var PixelType2 = new StructType({x: uint8, y: uint8});
+ var LineType2 = new StructType({from: PixelType2, to: PixelType2});
+ assertEquivalent(PixelType1, PixelType2);
+ assertEquivalent(LineType1, LineType2);
+
+ // Define the pixel type with field order reversed. Not equivalent.
+ var PixelType3 = new StructType({y: uint8, x: uint8});
+ var LineType3 = new StructType({from: PixelType3, to: PixelType3});
+ assertNotEquivalent(PixelType1, PixelType3);
+ assertNotEquivalent(LineType1, LineType3);
+
+ // Define the line type with field order reversed. Not equivalent.
+ var PixelType4 = new StructType({x: uint8, y: uint8});
+ var LineType4 = new StructType({to: PixelType4, from: PixelType4});
+ assertEquivalent(PixelType1, PixelType4);
+ assertNotEquivalent(LineType1, LineType4);
+
+ reportCompare(true, true);
+ print("Tests complete");
+}
+
+runTests();
diff --git a/js/src/tests/ecma_7/TypedObject/structtypeenumerate.js b/js/src/tests/ecma_7/TypedObject/structtypeenumerate.js
new file mode 100644
index 000000000..3c7bd91a7
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/structtypeenumerate.js
@@ -0,0 +1,36 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 578700;
+var summary = 'TypedObjects StructType propery enumeration';
+
+var ArrayType = TypedObject.ArrayType;
+var StructType = TypedObject.StructType;
+var uint8 = TypedObject.uint8;
+var uint16 = TypedObject.uint16;
+var uint32 = TypedObject.uint32;
+var uint8Clamped = TypedObject.uint8Clamped;
+var int8 = TypedObject.int8;
+var int16 = TypedObject.int16;
+var int32 = TypedObject.int32;
+var float32 = TypedObject.float32;
+var float64 = TypedObject.float64;
+
+function runTests() {
+ var RgbColor = new StructType({r: uint8, g: uint8, b: uint8});
+ var Fade = new StructType({from: RgbColor, to: RgbColor});
+
+ var white = new RgbColor({r: 255, g: 255, b: 255});
+ var gray = new RgbColor({r: 129, g: 128, b: 127});
+ var fade = new Fade({from: white, to: gray});
+
+ var keys = Object.keys(gray);
+ assertEqArray(keys, ["r", "g", "b"]);
+
+ var keys = Object.keys(fade);
+ assertEqArray(keys, ["from", "to"]);
+
+ reportCompare(true, true);
+ print("Tests complete");
+}
+
+runTests();
+
diff --git a/js/src/tests/ecma_7/TypedObject/structtypegetownproperty.js b/js/src/tests/ecma_7/TypedObject/structtypegetownproperty.js
new file mode 100644
index 000000000..aa7907595
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/structtypegetownproperty.js
@@ -0,0 +1,28 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 1122552;
+var summary = 'Introduce [[GetOwnProperty]] object op';
+
+var StructType = TypedObject.StructType;
+var uint8 = TypedObject.uint8;
+
+function runTests() {
+ print(BUGNUMBER + ": " + summary);
+
+ var PixelType = new StructType({x: uint8, y: uint8});
+ var pixel = new PixelType({x: 15, y: 16});
+
+ var desc = Object.getOwnPropertyDescriptor(pixel, 'x');
+ assertEq(typeof desc, "object");
+ assertEq(desc.value, 15);
+ assertEq(desc.enumerable, true);
+ assertEq(desc.writable, true);
+ assertEq(desc.configurable, false);
+
+ desc = Object.getOwnPropertyDescriptor(pixel, 'dummy');
+ assertEq(typeof desc, "undefined");
+
+ reportCompare(true, true);
+ print("Tests complete");
+}
+
+runTests();
diff --git a/js/src/tests/ecma_7/TypedObject/structtypeindexedfields.js b/js/src/tests/ecma_7/TypedObject/structtypeindexedfields.js
new file mode 100644
index 000000000..e94be3cf8
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/structtypeindexedfields.js
@@ -0,0 +1,31 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 578700;
+var summary = 'TypedObjects: indexed properties are illegal in a StructType';
+
+var ArrayType = TypedObject.ArrayType;
+var StructType = TypedObject.StructType;
+var uint8 = TypedObject.uint8;
+var uint16 = TypedObject.uint16;
+var uint32 = TypedObject.uint32;
+var uint8Clamped = TypedObject.uint8Clamped;
+var int8 = TypedObject.int8;
+var int16 = TypedObject.int16;
+var int32 = TypedObject.int32;
+var float32 = TypedObject.float32;
+var float64 = TypedObject.float64;
+
+function runTests() {
+ print(BUGNUMBER + ": " + summary);
+
+ var failed;
+ try {
+ new StructType({1: int32, 2: uint8, 3: float64});
+ failed = false;
+ } catch (e) {
+ failed = true;
+ }
+ reportCompare(failed, true);
+ print("Tests complete");
+}
+
+runTests();
diff --git a/js/src/tests/ecma_7/TypedObject/structtypeprototype.js b/js/src/tests/ecma_7/TypedObject/structtypeprototype.js
new file mode 100644
index 000000000..b54ff4249
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/structtypeprototype.js
@@ -0,0 +1,80 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 578700;
+var summary = 'TypedObjects StructType prototype chains';
+
+var ArrayType = TypedObject.ArrayType;
+var StructType = TypedObject.StructType;
+var uint8 = TypedObject.uint8;
+var uint16 = TypedObject.uint16;
+var uint32 = TypedObject.uint32;
+var uint8Clamped = TypedObject.uint8Clamped;
+var int8 = TypedObject.int8;
+var int16 = TypedObject.int16;
+var int32 = TypedObject.int32;
+var float32 = TypedObject.float32;
+var float64 = TypedObject.float64;
+
+function runTests() {
+ var RgbColor1 = new StructType({r: uint8, g: uint8, b: uint8});
+ var RgbColor2 = new StructType({r: uint8, g: uint8, b: uint8});
+ var Fade1 = new StructType({from: RgbColor1, to: RgbColor1});
+ var Fade2 = new StructType({from: RgbColor2, to: RgbColor2});
+
+ // Available on all struct types (even though it would only make
+ // sense on a RgbColor1 or RgbColor2 instance)
+ StructType.prototype.prototype.sub = function(c) {
+ this.r -= c;
+ this.g -= c;
+ this.b -= c;
+ };
+
+ // Available on `RgbColor2` instances only
+ RgbColor2.prototype.add = function(c) {
+ this.r += c;
+ this.g += c;
+ this.b += c;
+ };
+
+ var black = new RgbColor1({r: 0, g: 0, b: 0});
+ var gray = new RgbColor2({r: 129, g: 128, b: 127});
+
+ // `add` works on `RgbColor2`
+ assertThrows(function() { black.add(1); });
+ gray.add(1);
+ assertEq(130, gray.r);
+ assertEq(129, gray.g);
+ assertEq(128, gray.b);
+
+ // `add` fails (for both!) when accessed via `fade1`
+ var fade1 = new Fade1({from: black, to: gray});
+ assertThrows(function() { fade1.from.add(1); });
+ assertThrows(function() { fade1.to.add(1); });
+
+ // `sub` works on both
+ black.sub(1);
+ assertEq(black.r, 255);
+ assertEq(black.g, 255);
+ assertEq(black.b, 255);
+ gray.sub(1);
+ assertEq(gray.r, 129);
+ assertEq(gray.g, 128);
+ assertEq(gray.b, 127);
+
+ // `add` works (for both!) when accessed via `fade2`
+ var fade2 = new Fade2(fade1);
+ fade2.from.add(1);
+ assertEq(fade2.from.r, 1);
+ assertEq(fade2.from.g, 1);
+ assertEq(fade2.from.b, 1);
+ fade2.to.add(1);
+ assertEq(fade2.to.r, 131);
+ assertEq(fade2.to.g, 130);
+ assertEq(fade2.to.b, 129);
+
+ reportCompare(true, true);
+ print("Tests complete");
+}
+
+runTests();
+
+
diff --git a/js/src/tests/ecma_7/TypedObject/structtypereflection.js b/js/src/tests/ecma_7/TypedObject/structtypereflection.js
new file mode 100644
index 000000000..0904401ed
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/structtypereflection.js
@@ -0,0 +1,47 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 578700;
+var summary = 'TypedObjects: check reflection on StructType objects';
+
+var ArrayType = TypedObject.ArrayType;
+var StructType = TypedObject.StructType;
+var uint8 = TypedObject.uint8;
+var uint16 = TypedObject.uint16;
+var uint32 = TypedObject.uint32;
+var uint8Clamped = TypedObject.uint8Clamped;
+var int8 = TypedObject.int8;
+var int16 = TypedObject.int16;
+var int32 = TypedObject.int32;
+var float32 = TypedObject.float32;
+var float64 = TypedObject.float64;
+
+function runTests() {
+ print(BUGNUMBER + ": " + summary);
+
+ var S = new StructType({x: int32, y: uint8, z: float64});
+ assertEq(S.__proto__, StructType.prototype);
+ assertEq(S.prototype.__proto__, StructType.prototype.prototype);
+ assertEq(S.toSource(), "new StructType({x: int32, y: uint8, z: float64})");
+ assertEq(S.byteLength, 16);
+ assertEq(S.byteAlignment, 8);
+ var fieldNames = Object.getOwnPropertyNames(S.fieldTypes);
+ assertEq(fieldNames[0], "x");
+ assertEq(fieldNames[1], "y");
+ assertEq(fieldNames[2], "z");
+ assertEq(fieldNames.length, 3);
+ assertEq(S.fieldTypes.x, int32);
+ assertEq(S.fieldTypes.y, uint8);
+ assertEq(S.fieldTypes.z, float64);
+ assertEq(S.fieldOffsets.x, 0);
+ assertEq(S.fieldOffsets.y, 4);
+ assertEq(S.fieldOffsets.z, 8);
+
+ // fieldTypes and fieldOffsets should be frozen
+ assertEq(Object.isFrozen(S.fieldTypes), true);
+ assertEq(Object.isFrozen(S.fieldOffsets), true);
+
+ if (typeof reportCompare === "function")
+ reportCompare(true, true);
+ print("Tests complete");
+}
+
+runTests();
diff --git a/js/src/tests/ecma_7/TypedObject/structtypestructuralassign.js b/js/src/tests/ecma_7/TypedObject/structtypestructuralassign.js
new file mode 100644
index 000000000..b16901092
--- /dev/null
+++ b/js/src/tests/ecma_7/TypedObject/structtypestructuralassign.js
@@ -0,0 +1,94 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 578700;
+var summary = 'TypedObjects StructType structural assignment';
+
+var ArrayType = TypedObject.ArrayType;
+var StructType = TypedObject.StructType;
+var uint8 = TypedObject.uint8;
+var uint16 = TypedObject.uint16;
+var uint32 = TypedObject.uint32;
+var uint8Clamped = TypedObject.uint8Clamped;
+var int8 = TypedObject.int8;
+var int16 = TypedObject.int16;
+var int32 = TypedObject.int32;
+var float32 = TypedObject.float32;
+var float64 = TypedObject.float64;
+
+function assertEqColor(c1, c2) {
+ assertEq(c1.r, c2.r);
+ assertEq(c1.g, c2.g);
+ assertEq(c1.b, c2.b);
+}
+
+function runTests() {
+ var RgbColor = new StructType({r: uint8, g: uint8, b: uint8});
+ var Fade = new StructType({from: RgbColor, to: RgbColor});
+
+ var white = new RgbColor({r: 255, g: 255, b: 255});
+ var gray = new RgbColor({r: 129, g: 128, b: 127});
+ var black = new RgbColor({r: 0, g: 0, b: 0});
+
+ var fade = new Fade({from: white, to: white});
+ assertEqColor(white, fade.from);
+ assertEqColor(white, fade.to);
+
+ fade.to = gray;
+ assertEqColor(white, fade.from);
+ assertEqColor(gray, fade.to);
+
+ fade.to = black;
+ assertEqColor(white, fade.from);
+ assertEqColor(black, fade.to);
+
+ fade.to = {r: 129, g: 128, b: 127};
+ assertEqColor(white, fade.from);
+ assertEqColor(gray, fade.to);
+
+ fade.from = {r: 0, g: 0, b: 0};
+ assertEqColor(black, fade.from);
+ assertEqColor(gray, fade.to);
+
+ // Create a variation of color which is still binary data but the
+ // properties are in the wrong order. This will prevent a simple
+ // memcopy, but it should still work, just on the "slow path".
+ var BrgColor = new StructType({b: uint8, r: uint8, g: uint8});
+ var brgGray = new BrgColor(gray);
+ assertEqColor(gray, brgGray);
+
+ fade.from = brgGray;
+ assertEqColor(gray, fade.from);
+
+ // One last test where we have to recursively adapt:
+ var BrgFade = new StructType({from: BrgColor, to: BrgColor});
+ var brgFade = new BrgFade(fade);
+ assertEqColor(brgFade.from, fade.from);
+ assertEqColor(brgFade.to, fade.to);
+
+ // Test that extra and missing properties are ok:
+ fade.from = {r: 129, g: 128, b: 127, a: 126};
+ assertEqColor(fade.from, gray);
+
+ // Missing properties are just treated as undefined:
+ fade.from = {r: 129, g: 128};
+ assertEq(fade.from.r, 129);
+ assertEq(fade.from.g, 128);
+ assertEq(fade.from.b, 0);
+
+ // Which means weird stuff like this is legal:
+ fade.from = [];
+ assertEqColor(fade.from, black);
+ fade.from = {};
+ assertEqColor(fade.from, black);
+
+ // But assignment from a scalar is NOT:
+ var failed = false;
+ try {
+ civic.color = 5;
+ } catch(e) { failed = true; }
+ if (!failed) throw new Exception("Should have thrown");
+
+ reportCompare(true, true);
+ print("Tests complete");
+}
+
+runTests();
diff --git a/js/src/tests/ecma_7/browser.js b/js/src/tests/ecma_7/browser.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/js/src/tests/ecma_7/browser.js
diff --git a/js/src/tests/ecma_7/extensions/browser.js b/js/src/tests/ecma_7/extensions/browser.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/js/src/tests/ecma_7/extensions/browser.js
diff --git a/js/src/tests/ecma_7/extensions/parse-rest-destructuring-parameter.js b/js/src/tests/ecma_7/extensions/parse-rest-destructuring-parameter.js
new file mode 100644
index 000000000..dda67c95f
--- /dev/null
+++ b/js/src/tests/ecma_7/extensions/parse-rest-destructuring-parameter.js
@@ -0,0 +1,27 @@
+// |reftest| skip-if(!xulRuntime.shell)
+/* 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/. */
+
+function funArgs(params) {
+ return Reflect.parse(`function f(${params}) {}`).body[0].rest;
+}
+
+var arrayRest = funArgs("...[]");
+assertEq(arrayRest.type, "ArrayPattern");
+assertEq(arrayRest.elements.length, 0);
+
+arrayRest = funArgs("...[a]");
+assertEq(arrayRest.type, "ArrayPattern");
+assertEq(arrayRest.elements.length, 1);
+
+var objectRest = funArgs("...{}");
+assertEq(objectRest.type, "ObjectPattern");
+assertEq(objectRest.properties.length, 0);
+
+objectRest = funArgs("...{p: a}");
+assertEq(objectRest.type, "ObjectPattern");
+assertEq(objectRest.properties.length, 1);
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_7/extensions/shell.js b/js/src/tests/ecma_7/extensions/shell.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/js/src/tests/ecma_7/extensions/shell.js
diff --git a/js/src/tests/ecma_7/shell.js b/js/src/tests/ecma_7/shell.js
new file mode 100644
index 000000000..f47e78108
--- /dev/null
+++ b/js/src/tests/ecma_7/shell.js
@@ -0,0 +1,205 @@
+/* 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/. */
+
+
+if (typeof assertThrowsInstanceOf === 'undefined') {
+ var assertThrowsInstanceOf = function assertThrowsInstanceOf(f, ctor, msg) {
+ var fullmsg;
+ try {
+ f();
+ } catch (exc) {
+ if (exc instanceof ctor)
+ return;
+ fullmsg = "Assertion failed: expected exception " + ctor.name + ", got " + exc;
+ }
+ if (fullmsg === undefined)
+ fullmsg = "Assertion failed: expected exception " + ctor.name + ", no exception thrown";
+ if (msg !== undefined)
+ fullmsg += " - " + msg;
+ throw new Error(fullmsg);
+ };
+}
+
+if (typeof assertThrowsValue === 'undefined') {
+ var assertThrowsValue = function assertThrowsValue(f, val, msg) {
+ var fullmsg;
+ try {
+ f();
+ } catch (exc) {
+ if ((exc === val) === (val === val) && (val !== 0 || 1 / exc === 1 / val))
+ return;
+ fullmsg = "Assertion failed: expected exception " + val + ", got " + exc;
+ }
+ if (fullmsg === undefined)
+ fullmsg = "Assertion failed: expected exception " + val + ", no exception thrown";
+ if (msg !== undefined)
+ fullmsg += " - " + msg;
+ throw new Error(fullmsg);
+ };
+}
+
+if (typeof assertDeepEq === 'undefined') {
+ var assertDeepEq = (function(){
+ var call = Function.prototype.call,
+ Array_isArray = Array.isArray,
+ Map_ = Map,
+ Error_ = Error,
+ Map_has = call.bind(Map.prototype.has),
+ Map_get = call.bind(Map.prototype.get),
+ Map_set = call.bind(Map.prototype.set),
+ Object_toString = call.bind(Object.prototype.toString),
+ Function_toString = call.bind(Function.prototype.toString),
+ Object_getPrototypeOf = Object.getPrototypeOf,
+ Object_hasOwnProperty = call.bind(Object.prototype.hasOwnProperty),
+ Object_getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor,
+ Object_isExtensible = Object.isExtensible,
+ Object_getOwnPropertyNames = Object.getOwnPropertyNames,
+ uneval_ = uneval;
+
+ // Return true iff ES6 Type(v) isn't Object.
+ // Note that `typeof document.all === "undefined"`.
+ function isPrimitive(v) {
+ return (v === null ||
+ v === undefined ||
+ typeof v === "boolean" ||
+ typeof v === "number" ||
+ typeof v === "string" ||
+ typeof v === "symbol");
+ }
+
+ function assertSameValue(a, b, msg) {
+ try {
+ assertEq(a, b);
+ } catch (exc) {
+ throw Error_(exc.message + (msg ? " " + msg : ""));
+ }
+ }
+
+ function assertSameClass(a, b, msg) {
+ var ac = Object_toString(a), bc = Object_toString(b);
+ assertSameValue(ac, bc, msg);
+ switch (ac) {
+ case "[object Function]":
+ assertSameValue(Function_toString(a), Function_toString(b), msg);
+ }
+ }
+
+ function at(prevmsg, segment) {
+ return prevmsg ? prevmsg + segment : "at _" + segment;
+ }
+
+ // Assert that the arguments a and b are thoroughly structurally equivalent.
+ //
+ // For the sake of speed, we cut a corner:
+ // var x = {}, y = {}, ax = [x];
+ // assertDeepEq([ax, x], [ax, y]); // passes (?!)
+ //
+ // Technically this should fail, since the two object graphs are different.
+ // (The graph of [ax, y] contains one more object than the graph of [ax, x].)
+ //
+ // To get technically correct behavior, pass {strictEquivalence: true}.
+ // This is slower because we have to walk the entire graph, and Object.prototype
+ // is big.
+ //
+ return function assertDeepEq(a, b, options) {
+ var strictEquivalence = options ? options.strictEquivalence : false;
+
+ function assertSameProto(a, b, msg) {
+ check(Object_getPrototypeOf(a), Object_getPrototypeOf(b), at(msg, ".__proto__"));
+ }
+
+ function failPropList(na, nb, msg) {
+ throw Error_("got own properties " + uneval_(na) + ", expected " + uneval_(nb) +
+ (msg ? " " + msg : ""));
+ }
+
+ function assertSameProps(a, b, msg) {
+ var na = Object_getOwnPropertyNames(a),
+ nb = Object_getOwnPropertyNames(b);
+ if (na.length !== nb.length)
+ failPropList(na, nb, msg);
+
+ // Ignore differences in whether Array elements are stored densely.
+ if (Array_isArray(a)) {
+ na.sort();
+ nb.sort();
+ }
+
+ for (var i = 0; i < na.length; i++) {
+ var name = na[i];
+ if (name !== nb[i])
+ failPropList(na, nb, msg);
+ var da = Object_getOwnPropertyDescriptor(a, name),
+ db = Object_getOwnPropertyDescriptor(b, name);
+ var pmsg = at(msg, /^[_$A-Za-z0-9]+$/.test(name)
+ ? /0|[1-9][0-9]*/.test(name) ? "[" + name + "]" : "." + name
+ : "[" + uneval_(name) + "]");
+ assertSameValue(da.configurable, db.configurable, at(pmsg, ".[[Configurable]]"));
+ assertSameValue(da.enumerable, db.enumerable, at(pmsg, ".[[Enumerable]]"));
+ if (Object_hasOwnProperty(da, "value")) {
+ if (!Object_hasOwnProperty(db, "value"))
+ throw Error_("got data property, expected accessor property" + pmsg);
+ check(da.value, db.value, pmsg);
+ } else {
+ if (Object_hasOwnProperty(db, "value"))
+ throw Error_("got accessor property, expected data property" + pmsg);
+ check(da.get, db.get, at(pmsg, ".[[Get]]"));
+ check(da.set, db.set, at(pmsg, ".[[Set]]"));
+ }
+ }
+ };
+
+ var ab = new Map_();
+ var bpath = new Map_();
+
+ function check(a, b, path) {
+ if (typeof a === "symbol") {
+ // Symbols are primitives, but they have identity.
+ // Symbol("x") !== Symbol("x") but
+ // assertDeepEq(Symbol("x"), Symbol("x")) should pass.
+ if (typeof b !== "symbol") {
+ throw Error_("got " + uneval_(a) + ", expected " + uneval_(b) + " " + path);
+ } else if (uneval_(a) !== uneval_(b)) {
+ // We lamely use uneval_ to distinguish well-known symbols
+ // from user-created symbols. The standard doesn't offer
+ // a convenient way to do it.
+ throw Error_("got " + uneval_(a) + ", expected " + uneval_(b) + " " + path);
+ } else if (Map_has(ab, a)) {
+ assertSameValue(Map_get(ab, a), b, path);
+ } else if (Map_has(bpath, b)) {
+ var bPrevPath = Map_get(bpath, b) || "_";
+ throw Error_("got distinct symbols " + at(path, "") + " and " +
+ at(bPrevPath, "") + ", expected the same symbol both places");
+ } else {
+ Map_set(ab, a, b);
+ Map_set(bpath, b, path);
+ }
+ } else if (isPrimitive(a)) {
+ assertSameValue(a, b, path);
+ } else if (isPrimitive(b)) {
+ throw Error_("got " + Object_toString(a) + ", expected " + uneval_(b) + " " + path);
+ } else if (Map_has(ab, a)) {
+ assertSameValue(Map_get(ab, a), b, path);
+ } else if (Map_has(bpath, b)) {
+ var bPrevPath = Map_get(bpath, b) || "_";
+ throw Error_("got distinct objects " + at(path, "") + " and " + at(bPrevPath, "") +
+ ", expected the same object both places");
+ } else {
+ Map_set(ab, a, b);
+ Map_set(bpath, b, path);
+ if (a !== b || strictEquivalence) {
+ assertSameClass(a, b, path);
+ assertSameProto(a, b, path);
+ assertSameProps(a, b, path);
+ assertSameValue(Object_isExtensible(a),
+ Object_isExtensible(b),
+ at(path, ".[[Extensible]]"));
+ }
+ }
+ }
+
+ check(a, b, "");
+ };
+ })();
+}