diff options
Diffstat (limited to 'js/src/tests/ecma_7')
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, ""); + }; + })(); +} |