diff --git a/implementation-contributed/javascriptcore/wasm/README.md b/implementation-contributed/javascriptcore/wasm/README.md deleted file mode 100644 index 06515755fb62d147ed35380e532c0372d2961c98..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/README.md +++ /dev/null @@ -1,98 +0,0 @@ -# `wasmjs`: JavaScript tooling for WebAssembly - -`wasmjs` is a self-contained collection of JavaScript tools which can create and -manipulate WebAssembly representations and binaries. At its core is `wasm.json`, -a JSON decription of the WebAssembly format and other interesting facts about -WebAssembly as used by the Webkit project (such as the names of associated -JavaScriptCore B3 opcodes). - -`wasmjs` requires modern JavaScript features such as ES6 modules, which is -acceptable because WebAssembly is itself contemporary to these other features. - - -# `Builder` API - -The current core API of `wasmjs` is the `Builder` API from `Builder.js`. It is -used to build WebAssembly modules, and assemble them to valid `.wasm` binaries -(held in an `ArrayBuffer`). The `Builder` is a small DSL which looks similar to -the WebAssembly [binary format][]. Each section is declared through a property -on the `Builder` object, and each declaration returns a proxy object which has -properties specific to that section. Proxies are "popped" back by invoking their -`.End()` property. - -The `Code` section has properties for each [WebAssembly opcode][]. Opcode which -create a scope can be nested using a lambda. - - [binary format]: https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md#high-level-structure - [WebAssembly opcode]: https://github.com/WebAssembly/design/blob/master/Semantics.md - -A simple example: - -```javascript -import Builder from 'Builder.js'; - -const builder = new Builder(); - -// Construct the equivalent of: (module (func "answer" (i32.const 42) (return))) -builder - // Declare a Type section, which the builder will auto-fill as functions are defined. - .Type().End() - // Declare a Function section, which the builder will auto-fill as functions are defined. - .Function().End() - .Export() - // Export the "answer" function (defined below) to JavaScript. - .Function("answer") - .End() - .Code() - // The "answer" function takes an i32 parameters, and returns an i32. - .Function("answer", { params: ["i32"], ret: "i32" }) - // Create a block returning an i32, whose body is the enclosed lambda. - .Block("i32", b => b - .GetLocal(0) // Parameters are in the same index space as locals. - .I32Const(0) // Generate an i32 constant. - .I32Eq() // A comparison, using the two values currently on the stack. - .If("i32") // Consume the comparison result, returning an i32. - .I32Const(42) - .Else() - .I32Const(1) - .End() - ) - .Return() // Return the top of the stack: the value returned by the block. - .End() // End the current function. - .End(); // End the Code section. - -// Create an ArrayBuffer which is a valid WebAssembly `.wasm` file. -const bin = builder.WebAssembly().get(); - -// Use the standard WebAssembly JavaScript API to compile the module, and instantiate it. -const module = new WebAssembly.Module(bin); -const instance = new WebAssembly.Instance(module); - -// Invoke the compiled WebAssembly function. -const result0 = instance.exports.answer(0); -if (result0 !== 42) - throw new Error(`Expected 42, got ${result0}.`); - -const result1 = instance.exports.answer(1); -if (result1 !== 1) - throw new Error(`Expected 1, got ${result1}.`); -``` - - -# Testing - -* `self-test` tests `wasmjs` itself. -* `js-api` tests the [WebAssembly JavaScript API](https://github.com/WebAssembly/design/blob/master/JS.md). -* `function-tests` tests the WebAssembly compiler's implementation. - -All tests can be executed using: - -```bash -JSSHELL=/path/to/my/js-shell test.sh -``` - -They can also be executed by using WebKit's `run-javascriptcore-tests` tool: - -```bash -./Tools/Scripts/run-javascriptcore-tests --release --filter wasm -arch x86_64 -``` diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/add-12.js b/implementation-contributed/javascriptcore/wasm/function-tests/add-12.js deleted file mode 100644 index 67ac1d72db329e0169ae9a284bc5eb0ce007c9ce..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/add-12.js +++ /dev/null @@ -1,72 +0,0 @@ -import Builder from '../Builder.js' -import * as assert from '../assert.js' - -const b = new Builder(); -b.Type().End() - .Function().End() - .Export().Function("f0").Function("f1").End() - .Code() - .Function("f0", { params: ["i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32"], ret: "i32" }) - .GetLocal(0) - .GetLocal(1) - .I32Add() - .GetLocal(2) - .I32Add() - .GetLocal(3) - .I32Add() - .GetLocal(4) - .I32Add() - .GetLocal(5) - .I32Add() - .GetLocal(6) - .I32Add() - .GetLocal(7) - .I32Add() - .GetLocal(8) - .I32Add() - .GetLocal(9) - .I32Add() - .GetLocal(10) - .I32Add() - .GetLocal(11) - .I32Add() - .Return() - .End() - .Function("f1", { params: ["i32"], ret: "i32" }) - .GetLocal(0) - .GetLocal(0) - .GetLocal(0) - .GetLocal(0) - .GetLocal(0) - .GetLocal(0) - .GetLocal(0) - .GetLocal(0) - .GetLocal(0) - .GetLocal(0) - .GetLocal(0) - .GetLocal(0) - .Call(0) - .Return() - .End() - .End() - -const bin = b.WebAssembly().get(); -const instance = new WebAssembly.Instance(new WebAssembly.Module(bin)); -function testWasmModuleFunctions(...tests) { - for (let i = 0; i < tests.length; i++) { - const func = instance.exports['f' + i]; - for (let test of tests[i]) { - let result = test[0].value; - let args = test[1].map(x => x.value); - assert.eq(result, func(...args)); - } - } -} - -testWasmModuleFunctions([[{ type: "i32", value: 78 }, [{ type: "i32", value: 1 }, { type: "i32", value: 2 }, { type: "i32", value: 3 }, { type: "i32", value: 4 }, { type: "i32", value: 5 }, { type: "i32", value: 6 }, { type: "i32", value: 7 }, { type: "i32", value: 8 }, { type: "i32", value: 9 }, { type: "i32", value: 10 }, { type: "i32", value: 11 }, { type: "i32", value: 12 }]], - [{ type: "i32", value: 166 }, [{ type: "i32", value: 1 }, { type: "i32", value: 2 }, { type: "i32", value: 3 }, { type: "i32", value: 4 }, { type: "i32", value: 5 }, { type: "i32", value: 6 }, { type: "i32", value: 7 }, { type: "i32", value: 8 }, { type: "i32", value: 9 }, { type: "i32", value: 10 }, { type: "i32", value: 11 }, { type: "i32", value: 100 }]] - ], - [[{ type: "i32", value: 12 }, [{ type: "i32", value: 1 }]], - [{ type: "i32", value: 1200 }, [{ type: "i32", value: 100 }]], - [{ type: "i32", value: 0 }, [{ type: "i32", value: 0 }]], - ]); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/basic-element.js b/implementation-contributed/javascriptcore/wasm/function-tests/basic-element.js deleted file mode 100644 index 114f3c814c06aa5d1be516c6217e24971211a290..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/basic-element.js +++ /dev/null @@ -1,34 +0,0 @@ -import Builder from '../Builder.js'; -import * as assert from '../assert.js'; - - -const tableDescription = {initial: 1, element: "anyfunc"}; -const builder = new Builder() - .Type().End() - .Import() - .Table("imp", "table", tableDescription) - .End() - .Function().End() - .Element() - .Element({tableIndex: 0, offset: 0, functionIndices: [0]}) - .End() - .Code() - .Function("foo", {params: ["i32"], ret: "i32"}) - .GetLocal(0) - .I32Const(42) - .I32Add() - .Return() - .End() - .End(); - -const bin = builder.WebAssembly().get(); -const module = new WebAssembly.Module(bin); -const table = new WebAssembly.Table(tableDescription); -new WebAssembly.Instance(module, {imp: {table}}); -const foo = table.get(0); -const objs = []; -for (let i = 0; i < 10000; i++) { - objs.push(new String("foo")); - if (foo(20) !== 20 + 42) - throw new Error("bad!!!"); -} diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/br-as-return.js b/implementation-contributed/javascriptcore/wasm/function-tests/br-as-return.js deleted file mode 100644 index 763657fc0907576428c2360931d00a43dd3dcb89..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/br-as-return.js +++ /dev/null @@ -1,31 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -const builder = (new Builder()) - .Type().End() - .Function().End() - .Export() - .Function("br1") - .Function("br0") - .End() - .Code() - .Function("br1", { params: [], ret: "i32" }) - .Block("void", b => { - return b.I32Const(0) - .Br(1) - }) - .Unreachable() - .End() - - .Function("br0", { params: [], ret: "i32" }) - .I32Const(0) - .Br(0) - .End() - - .End(); - -const bin = builder.WebAssembly().get(); -const module = new WebAssembly.Module(bin); -const instance = new WebAssembly.Instance(module); -assert.eq(instance.exports.br1(), 0) -assert.eq(instance.exports.br0(), 0) diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/br-if-as-return.js b/implementation-contributed/javascriptcore/wasm/function-tests/br-if-as-return.js deleted file mode 100644 index ea2e6bd4a227aaf93427638b3ccc78349360fb95..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/br-if-as-return.js +++ /dev/null @@ -1,32 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -const builder = (new Builder()) - .Type().End() - .Function().End() - .Export() - .Function("br1") - .Function("br0") - .End() - .Code() - .Function("br1", { params: [], ret: "i32" }) - .Block("i32", b => { - return b.I32Const(0) - .I32Const(1) - .BrIf(1) - }) - .End() - - .Function("br0", { params: [], ret: "i32" }) - .I32Const(0) - .I32Const(1) - .BrIf(0) - .End() - - .End(); - -const bin = builder.WebAssembly().get(); -const module = new WebAssembly.Module(bin); -const instance = new WebAssembly.Instance(module); -assert.eq(instance.exports.br1(), 0) -assert.eq(instance.exports.br0(), 0) diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/br-if-loop-less-than.js b/implementation-contributed/javascriptcore/wasm/function-tests/br-if-loop-less-than.js deleted file mode 100644 index ee05e159a055ecb4dd47a063cf14094e0039c465..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/br-if-loop-less-than.js +++ /dev/null @@ -1,65 +0,0 @@ -import Builder from '../Builder.js' -import * as assert from '../assert.js' - -const b = new Builder(); -b.Type().End() - .Function().End() - .Export().Function("f0").End() - .Code() - .Function("f0", { params: ["i32", "i32"], ret: "i32" }) - .Loop("void") - .Block("void", b => - b.Block("void", b => - b.GetLocal(0) - .GetLocal(1) - .I32Eq() - .BrIf(0) - .Br(1) - ) - .I32Const(0) - .Return() - ) - .Block("void", b => - b.Block("void", b => - b.GetLocal(0) - .I32Const(0) - .I32Eq() - .BrIf(0) - .Br(1) - ) - .I32Const(1) - .Return() - ) - .GetLocal(0) - .I32Const(1) - .I32Sub() - .SetLocal(0) - .Br(0) - .End() - .Unreachable() - .End() - .End() - -const bin = b.WebAssembly().get(); -const instance = new WebAssembly.Instance(new WebAssembly.Module(bin)); - -function testWasmModuleFunctions(...tests) { - for (let i = 0; i < tests.length; i++) { - const func = instance.exports['f' + i]; - for (let test of tests[i]) { - let result = test[0].value; - let args = test[1].map(x => x.value); - assert.eq(result, func(...args)); - } - } -} - -testWasmModuleFunctions([[{type: "i32", value: 1 }, [{ type: "i32", value: 0 }, { type: "i32", value: 1 }]], - [{type: "i32", value: 0 }, [{ type: "i32", value: 1 }, { type: "i32", value: 0 }]], - [{type: "i32", value: 0 }, [{ type: "i32", value: 2 }, { type: "i32", value: 1 }]], - [{type: "i32", value: 1 }, [{ type: "i32", value: 1 }, { type: "i32", value: 2 }]], - [{type: "i32", value: 0 }, [{ type: "i32", value: 2 }, { type: "i32", value: 2 }]], - [{type: "i32", value: 0 }, [{ type: "i32", value: 1 }, { type: "i32", value: 1 }]], - [{type: "i32", value: 1 }, [{ type: "i32", value: 2 }, { type: "i32", value: 6 }]], - [{type: "i32", value: 0 }, [{ type: "i32", value: 100 }, { type: "i32", value: 6 }]] - ]); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/br-table-as-return.js b/implementation-contributed/javascriptcore/wasm/function-tests/br-table-as-return.js deleted file mode 100644 index c7ad86b77a1b6fffd4e011829ec4efbdd3875606..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/br-table-as-return.js +++ /dev/null @@ -1,52 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -const builder = (new Builder()) - .Type().End() - .Function().End() - .Export() - .Function("br1Default") - .Function("br0Default") - .Function("br1Case") - .Function("br0Case") - .End() - .Code() - .Function("br1Default", { params: [], ret: "i32" }) - .Block("void", b => { - return b.I32Const(0) - .I32Const(100) - .BrTable(1, 1) - }) - .Unreachable() - .End() - - .Function("br0Default", { params: [], ret: "i32" }) - .I32Const(0) - .I32Const(100) - .BrTable(0, 0) - .End() - - .Function("br1Case", { params: [], ret: "i32" }) - .Block("void", b => { - return b.I32Const(0) - .I32Const(100) - .BrTable(1, 1) - }) - .Unreachable() - .End() - - .Function("br0Case", { params: [], ret: "i32" }) - .I32Const(0) - .I32Const(0) - .BrTable(0, 0) - .End() - - .End(); - -const bin = builder.WebAssembly().get(); -const module = new WebAssembly.Module(bin); -const instance = new WebAssembly.Instance(module); -assert.eq(instance.exports.br1Default(), 0) -assert.eq(instance.exports.br0Default(), 0) -assert.eq(instance.exports.br1Case(), 0) -assert.eq(instance.exports.br0Case(), 0) diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/brTableAsIf.js b/implementation-contributed/javascriptcore/wasm/function-tests/brTableAsIf.js deleted file mode 100644 index 0e3fe766854259ede9e3c1bab0e44e984c7bda2b..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/brTableAsIf.js +++ /dev/null @@ -1,38 +0,0 @@ -import Builder from '../Builder.js' -import * as assert from '../assert.js' - -const b = new Builder(); -b.Type().End() - .Function().End() - .Export().Function('f0').End() - .Code() - .Function('f0', { params: ["i32"], ret: "i32" }, ["i32"]) - .Block("void", (b) => - b.Block("void", (b) => - b.GetLocal(0) - .BrTable(1, 0) - .I32Const(21) - .Return() - ).I32Const(20) - .Return() - ).I32Const(22) - .End() - .End() - -const bin = b.WebAssembly().get(); -const instance = new WebAssembly.Instance(new WebAssembly.Module(bin)); -function testWasmModuleFunctions(...tests) { - for (let i = 0; i < tests.length; i++) { - const func = instance.exports['f' + i]; - for (let test of tests[i]) { - let result = test[0].value; - let args = test[1].map(x => x.value); - assert.eq(result, func(...args)); - } - } -} -testWasmModuleFunctions([[{type: "i32", value: 22 }, [{ type: "i32", value: 0 }]], - [{type: "i32", value: 20 }, [{ type: "i32", value: 1 }]], - [{type: "i32", value: 20 }, [{ type: "i32", value: 11 }]], - [{type: "i32", value: 20 }, [{ type: "i32", value: -100 }]] - ]); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/brTableManyValues.js b/implementation-contributed/javascriptcore/wasm/function-tests/brTableManyValues.js deleted file mode 100644 index 2c4ef16bb7c63daeb148811df4eec18caff02992..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/brTableManyValues.js +++ /dev/null @@ -1,56 +0,0 @@ -import Builder from '../Builder.js' -import * as assert from '../assert.js' - -const b = new Builder(); -b.Type().End() - .Function().End() - .Export().Function('f0').End() - .Code() - .Function('f0', { params: ["i32"], ret: "i32" }, ["i32"]) - .Block("i32", (b) => - b.Block("i32", (b) => - b.Block("i32", (b) => - b.Block("i32", (b) => - b.Block("i32", (b) => - b.I32Const(200) - .GetLocal(0) - .BrTable(3, 2, 1, 0, 4) - ).I32Const(10) - .I32Add() - .Return() - ).I32Const(11) - .I32Add() - .Return() - ).I32Const(12) - .I32Add() - .Return() - ).I32Const(13) - .I32Add() - .Return() - ).I32Const(14) - .I32Add() - .Return() - .End() - .End() - -const bin = b.WebAssembly().get(); -const instance = new WebAssembly.Instance(new WebAssembly.Module(bin)); -function testWasmModuleFunctions(...tests) { - for (let i = 0; i < tests.length; i++) { - const func = instance.exports['f' + i]; - for (let test of tests[i]) { - let result = test[0].value; - let args = test[1].map(x => x.value); - assert.eq(result, func(...args)); - } - } -} -testWasmModuleFunctions([[{type: "i32", value: 213 }, [{ type: "i32", value: 0 }]], - [{type: "i32", value: 212 }, [{ type: "i32", value: 1 }]], - [{type: "i32", value: 211 }, [{ type: "i32", value: 2 }]], - [{type: "i32", value: 210 }, [{ type: "i32", value: 3 }]], - [{type: "i32", value: 214 }, [{ type: "i32", value: 4 }]], - [{type: "i32", value: 214 }, [{ type: "i32", value: 5 }]], - [{type: "i32", value: 214 }, [{ type: "i32", value: -1 }]], - [{type: "i32", value: 214 }, [{ type: "i32", value: -1000 }]] - ]); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/brTableWithLoop.js b/implementation-contributed/javascriptcore/wasm/function-tests/brTableWithLoop.js deleted file mode 100644 index 86d1811386de62f45ca5a1940d662da490fe9de7..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/brTableWithLoop.js +++ /dev/null @@ -1,42 +0,0 @@ -import Builder from '../Builder.js' -import * as assert from '../assert.js' - -const b = new Builder(); -b.Type().End() - .Function().End() - .Export().Function('f0').End() - .Code() - .Function('f0', { params: ["i32"], ret: "i32" }, ["i32"]) - .Loop("void") - .Block("void", (b) => - - b.GetLocal(0) - .GetLocal(1) - .I32Const(1) - .I32Add() - .SetLocal(1) - .GetLocal(0) - .I32Const(1) - .I32Sub() - .SetLocal(0) - .BrTable(0, 1)) - .End() - .GetLocal(1) - .End() - .End() - -const bin = b.WebAssembly().get(); -const instance = new WebAssembly.Instance(new WebAssembly.Module(bin)); -function testWasmModuleFunctions(...tests) { - for (let i = 0; i < tests.length; i++) { - const func = instance.exports['f' + i]; - for (let test of tests[i]) { - let result = test[0].value; - let args = test[1].map(x => x.value); - assert.eq(result, func(...args)); - } - } -} -testWasmModuleFunctions([[{type: "i32", value: 1 }, [{ type: "i32", value: 0 }]], - [{type: "i32", value: 2 }, [{ type: "i32", value: 1 }]] - ]); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/context-switch.js b/implementation-contributed/javascriptcore/wasm/function-tests/context-switch.js deleted file mode 100644 index 0595e6d9eecba8850c6b6c3ce21e0eb1adefa4da..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/context-switch.js +++ /dev/null @@ -1,277 +0,0 @@ -import Builder from '../Builder.js' -import * as assert from '../assert.js' - -{ - function makeInstance() { - const tableDescription = {initial: 1, element: "anyfunc"}; - const builder = new Builder() - .Type() - .Func([], "void") - .End() - .Import() - .Table("imp", "table", tableDescription) - .End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", {params:["i32"], ret:"void"}) - .GetLocal(0) // parameter to call - .GetLocal(0) // call index - .CallIndirect(0, 0) // calling function of type [] => 'void' - .Return() - .End() - .End(); - - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const table = new WebAssembly.Table(tableDescription); - return {instance: new WebAssembly.Instance(module, {imp: {table}}), table}; - } - - function makeInstance2(f) { - const builder = new Builder() - .Type() - .End() - .Import() - .Function("imp", "f", {params:[], ret:"void"}) - .End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", {params: [], ret: "void" }) - .Call(0) - .Return() - .End() - .End(); - - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - return new WebAssembly.Instance(module, {imp: {f}}); - } - - const {instance: i1, table: t1} = makeInstance(); - const foo = i1.exports.foo; - - let called = false; - let shouldThrow = false; - const i2 = makeInstance2(function() { - called = true; - if (shouldThrow) - throw new Error("Threw"); - }); - - t1.set(0, i2.exports.foo); - for (let i = 0; i < 1000; ++i) { - foo(0); - assert.eq(called, true); - called = false; - } - shouldThrow = true; - for (let i = 0; i < 1000; ++i) { - assert.throws(() => foo(0), Error, "Threw"); - assert.eq(called, true); - called = false; - } -} - -{ - function makeInstance() { - const tableDescription = {initial: 1, element: "anyfunc"}; - const builder = new Builder() - .Type() - .Func(["i32"], "void") - .End() - .Import() - .Table("imp", "table", tableDescription) - .End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", {params:["i32", "i32"], ret:"void"}) - .GetLocal(1) // parameter to call - .GetLocal(0) // call index - .CallIndirect(0, 0) // calling function of type ['i32'] => 'void' - .Return() - .End() - .End(); - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const table = new WebAssembly.Table(tableDescription); - return {instance: new WebAssembly.Instance(module, {imp: {table}}), table}; - } - - function makeInstance2(memory, f) { - const builder = new Builder() - .Type() - .End() - .Import() - .Function("imp", "f", {params:['i32', 'i32'], ret:"void"}) - .Memory("imp", "memory", memoryDescription) - .End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", {params: ["i32"], ret: "void" }) - .GetLocal(0) - .GetLocal(0) - .I32Load(2, 0) - .Call(0) - .Return() - .End() - .End(); - - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - return new WebAssembly.Instance(module, {imp: {f, memory}}); - } - - const {instance: i1, table: t1} = makeInstance(); - const foo = (memOffset) => i1.exports.foo(0, memOffset); - - const memoryDescription = {initial:1}; - const mem = new WebAssembly.Memory(memoryDescription); - let called = false; - - const pageSize = 64 * 1024; - let buf = new Uint32Array(mem.buffer); - const i2 = makeInstance2(mem, function(i, value) { - assert.eq(i & 3, 0); - assert.eq(buf[i/4], value); - called = true; - }); - t1.set(0, i2.exports.foo); - - for (let i = 0; i < pageSize/4; ++i) { - buf[i] = i+1; - } - - for (let i = 0; i < pageSize/4; ++i) { - foo(i*4); - assert.eq(called, true); - called = false; - } - - for (let i = pageSize/4; i < 2*pageSize/4; ++i) { - assert.throws(() => foo(i*4), WebAssembly.RuntimeError, "Out of bounds memory access"); - assert.eq(called, false); - } -} - -{ - function makeInstance() { - const tableDescription = {initial: 1, element: "anyfunc"}; - const builder = new Builder() - .Type() - .Func(["i32"], "void") - .End() - .Import() - .Table("imp", "table", tableDescription) - .End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", {params:["i32", "i32"], ret:"void"}) - .GetLocal(1) // parameter to call - .GetLocal(0) // call index - .CallIndirect(0, 0) // calling function of type ['i32'] => 'void' - .Return() - .End() - .End(); - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const table = new WebAssembly.Table(tableDescription); - return {instance: new WebAssembly.Instance(module, {imp: {table}}), table}; - } - - function makeInstance2(memory, f) { - const builder = new Builder() - .Type() - .End() - .Import() - .Function("imp", "f", {params:['i32', 'i32'], ret:"void"}) - .Memory("imp", "memory", memoryDescription) - .End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", {params: ["i32"], ret: "void" }) - .GetLocal(0) - .GetLocal(0) - .I32Load(2, 0) - .Call(0) - .Return() - .End() - .End(); - - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - return new WebAssembly.Instance(module, {imp: {f, memory}}); - } - - function exportImport(f) { - let builder = (new Builder()) - .Type().End() - .Import() - .Function("imp", "f", {params: ['i32'], ret:"void"}) - .End() - .Function().End() - .Export() - .Function("func", {module: "imp", field: "f"}) - .End() - .Code().End(); - return (new WebAssembly.Instance(new WebAssembly.Module(builder.WebAssembly().get()), {imp: {f}})).exports.func; - } - - const {instance: i1, table: t1} = makeInstance(); - const foo = (memOffset) => i1.exports.foo(0, memOffset); - - const memoryDescription = {initial:1}; - const mem = new WebAssembly.Memory(memoryDescription); - let called = false; - - const pageSize = 64 * 1024; - let buf = new Uint32Array(mem.buffer); - const i2 = makeInstance2(mem, function(i, value) { - assert.eq(i & 3, 0); - assert.eq(buf[i/4], value); - called = true; - }); - - const exportedImport = exportImport(function(offset) { - i2.exports.foo(offset); - }); - t1.set(0, exportedImport); - - for (let i = 0; i < pageSize/4; ++i) { - buf[i] = i+1; - } - - for (let i = 0; i < pageSize/4; ++i) { - foo(i*4); - assert.eq(called, true); - called = false; - } - - for (let i = pageSize/4; i < 2*pageSize/4; ++i) { - assert.throws(() => foo(i*4), WebAssembly.RuntimeError, "Out of bounds memory access"); - assert.eq(called, false); - } -} diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/dead-call.js b/implementation-contributed/javascriptcore/wasm/function-tests/dead-call.js deleted file mode 100644 index d56e15b11d205946ba2e24091a5eb72c39f59fa1..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/dead-call.js +++ /dev/null @@ -1,29 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -const builder = (new Builder()) - .Type().End() - .Function().End() - .Export() - .Function("dead-call") - .End() - .Code() - .Function("crash", { params: [], ret: "i32" }) - .Unreachable() - .End() - - .Function("dead-call", { params: [], ret: "i32" }) - .I32Const(0) - .If("i32", b => - b.Call(0) - .Return() - .Else() - .I32Const(1) - ) - .End() - - .End(); - -const bin = builder.WebAssembly().get(); -const module = new WebAssembly.Module(bin); -const instance = new WebAssembly.Instance(module); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/double-instance.js b/implementation-contributed/javascriptcore/wasm/function-tests/double-instance.js deleted file mode 100644 index 0c4eadddd1288e7131c4e846f17955ee143ca182..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/double-instance.js +++ /dev/null @@ -1,64 +0,0 @@ -import Builder from '../Builder.js' -import * as assert from '../assert.js' - -// The call sequence is as follows: -// -// js -js2wasm-> i1.callAnother() -// -wasm2wasm-> i0.callAnother() -// -wasm2js-> i1.boom() -// -calldirect-> i1.doStackCheck() -// -calldirect-> dummy() -// -calldirect-> i1.doStackCheck() -// -calldirect-> dummy() -// -// We therefore have i1 indirectly calling into itself, through another -// instance. When returning its cached stack limit should still be valid, but -// our implementation used to set it to UINTPTR_MAX causing an erroneous stack -// check failure at the second doStackCheck() call. - -const builder = new Builder() - .Type() - .End() - .Import() - .Function("imp", "boom", {params:["i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32"], ret:"i32"}) - .Function("imp", "callAnother", {params:["i32"], ret:"i32"}) - .End() - .Function().End() - .Export() - .Function("boom") - .Function("callAnother") - .End() - .Code() - .Function("boom", {params:["i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32"], ret:"i32"}) - /* call doStackCheck */.GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).Call(4) - .Return() - .End() - .Function("callAnother", {params:["i32"], ret:"i32"}) - /* call imp:callAnother */.GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).Call(1) - /* call doStackCheck */.GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).Call(4) - .Return() - .End() - .Function("doStackCheck", {params:["i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32"], ret:"i32"}) - /* call dummy */.GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).GetLocal(0).Call(5) - .Return() - .End() - .Function("dummy", {params:["i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32"], ret:"i32"}) - .GetLocal(0) - .Return() - .End() - .End(); - -const bin = builder.WebAssembly().get(); -const module = new WebAssembly.Module(bin); - -let i1; - -const imp = { - boom: () => { throw new Error(`This boom should not get called!`); }, - callAnother: () => { i1.exports["boom"](0xdeadbeef); }, -} - -const i0 = new WebAssembly.Instance(module, { imp }); -i1 = new WebAssembly.Instance(module, { imp: i0.exports }); - -i1.exports["callAnother"](0xc0defefe); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/exceptions.js b/implementation-contributed/javascriptcore/wasm/function-tests/exceptions.js deleted file mode 100644 index 952513f265a3f06f9c679333aaefd4a976da9972..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/exceptions.js +++ /dev/null @@ -1,67 +0,0 @@ -import Builder from '../Builder.js' -import * as assert from '../assert.js' - -function makeInstance() { - const tableDescription = {initial: 1, element: "anyfunc"}; - const builder = new Builder() - .Type() - .Func(["i32", "i32"], "i32") - .Func(["i32"], "i32") - .End() - .Import() - .Table("imp", "table", tableDescription) - .End() - .Function().End() - .Export() - .Function("foo") - .Function("bar") - .End() - .Code() - .Function("foo", 0 /*['i32', 'i32'] => 'i32'*/) - .GetLocal(1) // parameter to call - .GetLocal(0) // call index - .CallIndirect(1, 0) // calling function of type ['i32'] => 'i32' - .Return() - .End() - .Function("bar", 1 /*['i32'] => 'i32'*/) - .GetLocal(0) - .I32Const(42) - .I32Add() - .Return() - .End() - .End(); - - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const table = new WebAssembly.Table(tableDescription); - return {instance: new WebAssembly.Instance(module, {imp: {table}}), table}; -} - -{ - const {instance, table} = makeInstance(); - const foo = instance.exports.foo; - const bar = instance.exports.bar; - assert.eq(table.get(0), null); - - for (let i = 0; i < 1000; i++) { - assert.throws(() => foo(0, i), WebAssembly.RuntimeError, "call_indirect to a null table entry"); - } - - table.set(0, foo); - assert.eq(table.get(0), foo); - - for (let i = 0; i < 1000; i++) { - assert.throws(() => foo(1 + i, i), WebAssembly.RuntimeError, "Out of bounds call_indirect"); - } - - for (let i = 0; i < 1000; i++) { - assert.throws(() => foo(0, i), WebAssembly.RuntimeError, "call_indirect to a signature that does not match"); - } - - table.set(0, bar); - assert.eq(table.get(0), bar); - for (let i = 0; i < 25; i++) { - assert.eq(foo(0, i), i + 42); - } -} diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/f32-const.js b/implementation-contributed/javascriptcore/wasm/function-tests/f32-const.js deleted file mode 100644 index f76beaf909ea6827779235e5cefd63904827315d..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/f32-const.js +++ /dev/null @@ -1,26 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -const builder = (new Builder()) - .Type().End() - .Function().End() - .Export() - .Function("answer") - .Function("minInt") - .End() - .Code() - .Function("answer", { params: [], ret: "f32" }) - .F32Const(.5) - .End() - - .Function("minInt", { params: [], ret: "f32" }) - .F32Const(-1) - .End() - - .End(); - -const bin = builder.WebAssembly().get(); -const module = new WebAssembly.Module(bin); -const instance = new WebAssembly.Instance(module); -assert.eq(instance.exports.answer(), .5); -assert.eq(instance.exports.minInt(), -1); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/f64-const.js b/implementation-contributed/javascriptcore/wasm/function-tests/f64-const.js deleted file mode 100644 index dedfc21ac2f8ae00a9660888695dd76f9ab47b2e..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/f64-const.js +++ /dev/null @@ -1,26 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -const builder = (new Builder()) - .Type().End() - .Function().End() - .Export() - .Function("answer") - .Function("minInt") - .End() - .Code() - .Function("answer", { params: [], ret: "f64" }) - .F64Const(42.424242) - .End() - - .Function("minInt", { params: [], ret: "f64" }) - .F64Const(-1) - .End() - - .End(); - -const bin = builder.WebAssembly().get(); -const module = new WebAssembly.Module(bin); -const instance = new WebAssembly.Instance(module); -assert.eq(instance.exports.answer(), 42.424242); -assert.eq(instance.exports.minInt(), -1); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/factorial.js b/implementation-contributed/javascriptcore/wasm/function-tests/factorial.js deleted file mode 100644 index d01d37316aa537c2876320f38f587ae02ba9d651..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/factorial.js +++ /dev/null @@ -1,36 +0,0 @@ -import * as assert from '../assert.js' -import Builder from '../Builder.js' - -const b = new Builder(); -b.Type().End() - .Import().End() - .Function().End() - .Export() - .Function("fac") - .End() - .Code() - .Function("fac", { params: ["i32"], ret: "i32" }) - .GetLocal(0) - .I32Const(0) - .I32Eq() - .If("void", b => - b.I32Const(1) - .Return() - ) - .GetLocal(0) - .GetLocal(0) - .I32Const(1) - .I32Sub() - .Call(0) - .I32Mul() - .Return() - .End() - .End() - -const m = new WebAssembly.Module(b.WebAssembly().get()); -const fac = (new WebAssembly.Instance(m)).exports.fac; -assert.eq(fac(0), 1); -assert.eq(fac(1), 1); -assert.eq(fac(2), 2); -assert.eq(fac(4), 24); -assert.throws(() => fac(1e7), RangeError, "Maximum call stack size exceeded."); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/float-sub.js b/implementation-contributed/javascriptcore/wasm/function-tests/float-sub.js deleted file mode 100644 index e29ab7aa7286f58f6ca537c97c9a8b8a740cd2a7..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/float-sub.js +++ /dev/null @@ -1,42 +0,0 @@ -import * as assert from '../assert.js' -import Builder from '../Builder.js' - -const b = new Builder(); -b.Type().End() - .Function().End() - .Export() - .Function("foo") - .Function("bar") - .End() - .Code() - .Function("bar", { params: ["f32", "f32"], ret: "f32" }, []) - .GetLocal(0) - .GetLocal(1) - .F32Sub() - .Return() - .End() - - .Function("foo", { params: ["f32", "f32"], ret: "f32" }, []) - .GetLocal(0) - .GetLocal(1) - .Call(0) - .Return() - .End() - .End() - -const bin = b.WebAssembly() -bin.trim(); -const instance = new WebAssembly.Instance(new WebAssembly.Module(bin.get())); - -let x = new Float32Array(3); -x[0] = 0; -x[1] = 1.5; -x[2] = x[0] - x[1]; -assert.eq(instance.exports.bar(x[0], x[1]), x[2]); -assert.eq(instance.exports.foo(x[0], x[1]), x[2]); - -x[0] = 100.1234 -x[1] = 12.5; -x[2] = x[0] - x[1]; -assert.eq(instance.exports.bar(x[0], x[1]), x[2]); -assert.eq(instance.exports.foo(x[0], x[1]), x[2]); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/function-import-return-value.js b/implementation-contributed/javascriptcore/wasm/function-tests/function-import-return-value.js deleted file mode 100644 index 6e11782ed032906854be1ab981fc59ee0e2a4524..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/function-import-return-value.js +++ /dev/null @@ -1,247 +0,0 @@ -import Builder from '../Builder.js' -import * as assert from '../assert.js' - -{ - let called = false; - - const tests = { - i32: [ - [20, (x) => assert.eq(x, 20)], - [20.888, (x) => assert.eq(x, 20.888 | 0)], - [Math.PI, (x) => assert.eq(x, Math.PI | 0)], - [{valueOf() { assert.truthy(!called); called = true; return 25; } }, (x) => { assert.truthy(called); assert.eq(x, 25); called = false; }], - [NaN, (x) => assert.eq(x, NaN | 0)], - [-0.0, (x) => assert.eq(1/x, Infinity)], - [undefined, (x) => assert.eq(x, undefined | 0)], - [null, (x) => assert.eq(x, null | 0)], - [Number.MAX_SAFE_INTEGER, (x) => assert.eq(x, Number.MAX_SAFE_INTEGER | 0)], - [2**32 - 1, (x) => assert.eq(x, (2**32 - 1) | 0)], - [2**32 - 1000, (x) => assert.eq(x, (2**32 - 1000) | 0)], - [-1000, (x) => assert.eq(x, -1000)], - ], - f32: [ - [20, (x) => assert.eq(x, 20)], - [20.888, (x) => assert.eq(x, Math.fround(20.888))], - [Math.PI, (x) => assert.eq(x, Math.fround(Math.PI))], - [{valueOf() { assert.truthy(!called); called = true; return 25.82; } }, (x) => { assert.truthy(called); assert.eq(x, Math.fround(25.82)); called = false; }], - [NaN, (x) => assert.truthy(isNaN(x))], - [-0.0, (x) => assert.eq(1/x, -Infinity)], - [undefined, (x) => assert.truthy(isNaN(x))], - [null, (x) => assert.eq(x, 0)], - [Number.MAX_SAFE_INTEGER, (x) => assert.eq(x, Math.fround(Number.MAX_SAFE_INTEGER))], - [-1000, (x) => assert.eq(x, -1000)], - ], - f64: [ - [20, (x) => assert.eq(x, 20)], - [2**24, (x) => assert.eq(x, 2**24)], - [2**52, (x) => assert.eq(x, 2**52)], - [20.8888888, (x) => assert.eq(x, 20.8888888)], - [Math.PI, (x) => assert.eq(x, Math.PI)], - [{valueOf() { assert.truthy(!called); called = true; return 25.82; } }, (x) => { assert.truthy(called); assert.eq(x, 25.82); called = false; }], - [NaN, (x) => assert.truthy(isNaN(x))], - [-0.0, (x) => assert.eq(1/x, -Infinity)], - [undefined, (x) => assert.truthy(isNaN(x))], - [null, (x) => assert.eq(x, 0)], - [Number.MAX_SAFE_INTEGER, (x) => assert.eq(x, Number.MAX_SAFE_INTEGER)], - [-1000, (x) => assert.eq(x, -1000)], - ] - }; - - for (let type of Reflect.ownKeys(tests)) { - const builder = new Builder() - .Type().End() - .Import() - .Function("imp", "func", { params: [], ret: type}) - .End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", {params: [], ret: type}) - .Call(0) - .Return() - .End() - .End(); - - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - - for (let test of tests[type]) { - const func = () => { - return test[0]; - }; - - const instance = new WebAssembly.Instance(module, {imp: {func}}); - const ret = instance.exports.foo(); - test[1](ret); - } - } -} - -{ - let types = ["i32", "f32", "f64"]; - for (let type of types) { - const builder = new Builder() - .Type().End() - .Import() - .Function("imp", "func", { params: [], ret: type}) - .End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", {params: [], ret: type}) - .Call(0) - .Unreachable() - .End() - .End(); - - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - let error = null; - const func = () => { - return { - valueOf() { - error = new Error; - throw error; - } - }; - }; - - const instance = new WebAssembly.Instance(module, {imp: {func}}); - for (let i = 0; i < 100; i++) { - let threw = false; - try { - instance.exports.foo(); - } catch(e) { - assert.eq(e, error); - threw = true; - error = null; - } - assert.truthy(threw); - } - } -} - -{ - const builder = new Builder() - .Type().End() - .Import() - .Function("imp", "func", { params: [], ret: "i64"}) - .End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", {params: [], ret: "void"}) - .Call(0) - .Drop() - .Return() - .End() - .End(); - - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const func = () => 20; - const instance = new WebAssembly.Instance(module, {imp: {func}}); - for (let i = 0; i < 100; i++) { - assert.throws(() => instance.exports.foo(), TypeError, "i64 not allowed as return type or argument to an imported function"); - } -} - -{ - const builder = new Builder() - .Type().End() - .Import() - .Function("imp", "func", { params: ["i64"], ret: "void"}) - .End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", {params: [], ret: "void"}) - .I64Const(20) - .Call(0) - .Return() - .End() - .End(); - - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const func = () => 20; - const instance = new WebAssembly.Instance(module, {imp: {func}}); - for (let i = 0; i < 100; i++) { - assert.throws(() => instance.exports.foo(), TypeError, "i64 not allowed as return type or argument to an imported function"); - } -} - -{ - const builder = new Builder() - .Type().End() - .Import() - .Function("imp", "func", { params: ["i64"], ret: "void"}) - .End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", {params: [], ret: "void"}) - .I64Const(20) - .Call(0) - .Return() - .End() - .End(); - - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - let called = false; - const func = () => { - called = true; - } - const instance = new WebAssembly.Instance(module, {imp: {func}}); - for (let i = 0; i < 100; i++) { - assert.throws(() => instance.exports.foo(), TypeError, "i64 not allowed as return type or argument to an imported function"); - assert.eq(called, false); - } -} - -{ - const builder = new Builder() - .Type().End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", {params: ["i64"], ret: "void"}) - .I64Const(20) - .Call(0) - .Return() - .End() - .End(); - - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - let called = false; - let value = { - valueOf() { - called = true; - } - }; - const instance = new WebAssembly.Instance(module); - for (let i = 0; i < 100; i++) { - assert.throws(() => instance.exports.foo(value), Error, "WebAssembly function with an i64 argument can't be called from JavaScript"); - assert.eq(called, false); - } -} diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/grow-memory-2.js b/implementation-contributed/javascriptcore/wasm/function-tests/grow-memory-2.js deleted file mode 100644 index fba01318f8a4f9879f522e7f188d7332493b1143..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/grow-memory-2.js +++ /dev/null @@ -1,82 +0,0 @@ -import Builder from '../Builder.js'; -import * as assert from '../assert.js'; - -{ - const memoryDescription = {initial: 0, maximum: 2}; - const builder = (new Builder()) - .Type().End() - .Import() - .Memory("imp", "memory", memoryDescription) - .Function("imp", "func", {params: [], ret: "void"}) - .End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", {params: ["i32"], ret: "i32"}) - .Call(0) - .GetLocal(0) - .I32Load(0, 0) - .Return() - .End() - .End(); - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const memory = new WebAssembly.Memory(memoryDescription); - - const func = () => { - memory.grow(1); - (new Uint32Array(memory.buffer))[0] = 42; - }; - - const instance = new WebAssembly.Instance(module, {imp: {memory, func}}); - assert.eq(instance.exports.foo(0), 42); -} - -{ - const memoryDescription = {initial: 0, maximum: 2}; - const tableDescription = {initial: 1, maximum: 1, element: "anyfunc"}; - const builder = (new Builder()) - .Type() - .Func([], "void") - .End() - .Import() - .Memory("imp", "memory", memoryDescription) - .Function("imp", "func", {params: [], ret: "void"}) - .Table("imp", "table", tableDescription) - .End() - .Function().End() - .Export() - .Function("foo") - .Function("bar") - .End() - .Code() - .Function("foo", {params: ["i32"], ret: "i32"}) - .I32Const(0) - .CallIndirect(0, 0) // call [] => void - .GetLocal(0) - .I32Load(0, 0) - .Return() - .End() - .Function("bar", {params: [], ret: "void"}) - .Call(0) - .Return() - .End() - .End(); - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const memory = new WebAssembly.Memory(memoryDescription); - const table = new WebAssembly.Table(tableDescription); - - const func = () => { - memory.grow(1); - (new Uint32Array(memory.buffer))[0] = 0xbadbeef; - }; - - const instance = new WebAssembly.Instance(module, {imp: {memory, func, table}}); - table.set(0, instance.exports.bar); - assert.eq(instance.exports.foo(0), 0xbadbeef); -} diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/grow-memory-3.js b/implementation-contributed/javascriptcore/wasm/function-tests/grow-memory-3.js deleted file mode 100644 index d2e1145b0f436e862696bffeed73aec861be74a7..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/grow-memory-3.js +++ /dev/null @@ -1,34 +0,0 @@ -import Builder from '../Builder.js'; -import * as assert from '../assert.js'; - -{ - const memoryDescription = {initial: 0, maximum: 2}; - const builder = (new Builder()) - .Type().End() - .Import() - .Memory("imp", "memory", memoryDescription) - .End() - .Function().End() - .Export() - .Function("foo") - .Function("bar") - .End() - .Code() - .Function("foo", {params: [], ret: "void"}) - .Unreachable() - .GrowMemory(0) - .End() - .Function("bar", {params: [], ret: "void"}) - .Unreachable() - .CurrentMemory(0) - .End() - .End(); - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); // Just make sure it parses. - const memory = new WebAssembly.Memory(memoryDescription); - const instance = new WebAssembly.Instance(module, {imp: {memory}}); - - assert.throws(() => instance.exports.foo(), WebAssembly.RuntimeError, "Unreachable code should not be executed") - assert.throws(() => instance.exports.bar(), WebAssembly.RuntimeError, "Unreachable code should not be executed") -} diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/grow-memory-4.js b/implementation-contributed/javascriptcore/wasm/function-tests/grow-memory-4.js deleted file mode 100644 index f26709a5eb23d938c9994fa7219307f01bc2e96b..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/grow-memory-4.js +++ /dev/null @@ -1,34 +0,0 @@ -import Builder from '../Builder.js'; -import * as assert from '../assert.js'; - -{ - const memoryDescription = {initial: 0, maximum: 50}; - const builder = (new Builder()) - .Type().End() - .Import() - .Memory("imp", "memory", memoryDescription) - .Function("imp", "func", {params: [], ret: "void"}) - .End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", {params: [], ret: "i32"}) - .Call(0) - .CurrentMemory(0) - .Return() - .End() - .End(); - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const memory = new WebAssembly.Memory(memoryDescription); - - const func = () => { - memory.grow(42); - }; - - const instance = new WebAssembly.Instance(module, {imp: {memory, func}}); - assert.eq(instance.exports.foo(), 42); -} diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/grow-memory-cause-gc.js b/implementation-contributed/javascriptcore/wasm/function-tests/grow-memory-cause-gc.js deleted file mode 100644 index 007aaf1a340ede5a5911cdf1321022b821d9d5f2..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/grow-memory-cause-gc.js +++ /dev/null @@ -1,61 +0,0 @@ -import Builder from '../Builder.js'; -import * as assert from '../assert.js'; - -function escape(){} -noInline(escape); - -for (let i = 0; i < 10; ++i) { - const max = 1024*2; - const memoryDescription = {initial: 0, maximum: max}; - const growMemoryAmount = 256; - - const builder = (new Builder()) - .Type().End() - .Import() - .Function("imp", "func", {params: [], ret: "void"}) - .Memory("imp", "memory", memoryDescription) - .End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", {params: [], ret: "i32"}) - .I32Const(1) - .I32Const(1) - .I32Const(1) - .I32Const(1) - .I32Const(1) - .I32Const(1) - .I32Const(1) - .I32Const(1) - .I32Const(1) - .I32Const(1) - .I32Const(1) - .I32Const(1) - .I32Const(1) - .I32Const(1) - .I32Const(1) - .I32Const(1) - .Call(2) - .I32Const(growMemoryAmount) - .GrowMemory(0) - .Return() - .End() - .Function("bar", {params: ["i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32"], ret: "void"}) - .Call(0) - .Return() - .End() - .End(); - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const memory = new WebAssembly.Memory(memoryDescription); - - function func() { } - - const instance = new WebAssembly.Instance(module, {imp: {memory, func}}); - for (let i = 0; i < max/growMemoryAmount; ++i) { - instance.exports.foo(); - } -} diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/grow-memory.js b/implementation-contributed/javascriptcore/wasm/function-tests/grow-memory.js deleted file mode 100644 index a30603a5f54ff14422018b3528e3b3a2b66b44a9..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/grow-memory.js +++ /dev/null @@ -1,207 +0,0 @@ -import Builder from '../Builder.js'; -import * as assert from '../assert.js'; - -const pageSize = 64 * 1024; -const maxPageCount = (2**32) / pageSize; - -function binaryShouldNotParse(builder, msg = "") { - const bin = builder.WebAssembly().get(); - let threw = false; - try { - const module = new WebAssembly.Module(bin); - } catch(e) { - assert.truthy(e instanceof WebAssembly.CompileError); - if (msg) - assert.truthy(e.message.indexOf(msg) !== -1); - threw = true; - } - assert.truthy(threw); -} - -{ - // Can't grow_memory if no memory is defined. - const builder = (new Builder()) - .Type().End() - .Function().End() - .Export().End() - .Code() - .Function({ret: "void", params: []}) - .I32Const(25) - .GrowMemory(0) - .Drop() - .End() - .End(); - - binaryShouldNotParse(builder, "grow_memory is only valid if a memory is defined or imported"); -} - -{ - // Can't current_memory if no memory is defined. - const builder = (new Builder()) - .Type().End() - .Function().End() - .Export().End() - .Code() - .Function({ret: "void", params: []}) - .I32Const(25) - .CurrentMemory(0) - .Drop() - .End() - .End(); - - binaryShouldNotParse(builder, "current_memory is only valid if a memory is defined or imported"); -} - -{ - const builder = (new Builder()) - .Type().End() - .Function().End() - .Memory().InitialMaxPages(1, 1).End() - .Export().End() - .Code() - .Function({ret: "void", params: []}) - .I32Const(25) - .GrowMemory(1) - .Drop() - .End() - .End(); - - binaryShouldNotParse(builder, "reserved varUint1 for grow_memory must be zero"); -} - -{ - const builder = (new Builder()) - .Type().End() - .Function().End() - .Memory().InitialMaxPages(1, 1).End() - .Export().End() - .Code() - .Function({ret: "void", params: []}) - .I32Const(25) - .CurrentMemory(1) - .Drop() - .End() - .End(); - - binaryShouldNotParse(builder, "reserved varUint1 for current_memory must be zero"); -} - -{ - const builder = (new Builder()) - .Type().End() - .Function().End() - .Memory().InitialMaxPages(1, 1).End() - .Export().End() - .Code() - .Function({ret: "void", params: []}) - .I32Const(25) - .CurrentMemory(0xffffff00) - .Drop() - .End() - .End(); - - binaryShouldNotParse(builder, "can't parse reserved varUint1 for current_memory"); -} - -{ - const builder = (new Builder()) - .Type().End() - .Function().End() - .Memory().InitialMaxPages(1, 1).End() - .Export().End() - .Code() - .Function({ret: "void", params: []}) - .I32Const(25) - .GrowMemory(0xffffff00) - .Drop() - .End() - .End(); - - binaryShouldNotParse(builder, "can't parse reserved varUint1 for grow_memory"); -} - -{ - const memoryDescription = {initial: 20, maximum: 50}; - const builder = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", memoryDescription).End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", { params: ["i32"], ret: "i32"}) - .GetLocal(0) - .GrowMemory(0) - .Return() - .End() - .End(); - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const instance = new WebAssembly.Instance(module, {imp: {memory: new WebAssembly.Memory(memoryDescription)}}); - let currentPageSize = memoryDescription.initial; - for (let i = 0; i < memoryDescription.maximum - memoryDescription.initial; i++) { - assert.eq(instance.exports.foo(1), currentPageSize); - ++currentPageSize; - } - - for (let i = 0; i < 1000; i++) { - assert.eq(instance.exports.foo(1), -1); - assert.eq(instance.exports.foo(0), currentPageSize); - } -} - -{ - const memoryDescription = {initial: 20, maximum: 100}; - const builder = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", memoryDescription).End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", { params: [], ret: "i32"}) - .CurrentMemory(0) - .Return() - .End() - .End(); - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const memory = new WebAssembly.Memory(memoryDescription); - const instance = new WebAssembly.Instance(module, {imp: {memory}}); - let currentPageSize = memoryDescription.initial; - for (let i = 0; i < memoryDescription.maximum - memoryDescription.initial; i++) { - assert.eq(instance.exports.foo(), currentPageSize); - ++currentPageSize; - memory.grow(1); - } -} - -{ - const memoryDescription = {initial: 20, maximum: 100}; - const builder = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", memoryDescription).End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", { params: [], ret: "i32"}) - .I32Const(-1) - .GrowMemory(0) - .Return() - .End() - .End(); - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const memory = new WebAssembly.Memory(memoryDescription); - const instance = new WebAssembly.Instance(module, {imp: {memory}}); - for (let i = 0; i < 20; i++) { - assert.eq(instance.exports.foo(), -1); - } -} diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/i32-const.js b/implementation-contributed/javascriptcore/wasm/function-tests/i32-const.js deleted file mode 100644 index aae67a252b69828eb2a8d0920436a53020fbb469..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/i32-const.js +++ /dev/null @@ -1,32 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - - -const builder = (new Builder()) - .Type().End() - .Function().End() - .Export() - .Function("answer") - .Function("minInt") - .Function("maxInt") - .End() - .Code() - .Function("answer", { params: [], ret: "i32" }) - .I32Const(42) - .End() - - .Function("minInt", { params: [], ret: "i32" }) - .I32Const(-1) - .End() - - .Function("maxInt", { params: [], ret: "i32" }) - .I32Const(0xffffffff) - .End() - .End(); - -const bin = builder.WebAssembly().get(); -const module = new WebAssembly.Module(bin); -const instance = new WebAssembly.Instance(module); -assert.eq(instance.exports.answer(), 42); -assert.eq(instance.exports.minInt(), -1); -assert.eq(instance.exports.maxInt(), -1); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/i32-load.js b/implementation-contributed/javascriptcore/wasm/function-tests/i32-load.js deleted file mode 100644 index 0c220cfc7447e3acaaabeede0730596e387e3720..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/i32-load.js +++ /dev/null @@ -1,35 +0,0 @@ -import Builder from '../Builder.js' -import * as assert from '../assert.js' - -const b = new Builder(); -b.Type().End() - .Function().End() - .Memory().InitialMaxPages(1, 1).End() - .Export().Function('f0').End() - .Code() - .Function('f0', { params: ["i32", "i32"], ret: "i32" }) - .GetLocal(1) - .GetLocal(0) - .I32Store(2, 0) - .GetLocal(1) - .I32Load(2, 0) - .Return() - .End() - .End(); - -const bin = b.WebAssembly().get(); -const instance = new WebAssembly.Instance(new WebAssembly.Module(bin)); -function testWasmModuleFunctions(...tests) { - for (let i = 0; i < tests.length; i++) { - const func = instance.exports['f' + i]; - for (let test of tests[i]) { - let result = test[0].value; - let args = test[1].map(x => x.value); - assert.eq(result, func(...args)); - } - } -} -testWasmModuleFunctions([[{type: "i32", value: 0 }, [{ type: "i32", value: 0 }, { type: "i32", value: 10 }]], - [{type: "i32", value: 100 }, [{ type: "i32", value: 100 }, { type: "i32", value: 112 }]], - [{type: "i32", value: 1000000 }, [{ type: "i32", value: 1000000 }, { type: "i32", value: 10 }]] - ]); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/i32-load8-s.js b/implementation-contributed/javascriptcore/wasm/function-tests/i32-load8-s.js deleted file mode 100644 index 3582754e82ebccf6192d47cf70c01ec429deb218..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/i32-load8-s.js +++ /dev/null @@ -1,24 +0,0 @@ -import Builder from '../Builder.js' -import * as assert from '../assert.js' - -const b = new Builder(); -b.Type().End() - .Function().End() - .Memory().InitialMaxPages(1, 1).End() - .Export().Function("foo").End() - .Code() - .Function("foo", { params: ["i32", "i32"], ret: "i32" }) - .GetLocal(1) - .GetLocal(0) - .I32Store(2, 0) - .GetLocal(1) - .I32Load8S(0, 0) - .Return() - .End() - .End() - -const bin = b.WebAssembly().get(); -const foo = (new WebAssembly.Instance(new WebAssembly.Module(bin))).exports.foo; -assert.eq(foo(0, 10), 0); -assert.eq(foo(100, 112), 100); -assert.eq(foo(1000000, 10), 0x40); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/i64-from-js-exceptions.js b/implementation-contributed/javascriptcore/wasm/function-tests/i64-from-js-exceptions.js deleted file mode 100644 index 4cd9cfcd22a970abffdedd601d25a45dca4724d2..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/i64-from-js-exceptions.js +++ /dev/null @@ -1,40 +0,0 @@ -import Builder from '../Builder.js' -import * as assert from '../assert.js' - -const builder = (new Builder()) - .Type().End() - .Import() - .Function("import", "sideEffects", {params: [], ret: "void"}) - .End() - .Function().End() - .Export() - .Function("foo") - .Function("bar") - .End() - .Code() - .Function("foo", {params: ["i64"], ret: "void"}) - .Call(0) - .Return() - .End() - .Function("bar", {params: [], ret: "i64"}) - .Call(0) - .I32Const(25) - .I64ExtendUI32() - .Return() - .End() - .End(); - -const bin = builder.WebAssembly().get(); -const module = new WebAssembly.Module(bin); -let called = false; -const imp = { - import: { - sideEffects() { called = true; } - } -}; - -const instance = new WebAssembly.Instance(module, imp); -assert.throws(() => instance.exports.foo(20), WebAssembly.RuntimeError, "WebAssembly function with an i64 argument can't be called from JavaScript"); -assert.throws(() => instance.exports.foo({valueOf() { throw new Error("Should not be called!"); }}), WebAssembly.RuntimeError, "WebAssembly function with an i64 argument can't be called from JavaScript"); -assert.throws(() => instance.exports.bar(), WebAssembly.RuntimeError, "WebAssembly function that returns i64 can't be called from JavaScript"); -assert.eq(called, false); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/if-no-else-non-void.js b/implementation-contributed/javascriptcore/wasm/function-tests/if-no-else-non-void.js deleted file mode 100644 index 8833164caa8a040225679cd6833a63cab317705b..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/if-no-else-non-void.js +++ /dev/null @@ -1,16 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -const builder = (new Builder()) - .Type().End() - .Function().End() - .Code() - .Function("bad-if", { params: [], ret: "i32" }) - .I32Const(0) - .If("i32", b => b.I32Const(0)) - .End() - - .End(); - -const bin = builder.WebAssembly().get(); -assert.throws(() => new WebAssembly.Module(bin), WebAssembly.CompileError, "WebAssembly.Module doesn't validate: If-block had a non-void result type: I32 but had no else-block, in function at index 0 (evaluating 'new WebAssembly.Module(bin)')"); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/invalid-duplicate-export.js b/implementation-contributed/javascriptcore/wasm/function-tests/invalid-duplicate-export.js deleted file mode 100644 index 418d51aa499019aa2469baa5f1fd8e1abd3bf291..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/invalid-duplicate-export.js +++ /dev/null @@ -1,19 +0,0 @@ -import Builder from '../Builder.js'; -import * as assert from '../assert.js'; - -{ - const builder = (new Builder()) - .Type().End() - .Function().End() - .Export() - .Function("foo") - .Function("foo") - .End() - .Code() - .Function("foo", {params: [], ret: "void"}) - .End() - .End(); - - const bin = builder.WebAssembly().get(); - assert.throws(() => new WebAssembly.Module(bin), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 31: duplicate export: 'foo'"); -} diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/load-offset.js b/implementation-contributed/javascriptcore/wasm/function-tests/load-offset.js deleted file mode 100644 index 7419a190ac78384b20ecd4fdb61daea7e3129c27..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/load-offset.js +++ /dev/null @@ -1,165 +0,0 @@ -import Builder from '../Builder.js' -import * as assert from '../assert.js' - -{ - const builder = (new Builder()) - .Type().End() - .Import() - .Memory("imp", "mem", {initial: 1}) - .End() - .Function().End() - .Export().Function("foo").End() - .Code() - .Function("foo", {params: ["i32"], ret: "i32"}) - .GetLocal(0) - .I32Load(2, 4) - .Return() - .End() - .End(); - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const memory = new WebAssembly.Memory({initial: 1}); - const instance = new WebAssembly.Instance(module, {imp: {mem: memory}}); - - const number = 0x0abbccdd; - (new Uint32Array(memory.buffer))[1] = number; - assert.eq(instance.exports.foo(0), number); -} - -{ - const builder = (new Builder()) - .Type().End() - .Import() - .Memory("imp", "mem", {initial: 1}) - .End() - .Function().End() - .Export().Function("foo").End() - .Code() - .Function("foo", {params: ["i32"], ret: "i32"}) - .GetLocal(0) - .I64Load32U(2, 4) - .I64Popcnt() - .I32WrapI64() - .Return() - .End() - .End(); - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const memory = new WebAssembly.Memory({initial: 1}); - const instance = new WebAssembly.Instance(module, {imp: {mem: memory}}); - - const number = 2**32 - 1; - (new Uint32Array(memory.buffer))[1] = number; - assert.eq(instance.exports.foo(0), 32); -} - -{ - const builder = (new Builder()) - .Type().End() - .Import() - .Memory("imp", "mem", {initial: 1}) - .End() - .Function().End() - .Export().Function("foo").End() - .Code() - .Function("foo", {params: ["i32"], ret: "i32"}) - .GetLocal(0) - .I64Load32S(2, 4) - .I64Popcnt() - .I32WrapI64() - .Return() - .End() - .End(); - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const memory = new WebAssembly.Memory({initial: 1}); - const instance = new WebAssembly.Instance(module, {imp: {mem: memory}}); - - const number = 2**32 - 1; - (new Uint32Array(memory.buffer))[1] = number; - assert.eq(instance.exports.foo(0), 64); -} - -{ - const builder = (new Builder()) - .Type().End() - .Import() - .Memory("imp", "mem", {initial: 1}) - .End() - .Function().End() - .Export().Function("foo").End() - .Code() - .Function("foo", {params: ["i32"], ret: "i32"}) - .GetLocal(0) - .I64Load(2, 4) - .I64Popcnt() - .I32WrapI64() - .Return() - .End() - .End(); - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const memory = new WebAssembly.Memory({initial: 1}); - const instance = new WebAssembly.Instance(module, {imp: {mem: memory}}); - - const number = 2**32 - 1; - (new Uint32Array(memory.buffer))[1] = number; - (new Uint32Array(memory.buffer))[2] = 0xff00ff00; - assert.eq(instance.exports.foo(0), 32 + 16); -} - -{ - const builder = (new Builder()) - .Type().End() - .Import() - .Memory("imp", "mem", {initial: 1}) - .End() - .Function().End() - .Export().Function("foo").End() - .Code() - .Function("foo", {params: ["i32"], ret: "f32"}) - .GetLocal(0) - .F32Load(2, 4) - .Return() - .End() - .End(); - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const memory = new WebAssembly.Memory({initial: 1}); - const instance = new WebAssembly.Instance(module, {imp: {mem: memory}}); - - const number = Math.PI; - (new Float32Array(memory.buffer))[1] = number; - assert.eq(instance.exports.foo(0), Math.fround(number)); -} - -{ - const builder = (new Builder()) - .Type().End() - .Import() - .Memory("imp", "mem", {initial: 1}) - .End() - .Function().End() - .Export().Function("foo").End() - .Code() - .Function("foo", {params: ["i32"], ret: "f64"}) - .GetLocal(0) - .F64Load(2, 8) - .Return() - .End() - .End(); - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const memory = new WebAssembly.Memory({initial: 1}); - const instance = new WebAssembly.Instance(module, {imp: {mem: memory}}); - - const number = Math.PI; - (new Float64Array(memory.buffer))[1] = number; - assert.eq(instance.exports.foo(0), number); -} diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/loop-mult.js b/implementation-contributed/javascriptcore/wasm/function-tests/loop-mult.js deleted file mode 100644 index ce39696791338bcdbbb2d219908a4fbf44e0ef6d..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/loop-mult.js +++ /dev/null @@ -1,43 +0,0 @@ -import Builder from '../Builder.js' -import * as assert from '../assert.js' - -const b = new Builder(); -b.Type().End() - .Function().End() - .Export() - .Function("loop") - .End() - .Code() - .Function("loop", { params: ["i32"], ret: "i32" }, ["i32"]) - .I32Const(0) - .SetLocal(1) - .Loop("void") - .Block("void", b => - b.GetLocal(0) - .I32Const(0) - .I32Eq() - .BrIf(0) - .GetLocal(0) - .GetLocal(1) - .I32Add() - .SetLocal(1) - .GetLocal(0) - .I32Const(1) - .I32Sub() - .SetLocal(0) - .Br(1) - ) - .End() - .GetLocal(1) - .Return() - .End() - .End() - -const bin = b.WebAssembly().get(); -const module = new WebAssembly.Module(bin); -const instance = new WebAssembly.Instance(module); - -assert.eq(0, instance.exports.loop(0)); -assert.eq(1, instance.exports.loop(1)); -assert.eq(3, instance.exports.loop(2)); -assert.eq(5050, instance.exports.loop(100)); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/loop-sum.js b/implementation-contributed/javascriptcore/wasm/function-tests/loop-sum.js deleted file mode 100644 index ce39696791338bcdbbb2d219908a4fbf44e0ef6d..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/loop-sum.js +++ /dev/null @@ -1,43 +0,0 @@ -import Builder from '../Builder.js' -import * as assert from '../assert.js' - -const b = new Builder(); -b.Type().End() - .Function().End() - .Export() - .Function("loop") - .End() - .Code() - .Function("loop", { params: ["i32"], ret: "i32" }, ["i32"]) - .I32Const(0) - .SetLocal(1) - .Loop("void") - .Block("void", b => - b.GetLocal(0) - .I32Const(0) - .I32Eq() - .BrIf(0) - .GetLocal(0) - .GetLocal(1) - .I32Add() - .SetLocal(1) - .GetLocal(0) - .I32Const(1) - .I32Sub() - .SetLocal(0) - .Br(1) - ) - .End() - .GetLocal(1) - .Return() - .End() - .End() - -const bin = b.WebAssembly().get(); -const module = new WebAssembly.Module(bin); -const instance = new WebAssembly.Instance(module); - -assert.eq(0, instance.exports.loop(0)); -assert.eq(1, instance.exports.loop(1)); -assert.eq(3, instance.exports.loop(2)); -assert.eq(5050, instance.exports.loop(100)); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/many-args-tail-call-sp-restored.js b/implementation-contributed/javascriptcore/wasm/function-tests/many-args-tail-call-sp-restored.js deleted file mode 100644 index 47bb53938233ba83b39c0c0ffce01237549981bb..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/many-args-tail-call-sp-restored.js +++ /dev/null @@ -1,72 +0,0 @@ -import Builder from '../Builder.js' -import * as assert from '../assert.js' - -{ - const count = 1000; - const signature = []; - for (let i = 0; i < count; ++i) - signature.push("i32"); - - let builder = new Builder() - .Type() - .End() - .Import() - .Function("imp", "f1", {params:signature, ret:"void"}) - .Function("imp", "f2", {params:signature, ret:"void"}) - .End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", {params: signature, ret: "void" }); - - for (let i = 0; i < count; ++i) - builder = builder.GetLocal(i); - - builder = builder.Call(0); - - for (let i = count; i--; ) - builder = builder.GetLocal(i); - - builder = builder.Call(1).Return().End().End(); - - let calledF1 = false; - let calledF2 = false; - - function f1(...args) { - calledF1 = true; - let realArgs = [...args, ...args]; - return end(...realArgs); - } - noInline(f1); - - function end() {} - noInline(end); - - - function f2(...args) { - calledF2 = true; - let called = false; - assert.eq(args.length, count); - for (let i = 0; i < args.length; ++i) { - assert.eq(args[i], args.length - i - 1); - } - } - noInline(f2); - - let instance = new WebAssembly.Instance(new WebAssembly.Module(builder.WebAssembly().get()), {imp: {f1, f2}}); - - const args = []; - for (let i = 0; i < count; ++i) - args.push(i); - - for (let i = 0; i < 50; ++i) { - instance.exports.foo(...args); - - assert.eq(calledF1, true); - assert.eq(calledF2, true); - calledF1 = false; - calledF2 = false; - } -} diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/many-arguments-to-function.js b/implementation-contributed/javascriptcore/wasm/function-tests/many-arguments-to-function.js deleted file mode 100644 index b14d08efa0c1fcb60661652557c13b15639b994b..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/many-arguments-to-function.js +++ /dev/null @@ -1,186 +0,0 @@ -import Builder from '../Builder.js' -import * as assert from '../assert.js' - -{ - const b = new Builder() - .Type().End() - .Import().Function("imp", "func", { params: ["i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32", "i32"], ret:"i32" }).End() - .Function().End() - .Export().Function("f0").End() - .Code() - .Function("f0", { params: [], ret: "i32" }) - .I32Const(0) - .I32Const(1) - .I32Const(2) - .I32Const(3) - .I32Const(4) - .I32Const(5) - .I32Const(6) - .I32Const(7) - .I32Const(8) - .I32Const(9) - .I32Const(10) - .I32Const(11) - .I32Const(12) - .I32Const(13) - .I32Const(14) - .I32Const(15) - .I32Const(16) - .I32Const(17) - .Call(0) - .Return() - .End() - .End() - - function foo(...args) { - for (let i = 0; i < args.length; i++) { - if (args[i] !== i) - throw new Error("Bad!"); - } - } - - let imp = {imp: {func: foo}} - let instance = new WebAssembly.Instance(new WebAssembly.Module(b.WebAssembly().get()), imp); - for (let i = 0; i < 100; i++) - instance.exports.f0(); -} - -{ - const b = new Builder() - .Type().End() - .Import().Function("imp", "func", { params: ["f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32"], ret:"f32" }).End() - .Function().End() - .Export().Function("f0").End() - .Code() - .Function("f0", { params: [], ret: "f32" }) - .F32Const(0.5) - .F32Const(1.5) - .F32Const(2.5) - .F32Const(3.5) - .F32Const(4.5) - .F32Const(5.5) - .F32Const(6.5) - .F32Const(7.5) - .F32Const(8.5) - .F32Const(9.5) - .F32Const(10.5) - .F32Const(11.5) - .F32Const(12.5) - .F32Const(13.5) - .F32Const(14.5) - .F32Const(15.5) - .F32Const(16.5) - .F32Const(17.5) - .Call(0) - .Return() - .End() - .End() - - function foo(...args) { - for (let i = 0; i < args.length; i++) { - if (args[i] !== (i + 0.5)) - throw new Error("Bad!"); - } - } - - let imp = {imp: {func: foo}} - let instance = new WebAssembly.Instance(new WebAssembly.Module(b.WebAssembly().get()), imp); - for (let i = 0; i < 100; i++) - instance.exports.f0(); -} - -{ - const b = new Builder() - .Type().End() - .Import().Function("imp", "func", { params: ["f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32"], ret:"f32" }).End() - .Function().End() - .Export().Function("f0").End() - .Code() - .Function("f0", { params: ["f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32", "f32"] , ret: "f32" }) - .GetLocal(0) - .GetLocal(1) - .GetLocal(2) - .GetLocal(3) - .GetLocal(4) - .GetLocal(5) - .GetLocal(6) - .GetLocal(7) - .GetLocal(8) - .GetLocal(9) - .GetLocal(10) - .GetLocal(11) - .GetLocal(12) - .GetLocal(13) - .GetLocal(14) - .GetLocal(15) - .GetLocal(16) - .GetLocal(17) - .Call(0) - .Return() - .End() - .End() - - function foo(...args) { - for (let i = 0; i < args.length; i++) { - if (args[i] !== i) - throw new Error("Bad!"); - } - } - - let imp = {imp: {func: foo}} - let instance = new WebAssembly.Instance(new WebAssembly.Module(b.WebAssembly().get()), imp); - let arr = []; - for (let i = 0; i < 18; i++) - arr.push(i); - for (let i = 0; i < 100; i++) - instance.exports.f0(...arr); -} - - -{ - let signature = []; - function addType(t, i) { - for (let j = 0; j < i; j++) { - signature.push(t); - } - } - addType("i32", 16); - addType("f32", 16); - - let b = new Builder() - .Type().End() - .Import().Function("imp", "func", { params: signature, ret:"f32" }).End() - .Function().End() - .Export().Function("f0").End() - .Code() - .Function("f0", { params: signature , ret: "f32" }); - for (let i = 0; i < (16 + 16); i++) { - b = b.GetLocal(i); - } - - b = b.Call(0).Return().End().End(); - - function foo(...args) { - if (args.length !== 32) - throw new Error("Bad!") - - for (let i = 0; i < 16; i++) { - if (args[i] !== i) - throw new Error("Bad!"); - if (args[i + 16] !== (i + 16 + 0.5)) - throw new Error("Bad!"); - } - } - - let imp = {imp: {func: foo}} - let instance = new WebAssembly.Instance(new WebAssembly.Module(b.WebAssembly().get()), imp); - let arr = []; - for (let i = 0; i < 16; i++) - arr.push(i); - for (let i = 16; i < 32; i++) - arr.push(i + 0.5); - for (let i = 0; i < 100; i++) - instance.exports.f0(...arr); -} - - diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/memory-access-past-4gib.js b/implementation-contributed/javascriptcore/wasm/function-tests/memory-access-past-4gib.js deleted file mode 100644 index 1d3494ddd2f86e2a5252e7902955a9434aea9b8a..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/memory-access-past-4gib.js +++ /dev/null @@ -1,130 +0,0 @@ -import Builder from '../Builder.js'; -import * as assert from '../assert.js'; -import * as LLB from '../LowLevelBinary.js'; -import * as WASM from '../WASM.js'; -import * as util from '../utilities.js'; - -const verbose = false; - -const pageSize = 64 * 1024; -const fourGiB = pageSize * 65536; -const initial = 64; -const maximum = 128; - -// When using fast memories, we allocate a redzone after the 4GiB huge -// allocation. This redzone is used to trap reg+imm accesses which exceed -// 32-bits. Anything past 4GiB must trap, but we cannot know statically that it -// will. - -const offsets = [ - 0, - 1, - 2, - 1024, - pageSize, - pageSize + pageSize / 2, - pageSize * 8, - pageSize * 16, - pageSize * 128, - pageSize * 512, - fourGiB / 4 - 4, - fourGiB / 4 - 3, - fourGiB / 4 - 2, - fourGiB / 4 - 1, - fourGiB / 4, - fourGiB / 4 + 1, - fourGiB / 4 + 2, - fourGiB / 4 + 3, - fourGiB / 4 + 4, - fourGiB / 2 - 4, - fourGiB / 2 - 3, - fourGiB / 2 - 2, - fourGiB / 2 - 1, - fourGiB / 2, - fourGiB / 2 + 1, - fourGiB / 2 + 2, - fourGiB / 2 + 3, - fourGiB / 2 + 4, - (fourGiB / 4) * 3, - fourGiB - 4, - fourGiB - 3, - fourGiB - 2, - fourGiB - 1, -]; - -for (let memoryDeclaration of [{ initial: initial }, { initial: initial, maximum: maximum }]) { - fullGC(); - - // Re-use a single memory so tests are more likely to get a fast memory. - const memory = new WebAssembly.Memory(memoryDeclaration); - if (verbose) - print(WebAssemblyMemoryMode(memory)); - const buf = new Uint8Array(memory.buffer); - - // Enumerate all memory access types. - for (const op of WASM.opcodes("memory")) { - const info = WASM.memoryAccessInfo(op); - - // The accesses should fault even if only the last byte is off the end. - let wiggles = [0]; - for (let wiggle = 0; wiggle !== info.width / 8; ++wiggle) - wiggles.push(wiggle); - - let builder = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", memoryDeclaration).End() - .Function().End() - .Export(); - - for (let offset of offsets) - switch (info.type) { - case "load": builder = builder.Function("get_" + offset); break; - case "store": builder = builder.Function("set_" + offset); break; - default: throw new Error(`Implementation problem: unknown memory access type ${info.type}`); - } - - builder = builder.End().Code(); - - const align = 0; // No need to be precise, it's just a hint. - const constInstr = util.toJavaScriptName(WASM.constForValueType(info.valueType)); - const instr = util.toJavaScriptName(op.name); - for (let offset of offsets) - switch (info.type) { - case "load": - builder = builder.Function("get_" + offset, { params: ["i32"] }).GetLocal(0)[instr](align, offset).Drop().End(); - break; - case "store": - builder = builder.Function("set_" + offset, { params: ["i32"] }).GetLocal(0)[constInstr](0xdead)[instr](align, offset).End(); - break; - default: - throw new Error(`Implementation problem: unknown memory access type ${info.type}`); - } - - builder = builder.End(); - - const instance = new WebAssembly.Instance(new WebAssembly.Module(builder.WebAssembly().get()), { imp: { memory: memory } }); - - for (let offset of offsets) { - for (let wiggle of wiggles) { - const address = LLB.varuint32Max - offset - wiggle; - if (verbose) - print(`${op.name.padStart(16, ' ')}: base address ${address > 0 ? '0x' : ' '}${address.toString(16).padStart(8, address > 0 ? '0' : ' ')} + offset 0x${offset.toString(16).padStart(8, '0')} - wiggle ${wiggle} = effective address 0x${(address + offset - wiggle).toString(16).padStart(16, '0')}`); - switch (info.type) { - case "load": - assert.throws(() => instance.exports["get_" + offset](address), WebAssembly.RuntimeError, `Out of bounds memory access`); - break; - case "store": - assert.throws(() => instance.exports["set_" + offset](address), WebAssembly.RuntimeError, `Out of bounds memory access`); - break; - default: throw new Error(`Implementation problem: unknown memory access type ${info.type}`); - } - } - } - - fullGC(); - } - - // Only check that the memory was untouched at the very end, before throwing it away entirely. - for (let idx = 0; idx < buf.byteLength; ++idx) - assert.eq(buf[idx], 0); -} diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/memory-alignment.js b/implementation-contributed/javascriptcore/wasm/function-tests/memory-alignment.js deleted file mode 100644 index e605898900aa1bed67b9d32ac6f2aa012eb299ee..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/memory-alignment.js +++ /dev/null @@ -1,48 +0,0 @@ -import Builder from '../Builder.js'; -import * as assert from '../assert.js'; -import * as WASM from '../WASM.js'; -import * as util from '../utilities.js'; - -const offset = 0; - -const memoryDeclaration = { initial: 1 }; -const memory = new WebAssembly.Memory(memoryDeclaration); - -for (const op of WASM.opcodes("memory")) { - const info = WASM.memoryAccessInfo(op); - const maxAlignLog2 = Math.log2(info.width / 8); - const constInstr = util.toJavaScriptName(WASM.constForValueType(info.valueType)); - const instr = util.toJavaScriptName(op.name); - for (let alignLog2 = 0; alignLog2 < 16; ++alignLog2) { - let builder = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", memoryDeclaration).End() - .Function().End() - .Code(); - let start, end; - switch (info.type) { - case "load": - builder = builder.Function({ params: ["i32"] }).GetLocal(0)[instr](alignLog2, offset).Drop().End(); - start = 5; - end = 8; - break; - case "store": - builder = builder.Function({ params: ["i32", info.valueType] }).GetLocal(0).GetLocal(1)[instr](alignLog2, offset).End(); - start = 7; - end = 9; - break; - default: - throw new Error(`Implementation problem: unknown memory access type ${info.type}`); - } - builder = builder.End(); - const instance = () => { - const module = new WebAssembly.Module(builder.WebAssembly().get()); - return new WebAssembly.Instance(module, { imp: { memory: memory } }); - }; - if (alignLog2 <= maxAlignLog2) - instance(); - else - assert.throws(instance, WebAssembly.CompileError, `WebAssembly.Module doesn't parse at byte ${start}: byte alignment ${1 << alignLog2} exceeds ${info.type}'s natural alignment ${1 << maxAlignLog2}, in function at index 0`); - - } -} diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/memory-grow-invalid.js b/implementation-contributed/javascriptcore/wasm/function-tests/memory-grow-invalid.js deleted file mode 100644 index ef62fd694e59f414c21a35871d6f76ffaded88cf..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/memory-grow-invalid.js +++ /dev/null @@ -1,29 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -const verbose = false; - -const initial = 0; -const max = 0; - -const builder = (new Builder()) - .Type().End() - .Function().End() - .Memory().InitialMaxPages(initial, max).End() - .Export().Function("current").Function("grow").End() - .Code() - .Function("current", { params: [], ret: "i32" }).CurrentMemory(0).Return().End() - .Function("grow", { params: ["i32"], ret: "i32" }).GetLocal(0).GrowMemory(0).Return().End() - .End(); - -let instance = new WebAssembly.Instance(new WebAssembly.Module(builder.WebAssembly().get())); - -const current = instance.exports.current(); -const by = 2; -const result = instance.exports.grow(current + by); -if (verbose) - print(`Grow from ${current} (max ${max}) to ${current + by} returned ${result}, current now ${instance.exports.current()}`); - -assert.eq(result, -1); -assert.eq(current, instance.exports.current()); -assert.le(instance.exports.current(), max); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/memory-import-and-grow.js b/implementation-contributed/javascriptcore/wasm/function-tests/memory-import-and-grow.js deleted file mode 100644 index 1398d92b52dc03fb3e50956b7683008e5c590722..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/memory-import-and-grow.js +++ /dev/null @@ -1,131 +0,0 @@ -import Builder from '../Builder.js'; -import * as assert from '../assert.js'; - -const pageSize = 64 * 1024; - -const verbose = false; - -// https://github.com/WebAssembly/design/blob/master/Modules.md#imports -// Says: -// -// A linear memory import includes the same set of fields defined in the Linear -// Memory section: initial length and optional maximum length. The host -// environment must only allow imports of WebAssembly linear memories that have -// initial length greater-or-equal than the initial length declared in the -// import and that have maximum length less-or-equal than the maximum length -// declared in the import. This ensures that separate compilation can assume: -// memory accesses below the declared initial length are always in-bounds, -// accesses above the declared maximum length are always out-of-bounds and if -// initial equals maximum, the length is fixed. - -const instantiate = (builder, importObject = undefined) => { - return new WebAssembly.Instance( - new WebAssembly.Module( - builder.WebAssembly().get()), - importObject); -}; - -const test = (memoryToImport, importedMemoryDeclaration, growMemoryToImportBy = undefined, growImportedMemoryDeclarationBy = undefined, expectedFinal) => { - const builder0 = (new Builder()) - .Type().End() - .Function().End() - .Memory().InitialMaxPages(memoryToImport.initial, memoryToImport.maximum).End() - .Export() - .Function("current").Function("grow").Function("get") - .Memory("memory", 0) - .End() - .Code() - .Function("current", { params: [], ret: "i32" }).CurrentMemory(0).Return().End() - .Function("grow", { params: ["i32"], ret: "i32" }).GetLocal(0).GrowMemory(0).Return().End() - .Function("get", { params: ["i32"], ret: "i32" }).GetLocal(0).I32Load(2, 0).Return().End() - .End(); - - const builder1 = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", importedMemoryDeclaration).End() - .Function().End() - .Export() - .Function("current").Function("grow").Function("get") - .Memory("memory", 0) - .End() - .Code() - .Function("current", { params: [], ret: "i32" }).CurrentMemory(0).Return().End() - .Function("grow", { params: ["i32"], ret: "i32" }).GetLocal(0).GrowMemory(0).Return().End() - .Function("get", { params: ["i32"], ret: "i32" }).GetLocal(0).I32Load(2, 0).Return().End() - .End(); - - const i0 = instantiate(builder0); - const i1 = instantiate(builder1, { imp: { memory: i0.exports.memory } }); - assert.eq(i0.exports.current(), i1.exports.current()); - assert.eq(i0.exports.current(), memoryToImport.initial); - - if (growMemoryToImportBy !== undefined) { - const grow = i0.exports.grow(growMemoryToImportBy); - if (verbose) - print(`currents: ${i0.exports.current()} and ${i1.exports.current()} -- grow result: ${grow}`); - } - - if (growImportedMemoryDeclarationBy !== undefined) { - const grow = i1.exports.grow(growImportedMemoryDeclarationBy); - if (verbose) - print(`currents: ${i0.exports.current()} and ${i1.exports.current()} -- grow result: ${grow}`); - } - - assert.eq(i0.exports.current(), i1.exports.current()); - assert.eq(i0.exports.current(), expectedFinal); -}; - -const u = undefined; - -// Identical Just Works. -test({ initial: 2, maximum: 4 }, { initial: 2, maximum: 4 }, 0, u, 2); -test({ initial: 2, maximum: 4 }, { initial: 2, maximum: 4 }, 1, u, 3); -test({ initial: 2, maximum: 4 }, { initial: 2, maximum: 4 }, 2, u, 4); -test({ initial: 2, maximum: 4 }, { initial: 2, maximum: 4 }, 3, u, 2); -test({ initial: 2, maximum: 4 }, { initial: 2, maximum: 4 }, u, 0, 2); -test({ initial: 2, maximum: 4 }, { initial: 2, maximum: 4 }, u, 1, 3); -test({ initial: 2, maximum: 4 }, { initial: 2, maximum: 4 }, u, 2, 4); -test({ initial: 2, maximum: 4 }, { initial: 2, maximum: 4 }, u, 3, 2); - -// Allowed: imported initial is greater than declared. -test({ initial: 2, maximum: 4 }, { initial: 1, maximum: 4 }, 0, u, 2); -test({ initial: 2, maximum: 4 }, { initial: 1, maximum: 4 }, 1, u, 3); -test({ initial: 2, maximum: 4 }, { initial: 1, maximum: 4 }, 2, u, 4); -test({ initial: 2, maximum: 4 }, { initial: 1, maximum: 4 }, 3, u, 2); -test({ initial: 2, maximum: 4 }, { initial: 0, maximum: 4 }, 0, u, 2); -test({ initial: 2, maximum: 4 }, { initial: 0, maximum: 4 }, 1, u, 3); -test({ initial: 2, maximum: 4 }, { initial: 0, maximum: 4 }, 2, u, 4); -test({ initial: 2, maximum: 4 }, { initial: 0, maximum: 4 }, 3, u, 2); -test({ initial: 2, maximum: 4 }, { initial: 1, maximum: 4 }, u, 0, 2); -test({ initial: 2, maximum: 4 }, { initial: 1, maximum: 4 }, u, 1, 3); -test({ initial: 2, maximum: 4 }, { initial: 1, maximum: 4 }, u, 2, 4); -test({ initial: 2, maximum: 4 }, { initial: 1, maximum: 4 }, u, 3, 2); -test({ initial: 2, maximum: 4 }, { initial: 0, maximum: 4 }, u, 0, 2); -test({ initial: 2, maximum: 4 }, { initial: 0, maximum: 4 }, u, 1, 3); -test({ initial: 2, maximum: 4 }, { initial: 0, maximum: 4 }, u, 2, 4); -test({ initial: 2, maximum: 4 }, { initial: 0, maximum: 4 }, u, 3, 2); - -// Allowed: imported maximum is lesser than declared. -test({ initial: 2, maximum: 3 }, { initial: 2, maximum: 4 }, 0, u, 2); -test({ initial: 2, maximum: 3 }, { initial: 2, maximum: 4 }, 1, u, 3); -test({ initial: 2, maximum: 3 }, { initial: 2, maximum: 4 }, 2, u, 2); -test({ initial: 2, maximum: 2 }, { initial: 2, maximum: 4 }, 0, u, 2); -test({ initial: 2, maximum: 2 }, { initial: 2, maximum: 4 }, 1, u, 2); -test({ initial: 2, maximum: 3 }, { initial: 2, maximum: 4 }, u, 0, 2); -test({ initial: 2, maximum: 3 }, { initial: 2, maximum: 4 }, u, 1, 3); -test({ initial: 2, maximum: 3 }, { initial: 2, maximum: 4 }, u, 2, 2); -test({ initial: 2, maximum: 2 }, { initial: 2, maximum: 4 }, u, 0, 2); -test({ initial: 2, maximum: 2 }, { initial: 2, maximum: 4 }, u, 1, 2); - -// Allowed: no declared maximum, same as above. -test({ initial: 2, maximum: 4 }, { initial: 2 }, 0, u, 2); - -// Disallowed: imported initial is lesser than declared. -assert.throws(() => test({ initial: 1, maximum: 4 }, { initial: 2, maximum: 4 }, u, u, 2), WebAssembly.LinkError, `Memory import imp:memory provided an 'initial' that is smaller than the module's declared 'initial' import memory size`); -assert.throws(() => test({ initial: 0, maximum: 4 }, { initial: 2, maximum: 4 }, u, u, 2), WebAssembly.LinkError, `Memory import imp:memory provided an 'initial' that is smaller than the module's declared 'initial' import memory size`); - -// Disallowed: imported maximum is greater than declared. -assert.throws(() => test({ initial: 2, maximum: 5 }, { initial: 2, maximum: 4 }, u, u, 2), WebAssembly.LinkError, `Memory import imp:memory provided a 'maximum' that is larger than the module's declared 'maximum' import memory size`); - -// Disallowed: no imported maximum, same as above. -assert.throws(() => test({ initial: 2 }, { initial: 2, maximum: 4 }, 0, u, 2), WebAssembly.LinkError, `Memory import imp:memory did not have a 'maximum' but the module requires that it does`); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/memory-many.js b/implementation-contributed/javascriptcore/wasm/function-tests/memory-many.js deleted file mode 100644 index ba43c62d9e89c93ab4df8eb10a6c1319a125978c..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/memory-many.js +++ /dev/null @@ -1,18 +0,0 @@ -const memories = 128; -const verbose = false; -const initial = 1; - -let types = {}; - -for (let m = 0; m < memories; ++m) { - let memory = new WebAssembly.Memory({ initial: initial }); - let type = WebAssemblyMemoryMode(memory); - types[type] = types[type] ? types[type] + 1 : 1; -} - -if (verbose) { - let got = "Got: "; - for (let p in types) - got += ` ${types[p]}: ${p}`; - print(got); -} diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/memory-multiagent.js b/implementation-contributed/javascriptcore/wasm/function-tests/memory-multiagent.js deleted file mode 100644 index bf98c85099925a8cb0809fd5a9ecfeb53f37971b..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/memory-multiagent.js +++ /dev/null @@ -1,125 +0,0 @@ -// This test times out, probably because of the while loop in the agent. -// https://bugs.webkit.org/show_bug.cgi?id=170958 -//@ skip - -const pageSize = 64 * 1024; - -const verbose = false; - -// Start multiple agents and create WebAssembly.Memory from each of -// them. Perform writes into each memory, and then check that the memory only -// contains that agent's writes. This would find bugs where an implementation's -// memory reuse is buggy. - -// Use the agent support from test262: https://github.com/tc39/test262/blob/master/INTERPRETING.md#host-defined-functions - -const testIterations = 2; -const numAgents = 8; -const initialPages = 64; -const numWrites = 1024; - -const stateWait = 0; -const stateReady = 1; -const stateCheck = 2; - -const startAgents = numAgentsToStart => { - for (let a = 0; a < numAgentsToStart; ++a) { - const agentScript = ` - let state = ${stateWait}; - let u8; - - if (${verbose}) - print("Agent ${a} started"); - $.agent.report("Agent ${a} started"); - - $.agent.receiveBroadcast((sab, newState) => { - if (${verbose}) - print("Agent ${a} received broadcast"); - u8 = new Uint8Array(sab); - state = newState; - }); - - const busyWaitForValue = value => { - // Busy-wait so that once the SAB write occurs all agents try to create a memory at the same time. - while (Atomics.load(u8, 0) !== value) ; - }; - - if (${verbose}) - print("Agent ${a} waits"); - $.agent.report("Agent ${a} waits"); - // FIXME: How can this work? The state variable is in the JS heap and the while loop - // prevents any JS-heap-modifying things from happening because JS is a synchronous - // language - // https://bugs.webkit.org/show_bug.cgi?id=170958 - while (state === ${stateWait}) ; - $.agent.report("Agent ${a} received SAB"); - // Use it for faster state change so all agents are more likely to execute at the same time. - busyWaitForValue(${stateReady}); - - let wasmMemory = new WebAssembly.Memory({ initial: ${initialPages} }); - let memory = new Uint8Array((wasmMemory).buffer); - if (${verbose}) - print("Agent ${a} performing writes"); - for (let write = 0; write < ${numWrites}; ++write) { - // Perform writes of our agent number at a random location. This memory should not be shared, if we see writes of other values then something went wrong. - const idx = (Math.random() * ${pageSize} * ${initialPages}) | 0; - memory[idx] = ${a}; - } - if (${verbose}) - print("Agent ${a} writes performed"); - $.agent.report("Agent ${a} performed writes"); - busyWaitForValue(${stateCheck}); - - if (${verbose}) - print("Agent ${a} checking"); - // Check that our memory only contains 0 and our agent number. - for (let idx = 0; idx < ${pageSize} * ${initialPages}; ++idx) - if (memory[idx] !== 0 && memory[idx] !== ${a}) - throw new Error("Agent ${a} found unexpected value " + memory[idx] + " at location " + idx); - $.agent.report("Agent ${a} checks out OK"); - $.agent.leaving(); - `; - - if (verbose) - print(`Starting agent ${a}`); - $.agent.start(agentScript); - } -}; - -const waitForAgents = numAgentsToWaitFor => { - for (let a = 0; a < numAgentsToWaitFor; ++a) { - while (true) { - const report = $.agent.getReport(); - if (report === null) { - $.agent.sleep(1); - continue; - } - if (verbose) - print(`Received: ${report}`); - break; - } - } -}; - -const broadcastToAgents = (sab, newState) => { - $.agent.broadcast(sab, newState); -}; - -const sab = new SharedArrayBuffer(1024); -const u8 = new Uint8Array(sab); - -for (let it = 0; it < testIterations; ++it) { - startAgents(numAgents); - waitForAgents(numAgents); - broadcastToAgents(sab, stateReady); - waitForAgents(numAgents); - $.agent.sleep(1); - Atomics.store(u8, 0, stateReady); - waitForAgents(numAgents); - $.agent.sleep(1); - Atomics.store(u8, 0, stateCheck); - waitForAgents(numAgents); - if (verbose) - print("Everyting was fine"); - $.agent.sleep(1); -} diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/memory-reuse.js b/implementation-contributed/javascriptcore/wasm/function-tests/memory-reuse.js deleted file mode 100644 index fecccceecd40e28a8c6d75ffca738346f3145b97..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/memory-reuse.js +++ /dev/null @@ -1,113 +0,0 @@ -import Builder from '../Builder.js' -import * as assert from '../assert.js' - -const count = 10; -const pages = 6; -const memoryDescription = {initial:1}; -const pageSize = 64 * 1024; - -function createWasmInstance(memory) { - const builder = new Builder() - .Type().End() - .Import() - .Memory("imp", "memory", memoryDescription) - .End() - .Function().End() - .Export() - .Function("current") - .Function("get") - .Function("grow") - .End() - .Code() - .Function("current", { params: [], ret: "i32" }) - .CurrentMemory(0) - .Return() - .End() - .Function("get", { params: ["i32"], ret: "i32" }) - .GetLocal(0) - .I32Load(2, 0) - .Return() - .End() - .Function("grow", { params: ["i32"], ret: "i32" }) - .GetLocal(0) - .GrowMemory(0) - .Return() - .End() - .End(); - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - return new WebAssembly.Instance(module, {imp: {memory}}); -} - -function doFillMemory(mem, length) { - const buf = new Uint32Array(mem.buffer); - - for (let i = 0; i < length; ++i) { - buf[i * 4] = i + 1; - } -} - -function doCheckTrap(instances, mem, numPages, length) { - const buf = new Uint32Array(mem.buffer); - - for (let instance of instances) { - const foo = instance.exports.get; - for (let i = 0; i < length; i++) { - assert.eq(foo(i * 4), buf[i]); - } - assert.throws(() => foo(numPages * pageSize + 1), WebAssembly.RuntimeError, "Out of bounds memory access"); - } -} - -function doCheckNoTrap(instances, mem, numPages, length) { - const buf = new Uint32Array(mem.buffer); - - for (let instance of instances) { - const foo = instance.exports.get; - for (let i = 0; i < length; i++) { - assert.eq(foo(i * 4), buf[i]); - } - assert.eq(foo(numPages * pageSize + 1), 0); - } -} - -function doMemoryGrow(instances) { - const instance = instances[0]; // Take first instance and grow shared memory - instance.exports.grow(1); -} - -function doCheck(mem, instances, numPages) { - const length = mem.buffer.byteLength / 4; - - doFillMemory(mem, length); - doCheckTrap(instances, mem, numPages, length); - doMemoryGrow(instances); - doCheckNoTrap(instances, mem, numPages, length); -} - -function checkWasmInstancesWithSharedMemory() { - const mem = new WebAssembly.Memory(memoryDescription); - - const instances = []; - for (let i = 0; i < count; i++) { - instances.push(createWasmInstance(mem)); - } - - for(let i = 1; i < pages; i++) { - doCheck(mem, instances, i); - } - - let instance; - for (let i = 0; i < count; i++) { - instance = instances.shift(); - } - - fullGC(); - - const survivedInstances = [ instance ]; // Should survive only one instance after full GC - - doCheck(mem, survivedInstances, pages); // Recheck only for survie instances -} - -checkWasmInstancesWithSharedMemory(); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/memory-section-and-import.js b/implementation-contributed/javascriptcore/wasm/function-tests/memory-section-and-import.js deleted file mode 100644 index 15207ef7188efa0f6923573c1dfea5a3ea5b71ff..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/memory-section-and-import.js +++ /dev/null @@ -1,31 +0,0 @@ -import Builder from '../Builder.js'; -import * as assert from '../assert.js'; - -const instantiate = (builder, importObject = undefined) => { - return new WebAssembly.Instance( - new WebAssembly.Module( - builder.WebAssembly().get()), - importObject); -}; - -const initial = 0; -const maximum = 2; - -const builder0 = (new Builder()) - .Type().End() - .Function().End() - .Memory().InitialMaxPages(initial, maximum).End() - .Export() - .Memory("memory", 0) - .End() - .Code().End(); - -const builder1 = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", { initial: initial, maximum: maximum }).End() - .Function().End() - .Memory().InitialMaxPages(initial, maximum).End() - .Code().End(); - -const i0 = instantiate(builder0); -assert.throws(() => instantiate(builder1, { imp: { memory: i0.exports.memory } }), WebAssembly.CompileError, `WebAssembly.Module doesn't parse at byte 35: there can at most be one Memory section for now`); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/nameSection.js b/implementation-contributed/javascriptcore/wasm/function-tests/nameSection.js deleted file mode 100644 index d4dcd35976905b1736684d8a5fedc4815f2b3174..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/nameSection.js +++ /dev/null @@ -1,72 +0,0 @@ -import * as assert from '../assert.js' - -/* -This test loads a WebAssembly file compiled by Emscripten with: - ./emsdk-portable/emscripten/incoming/em++ ./nameSection.cc -O2 -g4 -s WASM=1 -o nameSection.js -s EXPORTED_FUNCTIONS="['_parrot']" - -From the following C++ source file: - extern "C" { - int silly(int); - __attribute__((noinline)) int eggs(int i) { return silly(i); } - __attribute__((noinline)) int bacon(int i) { return eggs(i); } - __attribute__((noinline)) int spam(int i) { return bacon(i); } - __attribute__((noinline)) int parrot(int i) { return spam(i); } - } -*/ - -const verbose = false; -const wasmFile = 'nameSection.wasm'; - -const compile = (location, importObject = {}) => { - if (verbose) - print(`Processing ${location}`); - let buf = typeof readbuffer !== "undefined"? readbuffer(location) : read(location, 'binary'); - if (verbose) - print(` Size: ${buf.byteLength}`); - - let t0 = Date.now(); - let module = new WebAssembly.Module(buf); - let t1 = Date.now(); - if (verbose) - print(`new WebAssembly.Module(buf) took ${t1-t0} ms.`); - - if (verbose) - print(`Creating fake import object with ${WebAssembly.Module.imports(module).length} imports`); - for (let imp of WebAssembly.Module.imports(module)) { - if (typeof importObject[imp.module] === "undefined") - importObject[imp.module] = {}; - if (typeof importObject[imp.module][imp.name] === "undefined") { - switch (imp.kind) { - case "function": importObject[imp.module][imp.name] = () => {}; break; - case "table": importObject[imp.module][imp.name] = new WebAssembly.Table({ initial: 6, maximum: 6, element: "anyfunc" }); break; - case "memory": importObject[imp.module][imp.name] = new WebAssembly.Memory({ initial: 16777216 / (64 * 1024), maximum: 16777216 / (64 * 1024) }); break; - case "global": importObject[imp.module][imp.name] = 0; break; - } - } - - } - - let t2 = Date.now(); - let instance = new WebAssembly.Instance(module, importObject); - let t3 = Date.now(); - if (verbose) - print(`new WebAssembly.Module(buf) took ${t3-t2} ms.`); - - return instance; -}; - -let stacktrace; -const importObject = { env: { _silly: i => { stacktrace = (new Error).stack; return i + 42; } } }; -const instance = compile(wasmFile, importObject); -const result = instance.exports._parrot(1); -assert.eq(result, 1 + 42); - -assert.truthy(stacktrace); -stacktrace = stacktrace.split("\n"); -assert.falsy(stacktrace[0].indexOf("_silly") === -1); -assert.eq(stacktrace[1], "wasm-stub@[wasm code]"); // the wasm->js stub -assert.eq(stacktrace[2], "<?>.wasm-function[_eggs]@[wasm code]"); -assert.eq(stacktrace[3], "<?>.wasm-function[_bacon]@[wasm code]"); -assert.eq(stacktrace[4], "<?>.wasm-function[_spam]@[wasm code]"); -assert.eq(stacktrace[5], "<?>.wasm-function[_parrot]@[wasm code]"); -assert.eq(stacktrace[6], "wasm-stub@[wasm code]"); // wasm entry diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/ret5.js b/implementation-contributed/javascriptcore/wasm/function-tests/ret5.js deleted file mode 100644 index bc08e878ae75b8363a4ebdcc40e987a267ed263c..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/ret5.js +++ /dev/null @@ -1,21 +0,0 @@ -import Builder from '../Builder.js' -import * as assert from '../assert.js' - -const b = new Builder(); -b.Type().End() - .Function().End() - .Export() - .Function("ret5") - .End() - .Code() - .Function("ret5", { params: [], ret: "i32" }) - .I32Const(5) - .Return() - .End() - .End(); - -const bin = b.WebAssembly().get(); -const module = new WebAssembly.Module(bin); -const instance = new WebAssembly.Instance(module); - -assert.eq(instance.exports.ret5(), 5); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/rotl.js b/implementation-contributed/javascriptcore/wasm/function-tests/rotl.js deleted file mode 100644 index e978219be0e4877ca37211aa14e3c87f4d88912b..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/rotl.js +++ /dev/null @@ -1,32 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -const builder = (new Builder()) - .Type().End() - .Function().End() - .Export() - .Function("i32Rotl") - .Function("i64Rotl") - .End() - .Code() - .Function("i32Rotl", { params: ["i32", "i32"], ret: "i32" }) - .GetLocal(0) - .GetLocal(1) - .I32Rotl() - .End() - - .Function("i64Rotl", { params: ["i64", "i64"], ret: "i64" }) - .GetLocal(0) - .GetLocal(1) - .I64Rotl() - .End() - - .End(); - -const bin = builder.WebAssembly().get(); -const module = new WebAssembly.Module(bin); -const instance = new WebAssembly.Instance(module); -assert.eqI32(instance.exports.i32Rotl(1, 1), 2); -assert.eqI32(instance.exports.i32Rotl(1, 2), 4); -assert.eqI32(instance.exports.i32Rotl(0xf, 2), 0x3c); -assert.eqI32(instance.exports.i32Rotl(0xf0000000, 1), 0xe0000001); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/rotr.js b/implementation-contributed/javascriptcore/wasm/function-tests/rotr.js deleted file mode 100644 index 14f8d4532991417bad951f9182e1b6cc695596df..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/rotr.js +++ /dev/null @@ -1,31 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -const builder = (new Builder()) - .Type().End() - .Function().End() - .Export() - .Function("i32Rotr") - .Function("i64Rotr") - .End() - .Code() - .Function("i32Rotr", { params: ["i32", "i32"], ret: "i32" }) - .GetLocal(0) - .GetLocal(1) - .I32Rotr() - .End() - - .Function("i64Rotr", { params: ["i64", "i64"], ret: "i64" }) - .GetLocal(0) - .GetLocal(1) - .I64Rotr() - .End() - - .End(); - -const bin = builder.WebAssembly().get(); -const module = new WebAssembly.Module(bin); -const instance = new WebAssembly.Instance(module); -assert.eqI32(instance.exports.i32Rotr(1, 1), 0x80000000); -assert.eqI32(instance.exports.i32Rotr(1, 2), 0x40000000); -assert.eqI32(instance.exports.i32Rotr(0xf, 2), 0xc0000003); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/shl.js b/implementation-contributed/javascriptcore/wasm/function-tests/shl.js deleted file mode 100644 index 41ac11659d3d078b4328320439b45260a56e9f2e..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/shl.js +++ /dev/null @@ -1,32 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -const builder = (new Builder()) - .Type().End() - .Function().End() - .Export() - .Function("i32Shl") - .Function("i64Shl") - .End() - .Code() - .Function("i32Shl", { params: ["i32", "i32"], ret: "i32" }) - .GetLocal(0) - .GetLocal(1) - .I32Shl() - .End() - - .Function("i64Shl", { params: ["i64", "i64"], ret: "i64" }) - .GetLocal(0) - .GetLocal(1) - .I64Shl() - .End() - - .End(); - -const bin = builder.WebAssembly().get(); -const module = new WebAssembly.Module(bin); -const instance = new WebAssembly.Instance(module); -assert.eqI32(instance.exports.i32Shl(1, 1), 2); -assert.eqI32(instance.exports.i32Shl(1, 2), 4); -assert.eqI32(instance.exports.i32Shl(0xf, 2), 0x3c); -assert.eqI32(instance.exports.i32Shl(0xf0000000, 1), 0xe0000000); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/shr-s.js b/implementation-contributed/javascriptcore/wasm/function-tests/shr-s.js deleted file mode 100644 index ec55d3536ad81b70e1ec68bd92802d1046f48c5b..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/shr-s.js +++ /dev/null @@ -1,32 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -const builder = (new Builder()) - .Type().End() - .Function().End() - .Export() - .Function("i32ShrS") - .Function("i64ShrS") - .End() - .Code() - .Function("i32ShrS", { params: ["i32", "i32"], ret: "i32" }) - .GetLocal(0) - .GetLocal(1) - .I32ShrS() - .End() - - .Function("i64ShrS", { params: ["i64", "i64"], ret: "i64" }) - .GetLocal(0) - .GetLocal(1) - .I64ShrS() - .End() - - .End(); - -const bin = builder.WebAssembly().get(); -const module = new WebAssembly.Module(bin); -const instance = new WebAssembly.Instance(module); -assert.eqI32(instance.exports.i32ShrS(1, 1), 0); -assert.eqI32(instance.exports.i32ShrS(1, 2), 0); -assert.eqI32(instance.exports.i32ShrS(0xf, 2), 0x3); -assert.eqI32(instance.exports.i32ShrS(0xf0000000, 1), 0xf8000000); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/shr-u.js b/implementation-contributed/javascriptcore/wasm/function-tests/shr-u.js deleted file mode 100644 index 05ab2730e3af332550a8e4ca3e0320bd485108d9..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/shr-u.js +++ /dev/null @@ -1,32 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -const builder = (new Builder()) - .Type().End() - .Function().End() - .Export() - .Function("i32ShrU") - .Function("i64ShrU") - .End() - .Code() - .Function("i32ShrU", { params: ["i32", "i32"], ret: "i32" }) - .GetLocal(0) - .GetLocal(1) - .I32ShrU() - .End() - - .Function("i64ShrU", { params: ["i64", "i64"], ret: "i64" }) - .GetLocal(0) - .GetLocal(1) - .I64ShrU() - .End() - - .End(); - -const bin = builder.WebAssembly().get(); -const module = new WebAssembly.Module(bin); -const instance = new WebAssembly.Instance(module); -assert.eqI32(instance.exports.i32ShrU(1, 1), 0); -assert.eqI32(instance.exports.i32ShrU(1, 2), 0); -assert.eqI32(instance.exports.i32ShrU(0xf, 2), 0x3); -assert.eqI32(instance.exports.i32ShrU(0xf0000000, 1), 0x78000000); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/stack-overflow.js b/implementation-contributed/javascriptcore/wasm/function-tests/stack-overflow.js deleted file mode 100644 index cfbb5eed4649a5ae45cb5e34b122342086fc076d..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/stack-overflow.js +++ /dev/null @@ -1,221 +0,0 @@ -import Builder from '../Builder.js' -import * as assert from '../assert.js' - -{ - function makeInstance() { - const tableDescription = {initial: 1, element: "anyfunc"}; - const builder = new Builder() - .Type() - .Func(["i32"], "void") - .End() - .Import() - .Table("imp", "table", tableDescription) - .End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", 0 /*['i32'] => 'void'*/) - .GetLocal(0) // parameter to call - .GetLocal(0) // call index - .CallIndirect(0, 0) // calling function of type ['i32'] => 'i32' - .Return() - .End() - .End(); - - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const table = new WebAssembly.Table(tableDescription); - return {instance: new WebAssembly.Instance(module, {imp: {table}}), table}; - } - - const {instance: i1, table: t1} = makeInstance(); - const {instance: i2, table: t2} = makeInstance(); - t2.set(0, i1.exports.foo); - t1.set(0, i2.exports.foo); - - function assertOverflows(instance) { - let stack; - try { - instance.exports.foo(0) - } catch(e) { - stack = e.stack; - } - stack = stack.split("\n"); - assert.truthy(stack.length > 50); - for (let i = 0; i < 50; ++i) { - let item = stack[stack.length - i - 1]; - assert.eq(item, '<?>.wasm-function[0]@[wasm code]'); - } - } - assertOverflows(i1); - assertOverflows(i2); - -} - -{ - function makeInstance() { - const tableDescription = {initial: 1, element: "anyfunc"}; - const builder = new Builder() - .Type() - .Func([], "void") - .End() - .Import() - .Table("imp", "table", tableDescription) - .End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", {params:["i32"], ret:"void"}) - .GetLocal(0) // parameter to call - .GetLocal(0) // call index - .CallIndirect(0, 0) // calling function of type [] => 'void' - .Return() - .End() - .End(); - - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const table = new WebAssembly.Table(tableDescription); - return {instance: new WebAssembly.Instance(module, {imp: {table}}), table}; - } - - function makeInstance2(f) { - const builder = new Builder() - .Type() - .End() - .Import() - .Function("imp", "f", {params:['i32'], ret:"void"}) - .End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", {params: [], ret: "void" }) - .I32Const(0) - .Call(0) - .Return() - .End() - .End(); - - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - return new WebAssembly.Instance(module, {imp: {f}}); - } - - const {instance: i1, table: t1} = makeInstance(); - const foo = i1.exports.foo; - const i2 = makeInstance2(i1.exports.foo); - t1.set(0, i2.exports.foo); - - function assertThrows(instance) { - let stack; - try { - instance.exports.foo(); - } catch(e) { - stack = e.stack; - } - assert.truthy(stack); - - stack = stack.split("\n"); - assert.truthy(stack.length > 50); - const one = '<?>.wasm-function[1]@[wasm code]'; - const zero = '<?>.wasm-function[0]@[wasm code]'; - let currentIndex = (one === stack[stack.length - 1]) ? 1 : 0; - for (let i = 0; i < 50; ++i) { - let item = stack[stack.length - 1 - i]; - if (currentIndex === 1) { - assert.eq(item, one); - currentIndex = 0; - } else { - assert.eq(currentIndex, 0); - assert.eq(item, zero); - currentIndex = 1; - } - } - } - - for (let i = 0; i < 20; ++i) { - assertThrows(i2); - assertThrows(i1); - } - - for (let i = 0; i < 20; ++i) { - assertThrows(i1); - assertThrows(i2); - } -} - -{ - function test(numArgs) { - function makeSignature() { - let args = []; - for (let i = 0; i < numArgs; ++i) { - args.push("i32"); - } - return {params: args}; - } - function makeInstance(f) { - let builder = new Builder() - .Type() - .Func([], "void") - .End() - .Import() - .Function("imp", "f", makeSignature()) - .End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", {params:[], ret:"void"}); - for (let i = 0; i < numArgs; ++i) { - builder = builder.I32Const(i); - } - - builder = builder.Call(0).Return().End().End(); - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - return new WebAssembly.Instance(module, {imp: {f}}); - } - - function f(...args) { - assert.eq(args.length, numArgs); - for (let i = 0; i < args.length; ++i) - assert.eq(args[i], i); - - instance.exports.foo(); - } - let instance = makeInstance(f); - - let stack; - try { - instance.exports.foo(); - } catch(e) { - stack = e.stack; - } - assert.truthy(stack.split("\n").length > 25); - } - - for (let i = 0; i < 70; ++i) { - let r = Math.random() * 1000 | 0; - test(r); - } - - test(20); - test(20); - test(1000); - test(2); - test(1); - test(0); - test(700); - test(433); - test(42); -} diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/stack-trace.js b/implementation-contributed/javascriptcore/wasm/function-tests/stack-trace.js deleted file mode 100644 index 76e849d2e5988e4e1c372d49413150d5a158fd63..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/stack-trace.js +++ /dev/null @@ -1,53 +0,0 @@ -import Builder from '../Builder.js' -import * as assert from '../assert.js' - -const builder = (new Builder()) - .Type().End() - .Import() - .Function("imp", "f", { params: [], ret: "void" }) - .End() - .Function().End() - .Export().Function("entry").End() - .Code() - // idx 1 - .Function("entry", {params: []}) - .Call(3) - .End() - // idx 2 - .Function({params: []}) - .Call(4) - .End() - // idx 3 - .Function({params: []}) - .Call(2) - .End() - // idx 4 - .Function({params: []}) - .Call(0) - .End() - .End(); - -let stacktrace; -let imp = () => { - stacktrace = (new Error).stack; -} - - -const bin = builder.WebAssembly().get(); -const module = new WebAssembly.Module(bin); -let instance = new WebAssembly.Instance(module, {imp: {f: imp}}); -assert.falsy(stacktrace); -for (let i = 0; i < 10000; ++i) { - instance.exports.entry(); - assert.truthy(stacktrace); - stacktrace = stacktrace.split("\n"); - assert.truthy(stacktrace[0].indexOf("imp") !== -1); // the arrow function import named "imp". - assert.eq(stacktrace[1], "wasm-stub@[wasm code]"); // the wasm->js stub - assert.eq(stacktrace[2], "<?>.wasm-function[4]@[wasm code]"); - assert.eq(stacktrace[3], "<?>.wasm-function[2]@[wasm code]"); - assert.eq(stacktrace[4], "<?>.wasm-function[3]@[wasm code]"); - assert.eq(stacktrace[5], "<?>.wasm-function[1]@[wasm code]"); - assert.eq(stacktrace[6], "wasm-stub@[wasm code]"); // wasm entry - - stacktrace = null; -} diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/struct.js b/implementation-contributed/javascriptcore/wasm/function-tests/struct.js deleted file mode 100644 index cc5e21fd954ce9f5ed4f2d0c49b578fc21996957..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/struct.js +++ /dev/null @@ -1,28 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -const builder = (new Builder()) - -builder.Type().End() - .Function().End() - .Memory().InitialMaxPages(1, 1).End() - .Export() - .Function("callFunc") - .End() - .Code() - .Function("callFunc", { params: ["i32", "i32"], ret: "i32" }) - .GetLocal(0) - .If("void", b => { - return b.GetLocal(0) - .GetLocal(1) - .I32Load(0, 4) - .I32Sub() - .Return() - }) - .I32Const(42) - .Return() - .End() - .End(); -const bin = builder.WebAssembly().get(); -const module = new WebAssembly.Module(bin); -const instance = new WebAssembly.Instance(module); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/table-basic-2.js b/implementation-contributed/javascriptcore/wasm/function-tests/table-basic-2.js deleted file mode 100644 index 27361f4939b9c1131991646d07ef612c384c3c7a..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/table-basic-2.js +++ /dev/null @@ -1,57 +0,0 @@ -import Builder from '../Builder.js' -import * as assert from '../assert.js' - -function makeInstance(func) { - const builder = new Builder() - .Type() - .Func(["i32", "i32"], "i32") - .Func(["i32"], "i32") - .End() - .Import() - .Table("imp", "table", {initial: 20, element: "anyfunc"}) - .Function("imp", "func", { params: ["i32"], ret: "i32" }) - .End() - .Function().End() - .Export() - .Function("foo") - .Function("bar") - .End() - .Code() - .Function("foo", 0 /*['i32', 'i32'] => 'i32'*/) - .GetLocal(1) // parameter to call - .GetLocal(0) // call index - .CallIndirect(1, 0) // calling function of type ['i32'] => 'i32' - .Return() - .End() - .Function("bar", 1 /*['i32'] => 'i32'*/) - .GetLocal(0) - .Call(0) - .Return() - .End() - .End(); - - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const table = new WebAssembly.Table({initial: 20, element: "anyfunc"}); - return {instance: new WebAssembly.Instance(module, {imp: {table, func}}), table}; -} - -{ - let i; - function func(x) { - if (x !== i) - throw new Error("Bad argument"); - return x + 44; - } - const {instance, table} = makeInstance(func); - const exports = instance.exports; - const foo = exports.foo; - table.set(0, exports.bar); - assert.eq(table.get(0), exports.bar); - - for (i = 0; i < 10000; i++) { - if (foo(0, i) !== i + 44) - throw new Error("Bad call indirect"); - } -} diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/table-basic.js b/implementation-contributed/javascriptcore/wasm/function-tests/table-basic.js deleted file mode 100644 index 0ff3b4766423d372e5b9723dd2d7c83d8ff4284c..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/table-basic.js +++ /dev/null @@ -1,58 +0,0 @@ -import Builder from '../Builder.js' -import * as assert from '../assert.js' - -function makeInstance() { - const builder = new Builder() - .Type() - .Func(["i32", "i32"], "i32") - .Func(["i32"], "i32") - .End() - .Import() - .Table("imp", "table", {initial: 20, element: "anyfunc"}) - .End() - .Function().End() - .Export() - .Function("foo") - .Function("bar") - .End() - .Code() - .Function("foo", 0 /*['i32', 'i32'] => 'i32'*/) - .GetLocal(1) // parameter to call - .GetLocal(0) // call index - .CallIndirect(1, 0) // calling function of type ['i32'] => 'i32' - .Return() - .End() - .Function("bar", 1 /*['i32'] => 'i32'*/) - .GetLocal(0) - .I32Const(42) - .I32Add() - .Return() - .End() - .End(); - - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const table = new WebAssembly.Table({initial: 20, element: "anyfunc"}); - return {instance: new WebAssembly.Instance(module, {imp: {table}}), table}; -} - -{ - const {instance, table} = makeInstance(); - const exports = instance.exports; - const foo = exports.foo; - table.set(0, exports.bar); - assert.eq(table.get(0), exports.bar); - - for (let i = 0; i < 1000; i++) - assert.eq(foo(0, i), i + 42, "call_indirect"); -} - -{ - const {instance, table} = makeInstance(); - const foo = instance.exports.foo; - table.set(0, makeInstance().instance.exports.bar); // Cross instance function. - - for (let i = 0; i < 1000; i++) - assert.eq(foo(0, i), i + 42, "call_indirect"); -} diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/trap-after-cross-instance-call.js b/implementation-contributed/javascriptcore/wasm/function-tests/trap-after-cross-instance-call.js deleted file mode 100644 index 196334582a2a636668162775795f9cb085fa62a5..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/trap-after-cross-instance-call.js +++ /dev/null @@ -1,64 +0,0 @@ -import Builder from '../Builder.js' -import * as assert from '../assert.js' - -const pageSize = 64 * 1024; -const numPages = 10; - -const builder = (new Builder()) - .Type().End() - .Import() - .Memory("a", "b", {initial: numPages}) - .Function("foo", "bar", { params: [], ret: "void" }) - .End() - .Function().End() - .Export().Function("foo").End() - .Code() - .Function("foo", {params: ["i32"], ret: "i32"}) - .Call(0) - .GetLocal(0) - .I32Load(2, 0) - .Return() - .End() - .End(); - -const bin = builder.WebAssembly().get(); -const module = new WebAssembly.Module(bin); - -let importObject = {a: {b: new WebAssembly.Memory({initial: numPages})}}; - -{ - const builder = (new Builder()) - .Type().End() - .Import() - .Memory("a", "b", {initial: numPages}) - .End() - .Function().End() - .Export().Function("bar").End() - .Code() - .Function("bar", { params: [], ret: "void" }) - .Return() - .End() - .End(); - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - - importObject.foo = new WebAssembly.Instance(module, {a: {b: new WebAssembly.Memory({initial: numPages})}}).exports -} - -let foo1 = new WebAssembly.Instance(module, importObject).exports.foo; -importObject.foo = { bar() { } }; -let foo2 = new WebAssembly.Instance(module, importObject).exports.foo; - - -function wasmFrameCountFromError(e) { - let stackFrames = e.stack.split("\n").filter((s) => s.indexOf("wasm-") !== -1); - return stackFrames.length; -} - -for (let i = 0; i < 1000; i++) { - const e1 = assert.throws(() => foo1(numPages * pageSize + 1), WebAssembly.RuntimeError, "Out of bounds memory access"); - assert.eq(wasmFrameCountFromError(e1), 2); - const e2 = assert.throws(() => foo2(numPages * pageSize + 1), WebAssembly.RuntimeError, "Out of bounds memory access"); - assert.eq(wasmFrameCountFromError(e2), 2); -} diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/trap-from-start-async.js b/implementation-contributed/javascriptcore/wasm/function-tests/trap-from-start-async.js deleted file mode 100644 index 83c7f8921a79fd06fedc7603983b6fd2a6aa6eec..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/trap-from-start-async.js +++ /dev/null @@ -1,83 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -const memoryInfo = { initial: 2 }; -const tableInfo = { element: "anyfunc", initial: 8 }; - -async function StartTrapsAsync() { - const builder = (new Builder()) - .Type().End() - .Import() - .Memory("imp", "memory", memoryInfo) - .Table("imp", "table", tableInfo) - .Function("imp", "func", { params: ["i32"] }) - .End() - .Function().End() - .Start("startMeUp").End() - .Element() - .Element({ offset: 4, functionIndices: [0, 1] }) - .End() - .Code() - .Function("startMeUp", { params: [] }) - .I32Const(0).I32Load(2, 0).I32Const(0xfeedface).I32Store(2, 0) - .I32Const(4).I32Load(2, 0).I32Const(0xc0fec0fe).I32Store(2, 0) // This will trap. - // This is unreachable: - .I32Const(42).Call(0) // Calls func(42). - .End() - .End() - .Data() - .Segment([0xef, 0xbe, 0xad, 0xde]).Offset(1024).End() - .End(); - - const memory = new WebAssembly.Memory(memoryInfo); - const buffer = new Uint32Array(memory.buffer); - - const table = new WebAssembly.Table(tableInfo); - - // The instance will use these as addresses for stores. - buffer[0] = 128; - buffer[1] = 0xc0defefe; // This is out of bounds. - - // This function shouldn't get called because the trap occurs before the call. - let value = 0; - const func = v => value = v; - - const module = new WebAssembly.Module(builder.WebAssembly().get()); - const imp = { imp: { memory, table, func } }; - - const promise = WebAssembly.instantiate(module, imp); - await assert.throwsAsync(promise, WebAssembly.RuntimeError, `Out of bounds memory access`); - - assert.eq(value, 0); - - for (let i = 0; i < buffer.length; ++i) { - switch (i) { - case 0: assert.eq(buffer[i], 128); break; // Initial ArrayBuffer store. - case 1: assert.eq(buffer[i], 0xc0defefe); break; // Initial ArrayBuffer store. - case 32: assert.eq(buffer[i], 0xfeedface); break; // First store from start function. - case 256: assert.eq(buffer[i], 0xdeadbeef); break; // Data segment. - default: assert.eq(buffer[i], 0); break; // The rest. - } - } - - for (let i = 0; i < table.length; ++i) { - switch (i) { - case 4: assert.isFunction(table.get(i)); break; - case 5: assert.isFunction(table.get(i)); break; - default: assert.eq(table.get(i), null); break; - } - } - - // Call the imported `func`. - table.get(4)(0xf00f); - assert.eq(value, 0xf00f); - value = 0; - - // Call the start function again on the instance. The instance is otherwise inaccessible! - buffer[32] = 0; // Reset the location which will be set by the first store. - assert.throws(() => table.get(5)(), WebAssembly.RuntimeError, `Out of bounds memory access`); - assert.eq(buffer[32], 0xfeedface); // The first store should still succeed. - assert.eq(value, 0); -} - -assert.asyncTest(StartTrapsAsync()); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/trap-from-start.js b/implementation-contributed/javascriptcore/wasm/function-tests/trap-from-start.js deleted file mode 100644 index ea5a0ac716c04acd911c01547841df0cc9828bfa..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/trap-from-start.js +++ /dev/null @@ -1,80 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -const memoryInfo = { initial: 2 }; -const tableInfo = { element: "anyfunc", initial: 8 }; - -(function StartTraps() { - const builder = (new Builder()) - .Type().End() - .Import() - .Memory("imp", "memory", memoryInfo) - .Table("imp", "table", tableInfo) - .Function("imp", "func", { params: ["i32"] }) - .End() - .Function().End() - .Start("startMeUp").End() - .Element() - .Element({ offset: 4, functionIndices: [0, 1] }) - .End() - .Code() - .Function("startMeUp", { params: [] }) - .I32Const(0).I32Load(2, 0).I32Const(0xfeedface).I32Store(2, 0) - .I32Const(4).I32Load(2, 0).I32Const(0xc0fec0fe).I32Store(2, 0) // This will trap. - // This is unreachable: - .I32Const(42).Call(0) // Calls func(42). - .End() - .End() - .Data() - .Segment([0xef, 0xbe, 0xad, 0xde]).Offset(1024).End() - .End(); - - const memory = new WebAssembly.Memory(memoryInfo); - const buffer = new Uint32Array(memory.buffer); - - const table = new WebAssembly.Table(tableInfo); - - // The instance will use these as addresses for stores. - buffer[0] = 128; - buffer[1] = 0xc0defefe; // This is out of bounds. - - // This function shouldn't get called because the trap occurs before the call. - let value = 0; - const func = v => value = v; - - const module = new WebAssembly.Module(builder.WebAssembly().get()); - const imp = { imp: { memory, table, func } }; - - assert.throws(() => new WebAssembly.Instance(module, imp), WebAssembly.RuntimeError, `Out of bounds memory access`); - - assert.eq(value, 0); - - for (let i = 0; i < buffer.length; ++i) { - switch (i) { - case 0: assert.eq(buffer[i], 128); break; // Initial ArrayBuffer store. - case 1: assert.eq(buffer[i], 0xc0defefe); break; // Initial ArrayBuffer store. - case 32: assert.eq(buffer[i], 0xfeedface); break; // First store from start function. - case 256: assert.eq(buffer[i], 0xdeadbeef); break; // Data segment. - default: assert.eq(buffer[i], 0); break; // The rest. - } - } - - for (let i = 0; i < table.length; ++i) { - switch (i) { - case 4: assert.isFunction(table.get(i)); break; - case 5: assert.isFunction(table.get(i)); break; - default: assert.eq(table.get(i), null); break; - } - } - - // Call the imported `func`. - table.get(4)(0xf00f); - assert.eq(value, 0xf00f); - value = 0; - - // Call the start function again on the instance. The instance is otherwise inaccessible! - buffer[32] = 0; // Reset the location which will be set by the first store. - assert.throws(() => table.get(5)(), WebAssembly.RuntimeError, `Out of bounds memory access`); - assert.eq(buffer[32], 0xfeedface); // The first store should still succeed. - assert.eq(value, 0); -})(); diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/trap-load-2.js b/implementation-contributed/javascriptcore/wasm/function-tests/trap-load-2.js deleted file mode 100644 index a6a8973a9bffbc09d2cf1cc2ab4376a1b789bbc7..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/trap-load-2.js +++ /dev/null @@ -1,75 +0,0 @@ -import Builder from '../Builder.js' -import * as assert from '../assert.js' - -const pageSize = 64 * 1024; -const numPages = 10; - -const builder = (new Builder()) - .Type().End() - .Import() - .Memory("a", "b", {initial: numPages}) - .End() - .Function().End() - .Export().Function("foo").End() - .Code() - .Function("foo", {params: ["i32"], ret: "i32"}) - .GetLocal(0) - .I32Load(2, 0) - .Return() - .End() - .End(); - -function wasmFrameCountFromError(e) { - let stackFrames = e.stack.split("\n").filter((s) => s.indexOf("wasm-") !== -1); - return stackFrames.length; -} - -{ - const builder = (new Builder()) - .Type().End() - .Import() - .Memory("imp", "mem", {initial: numPages}) - .Function("imp", "func", { params: ["i32"] }) - .End() - .Function().End() - .Export().Function("foo").End() - .Code() - .Function("foo", {params: ["i32", "i32"]}) - .GetLocal(0) - .I32Const(0) - .I32Eq() - .If("void", b => - b.GetLocal(1) - .GetLocal(1) - .I32Load(2, 0) - .Br(0) - .Else() - .GetLocal(0) - .Call(0) - .Br(0) - ) - .End() - .End(); - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const imp = { - imp: { - mem: new WebAssembly.Memory({initial: numPages}), - func: continuation - } - }; - const foo = new WebAssembly.Instance(module, imp).exports.foo; - const address = numPages*pageSize + 1; - function continuation(x) { - foo(x - 1, address); - } - - for (let i = 0; i < 5000; i++) { - const e = assert.throws(() => foo(5, address), WebAssembly.RuntimeError, "Out of bounds memory access (evaluating 'foo(x - 1, address)')"); - // There are 5 total calls, and each call does: - // JS entry, wasm entry, js call stub. - // The last call that traps just has JS entry and wasm entry. - assert.eq(wasmFrameCountFromError(e), 5 * 3 + 2); - } -} diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/trap-load.js b/implementation-contributed/javascriptcore/wasm/function-tests/trap-load.js deleted file mode 100644 index 7cf0e980aa5edf7a0e59a9e05abe3e7f7a8d3aa2..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/trap-load.js +++ /dev/null @@ -1,34 +0,0 @@ -import Builder from '../Builder.js' -import * as assert from '../assert.js' - -const pageSize = 64 * 1024; -const numPages = 10; - -const builder = (new Builder()) - .Type().End() - .Import() - .Memory("a", "b", {initial: numPages}) - .End() - .Function().End() - .Export().Function("foo").End() - .Code() - .Function("foo", {params: ["i32"], ret: "i32"}) - .GetLocal(0) - .I32Load(2, 0) - .Return() - .End() - .End(); - -const bin = builder.WebAssembly().get(); -const module = new WebAssembly.Module(bin); -const foo = new WebAssembly.Instance(module, {a: {b: new WebAssembly.Memory({initial: numPages})}}).exports.foo; - -function wasmFrameCountFromError(e) { - let stackFrames = e.stack.split("\n").filter((s) => s.indexOf("wasm-") !== -1); - return stackFrames.length; -} - -for (let i = 0; i < 1000; i++) { - const e = assert.throws(() => foo(numPages * pageSize + 1), WebAssembly.RuntimeError, "Out of bounds memory access"); - assert.eq(wasmFrameCountFromError(e), 2); -} diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/trap-store-2.js b/implementation-contributed/javascriptcore/wasm/function-tests/trap-store-2.js deleted file mode 100644 index cc550d7774a78f5658d5eece279a23a479b8532d..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/trap-store-2.js +++ /dev/null @@ -1,50 +0,0 @@ -import Builder from '../Builder.js' -import * as assert from '../assert.js' - -const pageSize = 64 * 1024; -const numPages = 10; - -{ - const builder = (new Builder()) - .Type().End() - .Import() - .Memory("imp", "mem", {initial: numPages}) - .Function("imp", "func", { params: ["i32"] }) - .End() - .Function().End() - .Export().Function("foo").End() - .Code() - .Function("foo", {params: ["i32", "i32"]}) - .GetLocal(0) - .I32Const(0) - .I32Eq() - .If("void", b => - b.GetLocal(1) - .GetLocal(0) - .I32Store(2, 0) - .Br(0) - .Else() - .GetLocal(0) - .Call(0) - .Br(0) - ) - .End() - .End(); - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const imp = { - imp: { - mem: new WebAssembly.Memory({initial: numPages}), - func: continuation - } - }; - const foo = new WebAssembly.Instance(module, imp).exports.foo; - const address = numPages*pageSize + 1; - function continuation(x) { - foo(x - 1, address); - } - - for (let i = 0; i < 5000; i++) - assert.throws(() => foo(6, address), WebAssembly.RuntimeError, "Out of bounds memory access"); -} diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/trap-store.js b/implementation-contributed/javascriptcore/wasm/function-tests/trap-store.js deleted file mode 100644 index 365713a3058fa6dfddcf053922d31260f0e39fa2..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/trap-store.js +++ /dev/null @@ -1,29 +0,0 @@ -import Builder from '../Builder.js' -import * as assert from '../assert.js' - -const pageSize = 64 * 1024; -const numPages = 10; - -{ - const builder = (new Builder()) - .Type().End() - .Import() - .Memory("a", "b", {initial: numPages}) - .End() - .Function().End() - .Export().Function("foo").End() - .Code() - .Function("foo", {params: ["i32", "i32"]}) - .GetLocal(1) - .GetLocal(0) - .I32Store(2, 0) - .End() - .End(); - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const foo = new WebAssembly.Instance(module, {a: {b: new WebAssembly.Memory({initial: numPages})}}).exports.foo; - - for (let i = 0; i < 10000; i++) - assert.throws(() => foo(i, numPages * pageSize + 1), WebAssembly.RuntimeError, "Out of bounds memory access"); -} diff --git a/implementation-contributed/javascriptcore/wasm/function-tests/void-argument-type-should-be-a-validation-error.js b/implementation-contributed/javascriptcore/wasm/function-tests/void-argument-type-should-be-a-validation-error.js deleted file mode 100644 index 2178810a7817d97335e62f78b3fc517e3fe77e41..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/function-tests/void-argument-type-should-be-a-validation-error.js +++ /dev/null @@ -1,22 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -function getBinary(params) { - const builder = (new Builder()) - builder.Type().End() - .Function().End() - .Memory().InitialMaxPages(1, 1).End() - .Export() - .Function("callFunc") - .End() - .Code() - .Function("callFunc", { params, ret: "void" }) - .Return() - .End() - .End(); - return builder.WebAssembly().get(); -} - -assert.throws(() => new WebAssembly.Module(getBinary(["i32", "void"])), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 15: can't get 1th argument Type"); -assert.throws(() => new WebAssembly.Module(getBinary(["void"])), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 14: can't get 0th argument Type"); -assert.throws(() => new WebAssembly.Module(getBinary(["i32", "void", "i32"])), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 15: can't get 1th argument Type"); diff --git a/implementation-contributed/javascriptcore/wasm/fuzz/export-function.js b/implementation-contributed/javascriptcore/wasm/fuzz/export-function.js deleted file mode 100644 index e4e286d88f2332cdea815920ba67377fe091ea34..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/fuzz/export-function.js +++ /dev/null @@ -1,80 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -const numRandomIterations = 128; - -// Generate wasm export functions of arity [0, max), using each valid -// WebAssembly type as parameters. Make sure this number is high enough to force -// non-register calls. -const maxArities = 64; - -// Calls a "check" function for each parameter received. -const paramExporter = (params, returnedParam, imports) => { - const ret = params.length ? params[returnedParam] : "void"; - let builder = (new Builder()) - .Type().End() - .Import() - .Function("imp", "checki32", { params: ["i32"] }) - .Function("imp", "checkf32", { params: ["f32"] }) - .Function("imp", "checkf64", { params: ["f64"] }) - .End() - .Function().End() - .Export() - .Function("func") - .End() - .Code() - .Function("func", { params: params, ret: ret }); - for (let i = 0; i < params.length; ++i) { - builder = builder.GetLocal(i); - switch (params[i]) { - case "i32": builder = builder.Call(0); break; - case "f32": builder = builder.Call(1); break; - case "f64": builder = builder.Call(2); break; - default: throw new Error(`Unexpected type`); - } - } - if (ret !== "void") - builder = builder.GetLocal(returnedParam); - builder = builder.Return().End().End(); - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - return new WebAssembly.Instance(module, { imp: imports }); -}; - -var buffer = new ArrayBuffer(8); -var viewi16 = new Int16Array(buffer); -var viewi32 = new Int32Array(buffer); -var viewf32 = new Float32Array(buffer); -var viewf64 = new Float64Array(buffer); -const random16 = () => (Math.random() * (1 + 0xffff)) | 0; -const setBuffer = () => { - for (let i = 0; i < 4; ++i) - viewi16[i] = random16(); -}; -const types = [ - { type: "i32", generate: () => { setBuffer(); return viewi32[0]; } }, - // i64 isn't supported. - { type: "f32", generate: () => { setBuffer(); return viewf32[0]; } }, - { type: "f64", generate: () => { setBuffer(); return viewf64[0]; } }, -]; - -for (let iteration = 0; iteration < numRandomIterations; ++iteration) { - const arity = (Math.random() * (maxArities + 1)) | 0; - let params = []; - let args = []; - for (let a = 0; a < arity; ++a) { - const type =( Math.random() * types.length) | 0; - params.push(types[type].type); - args.push(types[type].generate()); - } - let numChecked = 0; - const imports = { - checki32: v => assert.eq(v, args[numChecked++]), - checkf32: v => assert.eq(v, args[numChecked++]), - checkf64: v => assert.eq(v, args[numChecked++]), - }; - const returnedParam = (Math.random() * params.length) | 0; - const instance = paramExporter(params, returnedParam, imports); - const result = instance.exports.func(...args); - assert.eq(result, args.length ? args[returnedParam] : undefined); -} diff --git a/implementation-contributed/javascriptcore/wasm/fuzz/memory.js b/implementation-contributed/javascriptcore/wasm/fuzz/memory.js deleted file mode 100644 index c5db2e9f8722acc8b19857f98a7a2875eb692d8d..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/fuzz/memory.js +++ /dev/null @@ -1,301 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -// FIXME: add the following: https://bugs.webkit.org/show_bug.cgi?id=171936 -// - add set() and shadow memory, this requires tracking when memory is shared -// - Support: empty, exported -// - Imported memory created through the JS API (both before and after instantiation, to cause recompilation) -// - recursive calls (randomly call other instance's exports, potentially exhausting stack) -// - Simplify code by allowing .Code().ExportFunction(...) in builder - -const tune = { - numRandomIterations: 64, - numRandomInvokes: 4, - maxInitial: 8, - maxMax: 8, - maxGrow: 8, - memoryGetCount: 1024, -}; - -const pageSize = 64 * 1024; // As determined by the WebAssembly specification. - -let logString = ""; -let log = what => logString += '\n' + what; - -let instances = []; - -const insert = (builder, importObject = undefined) => { - const location = (Math.random() * instances.length) | 0; - instances.splice(location, 0, new WebAssembly.Instance(new WebAssembly.Module(builder.WebAssembly().get()), importObject)); -} -const initialMaxObject = hasMax => { - const initial = (Math.random() * tune.maxInitial) | 0; - if (!hasMax) - return { initial: initial, max: undefined }; - const max = initial + ((Math.random() * tune.maxMax) | 0); - return { initial: initial, max: max }; -}; -const initialMaxObjectFrom = instance => { - const hasMax = instance.exports["max"] !== undefined; - const initial = (Math.random() * instance.exports.initial()) | 0; - if (!hasMax) - return { initial: initial }; - const max = Math.max(initial, instance.exports.max()) + ((Math.random() * tune.maxMax) | 0); - return { initial: initial, max: max }; -}; - -const action = { - '- delete': () => { - for (let count = 1 + (Math.random() * instances.length) | 0; instances.length && count; --count) { - const which = (Math.random() * instances.length) | 0; - log(` delete ${which} / ${instances.length}`); - instances.splice(which, 1); - } - }, - '^ invoke': () => { - if (!instances.length) { - log(` nothing to invoke`); - return; - } - for (let iterations = 0; iterations < tune.numRandomInvokes; ++iterations) { - const whichInstance = (Math.random() * instances.length) | 0; - const instance = instances[whichInstance]; - const whichExport = (Math.random() * Object.keys(instance.exports).length) | 0; - log(` instances[${whichInstance}].${Object.keys(instance.exports)[whichExport]}()`); - switch (Object.keys(instance.exports)[whichExport]) { - default: - throw new Error(`Implementation problem for key '${Object.keys(instance.exports)[whichExport]}'`); - case 'func': - assert.eq(instance.exports.func(), 42); - break; - case 'throws': { - let threw = false; - let address = 0; - if (instance.exports["current"]) { - // The instance has a memory. - const current = instance.exports.current(); - const max = instance.exports["max"] ? instance.exports.max() : (1 << 15); - address = pageSize * (current + ((Math.random() * (max - current)) | 0)); - } - // No memory in this instance. - try { instance.exports.throws(address); } - catch (e) { threw = true; } - assert.truthy(threw); - } break; - case 'get': { - const current = instance.exports.current(); - for (let access = tune.memoryGetCount; current && access; --access) { - const address = (Math.random() * (current * pageSize - 4)) | 0; - assert.eq(instance.exports.get(address), 0); - } - } break; - case 'current': - assert.le(instance.exports.initial(), instance.exports.current()); - break; - case 'initial': - assert.le(0, instance.exports.initial()); - break; - case 'max': - assert.le(instance.exports.initial(), instance.exports.max()); - assert.le(instance.exports.current(), instance.exports.max()); - break; - case 'memory': { - const current = instance.exports.current(); - const buffer = new Uint32Array(instance.exports.memory.buffer); - assert.eq(buffer.byteLength, current * pageSize); - for (let access = tune.memoryGetCount; current && access; --access) { - const address = (Math.random() * (current * pageSize - 4)) | 0; - assert.eq(instance.exports.get(address), 0); - } - } break; - case 'grow': { - const current = instance.exports.current(); - const by = (Math.random() * tune.maxGrow) | 0; - const hasMax = instance.exports["max"] !== undefined; - const result = instance.exports.grow(current + by); - log(` Grow from ${current} (max ${hasMax ? instance.exports.max() : "none"}) to ${current + by} returned ${result}, current now ${instance.exports.current()}`); - assert.le(current, instance.exports.current()); - if (result === -1) - assert.eq(current, instance.exports.current()); - if (hasMax) - assert.le(instance.exports.current(), instance.exports.max()); - } break; - } - } - }, - '+ memory: none': () => { - const builder = (new Builder()) - .Type().End() - .Function().End() - .Export().Function("func").Function("throws").End() - .Code() - .Function("func", { params: [], ret: "i32" }).I32Const(42).Return().End() - .Function("throws", { params: ["i32"] }).Unreachable().Return().End() - .End(); - insert(builder); - }, - '+ memory: empty, section': () => { - const builder = (new Builder()) - .Type().End() - .Function().End() - .Memory().InitialMaxPages(0, 0).End() - .Export().Function("func").Function("throws").Function("current").Function("initial").Function("grow").Function("max").End() - .Code() - .Function("func", { params: [], ret: "i32" }).I32Const(42).Return().End() - .Function("throws", { params: ["i32"] }).GetLocal(0).I32Load(2, 0).Return().End() - .Function("current", { params: [], ret: "i32" }).CurrentMemory(0).Return().End() - .Function("grow", { params: ["i32"], ret: "i32" }).GetLocal(0).GrowMemory(0).Return().End() - .Function("initial", { params: [], ret: "i32" }).I32Const(0).Return().End() - .Function("max", { params: [], ret: "i32" }).I32Const(0).Return().End() - .End(); - insert(builder); - }, - '+ memory: section': () => { - const initialMax = initialMaxObject(false); - const builder = (new Builder()) - .Type().End() - .Function().End() - .Memory().InitialMaxPages(initialMax.initial, initialMax.max).End() - .Export().Function("func").Function("throws").Function("get").Function("current").Function("initial").Function("grow").End() - .Code() - .Function("func", { params: [], ret: "i32" }).I32Const(42).Return().End() - .Function("throws", { params: ["i32"] }).GetLocal(0).I32Load(2, 0).Return().End() - .Function("get", { params: ["i32"], ret: "i32" }).GetLocal(0).I32Load(2, 0).Return().End() - .Function("current", { params: [], ret: "i32" }).CurrentMemory(0).Return().End() - .Function("grow", { params: ["i32"], ret: "i32" }).GetLocal(0).GrowMemory(0).Return().End() - .Function("initial", { params: [], ret: "i32" }).I32Const(initialMax.initial).Return().End() - .End(); - insert(builder); - }, - '+ memory: section, max': () => { - const initialMax = initialMaxObject(true); - const builder = (new Builder()) - .Type().End() - .Function().End() - .Memory().InitialMaxPages(initialMax.initial, initialMax.max).End() - .Export().Function("func").Function("throws").Function("get").Function("current").Function("initial").Function("grow").Function("max").End() - .Code() - .Function("func", { params: [], ret: "i32" }).I32Const(42).Return().End() - .Function("throws", { params: ["i32"] }).GetLocal(0).I32Load(2, 0).Return().End() - .Function("get", { params: ["i32"], ret: "i32" }).GetLocal(0).I32Load(2, 0).Return().End() - .Function("current", { params: [], ret: "i32" }).CurrentMemory(0).Return().End() - .Function("grow", { params: ["i32"], ret: "i32" }).GetLocal(0).GrowMemory(0).Return().End() - .Function("initial", { params: [], ret: "i32" }).I32Const(initialMax.initial).Return().End() - .Function("max", { params: [], ret: "i32" }).I32Const(initialMax.max).Return().End() - .End(); - insert(builder); - }, - '+ memory: section, exported': () => { - const initialMax = initialMaxObject(false); - const builder = (new Builder()) - .Type().End() - .Function().End() - .Memory().InitialMaxPages(initialMax.initial, initialMax.max).End() - .Export() - .Function("func").Function("throws").Function("get").Function("current").Function("initial") - .Memory("memory", 0) - .End() - .Code() - .Function("func", { params: [], ret: "i32" }).I32Const(42).Return().End() - .Function("throws", { params: ["i32"] }).GetLocal(0).I32Load(2, 0).Return().End() - .Function("get", { params: ["i32"], ret: "i32" }).GetLocal(0).I32Load(2, 0).Return().End() - .Function("current", { params: [], ret: "i32" }).CurrentMemory(0).Return().End() - .Function("grow", { params: ["i32"], ret: "i32" }).GetLocal(0).GrowMemory(0).Return().End() - .Function("initial", { params: [], ret: "i32" }).I32Const(initialMax.initial).Return().End() - .End(); - insert(builder); - }, - '+ memory: section, exported, max': () => { - const initialMax = initialMaxObject(true); - const builder = (new Builder()) - .Type().End() - .Function().End() - .Memory().InitialMaxPages(initialMax.initial, initialMax.max).End() - .Export() - .Function("func").Function("throws").Function("get").Function("current").Function("initial").Function("grow").Function("max") - .Memory("memory", 0) - .End() - .Code() - .Function("func", { params: [], ret: "i32" }).I32Const(42).Return().End() - .Function("throws", { params: ["i32"] }).GetLocal(0).I32Load(2, 0).Return().End() - .Function("get", { params: ["i32"], ret: "i32" }).GetLocal(0).I32Load(2, 0).Return().End() - .Function("current", { params: [], ret: "i32" }).CurrentMemory(0).Return().End() - .Function("grow", { params: ["i32"], ret: "i32" }).GetLocal(0).GrowMemory(0).Return().End() - .Function("initial", { params: [], ret: "i32" }).I32Const(initialMax.initial).Return().End() - .Function("max", { params: [], ret: "i32" }).I32Const(initialMax.max).Return().End() - .End(); - insert(builder); - }, - '+ memory: imported, exported': () => { - let importFrom; - for (let idx = 0; idx < instances.length; ++idx) - if (instances[idx].exports.memory) { - importFrom = instances[idx]; - break; - } - if (!importFrom) - return; // No memory could be imported. - const initialMax = initialMaxObjectFrom(importFrom); - if (importFrom.exports["max"] === undefined) { - const builder = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", initialMax).End() - .Function().End() - .Export() - .Function("func").Function("throws").Function("get").Function("current").Function("initial") - .Memory("memory", 0) - .End() - .Code() - .Function("func", { params: [], ret: "i32" }).I32Const(42).Return().End() - .Function("throws", { params: ["i32"] }).GetLocal(0).I32Load(2, 0).Return().End() - .Function("get", { params: ["i32"], ret: "i32" }).GetLocal(0).I32Load(2, 0).Return().End() - .Function("current", { params: [], ret: "i32" }).CurrentMemory(0).Return().End() - .Function("grow", { params: ["i32"], ret: "i32" }).GetLocal(0).GrowMemory(0).Return().End() - .Function("initial", { params: [], ret: "i32" }).I32Const(initialMax.initial).Return().End() - .End(); - insert(builder, { imp: { memory: importFrom.exports.memory } }); - } else { - const builder = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", initialMax).End() - .Function().End() - .Export() - .Function("func").Function("throws").Function("get").Function("current").Function("initial").Function("grow").Function("max") - .Memory("memory", 0) - .End() - .Code() - .Function("func", { params: [], ret: "i32" }).I32Const(42).Return().End() - .Function("throws", { params: ["i32"] }).GetLocal(0).I32Load(2, 0).Return().End() - .Function("get", { params: ["i32"], ret: "i32" }).GetLocal(0).I32Load(2, 0).Return().End() - .Function("current", { params: [], ret: "i32" }).CurrentMemory(0).Return().End() - .Function("grow", { params: ["i32"], ret: "i32" }).GetLocal(0).GrowMemory(0).Return().End() - .Function("initial", { params: [], ret: "i32" }).I32Const(initialMax.initial).Return().End() - .Function("max", { params: [], ret: "i32" }).I32Const(initialMax.max).Return().End() - .End(); - insert(builder, { imp: { memory: importFrom.exports.memory } }); - } - }, -}; -const numActions = Object.keys(action).length; -const performAction = () => { - const which = (Math.random() * numActions) | 0; - const key = Object.keys(action)[which]; - log(`${key}:`); - action[key](); -}; - -try { - for (let iteration = 0; iteration < tune.numRandomIterations; ++iteration) - performAction(); - log(`Finalizing:`); - // Finish by deleting the instances in a random order. - while (instances.length) - action["- delete"](); -} catch (e) { - // Ignore OOM while fuzzing. It can just happen. - if (e.message !== "Out of memory") { - print(`Failed: ${e}`); - print(logString); - throw e; - } -} diff --git a/implementation-contributed/javascriptcore/wasm/js-api/Instance.imports.exports.unicode.js b/implementation-contributed/javascriptcore/wasm/js-api/Instance.imports.exports.unicode.js deleted file mode 100644 index e86c209ecd4f22610c7f9096952b5dc85256425f..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/Instance.imports.exports.unicode.js +++ /dev/null @@ -1,96 +0,0 @@ -import Builder from '../Builder.js'; -import * as assert from '../assert.js'; - -// Interesting Unicode corner cases. - -const names = [ - "", // Empty string. - "\u0000", // NUL - "â€", // SYMBOL FOR NUL - "\ufeff", // BYTE ORDER MARK - "\ufffc", // OBJECT REPLACEMENT CHARACTER - "�", // REPLACEMENT CHARACTER in case anything gets substituted this would be a duplicate, which WebAssembly disallows. - "\ufffe", // NONCHARACTER-FFFE - "\uffff", // NONCHARACTER-FFFF - "\u200e", // LEFT-TO-RIGHT MARK - "\u200f", // RIGHT-TO-LEFT MARK - "\u202a", // LEFT-TO-RIGHT EMBEDDING - "\u202b", // RIGHT-TO-LEFT EMBEDDING - "\u202d", // LEFT-TO-RIGHT OVERRIDE - "\u202e", // RIGHT-TO-LEFT OVERRIDE - "\u202c", // POP DIRECTIONAL FORMATTING - "🇨🇦", // REGIONAL INDICATOR SYMBOL LETTER C + REGIONAL INDICATOR SYMBOL LETTER A - "🈹", // PLAYING CARD BLACK JOKER - "👨â€â¤ï¸â€ðŸ’‹â€ðŸ‘¨", // Combine a bunch of emoji - - // Duplicate entries are invalid, so normalization would cause issues. We want to catch those issues. - "한글", - "한글", // Normalized version of the above. - "Ã…", // LATIN CAPITAL LETTER A WITH RING ABOVE - "â„«", // ANGSTROM SIGN - "AÌŠ", // LATIN CAPITAL LETTER A + COMBINING RING ABOVE - "AÌ€", // LATIN CAPITAL LETTER A + COMBINING GRAVE ACCENT - "À", // LATIN CAPITAL LETTER A WITH GRAVE - "ą̂́", // LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE + COMBINING OGONEK - "Ä…Ì‚Ì", // LATIN SMALL LETTER A WITH OGONEK + COMBINING CIRCUMFLEX ACCENT + COMBINING ACUTE ACCENT - "Q̣̀", // LATIN CAPITAL LETTER Q + COMBINING GRAVE ACCENT + COMBINING DOT BELOW - "Q̣̀", // LATIN CAPITAL LETTER + COMBINING DOT BELOW + COMBINING GRAVE ACCENT - - // Combine way too many things: - - - - "ĴͯĮ̸̛͙̙̱̯̺̖͔͎̣͓̬͉͓͙͔͈̥̖͎̀̂͆̓̂̑ͥͧͤ͋̔ͥaÌ€Í‚Í«Ì…Í¦Í¦ÌˆÌ„Ì‰Ì…Ì¾ÌŠÌ½Í‘ÌšÍ¬Ì›Ì·Í ÍŸÌ¤Ì»Ì¦Í“Í“Ì–ÌªÌŸÍ“v͆̿ͩ͗ͩ̀ͧ͂͆̾Ì͑ͦÍ̡͙͕̟͎̰̽ͦ̀͘a̧̻͖͓̗̻̩͌ͮ͗̈́͊̊̑̉̚̕SͪͧÌ͒̔̿̈ͫͥ̇ͦÌÍ̃ÍÌÍ̡͢Í͖̱͈͚͉̩̺͎cͫ̽ͤ̓̊̇͆̀ͫ͂̒Í̧̧͎̮̤̙̗̻̯͖̮̙̰̞ͬ̇͂̉͒ͫ̚͘͞ͅṙ̓͛̅̑̉ÌÍ‚Í£ÌÌÍ‹Ì̷͓̹͈̮̪͔͓̫̓̚ͅiÌͪͩ̚Ì̽ͣ̊ͮ͞ÍÌ´Í€ÌµÌ¯Ì¹Ì Í–ÍˆÌ ÍŽÌ¦pÌÌͯÍͧ͋̊̃̈̈͢ÍÍ™Ì̗̥̻̯̰͚̫t̓Ìͫ̀̋̓ÍÌ·ÍÍŽÌ»Ì©Ì Ì¬Ì™Ì¦Ì°Í“Ì©Ì—Ì̱̣", - - - - -]; - -// WebAssembly import objects have a two-level namespace with module and field. Both must be UTF-8. -let importObject = {}; -for (let idxModule = 0; idxModule < names.length; ++idxModule) { - assert.falsy(importObject.hasOwnProperty(names[idxModule])); - importObject[names[idxModule]] = {}; - for (let idxField = 0; idxField < names.length; ++idxField) { - assert.falsy(importObject[names[idxModule]].hasOwnProperty(names[idxField])); - importObject[names[idxModule]][names[idxField]] = () => 10000 * idxModule + idxField; - } -} - -let b = (new Builder()) - .Type().End(); - -b = b.Import(); -for (let idxModule = 0; idxModule < names.length; ++idxModule) - for (let idxField = 0; idxField < names.length; ++idxField) - b = b.Function(names[idxModule], names[idxField], { params: [], ret: "i32" }); -b = b.End(); - -b = b.Function().End(); - -b = b.Export(); -for (let idx = 0; idx < names.length; ++idx) - b = b.Function(names[idx]); -b = b.End(); - -b = b.Code(); -for (let idx = 0; idx < names.length; ++idx) - b = b.Function(names[idx], { params: [], ret: "i32" }).I32Const(idx).Return().End(); -b = b.End(); - -const module = new WebAssembly.Module(b.WebAssembly().get()); - -for (let idxModule = 0; idxModule < names.length; ++idxModule) - for (let idxField = 0; idxField < names.length; ++idxField) { - assert.eq(WebAssembly.Module.imports(module)[idxModule * names.length + idxField].module, names[idxModule]); - assert.eq(WebAssembly.Module.imports(module)[idxModule * names.length + idxField].name, names[idxField]); - } - -for (let idx = 0; idx < names.length; ++idx) - assert.eq(WebAssembly.Module.exports(module)[idx].name, names[idx]); - -const instance = new WebAssembly.Instance(module, importObject); - -for (let idx = 0; idx < names.length; ++idx) - assert.eq(instance.exports[names[idx]](), idx); diff --git a/implementation-contributed/javascriptcore/wasm/js-api/Module-compile.js b/implementation-contributed/javascriptcore/wasm/js-api/Module-compile.js deleted file mode 100644 index d723bf4d70b49c49a1365fdc67b45242b38272e6..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/Module-compile.js +++ /dev/null @@ -1,60 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -assert.isFunction(WebAssembly.compile); -assert.isFunction(WebAssembly.__proto__.compile); -assert.eq(WebAssembly.compile.length, 1); - -async function testPromiseAPI() { - { - // Can't declare more than one memory. - const builder = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", {initial: 20}).End() - .Function().End() - .Memory().InitialMaxPages(1, 1).End() - .Export().End() - .Code() - .End(); - - try { - await WebAssembly.compile(builder.WebAssembly().get()); - } catch(e) { - assert.truthy(e instanceof WebAssembly.CompileError); - assert.truthy(e.message === "WebAssembly.Module doesn't parse at byte 34: there can at most be one Memory section for now"); - } - } - - { - try { - await WebAssembly.compile(); - } catch(e) { - assert.truthy(e instanceof TypeError); - assert.eq(e.message, "first argument must be an ArrayBufferView or an ArrayBuffer (evaluating 'WebAssembly.compile()')"); - } - } - - { - try { - await WebAssembly.compile(20); - } catch(e) { - assert.truthy(e instanceof TypeError); - assert.eq(e.message, "first argument must be an ArrayBufferView or an ArrayBuffer (evaluating 'WebAssembly.compile(20)')"); - } - } - - { - const builder = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", {initial: 20}).End() - .Function().End() - .Export().End() - .Code() - .End(); - - let module = await WebAssembly.compile(builder.WebAssembly().get()); - assert.truthy(module instanceof WebAssembly.Module); - } -} - -assert.asyncTest(testPromiseAPI()); diff --git a/implementation-contributed/javascriptcore/wasm/js-api/Module.customSection.js b/implementation-contributed/javascriptcore/wasm/js-api/Module.customSection.js deleted file mode 100644 index ccd1a724a9a2f146c6b26950395d4a7c856ea6a9..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/Module.customSection.js +++ /dev/null @@ -1,77 +0,0 @@ -import Builder from '../Builder.js'; -import * as assert from '../assert.js'; - -assert.throws(() => WebAssembly.Module.customSections(undefined, ""), TypeError, `WebAssembly.Module.customSections called with non WebAssembly.Module argument`); -assert.eq(WebAssembly.Module.customSections.length, 2); - -{ - const empty = new WebAssembly.Module((new Builder()).WebAssembly().get()); - assert.isArray(WebAssembly.Module.customSections(empty, "")); - assert.eq(WebAssembly.Module.customSections(empty, "").length, 0); -} - -{ - const single = new WebAssembly.Module((new Builder()) - .Unknown("hello").Byte(0x00).Byte(0x42).Byte(0xFF).End() - .WebAssembly().get()); - assert.eq(WebAssembly.Module.customSections(single, "").length, 0); - const hello = WebAssembly.Module.customSections(single, "hello"); - assert.eq(hello.length, 1); - assert.eq(hello[0].byteLength, 3); - const helloI8 = new Int8Array(hello[0]); - assert.eq(helloI8[0], 0x00); - assert.eq(helloI8[1], 0x42); - assert.eq(helloI8[2], -1); -} - -{ - const unicode = new WebAssembly.Module((new Builder()) - .Unknown("👨â€â¤ï¸â€ðŸ’‹â€ðŸ‘¨").Byte(42).End() - .WebAssembly().get()); - const family = WebAssembly.Module.customSections(unicode, "👨â€â¤ï¸â€ðŸ’‹â€ðŸ‘¨"); - assert.eq(family.length, 1); - assert.eq(family[0].byteLength, 1); - const familyI8 = new Int8Array(family[0]); - assert.eq(familyI8[0], 42); -} - -{ - const many = new WebAssembly.Module((new Builder()) - .Unknown("zero").Byte(0).End() - .Unknown("one").Byte(1).Byte(1).End() - .Unknown("one").Byte(2).Byte(2).Byte(2).End() - .Unknown("two").Byte(3).Byte(3).Byte(3).Byte(3).End() - .Unknown("one").Byte(4).Byte(4).Byte(4).Byte(4).Byte(4).End() - .WebAssembly().get()); - - const zero = WebAssembly.Module.customSections(many, "zero"); - assert.eq(zero.length, 1); - assert.eq(zero[0].byteLength, 1); - const zeroI8 = new Int8Array(zero[0]); - assert.eq(zeroI8[0], 0); - - const two = WebAssembly.Module.customSections(many, "two"); - assert.eq(two.length, 1); - assert.eq(two[0].byteLength, 4); - const twoI8 = new Int8Array(two[0]); - assert.eq(twoI8[0], 3); - assert.eq(twoI8[1], 3); - assert.eq(twoI8[2], 3); - assert.eq(twoI8[3], 3); - - const one = WebAssembly.Module.customSections(many, "one"); - assert.eq(one.length, 3); - let seen = 0; - const expect = [ - [1, 1], - [2, 2, 2], - [4, 4, 4, 4, 4], - ]; - for (const section of one) { - assert.eq(section.byteLength, expect[seen].length); - const I8 = new Int8Array(section); - for (let i = 0; i < expect[seen].length; ++i) - assert.eq(I8[i], expect[seen][i]); - ++seen; - } -} diff --git a/implementation-contributed/javascriptcore/wasm/js-api/Module.exports.js b/implementation-contributed/javascriptcore/wasm/js-api/Module.exports.js deleted file mode 100644 index 76e3fd3fa5c0ea2c66c64db49564b3115e0af59d..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/Module.exports.js +++ /dev/null @@ -1,43 +0,0 @@ -import Builder from '../Builder.js'; -import * as assert from '../assert.js'; - -assert.throws(() => WebAssembly.Module.exports(undefined), TypeError, `WebAssembly.Module.exports called with non WebAssembly.Module argument`); -assert.eq(WebAssembly.Module.exports.length, 1); - -{ - const m = new WebAssembly.Module((new Builder()).WebAssembly().get()); - assert.isArray(WebAssembly.Module.exports(m)); - assert.eq(WebAssembly.Module.exports(m).length, 0); - assert.truthy(WebAssembly.Module.exports(m) !== WebAssembly.Module.exports(m)); -} - -{ - const m = new WebAssembly.Module( - (new Builder()) - .Type().End() - .Function().End() - .Table() - .Table({initial: 20, maximum: 30, element: "anyfunc"}) - .End() - .Memory().InitialMaxPages(1, 1).End() - .Global().I32(42, "immutable").End() - .Export() - .Function("func") - .Table("tab", 0) - .Memory("mem", 0) - .Global("glob", 0) - .End() - .Code() - .Function("func", { params: [] }).Return().End() - .End() - .WebAssembly().get()); - assert.eq(WebAssembly.Module.exports(m).length, 4); - assert.eq(WebAssembly.Module.exports(m)[0].name, "func"); - assert.eq(WebAssembly.Module.exports(m)[0].kind, "function"); - assert.eq(WebAssembly.Module.exports(m)[1].name, "tab"); - assert.eq(WebAssembly.Module.exports(m)[1].kind, "table"); - assert.eq(WebAssembly.Module.exports(m)[2].name, "mem"); - assert.eq(WebAssembly.Module.exports(m)[2].kind, "memory"); - assert.eq(WebAssembly.Module.exports(m)[3].name, "glob"); - assert.eq(WebAssembly.Module.exports(m)[3].kind, "global"); -} diff --git a/implementation-contributed/javascriptcore/wasm/js-api/Module.imports.js b/implementation-contributed/javascriptcore/wasm/js-api/Module.imports.js deleted file mode 100644 index 1fc2dd56b7a706ef9db7d40c1a42dc18d6bb4f33..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/Module.imports.js +++ /dev/null @@ -1,38 +0,0 @@ -import Builder from '../Builder.js'; -import * as assert from '../assert.js'; - -assert.throws(() => WebAssembly.Module.imports(undefined), TypeError, `WebAssembly.Module.imports called with non WebAssembly.Module argument`); -assert.eq(WebAssembly.Module.imports.length, 1); - -{ - const m = new WebAssembly.Module((new Builder()).WebAssembly().get()); - assert.isArray(WebAssembly.Module.imports(m)); - assert.eq(WebAssembly.Module.imports(m).length, 0); - assert.truthy(WebAssembly.Module.imports(m) !== WebAssembly.Module.imports(m)); -} - -{ - const m = new WebAssembly.Module( - (new Builder()) - .Type().End() - .Import() - .Function("fooFunction", "barFunction", { params: [] }) - .Table("fooTable", "barTable", {initial: 20, element: "anyfunc"}) - .Memory("fooMemory", "barMemory", {initial: 20}) - .Global().I32("fooGlobal", "barGlobal", "immutable").End() - .End() - .WebAssembly().get()); - assert.eq(WebAssembly.Module.imports(m).length, 4); - assert.eq(WebAssembly.Module.imports(m)[0].module, "fooFunction"); - assert.eq(WebAssembly.Module.imports(m)[0].name, "barFunction"); - assert.eq(WebAssembly.Module.imports(m)[0].kind, "function"); - assert.eq(WebAssembly.Module.imports(m)[1].module, "fooTable"); - assert.eq(WebAssembly.Module.imports(m)[1].name, "barTable"); - assert.eq(WebAssembly.Module.imports(m)[1].kind, "table"); - assert.eq(WebAssembly.Module.imports(m)[2].module, "fooMemory"); - assert.eq(WebAssembly.Module.imports(m)[2].name, "barMemory"); - assert.eq(WebAssembly.Module.imports(m)[2].kind, "memory"); - assert.eq(WebAssembly.Module.imports(m)[3].module, "fooGlobal"); - assert.eq(WebAssembly.Module.imports(m)[3].name, "barGlobal"); - assert.eq(WebAssembly.Module.imports(m)[3].kind, "global"); -} diff --git a/implementation-contributed/javascriptcore/wasm/js-api/call-indirect.js b/implementation-contributed/javascriptcore/wasm/js-api/call-indirect.js deleted file mode 100644 index 01cd42f9b79a921b1bbaa5ab576fc0d910438328..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/call-indirect.js +++ /dev/null @@ -1,106 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -const wasmModuleWhichImportJS = () => { - const builder = (new Builder()) - .Type().End() - .Import() - .Function("imp", "func", { params: ["i32"] }) - .Table("imp", "table", { initial: 1, maximum: 1, element: "anyfunc"}) - .End() - .Function().End() - .Export() - .Function("changeCounter") - .Function("callFunc") - .End() - .Code() - .Function("changeCounter", { params: ["i32", "i32"] }) - .I32Const(42) - .GetLocal(0) - .I32Add() - .GetLocal(1) - .CallIndirect(0, 0) // Calls table[0](param[0] + 42). - .End() - .Function("callFunc", { params: ["i32"] }) - .GetLocal(0) - .Call(0) // Calls func(param[0] + 42) - .End() - .End(); - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - return module; -}; - -const makeTable = () => { - return new WebAssembly.Table({initial: 1, maximum: 1, element: "anyfunc"}); -}; - -(function MonomorphicImport() { - let counter = 0; - const counterSetter = v => counter = v; - const table = makeTable(); - const module = wasmModuleWhichImportJS(); - const instance = new WebAssembly.Instance(module, { imp: { func: counterSetter, table} }); - table.set(0, instance.exports.callFunc); - for (let i = 0; i < 4096; ++i) { - // Invoke this a bunch of times to make sure the IC in the wasm -> JS stub works correctly. - instance.exports.changeCounter(i, 0); - assert.eq(counter, i + 42); - } -})(); - -(function Polyphic2Import() { - let counterA = 0; - let counterB = undefined; - const counterASetter = v => counterA = v; - const counterBSetter = v => counterB = { valueB: v }; - const module = wasmModuleWhichImportJS(); - - const tableA = makeTable(); - const instanceA = new WebAssembly.Instance(module, { imp: { func: counterASetter, table: tableA} }); - tableA.set(0, instanceA.exports.callFunc); - - const tableB = makeTable(); - const instanceB = new WebAssembly.Instance(module, { imp: { func: counterBSetter, table: tableB} }); - tableB.set(0, instanceB.exports.callFunc); - for (let i = 0; i < 2048; ++i) { - instanceA.exports.changeCounter(i, 0); - assert.isA(counterA, "number"); - assert.eq(counterA, i + 42); - instanceB.exports.changeCounter(i, 0); - assert.isA(counterB, "object"); - assert.eq(counterB.valueB, i + 42); - } -})(); - -(function VirtualImport() { - const counterSetters = [ - v => counters[0] = v, - v => counters[1] = v + 1, - v => counters[2] = v + 2, - v => counters[3] = v + 3, - v => counters[4] = v + 4, - v => counters[5] = v + 5, - v => counters[6] = v + 6, - v => counters[7] = v + 7, - v => counters[8] = v + 8, - v => counters[9] = v + 9, - ]; - const num = counterSetters.length; - let counters = counterSetters.map(() => 0); - assert.eq(counters.length, num); - const module = wasmModuleWhichImportJS(); - let instances = []; - for (let i = 0; i < num; ++i) { - let table = makeTable(); - instances[i] = new WebAssembly.Instance(module, { imp: { func: counterSetters[i], table} }); - table.set(0, instances[i].exports.callFunc); - } - for (let i = 0; i < 2048; ++i) { - for (let j = 0; j < num; ++j) { - instances[j].exports.changeCounter(i, 0); - assert.isA(counters[j], "number"); - assert.eq(counters[j], i + 42 + j); - } - } -})(); diff --git a/implementation-contributed/javascriptcore/wasm/js-api/dont-mmap-zero-byte-memory.js b/implementation-contributed/javascriptcore/wasm/js-api/dont-mmap-zero-byte-memory.js deleted file mode 100644 index c4ec097c2fbe5f96d5ebeba318c282ba2a654d5f..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/dont-mmap-zero-byte-memory.js +++ /dev/null @@ -1,54 +0,0 @@ -import Builder from '../Builder.js'; -import * as assert from '../assert.js'; - -let mems = []; -function makeMem(initial) { - const desc = {initial}; - mems.push([desc, new WebAssembly.Memory(desc)]); -} -for (let i = 0; i < 100; ++i) { - makeMem(1); -} - -// This loop should not OOM! This tests a bug where we -// would call mmap with zero bytes if we ran out of -// fast memories but created a slow memory with zero -// initial page count. -for (let i = 0; i < 100; ++i) { - makeMem(0); -} - -function testMems() { - for (const [memDesc, mem] of mems) { - const builder = (new Builder()) - .Type().End() - .Import() - .Memory("imp", "memory", memDesc) - .End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", { params: [], ret: "i32" }) - .I32Const(0) - .I32Load8U(0, 0) - .Return() - .End() - .End(); - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const instance = new WebAssembly.Instance(module, {imp: {memory: mem}}); - if (mem.buffer.byteLength > 0) - assert.eq(instance.exports.foo(), 0); - else - assert.throws(() => instance.exports.foo(), WebAssembly.RuntimeError, "Out of bounds memory access"); - } -} - -testMems(); - -for (const [_, mem] of mems) - mem.grow(1); - -testMems(); diff --git a/implementation-contributed/javascriptcore/wasm/js-api/element-data.js b/implementation-contributed/javascriptcore/wasm/js-api/element-data.js deleted file mode 100644 index cb43f4f1ff4492a7be2f4ff6468f1f45af33f176..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/element-data.js +++ /dev/null @@ -1,47 +0,0 @@ -import Builder from '../Builder.js'; -import * as assert from '../assert.js'; - -const memSizeInPages = 1; -const pageSizeInBytes = 64 * 1024; -const memoryDescription = { initial: memSizeInPages, maximum: memSizeInPages }; - -(function ElementBeforeData() { - const builder = (new Builder()) - .Type().End() - .Import() - .Memory("imp", "memory", memoryDescription) - .Table("imp", "table", {element: "anyfunc", initial: 19}) // unspecified maximum. - .End() - .Function().End() - .Element() - .Element({offset: 19, functionIndices: [0, 0, 0, 0, 0]}) - .End() - .Code() - .Function("foo", {params: ["i32"], ret: "i32"}) - .GetLocal(0) - .I32Const(42) - .I32Add() - .Return() - .End() - .End() - .Data() - .Segment([0xde, 0xad, 0xbe, 0xef]).Offset(0).End() - .End(); - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const memory = new WebAssembly.Memory(memoryDescription); - const table = new WebAssembly.Table({element: "anyfunc", initial: 19}); - const imports = { - imp: { - memory: memory, - table: table, - } - }; - assert.throws(() => new WebAssembly.Instance(module, imports), WebAssembly.LinkError, `Element is trying to set an out of bounds table index (evaluating 'new WebAssembly.Instance(module, imports)')`); - // On Element failure, the Data section shouldn't have executed. - const buffer = new Uint8Array(memory.buffer); - for (let idx = 0; idx < memSizeInPages * pageSizeInBytes; ++idx) { - const value = buffer[idx]; - assert.eq(value, 0x00); - } -})(); diff --git a/implementation-contributed/javascriptcore/wasm/js-api/element.js b/implementation-contributed/javascriptcore/wasm/js-api/element.js deleted file mode 100644 index fcbe2827f371663aa84fdf5c10100b8178177390..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/element.js +++ /dev/null @@ -1,219 +0,0 @@ -import Builder from '../Builder.js'; -import * as assert from '../assert.js'; - -{ - // Bad element section b/c no Table section/import. - const builder = new Builder() - .Type().End() - .Function().End() - .Element() - .Element({tableIndex: 0, offset: 0, functionIndices: [0]}) - .End() - .Code() - .Function("foo", {params: ["i32"], ret: "i32"}) - .GetLocal(0) - .I32Const(42) - .I32Add() - .Return() - .End() - .End(); - - assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 24: Element section for Table 0 exceeds available Table 0"); -} - -{ - // Bad table index. - const builder = new Builder() - .Type().End() - .Function().End() - .Table() - .Table({element: "anyfunc", initial: 20}) - .End() - .Element() - .Element({tableIndex: 1, offset: 0, functionIndices: [0]}) - .End() - .Code() - .Function("foo", {params: ["i32"], ret: "i32"}) - .GetLocal(0) - .I32Const(42) - .I32Add() - .Return() - .End() - .End(); - - assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 30: Element section for Table 1 exceeds available Table 1"); -} - -{ - // Overflow table maximum size. - const builder = new Builder() - .Type().End() - .Function().End() - .Table() - .Table({element: "anyfunc", initial: 20, maximum: 20}) - .End() - .Element() - .Element({offset: 19, functionIndices: [0, 0]}) - .End() - .Code() - .Function("foo", {params: ["i32"], ret: "i32"}) - .GetLocal(0) - .I32Const(42) - .I32Add() - .Return() - .End() - .End(); - - const module = new WebAssembly.Module(builder.WebAssembly().get()); - assert.throws(() => new WebAssembly.Instance(module), WebAssembly.LinkError, "Element is trying to set an out of bounds table index"); -} - -{ - // Overflow table maximum size. - const builder = new Builder() - .Type().End() - .Function().End() - .Table() - .Table({element: "anyfunc", initial: 20, maximum: 20}) - .End() - .Element() - .Element({offset: 20, functionIndices: [0]}) - .End() - .Code() - .Function("foo", {params: ["i32"], ret: "i32"}) - .GetLocal(0) - .I32Const(42) - .I32Add() - .Return() - .End() - .End(); - - const module = new WebAssembly.Module(builder.WebAssembly().get()); - assert.throws(() => new WebAssembly.Instance(module), WebAssembly.LinkError, "Element is trying to set an out of bounds table index"); -} - -{ - // Overflow function index space. - const builder = new Builder() - .Type().End() - .Function().End() - .Table() - .Table({element: "anyfunc", initial: 20, maximum: 20}) - .End() - .Element() - .Element({offset: 0, functionIndices: [0, 0, 1]}) - .End() - .Code() - .Function("foo", {params: ["i32"], ret: "i32"}) - .GetLocal(0) - .I32Const(42) - .I32Add() - .Return() - .End() - .End(); - - assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 38: Element section's 0th element's 2th index is 1 which exceeds the function index space size of 1 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"); -} - -{ - function badInstantiation(actualTable, errorType, msg) { - // Overflow function index space. - const builder = new Builder() - .Type().End() - .Import() - .Table("imp", "table", {element: "anyfunc", initial: 19}) // unspecified maximum. - .End() - .Function().End() - .Element() - .Element({offset: 19, functionIndices: [0, 0, 0, 0, 0]}) - .End() - .Code() - .Function("foo", {params: ["i32"], ret: "i32"}) - .GetLocal(0) - .I32Const(42) - .I32Add() - .Return() - .End() - .End(); - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - assert.throws(() => new WebAssembly.Instance(module, {imp: {table: actualTable}}), errorType, msg); - } - - for (let i = 19; i < 19 + 5; i++) { - const table = new WebAssembly.Table({element: "anyfunc", initial: i}); - badInstantiation(table, WebAssembly.LinkError, "Element is trying to set an out of bounds table index (evaluating 'new WebAssembly.Instance(module, {imp: {table: actualTable}})')"); - } -} - -{ - function makeModule() { - const builder = new Builder() - .Type().End() - .Import() - .Table("imp", "table", {element: "anyfunc", initial: 19}) // unspecified maximum. - .Global().I32("imp", "global", "immutable").End() - .End() - .Function().End() - .Element() - .Element({offset: {op: "get_global", initValue: 0}, functionIndices: [0]}) - .End() - .Code() - .Function("foo", {params: ["i32"], ret: "i32"}) - .GetLocal(0) - .I32Const(42) - .I32Add() - .Return() - .End() - .End(); - - const bin = builder.WebAssembly().get(); - return new WebAssembly.Module(bin); - } - - function test(i) { - const table = new WebAssembly.Table({element: "anyfunc", initial: 19}); - const global = i; - const module = makeModule(); - const instance = new WebAssembly.Instance(module, {imp: {table, global}}); - for (let j = 0; j < 19; j++) { - if (j === i) - assert.eq(table.get(j)(i*2), i*2 + 42); - else - assert.throws(() => table.get(j)(i*2), TypeError, "table.get(j) is not a function. (In 'table.get(j)(i*2)', 'table.get(j)' is null)"); - } - } - for (let i = 0; i < 19; i++) - test(i); - - assert.throws(() => test(19), Error, "Element is trying to set an out of bounds table index"); -} - -{ - function badModule() { - const builder = new Builder() - .Type().End() - .Import() - .Table("imp", "table", {element: "anyfunc", initial: 19}) // unspecified maximum. - .Global().F32("imp", "global", "immutable").End() - .End() - .Function().End() - .Element() - .Element({offset: {op: "get_global", initValue: 0}, functionIndices: [0]}) - .End() - .Code() - .Function("foo", {params: ["i32"], ret: "i32"}) - .GetLocal(0) - .I32Const(42) - .I32Add() - .Return() - .End() - .End(); - - const bin = builder.WebAssembly().get(); - return new WebAssembly.Module(bin); - } - - assert.throws(() => badModule(), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 58: Element init_expr must produce an i32"); -} diff --git a/implementation-contributed/javascriptcore/wasm/js-api/export-arity.js b/implementation-contributed/javascriptcore/wasm/js-api/export-arity.js deleted file mode 100644 index 41579532e67f9537caa83a97904c22900ba90601..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/export-arity.js +++ /dev/null @@ -1,65 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -// Generate wasm export functions of arity [0, max), and call each of these -// export functions from JS with [0, max) parameters, for each valid WebAssembly -// type. Make sure this number is high enough to force non-register calls. -const maxArities = 64; - -const paramExporter = (numParams, paramType, imports) => { - let builder = (new Builder()) - .Type().End() - .Import() - .Function("imp", "check", { params: [paramType] }) - .End() - .Function().End() - .Export() - .Function("func") - .End() - .Code() - .Function("func", { params: Array(numParams).fill(paramType) }); - for (let i = 0; i < numParams; ++i) - builder = builder.GetLocal(i).Call(0); // Call the import for each received parameter. - builder = builder.Return().End().End(); - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - return new WebAssembly.Instance(module, { imp: imports }); -}; - -const types = [ - { type: "i32", value: 42, defaultWhenArityMismatch: 0 }, - // i64 isn't supported. - { type: "f32", value: 32.0, defaultWhenArityMismatch: NaN }, - { type: "f64", value: 64.0, defaultWhenArityMismatch: NaN }, -]; - -for (let type of types) { - for (let wasmArity = 0; wasmArity < maxArities; ++wasmArity) { - let numParamsCallingWith = undefined; - let numChecked = 0; - const check = value => { - assert.isNumber(value); - if (numParamsCallingWith <= wasmArity) { - if (numChecked < numParamsCallingWith) - assert.eq(value, type.value); - else - assert.eq(value, type.defaultWhenArityMismatch); - } else { - if (numChecked < wasmArity) - assert.eq(value, type.value); - else - assert.eq(value, type.defaultWhenArityMismatch); - } - ++numChecked; - }; - const instance = paramExporter(wasmArity, type.type, { check: check }); - for (let callerArity = 0; callerArity < maxArities; ++callerArity) { - numParamsCallingWith = callerArity; - const params = Array(callerArity).fill(type.value); - const result = instance.exports.func(...params); - assert.isUndef(result); - assert.eq(numChecked, wasmArity); // check() should be called as many times as the wasm function's arity. - numChecked = 0; // Reset the check counter for each arity iteration. - } - } -} diff --git a/implementation-contributed/javascriptcore/wasm/js-api/export-void-is-undef.js b/implementation-contributed/javascriptcore/wasm/js-api/export-void-is-undef.js deleted file mode 100644 index f9c93acb9abd8bf3b313a812e93c5fd283153008..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/export-void-is-undef.js +++ /dev/null @@ -1,19 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -let builder = (new Builder()) - .Type().End() - .Function().End() - .Export() - .Function("func") - .End() - .Code() - .Function("func", { params: [] }) - .Return() - .End() -.End(); -const bin = builder.WebAssembly().get(); -const module = new WebAssembly.Module(bin); -const instance = new WebAssembly.Instance(module); - -assert.isUndef(instance.exports.func()); diff --git a/implementation-contributed/javascriptcore/wasm/js-api/extension-MemoryMode.js b/implementation-contributed/javascriptcore/wasm/js-api/extension-MemoryMode.js deleted file mode 100644 index 5608526bc2fa905203e274c42a6d6be2e161b443..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/extension-MemoryMode.js +++ /dev/null @@ -1,117 +0,0 @@ -import Builder from '../Builder.js'; -import * as assert from '../assert.js'; - -const iterations = 32; -const verbose = false; - -// This API isn't part of WebAssembly's official spec. It is use for testing within the shell. - -const version = 0x01; -const emptyModuleArray = Uint8Array.of(0x0, 0x61, 0x73, 0x6d, version, 0x00, 0x00, 0x00); - -assert.isFunction(WebAssemblyMemoryMode); - -const message = `WebAssemblyMemoryMode expects either a WebAssembly.Memory or WebAssembly.Instance`; -assert.throws(() => WebAssemblyMemoryMode(null), TypeError, message); -assert.throws(() => WebAssemblyMemoryMode(undefined), TypeError, message); -assert.throws(() => WebAssemblyMemoryMode(1), TypeError, message); -assert.throws(() => WebAssemblyMemoryMode(""), TypeError, message); -assert.throws(() => WebAssemblyMemoryMode({}), TypeError, message); -assert.throws(() => WebAssemblyMemoryMode(new WebAssembly.Module(emptyModuleArray)), TypeError, message); -assert.throws(() => WebAssemblyMemoryMode(new WebAssembly.Table({initial: 1, element: "anyfunc"})), TypeError, message); - -const validateMode = what => { - const mode = WebAssemblyMemoryMode(what); - if (verbose) - print(` ${mode}`); - switch (mode) { - case "Signaling": - break; - case "BoundsChecking": - break; - default: - throw new Error(`Unexpected WebAssembly.Memory mode '${mode}'`); - } - return what; -} - -const instantiate = builder => { - const bin = builder.WebAssembly(); - const module = new WebAssembly.Module(bin.get()); - return new WebAssembly.Instance(module); -}; - -(function testMemoryNoMax() { - if (verbose) - print(`testMemoryNoMax`); - let memories = []; - for (let i = 0; i != iterations; ++i) - memories.push(validateMode(new WebAssembly.Memory({ initial: i }))); - return memories; -})(); - -fullGC(); - -(function testMemory() { - if (verbose) - print(`testMemory`); - let memories = []; - for (let i = 0; i != iterations; ++i) - memories.push(validateMode(new WebAssembly.Memory({ initial: i, maximum: i }))); - return memories; -})(); - -fullGC(); - -(function testInstanceNoMemory() { - if (verbose) - print(`testInstanceNoMemory`); - let instances = []; - for (let i = 0; i != iterations; ++i) { - const builder = (new Builder()) - .Type().End() - .Function().End() - .Code().End(); - const instance = instantiate(builder); - // No-memory instances should never be Signaling: it would be wasteful. - assert.eq(WebAssemblyMemoryMode(instance), "BoundsChecking"); - if (verbose) - print(` ${WebAssemblyMemoryMode(instance)}`); - instances.push(instance); - } - return instances; -})(); - -fullGC(); - -(function testInstanceNoMax() { - if (verbose) - print(`testInstanceNoMax`); - let instances = []; - for (let i = 0; i != iterations; ++i) { - // Note: not exported! The internal API can still access. - const builder = (new Builder()) - .Type().End() - .Function().End() - .Memory().InitialMaxPages(i).End() - .Code().End(); - instances.push(validateMode(instantiate(builder))); - } -})(); - -fullGC(); - -(function testInstance() { - if (verbose) - print(`testInstance`); - let instances = []; - for (let i = 0; i != iterations; ++i) { - // Note: not exported! The internal API can still access. - const builder = (new Builder()) - .Type().End() - .Function().End() - .Memory().InitialMaxPages(i, i).End() - .Code().End(); - instances.push(validateMode(instantiate(builder))); - } -})(); diff --git a/implementation-contributed/javascriptcore/wasm/js-api/global-error.js b/implementation-contributed/javascriptcore/wasm/js-api/global-error.js deleted file mode 100644 index d3edf898e7d9fa07e470cfc32c6ab36f1731b513..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/global-error.js +++ /dev/null @@ -1,212 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -{ - // Test init from non-import. - const builder = new Builder(); - - builder.Type().End() - .Function().End() - .Global().GetGlobal("i32", 0, "immutable").End() - .Export() - .Function("getGlobal") - .Global("global", 1) - .End() - .Code() - - .Function("getGlobal", { params: [], ret: "i32" }) - .GetGlobal(1) - .End() - - .End() - - const bin = builder.WebAssembly(); - bin.trim(); - - assert.throws(() => new WebAssembly.Module(bin.get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 26: get_global's index 0 exceeds the number of globals 0 (evaluating 'new WebAssembly.Module(bin.get())')"); -} - - -{ - // Test import mutable. - const builder = new Builder(); - - builder.Type().End() - .Import() - .Global().I32("imp", "global", "mutable").End() - .End() - .Function().End() - .Global().GetGlobal("i32", 0, "immutable").End() - .Export() - .Function("getGlobal") - .Global("global", 1) - .End() - .Code() - - .Function("getGlobal", { params: [], ret: "i32" }) - .GetGlobal(1) - .End() - - .End() - - const bin = builder.WebAssembly(); - bin.trim(); - - assert.throws(() => new WebAssembly.Module(bin.get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 32: Mutable Globals aren't supported (evaluating 'new WebAssembly.Module(bin.get())')"); -} - -{ - // Test export mutable. - const builder = new Builder(); - - builder.Type().End() - .Function().End() - .Global().I32(0, "mutable").End() - .Export() - .Function("setGlobal") - .Global("global", 0) - .End() - .Code() - - .Function("setGlobal", { params: [], ret: "i32" }) - .GetGlobal(1) - .End() - - .End() - - const bin = builder.WebAssembly(); - bin.trim(); - - assert.throws(() => new WebAssembly.Module(bin.get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 51: 1th Export isn't immutable, named 'global' (evaluating 'new WebAssembly.Module(bin.get())')"); -} - -{ - // Test set immutable. - const builder = new Builder(); - - builder.Type().End() - .Function().End() - .Global().I32(0, "immutable").End() - .Export() - .Function("setGlobal") - .Global("global", 0) - .End() - .Code() - - .Function("setGlobal", { params: [], ret: "i32" }) - .I32Const(0) - .SetGlobal(0) - .End() - - .End() - - const bin = builder.WebAssembly(); - bin.trim(); - - assert.throws(() => new WebAssembly.Module(bin.get()), WebAssembly.CompileError, "WebAssembly.Module doesn't validate: set_global 0 is immutable, in function at index 0 (evaluating 'new WebAssembly.Module(bin.get())')"); -} - - -{ - // Test set non-existant global. - const builder = new Builder(); - - builder.Type().End() - .Function().End() - .Global().I32(0, "immutable").End() - .Export() - .Function("setGlobal") - .Global("global", 0) - .End() - .Code() - - .Function("setGlobal", { params: [], ret: "i32" }) - .I32Const(0) - .SetGlobal(1) - .End() - - .End() - - const bin = builder.WebAssembly(); - bin.trim(); - - assert.throws(() => new WebAssembly.Module(bin.get()), WebAssembly.CompileError, "WebAssembly.Module doesn't validate: set_global 1 of unknown global, limit is 1, in function at index 0 (evaluating 'new WebAssembly.Module(bin.get())')"); -} - - -{ - // Test set to incorrect type - const builder = new Builder(); - - builder.Type().End() - .Function().End() - .Global().F32(0, "mutable").End() - .Export() - .Function("setGlobal") - .End() - .Code() - - .Function("setGlobal", { params: [], ret: "i32" }) - .I32Const(0) - .SetGlobal(0) - .End() - - .End() - - const bin = builder.WebAssembly(); - bin.trim(); - - assert.throws(() => new WebAssembly.Module(bin.get()), WebAssembly.CompileError, "WebAssembly.Module doesn't validate: set_global 0 with type F32 with a variable of type I32, in function at index 0 (evaluating 'new WebAssembly.Module(bin.get())')"); -} - -for ( let imp of [undefined, null, {}, () => {}, "number", new Number(4)]) { - // Test import non-number. - const builder = new Builder(); - - builder.Type().End() - .Import() - .Global().I32("imp", "global", "immutable").End() - .End() - .Function().End() - .Global().GetGlobal("i32", 0, "immutable").End() - .Export() - .Function("getGlobal") - .Global("global", 1) - .End() - .Code() - - .Function("getGlobal", { params: [], ret: "i32" }) - .GetGlobal(1) - .End() - - .End() - - const bin = builder.WebAssembly(); - bin.trim(); - - const module = new WebAssembly.Module(bin.get()); - assert.throws(() => new WebAssembly.Instance(module, { imp: { global: imp } }), WebAssembly.LinkError, "imported global imp:global must be a number (evaluating 'new WebAssembly.Instance(module, { imp: { global: imp } })')"); -} - -{ - const builder = new Builder() - .Type().End() - .Global().I64(0, "immutable").End() - .Export() - .Global("bigInt", 0) - .End(); - const module = new WebAssembly.Module(builder.WebAssembly().get()); - assert.throws(() => new WebAssembly.Instance(module), WebAssembly.LinkError, "exported global cannot be an i64 (evaluating 'new WebAssembly.Instance(module)')"); -} - -{ - const builder = new Builder() - .Type().End() - .Import() - .Global().I64("imp", "global", "immutable").End() - .End() - .Function().End() - .Global().GetGlobal("i64", 0, "immutable").End(); - const module = new WebAssembly.Module(builder.WebAssembly().get()); - assert.throws(() => new WebAssembly.Instance(module, { imp: { global: undefined } }), WebAssembly.LinkError, "imported global imp:global cannot be an i64 (evaluating 'new WebAssembly.Instance(module, { imp: { global: undefined } })')"); -} diff --git a/implementation-contributed/javascriptcore/wasm/js-api/global-external-init-from-import.js b/implementation-contributed/javascriptcore/wasm/js-api/global-external-init-from-import.js deleted file mode 100644 index 41fc6fa252f36469ed20d33cb293d6425113291d..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/global-external-init-from-import.js +++ /dev/null @@ -1,30 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -const builder = new Builder(); - -builder.Type().End() - .Import() - .Global().I32("imp", "global", "immutable").End() - .End() - .Function().End() - .Global().GetGlobal("i32", 0, "immutable").End() - .Export() - .Function("getGlobal") - .Global("global", 1) - .End() - .Code() - - .Function("getGlobal", { params: [], ret: "i32" }) - .GetGlobal(1) - .End() - - .End() - -const bin = builder.WebAssembly(); -bin.trim(); - -const module = new WebAssembly.Module(bin.get()); -const instance = new WebAssembly.Instance(module, { imp: { global: 5 } }); -assert.eq(instance.exports.getGlobal(), 5); -assert.eq(instance.exports.global, 5); diff --git a/implementation-contributed/javascriptcore/wasm/js-api/global-internal-init-from-import.js b/implementation-contributed/javascriptcore/wasm/js-api/global-internal-init-from-import.js deleted file mode 100644 index 91bf35ba7aedffaa7265d586de17623cdfdca07e..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/global-internal-init-from-import.js +++ /dev/null @@ -1,26 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -const builder = new Builder(); - -builder.Type().End() - .Import() - .Global().I32("imp", "global", "immutable").End() - .End() - .Function().End() - .Global().GetGlobal("i32", 0, "mutable").End() - .Export().Function("getGlobal").End() - .Code() - - .Function("getGlobal", { params: [], ret: "i32" }) - .GetGlobal(1) - .End() - - .End() - -const bin = builder.WebAssembly(); -bin.trim(); - -const module = new WebAssembly.Module(bin.get()); -const instance = new WebAssembly.Instance(module, { imp: { global: 5 } }); -assert.eq(instance.exports.getGlobal(), 5); diff --git a/implementation-contributed/javascriptcore/wasm/js-api/global-mutate.js b/implementation-contributed/javascriptcore/wasm/js-api/global-mutate.js deleted file mode 100644 index 06f7f2288d3f2ab611f5c1566f411e127690a1c5..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/global-mutate.js +++ /dev/null @@ -1,39 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -function createInternalGlobalModule() { - const builder = new Builder(); - - builder.Type().End() - .Function().End() - .Global().I32(5, "mutable").End() - .Export() - .Function("getGlobal") - .Function("setGlobal") - .End() - .Code() - - // GetGlobal - .Function("getGlobal", { params: [], ret: "i32" }) - .GetGlobal(0) - .End() - - // SetGlobal - .Function("setGlobal", { params: ["i32"] }) - .GetLocal(0) - .SetGlobal(0) - .End() - - .End() - - const bin = builder.WebAssembly(); - bin.trim(); - - const module = new WebAssembly.Module(bin.get()); - const instance = new WebAssembly.Instance(module); - assert.eq(instance.exports.getGlobal(), 5); - instance.exports.setGlobal(3); - assert.eq(instance.exports.getGlobal(), 3); -} - -createInternalGlobalModule(); diff --git a/implementation-contributed/javascriptcore/wasm/js-api/globals-export.js b/implementation-contributed/javascriptcore/wasm/js-api/globals-export.js deleted file mode 100644 index 66682694eb60e91e0708a9838782cb7d9305edf8..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/globals-export.js +++ /dev/null @@ -1,28 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -const builder = new Builder(); - -builder.Type().End() - .Import() - .Global().I32("imp", "global", "immutable").End() - .End() - .Function().End() - .Export() - .Function("getGlobal") - .Global("global", 0) - .End() - .Code() - - .Function("getGlobal", { params: [], ret: "i32" }) - .GetGlobal(0) - .End() - - .End() - -const bin = builder.WebAssembly(); -bin.trim(); - -const module = new WebAssembly.Module(bin.get()); -const instance = new WebAssembly.Instance(module, { imp: { global: 5 } }); -assert.eq(instance.exports.global, 5); diff --git a/implementation-contributed/javascriptcore/wasm/js-api/globals-import.js b/implementation-contributed/javascriptcore/wasm/js-api/globals-import.js deleted file mode 100644 index 29223234475aa928af7c9c965e4bb4ca9156ee2f..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/globals-import.js +++ /dev/null @@ -1,29 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -const builder = new Builder(); - -builder.Type().End() - .Import() - .Global().I32("imp", "global", "immutable").End() - .End() - .Function().End() - .Global().I32(5, "mutable").End() - .Export() - .Function("getGlobal") - .End() - .Code() - - // GetGlobal - .Function("getGlobal", { params: [], ret: "i32" }) - .GetGlobal(0) - .End() - - .End() - -const bin = builder.WebAssembly(); -bin.trim(); - -const module = new WebAssembly.Module(bin.get()); -const instance = new WebAssembly.Instance(module, { imp: { global: 5 } }); -assert.eq(instance.exports.getGlobal(), 5); diff --git a/implementation-contributed/javascriptcore/wasm/js-api/memory-grow.js b/implementation-contributed/javascriptcore/wasm/js-api/memory-grow.js deleted file mode 100644 index 0f8fc96a38b37a6f11f9578c0ea93a9efe4177af..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/memory-grow.js +++ /dev/null @@ -1,51 +0,0 @@ -import { eq as assertEq, throws as assertThrows } from "../assert.js"; -const pageSize = 64*1024; - -let buffers = []; -for (let i = 0; i < 100; i++) { - const max = 5; - let pageCount = 1; - let x = new WebAssembly.Memory({initial: 1, maximum: max}); - for (let i = 0; i < (max - 1); i++) { - let int8Array = new Uint8Array(x.buffer); - - for (let i = 0; i < pageSize; i++) { - assertEq(int8Array[pageSize*(pageCount - 1) + i], 0); - int8Array[pageSize*(pageCount - 1) + i] = pageCount; - } - - for (let i = 0; i < pageCount; i++) { - for (let j = 0; j < pageSize; j++) { - assertEq(int8Array[i * pageSize + j], i + 1); - } - } - - let buffer = x.buffer; - assertEq(buffer.byteLength, pageCount * pageSize); - buffers.push(buffer); - let previousPageSize = x.grow(1); - assertEq(buffer.byteLength, 0); - assertEq(previousPageSize, pageCount); - ++pageCount; - } -} - -for (let buffer of buffers) { - assertEq(buffer.byteLength, 0); -} - -{ - const memory = new WebAssembly.Memory({initial: 1, maximum: 5}); - let buffer = memory.buffer; - assertEq(buffer.byteLength, 1*64*1024); - memory.grow(1); - assertEq(buffer.byteLength, 0); - - buffer = memory.buffer; - assertEq(buffer.byteLength, 2*64*1024); - - // This shouldn't neuter the buffer since it fails. - assertThrows(() => memory.grow(1000), RangeError, "WebAssembly.Memory.grow would exceed the memory's declared maximum size"); - assertEq(buffer.byteLength, 2*64*1024); - assertEq(memory.buffer, buffer); -} diff --git a/implementation-contributed/javascriptcore/wasm/js-api/table.js b/implementation-contributed/javascriptcore/wasm/js-api/table.js deleted file mode 100644 index cf68b440495f6be6f8b27947712456d7ca7c8c6f..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/table.js +++ /dev/null @@ -1,322 +0,0 @@ -import Builder from '../Builder.js'; -import * as assert from '../assert.js'; - -{ - const builder = new Builder() - .Type().End() - .Import() - .Table("imp", "table", {initial: 20, element: "anyfunc"}) - .End() - .Function().End() - .Table() - .Table({initial: 20, maximum: 30, element: "anyfunc"}) - .End() - .Code() - .End(); - assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 34: Cannot have more than one Table for now"); -} - -{ - const builder = new Builder() - .Type().End() - .Function().End() - .Table() - // Table count is zero. - .End() - .Code() - .End(); - new WebAssembly.Module(builder.WebAssembly().get()); -} - -{ - const builder = new Builder() - .Type().End() - .Function().End() - .Table() - .Table({initial: 20, maximum: 30, element: "anyfunc"}) - .Table({initial: 20, maximum: 30, element: "anyfunc"}) - .End() - .Code() - .End(); - assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 17: Table count of 2 is invalid, at most 1 is allowed for now (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"); -} - -{ - const builder = new Builder() - .Type().End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", {params: ["i32"]}) - .GetLocal(0) - .CallIndirect(0, 0) - .End() - .End(); - assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 4: call_indirect is only valid when a table is defined or imported, in function at index 0 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"); -} - -{ - const builder = new Builder() - .Type().End() - .Function().End() - .Table() - .Table({initial:20, element:"anyfunc"}) - .End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", {params: ["i32"]}) - .GetLocal(0) - .CallIndirect(0, 1) - .End() - .End(); - assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 6: call_indirect's 'reserved' varuint1 must be 0x0, in function at index 0 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"); -} - -{ - // Can't export an undefined table - const builder = new Builder() - .Type().End() - .Function().End() - .Export() - .Table("foo", 0) - .End() - .Code() - .End(); - assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 23: can't export Table 0 there are 0 Tables"); -} - -{ - // Can't export a table at index 1. - const builder = new Builder() - .Type().End() - .Function().End() - .Table() - .Table({initial: 20, maximum: 30, element: "anyfunc"}) - .End() - .Export() - .Table("foo", 1) - .End() - .Code() - .End(); - assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 30: can't export Table 1 there are 1 Tables"); -} - -function assertBadTable(tableDescription, message) { - const builder = new Builder() - .Type().End() - .Function().End() - .Table() - .Table(tableDescription) - .End() - .Code() - .End(); - assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, message); -} - -function assertBadTableImport(tableDescription, message) { - const builder = new Builder() - .Type().End() - .Import() - .Table("imp", "table", tableDescription) - .End() - .Function().End() - .Code() - .End(); - assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, message); -} - -{ - let badDescriptions = [ - [{initial: 10, element: "i32"}, - "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc, got -1 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')", - "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc, got -1 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"], - [{initial: 10, element: "f32"}, - "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc, got -3 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')", - "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc, got -3 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"], - [{initial: 10, element: "f64"}, - "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc, got -4 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')", - "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc, got -4 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"], - [{initial: 10, element: "i64"}, - "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc, got -2 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')", - "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc, got -2 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"], - [{initial: 10, maximum: 20, element: "i32"}, - "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc, got -1 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')", - "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc, got -1 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"], - [{initial: 10, maximum: 20, element: "f32"}, - "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc, got -3 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')", - "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc, got -3 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"], - [{initial: 10, maximum: 20, element: "f64"}, - "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc, got -4 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')", - "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc, got -4 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"], - [{initial: 10, maximum: 20, element: "i64"}, - "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc, got -2 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')", - "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc, got -2 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"], - - [{initial: 10, maximum: 9, element: "anyfunc"}, - "WebAssembly.Module doesn't parse at byte 21: resizable limits has a initial page count of 10 which is greater than its maximum 9 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')", - "WebAssembly.Module doesn't parse at byte 29: resizable limits has a initial page count of 10 which is greater than its maximum 9 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"], - [{initial: 1, maximum: 0, element: "anyfunc"}, - "WebAssembly.Module doesn't parse at byte 21: resizable limits has a initial page count of 1 which is greater than its maximum 0 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')", - "WebAssembly.Module doesn't parse at byte 29: resizable limits has a initial page count of 1 which is greater than its maximum 0 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"], - [{initial: 2**32 - 1, maximum: 2**32 - 2, element: "anyfunc"}, - "WebAssembly.Module doesn't parse at byte 29: resizable limits has a initial page count of 4294967295 which is greater than its maximum 4294967294 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')", - "WebAssembly.Module doesn't parse at byte 37: resizable limits has a initial page count of 4294967295 which is greater than its maximum 4294967294 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"], - [{initial: 2**31, element: "anyfunc"}, - "WebAssembly.Module doesn't parse at byte 24: Table's initial page count of 2147483648 is too big, maximum 10000000 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')", - "WebAssembly.Module doesn't parse at byte 32: Table's initial page count of 2147483648 is too big, maximum 10000000 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"], - ]; - - for (const d of badDescriptions) { - assertBadTable(d[0], d[1]); - assertBadTableImport(d[0], d[2]); - } -} - -{ - const builder = new Builder() - .Type().End() - .Import() - .Table("imp", "table", {initial: 20, element: "anyfunc"}) - .Table("imp", "table", {initial: 20, element: "anyfunc"}) - .End() - .Function().End() - .Code() - .End(); - assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 39: Cannot have more than one Table for now"); -} - - -{ - function assertBadTableInstance(tableDescription, table, message) { - const builder = new Builder() - .Type().End() - .Import() - .Table("imp", "table", tableDescription) - .End() - .Function().End() - .Code() - .End(); - const module = new WebAssembly.Module(builder.WebAssembly().get()); - assert.throws(() => new WebAssembly.Instance(module, {imp: {table}}), WebAssembly.LinkError, message); - } - - const badTables = [ - [{initial: 100, maximum:100, element:"anyfunc"}, new WebAssembly.Table({initial:100, element: "anyfunc"}), "Table import imp:table does not have a 'maximum' but the module requires that it does (evaluating 'new WebAssembly.Instance(module, {imp: {table}})')"], - [{initial: 100, maximum:100, element:"anyfunc"}, new WebAssembly.Table({initial:100, maximum:101, element: "anyfunc"}), "Imported Table imp:table 'maximum' is larger than the module's expected 'maximum' (evaluating 'new WebAssembly.Instance(module, {imp: {table}})')"], - [{initial: 100, element:"anyfunc"}, new WebAssembly.Table({initial:10, element: "anyfunc"}), "Table import imp:table provided an 'initial' that is too small (evaluating 'new WebAssembly.Instance(module, {imp: {table}})')"], - [{initial: 10, element:"anyfunc"}, new WebAssembly.Table({initial:9, element: "anyfunc"}), "Table import imp:table provided an 'initial' that is too small (evaluating 'new WebAssembly.Instance(module, {imp: {table}})')"], - ]; - for (const [d, t, m] of badTables) { - assertBadTableInstance(d, t, m); - } -} - -assert.throws(() => WebAssembly.Table.prototype.grow(undefined), TypeError, `expected |this| value to be an instance of WebAssembly.Table`); - -{ - { - const table = new WebAssembly.Table({element: "anyfunc", initial: 20, maximum: 30}); - assert.eq(20, table.grow(0)); - assert.eq(20, table.length); - assert.eq(20, table.grow(1)); - assert.eq(21, table.length); - } - - { - const table = new WebAssembly.Table({element: "anyfunc", initial: 20, maximum: 30}); - assert.eq(20, table.grow(10)); - assert.eq(30, table.grow(0)); - assert.throws(() => table.grow(1), RangeError, "WebAssembly.Table.prototype.grow could not grow the table"); - } - - { - const table = new WebAssembly.Table({element: "anyfunc", initial: 20}); - let called = false; - table.grow({valueOf() { called = true; return 42; }}); - assert.truthy(called); - assert.eq(62, table.length); - } - - { - const table = new WebAssembly.Table({element: "anyfunc", initial: 20}); - assert.throws(() => table.get(20), RangeError, "WebAssembly.Table.prototype.get expects an integer less than the length of the table"); - for (let i = 0; i < 20; i++) - assert.eq(table.get(i), null); - } - - { - const table = new WebAssembly.Table({element: "anyfunc", initial: 20}); - assert.throws(() => table.set(20, null), RangeError, "WebAssembly.Table.prototype.set expects an integer less than the length of the table"); - for (let i = 0; i < 20; i++) - table.set(i, null); - } - - { - // This should not throw - new WebAssembly.Table({initial: 2**20, maximum: 2**32 - 1, element: "anyfunc"}); - } -} - -{ - - function assertBadTable(table) { - const builder = new Builder() - .Type().End() - .Import() - .Table("imp", "table", {initial: 25, element: "anyfunc"}) - .End() - .Function().End() - .Code() - .End(); - const module = new WebAssembly.Module(builder.WebAssembly().get()); - assert.throws(() => new WebAssembly.Instance(module, {imp: {table}}), WebAssembly.LinkError, "Table import imp:table is not an instance of WebAssembly.Table (evaluating 'new WebAssembly.Instance(module, {imp: {table}})')"); - } - assertBadTable(25); - assertBadTable(new Object); - assertBadTable([]); - assertBadTable(new WebAssembly.Memory({initial:1})); -} - -{ - const builder = new Builder() - .Type().End() - .Import() - .Table("imp", "table", {initial: 25, element: "anyfunc"}) - .End() - .Function().End() - .Export() - .Table("table", 0) - .Table("table2", 0) - .End() - .Code().End(); - - const module = new WebAssembly.Module(builder.WebAssembly().get()); - const table = new WebAssembly.Table({element: "anyfunc", initial: 25}); - const instance = new WebAssembly.Instance(module, {imp: {table}}); - assert.truthy(table === instance.exports.table); - assert.truthy(table === instance.exports.table2); -} - -{ - const builder = new Builder() - .Type().End() - .Function().End() - .Table() - .Table({initial: 20, maximum: 30, element: "anyfunc"}) - .End() - .Export() - .Table("table", 0) - .Table("table2", 0) - .End() - .Code().End(); - - const module = new WebAssembly.Module(builder.WebAssembly().get()); - const instance = new WebAssembly.Instance(module); - assert.eq(instance.exports.table, instance.exports.table2); - assert.eq(instance.exports.table.length, 20); - assert.truthy(instance.exports.table instanceof WebAssembly.Table); -} diff --git a/implementation-contributed/javascriptcore/wasm/js-api/test_Data.js b/implementation-contributed/javascriptcore/wasm/js-api/test_Data.js deleted file mode 100644 index 4171435128a084d5949d8ff2b8b12570b7f23375..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/test_Data.js +++ /dev/null @@ -1,180 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -const memSizeInPages = 1; -const pageSizeInBytes = 64 * 1024; -const memoryDescription = { initial: memSizeInPages, maximum: memSizeInPages }; -const emptyMemory = { initial: 0, maximum: 2 }; - -// FIXME Some corner cases are ill-specified: https://github.com/WebAssembly/design/issues/897 - -const assertMemoryAllZero = memory => { - const buffer = new Uint8Array(memory.buffer); - for (let idx = 0; idx < buffer.length; ++idx) { - const value = buffer[idx]; - assert.eq(value, 0x00); - } -}; - -(function DataSection() { - const builder = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", memoryDescription).End() - .Data() - .Segment([0xff, 0x2a]).Offset(4).End() - .Segment([0xde, 0xad, 0xbe, 0xef]).Offset(24).End() - .Segment([0xca, 0xfe]).Offset(25).End() // Overwrite. - .Segment([]).Offset(4).End() // Empty. - .End(); - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const memory = new WebAssembly.Memory(memoryDescription); - const instance = new WebAssembly.Instance(module, { imp: { memory: memory } }); - const buffer = new Uint8Array(memory.buffer); - for (let idx = 0; idx < memSizeInPages * pageSizeInBytes; ++idx) { - const value = buffer[idx]; - switch (idx) { - case 4: assert.eq(value, 0xff); break; - case 5: assert.eq(value, 0x2a); break; - case 24: assert.eq(value, 0xde); break; - case 25: assert.eq(value, 0xca); break; - case 26: assert.eq(value, 0xfe); break; - case 27: assert.eq(value, 0xef); break; - default: assert.eq(value, 0x00); break; - } - } -})(); - -(function DataSectionWithoutMemory() { - const builder = (new Builder()) - .Type().End() - .Data() - .Segment([0xff]).Offset(0).End() - .End(); - const bin = builder.WebAssembly().get(); - assert.throws(() => new WebAssembly.Module(bin), WebAssembly.CompileError, `WebAssembly.Module doesn't parse at byte 15: 0th Data segment has index 0 which exceeds the number of Memories 0`); -})(); - -(function EmptyDataSectionWithoutMemory() { - const builder = (new Builder()) - .Type().End() - .Data() - .Segment([]).Offset(0).End() - .End(); - const bin = builder.WebAssembly().get(); - assert.throws(() => new WebAssembly.Module(bin), WebAssembly.CompileError, `WebAssembly.Module doesn't parse at byte 15: 0th Data segment has index 0 which exceeds the number of Memories 0`); -})(); - -(function DataSectionBiggerThanMemory() { - const builder = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", memoryDescription).End() - .Data() - .Segment(Array(memSizeInPages * pageSizeInBytes + 1).fill(0xff)).Offset(0).End() - .End(); - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const memory = new WebAssembly.Memory(memoryDescription); - assert.throws(() => new WebAssembly.Instance(module, { imp: { memory: memory } }), WebAssembly.LinkError, `Invalid data segment initialization: segment of 65537 bytes memory of 65536 bytes, at offset 0, segment is too big (evaluating 'new WebAssembly.Instance(module, { imp: { memory: memory } })')`); - assertMemoryAllZero(memory); -})(); - -(function DataSectionOffTheEnd() { - const builder = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", memoryDescription).End() - .Data() - .Segment([0xff]).Offset(memSizeInPages * pageSizeInBytes).End() - .End(); - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const memory = new WebAssembly.Memory(memoryDescription); - assert.throws(() => new WebAssembly.Instance(module, { imp: { memory: memory } }), WebAssembly.LinkError, `Invalid data segment initialization: segment of 1 bytes memory of 65536 bytes, at offset 65536, segment writes outside of memory (evaluating 'new WebAssembly.Instance(module, { imp: { memory: memory } })')`); - assertMemoryAllZero(memory); -})(); - -(function DataSectionPartlyOffTheEnd() { - const builder = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", memoryDescription).End() - .Data() - .Segment([0xff, 0xff]).Offset(memSizeInPages * pageSizeInBytes - 1).End() - .End(); - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const memory = new WebAssembly.Memory(memoryDescription); - assert.throws(() => new WebAssembly.Instance(module, { imp: { memory: memory } }), WebAssembly.LinkError, `Invalid data segment initialization: segment of 2 bytes memory of 65536 bytes, at offset 65535, segment writes outside of memory (evaluating 'new WebAssembly.Instance(module, { imp: { memory: memory } })')`); - assertMemoryAllZero(memory); -})(); - -(function DataSectionEmptyOffTheEnd() { - const builder = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", memoryDescription).End() - .Data() - .Segment([]).Offset(memSizeInPages * pageSizeInBytes).End() - .End(); - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const memory = new WebAssembly.Memory(memoryDescription); - const instance = new WebAssembly.Instance(module, { imp: { memory: memory } }); - assertMemoryAllZero(memory); -})(); - -(function DataSectionEmptyOffTheEndWithEmptyMemory() { - const builder = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", emptyMemory).End() - .Data() - .Segment([]).Offset(memSizeInPages * pageSizeInBytes).End() - .End(); - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const memory = new WebAssembly.Memory(emptyMemory); - assert.throws(() => new WebAssembly.Instance(module, { imp: { memory: memory } }), WebAssembly.LinkError, `Invalid data segment initialization: segment of 0 bytes memory of 0 bytes, at offset 65536, segment writes outside of memory`); - assertMemoryAllZero(memory); -})(); - -(function DataSectionSeenByStart() { - const offset = 1024; - const builder = (new Builder()) - .Type().End() - .Import() - .Memory("imp", "memory", memoryDescription) - .Function("imp", "func", { params: ["i32"] }) - .End() - .Function().End() - .Start("foo").End() - .Code() - .Function("foo", { params: [] }) - .I32Const(offset) - .I32Load8U(0, 0) - .Call(0) // Calls func((i8.load(offset), align=2, offset=0). This should observe 0xff as set by the data section. - .End() - .End() - .Data() - .Segment([0xff]).Offset(offset).End() - .End(); - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const memory = new WebAssembly.Memory(memoryDescription); - let value = 0; - const setter = v => value = v; - const instance = new WebAssembly.Instance( - module, - { - imp: { - memory: memory, - func: setter - } - }); - assert.eq(value, 0xff); - const buffer = new Uint8Array(memory.buffer); - for (let idx = 0; idx < memSizeInPages * pageSizeInBytes; ++idx) { - const value = buffer[idx]; - if (idx == offset) - assert.eq(value, 0xff); - else - assert.eq(value, 0x00); - } -})(); diff --git a/implementation-contributed/javascriptcore/wasm/js-api/test_Instance.js b/implementation-contributed/javascriptcore/wasm/js-api/test_Instance.js deleted file mode 100644 index 8d63be82852559aa68a3c1aa56712169fca66eee..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/test_Instance.js +++ /dev/null @@ -1,162 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -(function EmptyModule() { - const builder = new Builder(); - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const instance = new WebAssembly.Instance(module); - assert.instanceof(instance, WebAssembly.Instance); -})(); - -(function ExportedAnswerI32() { - const builder = (new Builder()) - .Type().End() - .Function().End() - .Export() - .Function("answer") - .End() - .Code() - .Function("answer", { params: [], ret: "i32" }) - .I32Const(42) - .Return() - .End() - .End(); - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const instance = new WebAssembly.Instance(module); - const result = instance.exports.answer(); - assert.isA(result, "number"); - assert.eq(result, 42); -})(); - -(function ExportedNumber() { - for (let i = 0; i <= 129; ++i) { - const name = i.toString(); - const builder = (new Builder()) - .Type().End() - .Function().End() - .Export() - .Function(name) - .End() - .Code() - .Function(name, { params: [], ret: "i32" }) - .I32Const(i) - .Return() - .End() - .End(); - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const instance = new WebAssembly.Instance(module); - const result = instance.exports[name](); - assert.isA(result, "number"); - assert.eq(result, i); - } -})(); - -const wasmModuleWhichImportJS = () => { - const builder = (new Builder()) - .Type().End() - .Import() - .Function("imp", "func", { params: ["i32"] }) - .End() - .Function().End() - .Export() - .Function("changeCounter") - .End() - .Code() - .Function("changeCounter", { params: ["i32"] }) - .I32Const(42) - .GetLocal(0) - .I32Add() - .Call(0) // Calls func(param[0] + 42). - .End() - .End(); - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - return module; -}; - -(function MonomorphicImport() { - let counter = 0; - const counterSetter = v => counter = v; - const module = wasmModuleWhichImportJS(); - const instance = new WebAssembly.Instance(module, { imp: { func: counterSetter } }); - for (let i = 0; i < 4096; ++i) { - // Invoke this a bunch of times to make sure the IC in the wasm -> JS stub works correctly. - instance.exports.changeCounter(i); - assert.eq(counter, i + 42); - } -})(); - -(function Polyphic2Import() { - let counterA = 0; - let counterB = undefined; - const counterASetter = v => counterA = v; - const counterBSetter = v => counterB = { valueB: v }; - const module = wasmModuleWhichImportJS(); - const instanceA = new WebAssembly.Instance(module, { imp: { func: counterASetter } }); - const instanceB = new WebAssembly.Instance(module, { imp: { func: counterBSetter } }); - for (let i = 0; i < 2048; ++i) { - instanceA.exports.changeCounter(i); - assert.isA(counterA, "number"); - assert.eq(counterA, i + 42); - instanceB.exports.changeCounter(i); - assert.isA(counterB, "object"); - assert.eq(counterB.valueB, i + 42); - } -})(); - -(function Polyphic3Import() { - let counterA = 0; - let counterB = undefined; - let counterC = undefined; - const counterASetter = v => counterA = v; - const counterBSetter = v => counterB = { valueB: v }; - const counterCSetter = v => counterC = { valueC: v }; - const module = wasmModuleWhichImportJS(); - const instanceA = new WebAssembly.Instance(module, { imp: { func: counterASetter } }); - const instanceB = new WebAssembly.Instance(module, { imp: { func: counterBSetter } }); - const instanceC = new WebAssembly.Instance(module, { imp: { func: counterCSetter } }); - for (let i = 0; i < 2048; ++i) { - instanceA.exports.changeCounter(i); - assert.isA(counterA, "number"); - assert.eq(counterA, i + 42); - instanceB.exports.changeCounter(i); - assert.isA(counterB, "object"); - assert.eq(counterB.valueB, i + 42); - instanceC.exports.changeCounter(i); - assert.isA(counterC, "object"); - assert.eq(counterC.valueC, i + 42); - } -})(); - -(function VirtualImport() { - const num = 10; // It's definitely going virtual at 10! - let counters = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - const counterSetters = [ - v => counters[0] = v, - v => counters[1] = v + 1, - v => counters[2] = v + 2, - v => counters[3] = v + 3, - v => counters[4] = v + 4, - v => counters[5] = v + 5, - v => counters[6] = v + 6, - v => counters[7] = v + 7, - v => counters[8] = v + 8, - v => counters[9] = v + 9, - ]; - assert.eq(counters.length, num); - assert.eq(counterSetters.length, num); - const module = wasmModuleWhichImportJS(); - let instances = []; - for (let i = 0; i < num; ++i) - instances[i] = new WebAssembly.Instance(module, { imp: { func: counterSetters[i] } }); - for (let i = 0; i < 2048; ++i) { - for (let j = 0; j < num; ++j) { - instances[j].exports.changeCounter(i); - assert.isA(counters[j], "number"); - assert.eq(counters[j], i + 42 + j); - } - } -})(); diff --git a/implementation-contributed/javascriptcore/wasm/js-api/test_Module.js b/implementation-contributed/javascriptcore/wasm/js-api/test_Module.js deleted file mode 100644 index 94db1a436a387d08bb48fdfd3b1c1fc637348eee..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/test_Module.js +++ /dev/null @@ -1,19 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -(function EmptyModule() { - const builder = new Builder(); - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - assert.instanceof(module, WebAssembly.Module); -})(); - -(function ModuleWithImports() { - const builder = (new Builder()) - .Type().End() - .Import() - .Function("foo", "bar", { params: [] }) - .End(); - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); -})(); diff --git a/implementation-contributed/javascriptcore/wasm/js-api/test_Start.js b/implementation-contributed/javascriptcore/wasm/js-api/test_Start.js deleted file mode 100644 index 5c3150e1cabebfb84333ef71423a8886cde0eae8..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/test_Start.js +++ /dev/null @@ -1,35 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -(function StartNamedFunction() { - const b = (new Builder()) - .Type().End() - .Import() - .Function("imp", "func", { params: ["i32"] }) - .End() - .Function().End() - .Start("foo").End() - .Code() - .Function("foo", { params: [] }) - .I32Const(42) - .Call(0) // Calls func(42). - .End() - .End(); - const bin = b.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - let value = 0; - const setter = v => value = v; - const instance = new WebAssembly.Instance(module, { imp: { func: setter } }); - assert.eq(value, 42); -})(); - -(function InvalidStartFunctionIndex() { - const b = (new Builder()) - .setChecked(false) - .Type().End() - .Function().End() - .Start(0).End() // Invalid index. - .Code().End(); - const bin = b.WebAssembly().get(); - assert.throws(() => new WebAssembly.Module(bin), Error, `WebAssembly.Module doesn't parse at byte 17: Start index 0 exceeds function index space 0 (evaluating 'new WebAssembly.Module(bin)')`); -})(); diff --git a/implementation-contributed/javascriptcore/wasm/js-api/test_basic_api.js b/implementation-contributed/javascriptcore/wasm/js-api/test_basic_api.js deleted file mode 100644 index 1a2d2221030451df0645b30ea31bb2748f5536d0..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/test_basic_api.js +++ /dev/null @@ -1,128 +0,0 @@ -import * as assert from '../assert.js'; -import * as utilities from '../utilities.js'; - -const version = 0x01; -const emptyModuleArray = Uint8Array.of(0x0, 0x61, 0x73, 0x6d, version, 0x00, 0x00, 0x00); -const invalidConstructorInputs = [undefined, null, "", 1, {}, []]; -const invalidInstanceImports = [null, "", 1]; - -const checkOwnPropertyDescriptor = (obj, prop, expect) => { - const descriptor = Object.getOwnPropertyDescriptor(obj, prop); - assert.eq(typeof descriptor.value, expect.typeofvalue); - assert.eq(descriptor.writable, expect.writable); - assert.eq(descriptor.configurable, expect.configurable); - assert.eq(descriptor.enumerable, expect.enumerable); -}; - -const checkAccessorOwnPropertyDescriptor = (obj, prop, expect) => { - const descriptor = Object.getOwnPropertyDescriptor(obj, prop); - assert.eq(typeof descriptor.value, "undefined"); - assert.eq(typeof descriptor.writable, "undefined"); - assert.eq(descriptor.configurable, expect.configurable); - assert.eq(descriptor.enumerable, expect.enumerable); -}; - -const functionProperties = { - "validate": { length: 1 }, - "compile": { length: 1 }, -}; -const constructorProperties = { - "Module": { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1 }, - "Instance": { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1 }, - "Memory": { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1 }, - "Table": { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1 }, - "CompileError": { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1 }, - "LinkError": { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1 }, - "RuntimeError": { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1 }, -}; - - -assert.isNotUndef(WebAssembly); -checkOwnPropertyDescriptor(utilities.global, "WebAssembly", { typeofvalue: "object", writable: true, configurable: true, enumerable: false }); -assert.eq(String(WebAssembly), "[object WebAssembly]"); -assert.isUndef(WebAssembly.length); -assert.eq(WebAssembly instanceof Object, true); -assert.throws(() => WebAssembly(), TypeError, `WebAssembly is not a function. (In 'WebAssembly()', 'WebAssembly' is an instance of WebAssembly)`); -assert.throws(() => new WebAssembly(), TypeError, `WebAssembly is not a constructor (evaluating 'new WebAssembly()')`); - -for (const f in functionProperties) { - assert.isNotUndef(WebAssembly[f]); - assert.eq(WebAssembly[f].name, f); - assert.eq(WebAssembly[f].length, functionProperties[f].length); -} - -for (const c in constructorProperties) { - assert.isNotUndef(WebAssembly[c]); - assert.eq(WebAssembly[c].name, c); - assert.eq(WebAssembly[c].length, constructorProperties[c].length); - checkOwnPropertyDescriptor(WebAssembly, c, constructorProperties[c]); - checkOwnPropertyDescriptor(WebAssembly[c], "prototype", { typeofvalue: "object", writable: false, configurable: false, enumerable: false }); - if (["CompileError", "LinkError", "RuntimeError"].indexOf(c) >= 0) - WebAssembly[c](); // Per spec, the WebAssembly.*Error types match ye olden JavaScript NativeError behavior: they can be constructed without `new`. - else - assert.throws(() => WebAssembly[c](), TypeError, `calling WebAssembly.${c} constructor without new is invalid`); - switch (c) { - case "Module": - for (const invalid of invalidConstructorInputs) - assert.throws(() => new WebAssembly[c](invalid), TypeError, `first argument must be an ArrayBufferView or an ArrayBuffer (evaluating 'new WebAssembly[c](invalid)')`); - for (const buffer of [new ArrayBuffer(), new DataView(new ArrayBuffer()), new Int8Array(), new Uint8Array(), new Uint8ClampedArray(), new Int16Array(), new Uint16Array(), new Int32Array(), new Uint32Array(), new Float32Array(), new Float64Array()]) - // FIXME the following should be WebAssembly.CompileError. https://bugs.webkit.org/show_bug.cgi?id=163768 - assert.throws(() => new WebAssembly[c](buffer), Error, `WebAssembly.Module doesn't parse at byte 0: expected a module of at least 8 bytes (evaluating 'new WebAssembly[c](buffer)')`); - assert.instanceof(new WebAssembly[c](emptyModuleArray), WebAssembly.Module); - break; - case "Instance": - for (const invalid of invalidConstructorInputs) - assert.throws(() => new WebAssembly[c](invalid), TypeError, `first argument to WebAssembly.Instance must be a WebAssembly.Module (evaluating 'new WebAssembly[c](invalid)')`); - const instance = new WebAssembly[c](new WebAssembly.Module(emptyModuleArray)); - assert.instanceof(instance, WebAssembly.Instance); - for (const invalid of invalidInstanceImports) - assert.throws(() => new WebAssembly[c](new WebAssembly.Module(emptyModuleArray), invalid), TypeError, `second argument to WebAssembly.Instance must be undefined or an Object (evaluating 'new WebAssembly[c](new WebAssembly.Module(emptyModuleArray), invalid)')`); - assert.isNotUndef(instance.exports); - checkAccessorOwnPropertyDescriptor(WebAssembly.Instance.prototype, "exports", { configurable: true, enumerable: false }); - assert.throws(() => WebAssembly.Instance.prototype.exports = undefined, TypeError, `Attempted to assign to readonly property.`); - assert.throws(() => WebAssembly.Instance.prototype.exports, TypeError, `expected |this| value to be an instance of WebAssembly.Instance`); - assert.isUndef(instance.exports.__proto__); - assert.eq(Reflect.isExtensible(instance.exports), false); - assert.eq(Symbol.iterator in instance.exports, false); - assert.eq(Symbol.toStringTag in instance.exports, true); - assert.eq(Object.getOwnPropertySymbols(instance.exports).length, 1); - assert.eq(Object.getOwnPropertySymbols(instance.exports)[0], Symbol.toStringTag); - assert.throws(() => instance.exports[Symbol.toStringTag] = 42, TypeError, `Attempted to assign to readonly property.`); - break; - case "Memory": - new WebAssembly.Memory({initial: 20}); - break; - case "Table": - new WebAssembly.Table({initial: 20, element: "anyfunc"}); - new WebAssembly.Table({initial: 20, maximum: 20, element: "anyfunc"}); - new WebAssembly.Table({initial: 20, maximum: 25, element: "anyfunc"}); - break; - case "CompileError": - case "LinkError": - case "RuntimeError": { - { - const e = new WebAssembly[c]; - assert.eq(e instanceof WebAssembly[c], true); - assert.eq(e instanceof Error, true); - assert.eq(e instanceof TypeError, false); - assert.eq(e.message, ""); - assert.eq(typeof e.stack, "string"); - const sillyString = "uh-oh!"; - const e2 = new WebAssembly[c](sillyString); - assert.eq(e2.message, sillyString + " (evaluating 'new WebAssembly[c](sillyString)')"); - } - { - const e = WebAssembly[c](); - assert.eq(e instanceof WebAssembly[c], true); - assert.eq(e instanceof Error, true); - assert.eq(e instanceof TypeError, false); - assert.eq(e.message, ""); - assert.eq(typeof e.stack, "string"); - const sillyString = "uh-oh!"; - const e2 = WebAssembly[c](sillyString); - assert.eq(e2.message, sillyString); - } - } break; - default: throw new Error(`Implementation error: unexpected constructor property "${c}"`); - } -} diff --git a/implementation-contributed/javascriptcore/wasm/js-api/test_memory.js b/implementation-contributed/javascriptcore/wasm/js-api/test_memory.js deleted file mode 100644 index 520599270c50bdc8ec2a5e1a5195e1cccb09c948..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/test_memory.js +++ /dev/null @@ -1,401 +0,0 @@ -import Builder from '../Builder.js'; -import * as assert from '../assert.js'; - -const pageSize = 64 * 1024; -const maxPageCount = (2**32) / pageSize; - -function binaryShouldNotParse(builder) { - const bin = builder.WebAssembly().get(); - let threw = false; - try { - const module = new WebAssembly.Module(bin); - } catch(e) { - threw = true; - } - assert.truthy(threw); -} - -{ - // Can't declare more than one memory. - const builder = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", {initial: 20}).End() - .Function().End() - .Memory().InitialMaxPages(1, 1).End() - .Export().End() - .Code() - .End(); - binaryShouldNotParse(builder); -} - -{ - // Can't declare more than one memory. - const builder = (new Builder()) - .Type().End() - .Import() - .Memory("imp", "memory", {initial: 20}) - .Memory("imp", "memory", {initial: 30}) - .End() - .Function().End() - .Export().End() - .Code() - .End(); - binaryShouldNotParse(builder); -} - -{ - // initial must be <= maximum. - const builder = (new Builder()) - .Type().End() - .Import() - .Memory("imp", "memory", {initial: 20, maximum: 19}) - .End() - .Function().End() - .Export().End() - .Code() - .End(); - binaryShouldNotParse(builder); -} - -{ - // No loads when no memory defined. - const builder = (new Builder()) - .Type().End() - .Import().End() - .Function().End() - .Export().Function("foo").End() - .Code() - .Function("foo", { params: ["i32"], ret: "i32" }) - .GetLocal(0) - .I32Load(2, 0) - .Return() - .End() - .End(); - - binaryShouldNotParse(builder); -} - -{ - // No stores when no memory defined. - const builder = (new Builder()) - .Type().End() - .Import() - .End() - .Function().End() - .Export().Function("foo").End() - .Code() - .Function("foo", { params: ["i32"] }) - .GetLocal(0) - .GetLocal(0) - .I32Store(2, 0) - .Return() - .End() - .End(); - - binaryShouldNotParse(builder); -} - -{ - // Can't export an undefined memory. - const builder = (new Builder()) - .Type().End() - .Function().End() - .Export() - .Memory("memory", 0) - .End() - .Code() - .End(); - binaryShouldNotParse(builder); -} - -{ - // Can't export a non-zero memory index. - const builder = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", {initial: 20}).End() - .Function().End() - .Export() - .Memory("memory", 1) - .End() - .Code() - .End(); - binaryShouldNotParse(builder); -} - -{ - assert.throws(() => new WebAssembly.Memory(20), TypeError, "WebAssembly.Memory expects its first argument to be an object"); - assert.throws(() => new WebAssembly.Memory({}, {}), TypeError, "WebAssembly.Memory expects exactly one argument"); -} - -function test(f) { - noInline(f); - for (let i = 0; i < 2; i++) { - f(i); - } -} - -test(function() { - const memoryDescription = {initial: 2, maximum: 2}; - const builder = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", memoryDescription).End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", { params: ["i32", "i32"], ret: "i32" }) - .GetLocal(1) - .GetLocal(0) - .I32Store(2, 0) - .GetLocal(1) - .I32Load(2, 0) - .Return() - .End() - .End(); - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const memory = new WebAssembly.Memory(memoryDescription); - const instance = new WebAssembly.Instance(module, { imp: { memory: memory } }); - const foo = instance.exports.foo; - // foo(value, address) - - const bytes = memoryDescription.initial * pageSize; - for (let i = 0; i < (bytes/4); i++) { - let value = i + 1; - let address = i * 4; - let result = foo(value, address); - assert.truthy(result === value); - let arrayBuffer = memory.buffer; - let buffer = new Uint32Array(arrayBuffer); - assert.truthy(buffer[i] === value); - } -}); - -test(function() { - const memoryDescription = {initial: 2, maximum: 2}; - const builder = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", memoryDescription).End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", { params: ["i32", "i32"], ret: "i32"}) - .GetLocal(1) - .GetLocal(0) - .I32Store8(0, 0) - .GetLocal(1) - .I32Load8U(0, 0) - .Return() - .End() - .End(); - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const memory = new WebAssembly.Memory(memoryDescription); - const instance = new WebAssembly.Instance(module, { imp: { memory: memory } }); - const foo = instance.exports.foo; - // foo(value, address) - - const bytes = memoryDescription.initial * pageSize; - for (let i = 0; i < bytes; i++) { - let value = (i + 1); - let address = i; - let result = foo(value, address); - let expectedValue = (value & ((2**8) - 1)); - assert.truthy(result === expectedValue); - let arrayBuffer = memory.buffer; - let buffer = new Uint8Array(arrayBuffer); - assert.truthy(buffer[i] === expectedValue); - } -}); - -test(function() { - const memoryDescription = {initial: 2, maximum: 2}; - const builder = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", memoryDescription).End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", { params: ["f32", "i32"], ret: "f32"}) - .GetLocal(1) - .GetLocal(0) - .F32Store(2, 0) - .GetLocal(1) - .F32Load(2, 0) - .Return() - .End() - .End(); - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const memory = new WebAssembly.Memory(memoryDescription); - const instance = new WebAssembly.Instance(module, { imp: { memory: memory } }); - const foo = instance.exports.foo; - // foo(value, address) - - const bytes = memoryDescription.initial * pageSize; - for (let i = 0; i < (bytes/4); i++) { - let value = i + 1 + .0128213781289; - assert.truthy(value !== Math.fround(value)); - let address = i * 4; - let result = foo(value, address); - let expectedValue = Math.fround(result); - assert.truthy(result === expectedValue); - let arrayBuffer = memory.buffer; - let buffer = new Float32Array(arrayBuffer); - assert.truthy(buffer[i] === expectedValue); - } -}); - -test(function() { - const memoryDescription = {initial: 2, maximum: 2}; - const builder = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", memoryDescription).End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", { params: ["f64", "i32"], ret: "f64"}) - .GetLocal(1) - .GetLocal(0) - .F64Store(3, 0) - .GetLocal(1) - .F64Load(3, 0) - .Return() - .End() - .End(); - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const memory = new WebAssembly.Memory(memoryDescription); - const instance = new WebAssembly.Instance(module, { imp: { memory: memory } }); - const foo = instance.exports.foo; - // foo(value, address) - - const bytes = memoryDescription.initial * pageSize; - for (let i = 0; i < (bytes/8); i++) { - let value = i + 1 + .0128213781289; - let address = i * 8; - let result = foo(value, address); - let expectedValue = result; - assert.truthy(result === expectedValue); - let arrayBuffer = memory.buffer; - let buffer = new Float64Array(arrayBuffer); - assert.truthy(buffer[i] === expectedValue); - } -}); - -test(function() { - const memoryDescription = {initial: 20, maximum: 25}; - const builder = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", memoryDescription).End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", { params: ["f64", "i32"], ret: "f64"}) - .GetLocal(1) - .GetLocal(0) - .F64Store(3, 0) - .GetLocal(1) - .F64Load(3, 0) - .Return() - .End() - .End(); - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - - assert.throws(() => new WebAssembly.Instance(module, 20), TypeError, `second argument to WebAssembly.Instance must be undefined or an Object`); - assert.throws(() => new WebAssembly.Instance(module, {}), TypeError, `import imp:memory must be an object`); - assert.throws(() => new WebAssembly.Instance(module, {imp: { } }), WebAssembly.LinkError, `Memory import imp:memory is not an instance of WebAssembly.Memory`); - assert.throws(() => new WebAssembly.Instance(module, {imp: { memory: 20 } }), WebAssembly.LinkError, `Memory import imp:memory is not an instance of WebAssembly.Memory`); - assert.throws(() => new WebAssembly.Instance(module, {imp: { memory: [] } }), WebAssembly.LinkError, `Memory import imp:memory is not an instance of WebAssembly.Memory`); - assert.throws(() => new WebAssembly.Instance(module, {imp: { memory: new WebAssembly.Memory({initial: 19, maximum: 25}) } }), WebAssembly.LinkError, `Memory import imp:memory provided an 'initial' that is smaller than the module's declared 'initial' import memory size`); - assert.throws(() => new WebAssembly.Instance(module, {imp: { memory: new WebAssembly.Memory({initial: 20}) } }), WebAssembly.LinkError, `Memory import imp:memory did not have a 'maximum' but the module requires that it does`); - assert.throws(() => new WebAssembly.Instance(module, {imp: { memory: new WebAssembly.Memory({initial: 20, maximum: 26}) } }), WebAssembly.LinkError, `Memory import imp:memory provided a 'maximum' that is larger than the module's declared 'maximum' import memory size`); -}); - -test(function() { - const memoryDescription = {initial: 20}; - const builder = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", memoryDescription).End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", { params: ["f64", "i32"], ret: "f64"}) - .GetLocal(1) - .GetLocal(0) - .F64Store(3, 0) - .GetLocal(1) - .F64Load(3, 0) - .Return() - .End() - .End(); - - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - - function testMemImportError(instanceObj, expectedError) { - assert.throws(() => new WebAssembly.Instance(module, instanceObj), WebAssembly.LinkError, expectedError); - } - - testMemImportError({imp: { memory: new WebAssembly.Memory({initial: 19, maximum: 25}) } }, `Memory import imp:memory provided an 'initial' that is smaller than the module's declared 'initial' import memory size`); - testMemImportError({imp: { memory: new WebAssembly.Memory({initial: 19}) } }, `Memory import imp:memory provided an 'initial' that is smaller than the module's declared 'initial' import memory size`); - - // This should not throw. - new WebAssembly.Instance(module, {imp: {memory: new WebAssembly.Memory({initial:20})}}); - new WebAssembly.Instance(module, {imp: {memory: new WebAssembly.Memory({initial:20, maximum:20})}}); -}); - -{ - const builder = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", {initial: 20}).End() - .Function().End() - .Export() - .Memory("memory", 0) - .Memory("memory2", 0) - .End() - .Code() - .End(); - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const memory = new WebAssembly.Memory({initial: 20}); - const instance = new WebAssembly.Instance(module, {imp: {memory}}); - assert.truthy(memory === instance.exports.memory); - assert.truthy(memory === instance.exports.memory2); -} - -{ - const builder = (new Builder()) - .Type().End() - .Function().End() - .Memory().InitialMaxPages(20, 25).End() - .Export() - .Memory("memory", 0) - .Memory("memory2", 0) - .End() - .Code() - .End(); - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - const instance = new WebAssembly.Instance(module); - assert.eq(instance.exports.memory, instance.exports.memory2); - assert.eq(instance.exports.memory.buffer.byteLength, 20 * pageSize); - assert.truthy(instance.exports.memory instanceof WebAssembly.Memory); -} diff --git a/implementation-contributed/javascriptcore/wasm/js-api/test_memory_constructor.js b/implementation-contributed/javascriptcore/wasm/js-api/test_memory_constructor.js deleted file mode 100644 index b8893eab7af2fac0ea348c5ee52567c3ce54c6d9..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/test_memory_constructor.js +++ /dev/null @@ -1,83 +0,0 @@ -// FIXME: use the assert library: https://bugs.webkit.org/show_bug.cgi?id=165684 -//@ skip if $memoryLimited -import Builder from '../Builder.js'; - -function assert(b) { - if (!b) { - throw new Error("Bad assertion"); - } -} - -{ - let threw = false; - try { - new WebAssembly.Memory({initial: 20, maximum: 19}); - } catch(e) { - assert(e instanceof RangeError); - assert(e.message === "'maximum' page count must be than greater than or equal to the 'initial' page count"); - threw = true; - } - assert(threw); -} - -const pageSize = 64 * 1024; -const maxPageCount = (2**32) / pageSize; - -function testInvalidSize(description, propName) { - let threw = false; - try { - new WebAssembly.Memory(description); - } catch(e) { - threw = true; - assert(e instanceof RangeError); - assert(e.message === `WebAssembly.Memory '${propName}' page count is too large`); - } - assert(threw); -} - -{ - function testInvalidInitial(v) { - testInvalidSize({initial: v}, "initial"); - } - - try { - new WebAssembly.Memory({initial: maxPageCount}); - new WebAssembly.Memory({initial: maxPageCount, maximum: maxPageCount}); - } catch(e) { - // These might throw, since we're asking for a lot of memory. - } - - testInvalidInitial(2**31); - testInvalidInitial(maxPageCount + 1); -} - -{ - function testInvalidMaximum(v) { - testInvalidSize({initial: 1, maximum: v}, "maximum"); - } - - testInvalidMaximum(2**31); - testInvalidMaximum(maxPageCount + 1); -} - -{ - for (let i = 0; i < 5; i++) { - let x = Math.random() * (2**10); - x |= 0; - const mem = new WebAssembly.Memory({initial: x, maximum: x + 100}); - assert(mem.buffer.byteLength === x * pageSize); - } -} - -{ - let bufferGetter = Object.getOwnPropertyDescriptor((new WebAssembly.Memory({initial:1})).__proto__, "buffer").get; - let threw = false; - try { - bufferGetter.call({}); - } catch(e) { - assert(e instanceof TypeError); - assert(e.message === "WebAssembly.Memory.prototype.buffer getter called with non WebAssembly.Memory |this| value"); - threw = true; - } - assert(threw); -} diff --git a/implementation-contributed/javascriptcore/wasm/js-api/unique-signature.js b/implementation-contributed/javascriptcore/wasm/js-api/unique-signature.js deleted file mode 100644 index 8f5a55fca368b35c976db5c5611b4fe094f88285..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/unique-signature.js +++ /dev/null @@ -1,49 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -(function CallIndirectWithDuplicateSignatures() { - const builder = (new Builder()) - .Type() - .Func(["i32"], "i32") // 0 - .Func(["i32"], "i32") // 1 - .Func(["i32", "i32"], "i32") // 2 - .Func(["i32"], "i32") // 3 - .Func(["i32"], "i32") // 4 - .Func(["i32", "i32"], "i32") // 5 - .Func(["f64", "f64"], "f64") // 6 - .Func(["i32"], "f64") // 7 - .Func(["i32"], "f64") // 8 - .End() - .Function().End() - .Table() - .Table({initial: 4, maximum: 4, element: "anyfunc"}) - .End() - .Export() - .Function("entry") - .Table("table", 0) - .Function("callMe") - .End() - .Code() - .Function("entry", 1) - .I32Const(42) - .GetLocal(0) - .I32Add() - .I32Const(0) // Function index 0. - .CallIndirect(4, 0) // Different signature index, but same signature. - .Return() - .End() - .Function("callMe", 3) - .I32Const(3) - .GetLocal(0) - .I32Add() - .Return() - .End() - .End(); - const bin = builder.WebAssembly().get(); - const module = new WebAssembly.Module(bin); - let value0 = undefined; - const instance = new WebAssembly.Instance(module); - let table = instance.exports.table; - table.set(0, instance.exports.callMe); - assert.eq(instance.exports.entry(5), 5 + 42 + 3); -}()); diff --git a/implementation-contributed/javascriptcore/wasm/js-api/validate.js b/implementation-contributed/javascriptcore/wasm/js-api/validate.js deleted file mode 100644 index 4fe83c2869c5bb241db91de0ca8666f925859a98..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/validate.js +++ /dev/null @@ -1,47 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -assert.isFunction(WebAssembly.validate); -assert.isFunction(WebAssembly.__proto__.validate); -assert.eq(WebAssembly.validate.length, 1); - -{ - const builder = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", {initial: 20}).End() - .Function().End() - .Memory().InitialMaxPages(1, 1).End() - .Export().End() - .Code() - .End(); - - assert.truthy(!WebAssembly.validate(builder.WebAssembly().get())); -} - -{ - const builder = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", {initial: 20}).End() - .Function().End() - .Export().End() - .Code() - .End(); - - assert.truthy(WebAssembly.validate(builder.WebAssembly().get())); -} - -{ - const builder = (new Builder()); - builder.setChecked(false); - - builder.Type().End() - .Import().Memory("imp", "memory", {initial: 20}).End() - .Unknown("test").End() - .Import().Memory("imp", "memory", {initial: 20}).End() - .Function().End() - .Export().End() - .Code() - .End(); - - assert.falsy(WebAssembly.validate(builder.WebAssembly().get())); -} diff --git a/implementation-contributed/javascriptcore/wasm/js-api/version.js b/implementation-contributed/javascriptcore/wasm/js-api/version.js deleted file mode 100644 index 0486fcfddefd0821d39246cb6408734bfebf22e2..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/version.js +++ /dev/null @@ -1,9 +0,0 @@ -import * as assert from '../assert.js'; -import * as utilities from '../utilities.js'; - -for (let version = 0; version < 256; ++version) { - if (version === 1) - continue; - const emptyModuleArray = Uint8Array.of(0x0, 0x61, 0x73, 0x6d, version, 0x00, 0x00, 0x00); - assert.throws(() => new WebAssembly.Module(emptyModuleArray), WebAssembly.CompileError, `WebAssembly.Module doesn't parse at byte 8: unexpected version number ${version} expected 1`); -} diff --git a/implementation-contributed/javascriptcore/wasm/js-api/wasm-to-wasm-bad-signature.js b/implementation-contributed/javascriptcore/wasm/js-api/wasm-to-wasm-bad-signature.js deleted file mode 100644 index 169411ba5cf03418ee6afc9de430e96fc9940d84..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/wasm-to-wasm-bad-signature.js +++ /dev/null @@ -1,105 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -const importName = "pierOne"; -const types = ["i32", "i64", "f32", "f64", "void"]; -const typesNonVoid = ["i32", "i64", "f32", "f64"]; -const swapType = (type, index) => types[(types.indexOf(type) + index) % types.length]; -const swapTypeNonVoid = (type, index) => typesNonVoid[(typesNonVoid.indexOf(type) + index) % typesNonVoid.length]; - -const signatures = [ - { params: ["i32"], ret: "void" }, - { params: ["i64"], ret: "void" }, - { params: ["f32"], ret: "void" }, - { params: ["f64"], ret: "void" }, - { params: ["i32"], ret: "i32" }, - { params: ["i64"], ret: "i64" }, - { params: ["f32"], ret: "f32" }, - { params: ["f64"], ret: "f64" }, - { params: ["i32", "f32"], ret: "i32" }, - { params: ["f32", "i32"], ret: "i32" }, - { params: ["i64", "f64"], ret: "i64" }, - { params: ["f64", "i64"], ret: "i64" }, - { params: ["i32", "f32", "i32"], ret: "i32" }, - { params: ["i32", "f32", "i32"], ret: "i32" }, - { params: ["i64", "f64", "i64"], ret: "i64" }, - { params: ["i64", "f64", "i64"], ret: "i64" }, - { params: Array(32).fill("i32"), ret: "i64" }, - { params: Array(32).fill("i64"), ret: "i64" }, - { params: Array(32).fill("f32"), ret: "i64" }, - { params: Array(32).fill("f64"), ret: "i64" }, -]; - -const makeImporter = signature => { - const builder = (new Builder()) - .Type().End() - .Import().Function("exports", importName, signature).End(); - return new WebAssembly.Module(builder.WebAssembly().get()); -}; - -const makeImportee = signature => { - const builder = (new Builder()) - .Type().End() - .Function().End() - .Export() - .Function(importName) - .End() - .Code() - .Function(importName, signature); - switch (signature.ret) { - case "i32": builder.I32Const(0); break; - case "i64": builder.I64Const(0); break; - case "f32": builder.F32Const(0); break; - case "f64": builder.F64Const(0); break; - case "void": break; - } - return new WebAssembly.Instance(new WebAssembly.Module(builder.Return().End().End().WebAssembly().get())); -}; - -(function BadSignatureDropStartParams() { - for (let signature of signatures) { - const importee = makeImportee(signature); - for (let i = 1; i <= signature.params.length; ++i) { - const badParamSignature = { params: signature.params.slice(i, signature.params.length), ret: signature.ret }; - const importer = makeImporter(badParamSignature); - assert.throws(() => new WebAssembly.Instance(importer, importee), WebAssembly.LinkError, `imported function exports:${importName} signature doesn't match the provided WebAssembly function's signature (evaluating 'new WebAssembly.Instance(importer, importee)')`); - } - } -})(); - -(function BadSignatureDropEndParams() { - for (let signature of signatures) { - const importee = makeImportee(signature); - for (let i = 1; i < signature.params.length; ++i) { - const badParamSignature = { params: signature.params.slice(0, i), ret: signature.ret }; - const importer = makeImporter(badParamSignature); - assert.throws(() => new WebAssembly.Instance(importer, importee), WebAssembly.LinkError, `imported function exports:${importName} signature doesn't match the provided WebAssembly function's signature (evaluating 'new WebAssembly.Instance(importer, importee)')`); - } - } -})(); - -(function BadSignatureSwapParam() { - for (let signature of signatures) { - const importee = makeImportee(signature); - for (let signatureIndex = 0; signatureIndex < signature.length; ++signatureIndex) { - for (let typeIndex = 1; typeIndex < typesNonVoid.length; ++typeIndex) { - let badParams = signature.params.slice(); - badParams[signatureIndex] = swapTypeNonVoid(badParams[signatureIndex], typeIndex); - const badParamSignature = { params: badParams, ret: signature.ret }; - const importer = makeImporter(badParamSignature); - assert.throws(() => new WebAssembly.Instance(importer, importee), WebAssembly.LinkError, `imported function exports:${importName} signature doesn't match the provided WebAssembly function's signature (evaluating 'new WebAssembly.Instance(importer, importee)')`); - } - } - } -})(); - -(function BadSignatureRet() { - for (let signature of signatures) { - const importee = makeImportee(signature); - for (let typeIndex = 1; typeIndex < types.length; ++typeIndex) { - const badParamSignature = { params: signature.params, ret: swapType(signature.ret, typeIndex) }; - const importer = makeImporter(badParamSignature); - assert.throws(() => new WebAssembly.Instance(importer, importee), WebAssembly.LinkError, `imported function exports:${importName} signature doesn't match the provided WebAssembly function's signature (evaluating 'new WebAssembly.Instance(importer, importee)')`); - } - } -})(); diff --git a/implementation-contributed/javascriptcore/wasm/js-api/wasm-to-wasm.js b/implementation-contributed/javascriptcore/wasm/js-api/wasm-to-wasm.js deleted file mode 100644 index 2df46e68f7ded88a7a257dc3890e5212a4c4e92b..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/wasm-to-wasm.js +++ /dev/null @@ -1,72 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -const callerTopBits = 0xC0FEBEEF; -const innerReturnHi = 0xDEADFACE; -const innerReturnLo = 0xC0FEC0FE; - -const callerModule = () => { - const builder = (new Builder()) - .Type().End() - .Import() - .Function("exports", "callMe", { params: ["i64"], ret: "i64" }) - .End() - .Function().End() - .Export() - .Function("entry") - .End() - .Code() - .Function("entry", { params: ["i32"], ret: "i32" }, ["i64"]) - .I32Const(callerTopBits).I64ExtendUI32().I32Const(32).I64ExtendUI32().I64Shl() // ((i64)callerTopBits) << 32 - .GetLocal(0).I64ExtendUI32() - .I64Or() // value: param | (((i64)callerTopBits << 32)) - .Call(0) // Calls exports.callMe(param | (((i64)callerTopBits) << 32)). - .TeeLocal(1).I32WrapI64() // lo: (i32)callResult - .GetLocal(1).I32Const(32).I64ExtendUI32().I64ShrU().I32WrapI64() // hi: (i32)(callResult >> 32) - .I32Xor() - .Return() - .End() - .End(); - return new WebAssembly.Module(builder.WebAssembly().get()); -}; - -const calleeModule = () => { - const builder = (new Builder()) - .Type().End() - .Import() - .Function("imp", "func", { params: ["i32", "i32"], ret: "i32" }) - .End() - .Function().End() - .Export() - .Function("callMe") - .End() - .Code() - .Function("callMe", { params: ["i64"], ret: "i64" }) - .GetLocal(0).I32WrapI64() // lo: (i32)param - .GetLocal(0).I32Const(32).I64ExtendUI32().I64ShrU().I32WrapI64() // hi: (i32)(param >> 32) - .Call(0) // Calls imp.func with the 64-bit value as i32 { hi, lo }. - .Drop() - .I32Const(innerReturnHi).I64ExtendUI32().I32Const(32).I64ExtendUI32().I64Shl().I32Const(innerReturnLo).I64ExtendUI32().I64Or() // ((i64)hi << 32) | (i64)lo - .Return() - .End() - .End(); - return new WebAssembly.Module(builder.WebAssembly().get()); -}; - -(function WasmToWasm() { - let value; - const func = (hi, lo) => { value = { hi: hi, lo: lo }; return hi ^ lo; }; - const callee = new WebAssembly.Instance(calleeModule(), { imp: { func: func } }); - const caller = new WebAssembly.Instance(callerModule(), callee); - for (let i = 0; i < 4096; ++i) { - assert.eq(caller.exports.entry(i), innerReturnHi ^ innerReturnLo); - assert.eq(value.lo >>> 0, callerTopBits); - assert.eq(value.hi >>> 0, i); - } -})(); - -// FIXME test the following https://bugs.webkit.org/show_bug.cgi?id=166625 -// - wasm->wasm using 32-bit things (including float), as well as 64-bit NaNs that don't get canonicalized -// - Do a throw two-deep -// - Check that the first wasm's instance is back in OK state (with table or global?) -// - Test calling through a Table diff --git a/implementation-contributed/javascriptcore/wasm/js-api/web-assembly-compile-parallel.js b/implementation-contributed/javascriptcore/wasm/js-api/web-assembly-compile-parallel.js deleted file mode 100644 index 12feaecb9e8417283ec4a9aa74982b94cb409d68..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/web-assembly-compile-parallel.js +++ /dev/null @@ -1,58 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -async function throwExn() { - throw new Error(); -} - -async function test() { - const loopDepth = 10; - const numCompilations = 1; - const numVars = 30; - const params = []; - params.length = numVars; - params.fill("i32"); - - let builder = (new Builder()) - .Type().End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", { params, ret: "i32" }); - - const makeLoop = (builder, depth) => { - if (depth === 0) - return builder; - - builder = builder - .Loop("i32", (b) => { - b.GetLocal(0) - .I32Const(1) - .I32Sub() - .TeeLocal(0) - .GetLocal(0) - .I32Eqz() - .BrIf(1); - - return makeLoop(b, depth - 1).Br(0); - }); - return builder - - } - - builder = makeLoop(builder, loopDepth); - builder = builder.End().End(); - - const bin = builder.WebAssembly().get(); - - let compilations = []; - for (let i = 0; i < numCompilations; ++i) { - compilations.push(WebAssembly.compile(bin)); - } - - await Promise.all(compilations); -} - -assert.asyncTest(test()); diff --git a/implementation-contributed/javascriptcore/wasm/js-api/web-assembly-function.js b/implementation-contributed/javascriptcore/wasm/js-api/web-assembly-function.js deleted file mode 100644 index 3195662f20985497a3771b3ab8b4792b7adaada1..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/web-assembly-function.js +++ /dev/null @@ -1,25 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -const builder = (new Builder()) - .Type().End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", { params: [], ret: "i32" }) - .I32Const(1) - .End() - .End(); - -const bin = builder.WebAssembly().get(); -const module = new WebAssembly.Module(bin); -const instance = new WebAssembly.Instance(module); - -assert.eq(Object.getPrototypeOf(instance.exports.foo), Function.prototype); -{ - assert.truthy(typeof instance.exports.foo === "function", "is_function bytecode should handle wasm function."); - let value = typeof instance.exports.foo; - assert.eq(value, "function", "the result of typeof should be 'function'"); -} diff --git a/implementation-contributed/javascriptcore/wasm/js-api/web-assembly-instantiate-parallel.js b/implementation-contributed/javascriptcore/wasm/js-api/web-assembly-instantiate-parallel.js deleted file mode 100644 index b447bcad0b8880476a783bddc1a941cea4260dce..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/web-assembly-instantiate-parallel.js +++ /dev/null @@ -1,75 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -async function test() { - const loopDepth = 100; - const numCompilations = 1; - const numVars = 30; - const params = []; - params.length = numVars; - params.fill("i32"); - - let builder = (new Builder()) - .Type().End() - .Import() - .Memory("imp", "memory", { initial: 0 }) - .End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", { params, ret: "i32" }); - - const makeLoop = (builder, depth) => { - if (depth === 0) - return builder; - - builder = builder - .Loop("i32", (b) => { - b.GetLocal(0) - .I32Const(1) - .I32Sub() - .TeeLocal(0) - .GetLocal(0) - .I32Eqz() - .BrIf(1); - - return makeLoop(b, depth - 1).Br(0); - }); - return builder; - } - - builder = makeLoop(builder, loopDepth); - builder = builder.End().End(); - - const bin = builder.WebAssembly().get(); - const memory = new WebAssembly.Memory({ initial: 0 }); - const importObject = { "imp": { "memory": memory } }; - - // Compile a bunch of instances in parallel. - let compilations = []; - for (let i = 0; i < numCompilations; ++i) { - compilations.push(WebAssembly.instantiate(bin, importObject)); - } - - let [inst] = await Promise.all(compilations); - let module = inst.module; - - // Compile a bunch of instances from modules in parallel. - compilations = []; - for (let i = 0; i < numCompilations; ++i) { - compilations.push(WebAssembly.instantiate(module, importObject)); - } - - await Promise.all(compilations); - - // Compile an instance from a module in parallel, have sync compilation steal it. - compilations = []; - compilations.push(WebAssembly.instantiate(module, importObject)); - inst = new WebAssembly.Instance(module, importObject); - - await Promise.all(compilations); -} - -assert.asyncTest(test()); diff --git a/implementation-contributed/javascriptcore/wasm/js-api/web-assembly-instantiate.js b/implementation-contributed/javascriptcore/wasm/js-api/web-assembly-instantiate.js deleted file mode 100644 index f60672521e54431cfa11d5dcb3f793ff526d288b..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/web-assembly-instantiate.js +++ /dev/null @@ -1,192 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -assert.isFunction(WebAssembly.instantiate); -assert.isFunction(WebAssembly.__proto__.instantiate); -assert.eq(WebAssembly.instantiate.length, 1); - -{ - const builder = (new Builder()) - .Type().End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", { params: [], ret: "i32" }) - .I32Const(1) - .End() - .End(); - - const bin = builder.WebAssembly().get(); - - async function test() { - let {module, instance} = await WebAssembly.instantiate(bin); - assert.truthy(module instanceof WebAssembly.Module); - assert.truthy(instance instanceof WebAssembly.Instance); - assert.eq(instance.exports.foo(20), 1); - } - - assert.asyncTest(test()); -} - -{ - const builder = (new Builder()) - .Type().End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", { params: [], ret: "i32" }) - .I32Const(1) - .End() - .End(); - - const bin = builder.WebAssembly().get(); - - async function test() { - try { - let {module, instance} = await WebAssembly.instantiate(bin, null); - } catch(e) { - assert.eq(e.message, "second argument to WebAssembly.instantiate must be undefined or an Object (evaluating 'WebAssembly.instantiate(bin, null)')"); - } - } - - assert.asyncTest(test()); -} - -{ - const builder = (new Builder()) - .Type().End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", { params: [], ret: "i32" }) - .F32Const(1) - .End() - .End(); - - const bin = builder.WebAssembly().get(); - - async function test() { - try { - let {module, instance} = await WebAssembly.instantiate(bin); - } catch(e) { - assert.truthy(e instanceof WebAssembly.CompileError); - assert.eq(e.message, "WebAssembly.Module doesn't validate: control flow returns with unexpected type, in function at index 0"); - } - } - - assert.asyncTest(test()); -} - -{ - const builder = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", {initial:100}).End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", { params: [], ret: "i32" }) - .I32Const(1) - .End() - .End(); - - const bin = builder.WebAssembly().get(); - - async function test() { - try { - let {module, instance} = await WebAssembly.instantiate(bin, {imp: {memory: 20}}); - } catch(e) { - assert.eq(e.message, "Memory import imp:memory is not an instance of WebAssembly.Memory"); - } - } - - assert.asyncTest(test()); -} - -{ - const builder = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", {initial:100}).End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", { params: [], ret: "i32" }) - .I32Const(1) - .End() - .End(); - - const bin = builder.WebAssembly().get(); - - async function test() { - try { - const module = new WebAssembly.Module(bin); - let instance = await WebAssembly.instantiate(bin, {imp: {memory: 20}}); - } catch(e) { - assert.eq(e.message, "Memory import imp:memory is not an instance of WebAssembly.Memory"); - } - } - - assert.asyncTest(test()); -} - -{ - const builder = (new Builder()) - .Type().End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", { params: [], ret: "i32" }) - .I32Const(1) - .End() - .End(); - - const bin = builder.WebAssembly().get(); - - async function test() { - let module = new WebAssembly.Module(bin); - let instance = await WebAssembly.instantiate(module); - assert.truthy(instance instanceof WebAssembly.Instance); - assert.eq(instance.exports.foo(20), 1); - } - - assert.asyncTest(test()); -} - -{ - const builder = (new Builder()) - .Type().End() - .Import().Memory("imp", "memory", {initial:100}).End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", { params: [], ret: "i32" }) - .I32Const(1) - .End() - .End(); - - const bin = builder.WebAssembly().get(); - - async function test() { - try { - await WebAssembly.instantiate(25); - } catch(e) { - // FIXME: Better error message here. - assert.eq(e.message, "first argument must be an ArrayBufferView or an ArrayBuffer (evaluating 'WebAssembly.instantiate(25)')"); - } - } - - assert.asyncTest(test()); -} diff --git a/implementation-contributed/javascriptcore/wasm/js-api/wrapper-function.js b/implementation-contributed/javascriptcore/wasm/js-api/wrapper-function.js deleted file mode 100644 index e3bc398653e9aa59ea1596421ea4c5d7b2ad4d0d..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/js-api/wrapper-function.js +++ /dev/null @@ -1,151 +0,0 @@ -import Builder from '../Builder.js'; -import * as assert from '../assert.js'; - - -function exportImport(type) { - let builder = (new Builder()) - .Type().End() - .Import() - .Function("imp", "f", type) - .End() - .Function().End() - .Export() - .Function("func", {module: "imp", field: "f"}) - .End() - .Code().End(); - return new WebAssembly.Module(builder.WebAssembly().get()); -} - -{ - let type = { params: ["i32"], ret: "i32" }; - let module = exportImport(type); - let called = false; - let foo = (i) => { - called = true; - return i + 42; - }; - let instance = new WebAssembly.Instance(module, {imp: {f: foo}}); - assert.truthy(instance.exports.func !== foo); - for (let i = 0; i < 100; i++) { - let r1 = instance.exports.func(i); - assert.truthy(called); - called = false; - let r2 = foo(i); - called = false; - assert.eq(r1, r2); - } - - { - let builder = (new Builder()) - .Type().End() - .Import() - .Function("imp", "f", {params: []}) - .End() - .Function().End() - .Code().End(); - let module = new WebAssembly.Module(builder.WebAssembly().get()); - // This should not type check. - assert.throws(() => new WebAssembly.Instance(module, {imp: {f: instance.exports.func}}), WebAssembly.LinkError, "imported function imp:f signature doesn't match the provided WebAssembly function's signature"); - } - - { - assert.truthy(typeof instance.exports.func === "function", "is_function bytecode should handle wrapper function."); - let value = typeof instance.exports.func; - assert.eq(value, "function", "the result of typeof should be 'function'"); - } -} - -{ - const tableDescription = {element: "anyfunc", initial: 2}; - function makeInstance(type, imp) { - const builder = new Builder() - .Type() - .Func(["i32"], "i32") - .Func(["i32", "i32"], "i32") - .End() - .Import() - .Table("imp", "table", tableDescription) - .Function("imp", "f1", {params: ["i32"], ret:"i32"}) - .Function("imp", "f2", {params: ["i32", "i32"], ret:"i32"}) - .End() - .Function().End() - .Export() - .Function("foo") - .End() - .Element() - .Element({offset: 0, functionIndices: [0, 1]}) - .End() - .Code() - .Function("foo", 1) - .GetLocal(1) // parameter to call - .GetLocal(0) // call index - .CallIndirect(0, 0) // calling function of type ['i32'] => 'i32' - .Return() - .End() - .End(); - let module = new WebAssembly.Module(builder.WebAssembly().get()); - return new WebAssembly.Instance(module, imp); - } - - function Bar(){}; - noInline(Bar); - let called = false; - let foo = (i) => { - called = true; - new Bar; - return i*42; - } - let table = new WebAssembly.Table(tableDescription); - let inst = makeInstance({params:['i32'], ret:"i32"}, {imp: {f1: foo, f2:foo, table}}); - for (let i = 0; i < 1000; i++) { - let r1 = inst.exports.foo(0, i); - assert.truthy(called); - called = false; - let r2 = foo(i); - assert.truthy(called); - called = false; - assert.eq(r1, r2); - } - for (let i = 0; i < 1000; i++) { - assert.throws(() => inst.exports.foo(1, i), WebAssembly.RuntimeError, "call_indirect to a signature that does not match"); - assert.truthy(!called); - } - for (let i = 0; i < 1000; i++) { - let r1 = table.get(0)(i); - table.set(0, table.get(0)); // just make sure setting a wrapper function works. - assert.truthy(called); - called = false; - let r2 = table.get(1)(i); - assert.truthy(called); - called = false; - assert.eq(r1, r2); - } - - { - let nextInst = makeInstance({params:['i32'], ret:"i32"}, {imp: {f1: table.get(0), f2:inst.exports.foo, table}}); - for (let i = 0; i < 1000; i++) { - let r1 = nextInst.exports.foo(0, i); - assert.truthy(called); - called = false; - let r2 = foo(i); - assert.truthy(called); - called = false; - assert.eq(r1, r2); - } - - for (let i = 0; i < 1000; i++) { - assert.throws(() => nextInst.exports.foo(1, i), WebAssembly.RuntimeError, "call_indirect to a signature that does not match"); - assert.truthy(!called); - } - - for (let i = 0; i < 1000; i++) { - let r1 = table.get(1)(0, i); - assert.truthy(called); - called = false; - let r2 = foo(i); - assert.truthy(called); - called = false; - assert.eq(r1, r2); - } - } -} diff --git a/implementation-contributed/javascriptcore/wasm/lowExecutableMemory/executable-memory-oom.js b/implementation-contributed/javascriptcore/wasm/lowExecutableMemory/executable-memory-oom.js deleted file mode 100644 index e00aada8f158971584149b906f32091794680102..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/lowExecutableMemory/executable-memory-oom.js +++ /dev/null @@ -1,121 +0,0 @@ -import * as assert from '../assert.js' -import Builder from '../Builder.js' - -const verbose = false; -const maxInstructionCount = 500; -const instancesTotal = 8; -const invocationsTotal = 8; -const tierUpCalls = 20000; // Call enough to trigger tier up and get it to compile. - -// This test starts running with a few bytes of executable memory available. Try -// to create and instantiate a module which will fail to fit. - -const randomProgram = instructionCount => { - let b = new Builder() - .Type().End() - .Function().End() - .Export() - .Function("foo") - .Function("bar") - .End() - .Code() - .Function("foo", { params: [], ret: "f32" }) - .F32Const(2.0) - .Return() - .End() - .Function("bar", { params: ["f32", "f32"], ret: "f32" }) - .GetLocal(0); - - // Insert a bunch of dependent instructions in a single basic block so that - // our compiler won't be able to strength-reduce. - const actions = [ - b => b.GetLocal(0).F32Sub(), - b => b.GetLocal(1).F32Sub(), - b => b.GetLocal(0).F32Add(), - b => b.GetLocal(1).F32Add(), - b => b.GetLocal(0).F32Mul(), - b => b.GetLocal(1).F32Mul(), - ]; - - while (--instructionCount) - b = actions[(Math.random() * actions.length) | 0](b); - - b = b.Return().End().End(); - - return b.WebAssembly().get(); -} - -let failCount = 0; -let callCount = 0; -let instances = []; - -const invoke = (instance, count) => { - if (verbose) - print(`Invoking`); - for (let i = 0; i < count; ++i) - assert.eq(instance.exports["foo"](), 2.0); - for (let i = 0; i < count; ++i) - instance.exports["bar"](2.0, 6.0); - ++callCount; -}; - -while (failCount === 0) { - const instructionCount = (Math.random() * maxInstructionCount + 1) | 0; - - if (verbose) - print(`Trying module with ${instructionCount} instructions.`); - - const buf = randomProgram(instructionCount); - let module; - - try { - module = new WebAssembly.Module(buf); - } catch (e) { - if (e instanceof WebAssembly.CompileError) { - if (verbose) - print(`Caught: ${e}`); - ++failCount; - } - else - throw new Error(`Expected a WebAssembly.CompileError, got ${e}`); - } - - if (module !== undefined) { - if (verbose) - print(`Creating instance`); - - let instance; - try { - instance = new WebAssembly.Instance(module); - } catch (e) { - if (e instanceof WebAssembly.LinkError) { - if (verbose) - print(`Caught: ${e}`); - ++failCount; - } - else - throw new Error(`Expected a WebAssembly.LinkError, got ${e}`); - } - - if (instance !== undefined) { - instances.push(instance); - invoke(instance, 1); - } - } -} - -if (callCount === 0) - throw new Error(`Expected to be able to allocate a WebAssembly module, instantiate it, and call its exports at least once`); - -// Make sure we can still call all the instances we create, even after going -// OOM. This will try to force tier-up as well, which should fail. - -if (verbose) - print(`Invoking all previously created instances`); - -for (let instance of instances) - invoke(instance, tierUpCalls); - -// Do it twice to revisit what should have gotten tiered up. -for (let instance of instances) - invoke(instance, 1); diff --git a/implementation-contributed/javascriptcore/wasm/lowExecutableMemory/exports-oom.js b/implementation-contributed/javascriptcore/wasm/lowExecutableMemory/exports-oom.js deleted file mode 100644 index 0c3270ada0bef1fb470341bff9940e8cf8edbcd1..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/lowExecutableMemory/exports-oom.js +++ /dev/null @@ -1,107 +0,0 @@ -import * as assert from '../assert.js' -import Builder from '../Builder.js' - -const verbose = false; -const numFunctions = 2; -const maxParams = 128; - -// This test starts running with a few bytes of executable memory available. Try -// to create and instantiate modules which have way more exports than anything -// else. Hopefully they'll fail when trying to instantiate their entrypoints. - -const type = () => { - const types = ["i32", "f32", "f64"]; // Can't export i64. - return types[(Math.random() * types.length) | 0]; -}; - -const params = () => { - let p = []; - let count = (Math.random() * maxParams) | 0; - while (count--) - p.push(type()); - return p; -}; - -const randomProgram = () => { - let b = new Builder() - .Type().End() - .Function().End() - .Export(); - for (let f = 0; f < numFunctions; ++f) - b = b.Function(`f${f}`); - b = b.End().Code(); - for (let f = 0; f < numFunctions; ++f) - b = b.Function(`f${f}`, { params: params() }).Return().End(); - b = b.End(); - return b.WebAssembly().get(); -} - -let failCount = 0; -let callCount = 0; -let instances = []; - -const invoke = instance => { - let result = 0; - for (let f = 0; f < numFunctions; ++f) { - const name = `f${f}`; - if (verbose) - print(`Invoking ${name}`); - result += instance.exports[name](); - ++callCount; - } - return result; -}; - -while (failCount === 0) { - if (verbose) - print(`Trying...`); - - const buf = randomProgram(); - let module; - - try { - module = new WebAssembly.Module(buf); - } catch (e) { - if (e instanceof WebAssembly.CompileError) { - if (verbose) - print(`Caught: ${e}`); - ++failCount; - } - else - throw new Error(`Expected a WebAssembly.CompileError, got ${e}`); - } - - if (module !== undefined) { - if (verbose) - print(`Creating instance`); - - let instance; - try { - instance = new WebAssembly.Instance(module); - } catch (e) { - if (e instanceof WebAssembly.LinkError) { - if (verbose) - print(`Caught: ${e}`); - ++failCount; - } - else - throw new Error(`Expected a WebAssembly.LinkError, got ${e}`); - } - - if (instance !== undefined) { - instances.push(instance); - invoke(instance); - } - } -} - -if (callCount === 0) - throw new Error(`Expected to be able to allocate a WebAssembly module, instantiate it, and call its exports at least once`); - -// Make sure we can still call all the instances we create, even after going OOM. - -if (verbose) - print(`Invoking all previously created instances`); - -for (let instance of instances) - invoke(instance); diff --git a/implementation-contributed/javascriptcore/wasm/lowExecutableMemory/imports-oom.js b/implementation-contributed/javascriptcore/wasm/lowExecutableMemory/imports-oom.js deleted file mode 100644 index 44cd9737404ee8ae433c71290ace9a09711c903f..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/lowExecutableMemory/imports-oom.js +++ /dev/null @@ -1,124 +0,0 @@ -import * as assert from '../assert.js' -import Builder from '../Builder.js' - -const verbose = false; -const numFunctions = 2; -const maxParams = 32; - -// This test starts running with a few bytes of executable memory available. Try -// to create and instantiate modules which have way more imports than anything -// else. Hopefully they'll fail when trying to instantiate their entrypoints. - -const type = () => { - const types = ["i32", "f32", "f64"]; - return types[(Math.random() * types.length) | 0]; -}; - -const params = () => { - let p = []; - let count = (Math.random() * maxParams) | 0; - while (count--) - p.push(type()); - return p; -}; - -const randomProgram = () => { - let b = new Builder() - .Type().End() - .Import(); - const ps = params(); - for (let f = 0; f < numFunctions; ++f) - b = b.Function("imp", `${f}`, { params: ps }); - b = b.End() - .Function().End() - .Export(); - for (let f = 0; f < numFunctions; ++f) - b = b.Function(`call${f}`); - b = b.End() - .Code(); - for (let f = 0; f < numFunctions; ++f) { - b = b.Function(`call${f}`, { params: ps }); - for (let p = 0; p < ps.length; ++p) - b = b.GetLocal(p); - b = b.Call(f).End(); - } - b = b.End(); - return b.WebAssembly().get(); -} - -let failCount = 0; -let callCount = 0; -let instances = []; - -let imports = []; -for (let f = 0; f < numFunctions; ++f) - imports.push((...args) => { - if (verbose) - print(`Invoked ${f} with: ${args}`); - ++callCount; - }); - -const invoke = instance => { - let result = 0; - for (let f = 0; f < numFunctions; ++f) { - const name = `call${f}`; - if (verbose) - print(`Invoking ${name}`); - result += instance.exports[name](); - } - return result; -}; - -while (failCount === 0) { - if (verbose) - print(`Trying...`); - - const buf = randomProgram(); - let module; - - try { - module = new WebAssembly.Module(buf); - } catch (e) { - if (e instanceof WebAssembly.CompileError) { - if (verbose) - print(`Caught: ${e}`); - ++failCount; - } - else - throw new Error(`Expected a WebAssembly.CompileError, got ${e}`); - } - - if (module !== undefined) { - if (verbose) - print(`Creating instance`); - - let instance; - try { - instance = new WebAssembly.Instance(module, { imp: imports }); - } catch (e) { - if (e instanceof WebAssembly.LinkError) { - if (verbose) - print(`Caught: ${e}`); - ++failCount; - } - else - throw new Error(`Expected a WebAssembly.LinkError, got ${e}`); - } - - if (instance !== undefined) { - instances.push(instance); - invoke(instance); - } - } -} - -if (callCount === 0) - throw new Error(`Expected to be able to allocate a WebAssembly module, instantiate it, and call its exports at least once`); - -// Make sure we can still call all the instances we create, even after going OOM. - -if (verbose) - print(`Invoking all previously created instances`); - -for (let instance of instances) - invoke(instance); diff --git a/implementation-contributed/javascriptcore/wasm/regress/175693.js b/implementation-contributed/javascriptcore/wasm/regress/175693.js deleted file mode 100644 index b1ec7388b10d1b965db14397e5f52eea507e4c60..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/regress/175693.js +++ /dev/null @@ -1,46 +0,0 @@ -const file = "175693.wasm"; - -const verbose = false; - -if (typeof console === 'undefined') { - console = { log: print }; -} -var binary; -if (typeof process === 'object' && typeof require === 'function' /* node.js detection */) { - var args = process.argv.slice(2); - binary = require('fs').readFileSync(file); - if (!binary.buffer) binary = new Uint8Array(binary); -} else { - var args; - if (typeof scriptArgs != 'undefined') { - args = scriptArgs; - } else if (typeof arguments != 'undefined') { - args = arguments; - } - if (typeof readbuffer === 'function') { - binary = new Uint8Array(readbuffer(file)); - } else { - binary = read(file, 'binary'); - } -} -var instance = new WebAssembly.Instance(new WebAssembly.Module(binary), {}); -if (instance.exports.hangLimitInitializer) instance.exports.hangLimitInitializer(); -try { - if (verbose) - console.log('calling: func_0'); - instance.exports.func_0(); -} catch (e) { - if (verbose) - console.log(' exception: ' + e); -} -if (instance.exports.hangLimitInitializer) instance.exports.hangLimitInitializer(); -try { - if (verbose) - console.log('calling: hangLimitInitializer'); - instance.exports.hangLimitInitializer(); -} catch (e) { - if (verbose) - console.log(' exception: ' + e); -} -if (verbose) - console.log('done.') diff --git a/implementation-contributed/javascriptcore/wasm/regress/183342.js b/implementation-contributed/javascriptcore/wasm/regress/183342.js deleted file mode 100644 index 3e485fd176921891af3b923a921968932d9a087d..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/regress/183342.js +++ /dev/null @@ -1,57 +0,0 @@ -const verbose = false; - -{ - // The simplest module with a DataView offset. - let buffer = new Uint8Array(16); - buffer[ 8] = 0x00; // \0 - buffer[ 9] = 0x61; // a - buffer[10] = 0x73; // s - buffer[11] = 0x6d; // m - buffer[12] = 0x01; // version - buffer[13] = 0x00; // version - buffer[14] = 0x00; // version - buffer[15] = 0x00; // version - const view = new DataView(buffer.buffer, 8); - const module = new WebAssembly.Module(view); - const instance = new WebAssembly.Instance(module); -} - -{ - // A bunch of random offsets into large buffers with mostly valid content. - const headerSize = 16; - const roundToHeaderSize = s => Math.round(s / headerSize) * headerSize; - for (let attempt = 0; attempt < 100; ++attempt) { - const bufferSize = Math.max(roundToHeaderSize(Math.random() * 0xffff), headerSize * 2); - let buffer = new Uint8Array(bufferSize); - for (let i = 0; i < bufferSize; i += headerSize) { - buffer[ 0 + i] = 0x00; // \0 - buffer[ 1 + i] = 0x61; // a - buffer[ 2 + i] = 0x73; // s - buffer[ 3 + i] = 0x6d; // m - buffer[ 4 + i] = 0x01; // version - buffer[ 5 + i] = 0x00; // version - buffer[ 6 + i] = 0x00; // version - buffer[ 7 + i] = 0x00; // version - buffer[ 8 + i] = 0x00; // ID = custom - buffer[ 9 + i] = 0x80 | Math.round(Math.random() * 0x7f); // section byte size, LEB128 - buffer[10 + i] = 0x80 | Math.round(Math.random() * 0x7f); // section byte size, LEB128 - buffer[11 + i] = 0x00 | Math.round(Math.random() * 0x7f); // section byte size, LEB128 - buffer[12 + i] = 0x04; // custom section name length, LEB128 - buffer[13 + i] = 0x42; // B - buffer[14 + i] = 0x4f; // O - buffer[15 + i] = 0X4f; // O - buffer[16 + i] = 0x4d; // M - } - const viewOffset = roundToHeaderSize(Math.random() * bufferSize); - if (verbose) - print("Buffer size: ", bufferSize, " view offset: ", viewOffset, " view size: ", bufferSize - viewOffset); - const view = new DataView(buffer.buffer, viewOffset); - try { - const module = new WebAssembly.Module(view); - const instance = new WebAssembly.Instance(module); - } catch (e) { - if (verbose) - print(e); - } - } -} diff --git a/implementation-contributed/javascriptcore/wasm/regress/regress-189185.js b/implementation-contributed/javascriptcore/wasm/regress/regress-189185.js deleted file mode 100644 index d2588ad31f90062f58138c62e8768a3fe5b0616f..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/regress/regress-189185.js +++ /dev/null @@ -1,7 +0,0 @@ -//@ runWebAssembly -// This passes if it does not crash. -new WebAssembly.CompileError({ - valueOf() { - throw new Error(); - } -}); diff --git a/implementation-contributed/javascriptcore/wasm/self-test/test_BuilderJSON.js b/implementation-contributed/javascriptcore/wasm/self-test/test_BuilderJSON.js deleted file mode 100644 index bb1b97b19d5cc1c78b5f007dc690aadbd70d20f8..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/self-test/test_BuilderJSON.js +++ /dev/null @@ -1,673 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -const assertOpThrows = (opFn, message) => { - let f = (new Builder()).Type().End().Code().Function(); - assert.throws(opFn, Error, message, f); -}; - -(function EmptyModule() { - const b = new Builder(); - const j = JSON.parse(b.json()); - assert.isNotUndef(j.preamble); - assert.isNotUndef(j.preamble["magic number"]); - assert.isNotUndef(j.preamble.version); - assert.isNotUndef(j.section); - assert.eq(j.section.length, 0); -})(); - -(function CustomMagicNumber() { - const b = (new Builder()).setPreamble({ "magic number": 1337 }); - const j = JSON.parse(b.json()); - assert.eq(j.preamble["magic number"], 1337); - assert.isNotUndef(j.preamble.version); -})(); - -(function CustomVersion() { - const b = (new Builder()).setPreamble({ "version": 1337 }); - const j = JSON.parse(b.json()); - assert.eq(j.preamble["version"], 1337); - assert.isNotUndef(j.preamble.version); -})(); - -(function CustomSection() { - const b = new Builder(); - b.Unknown("custom section") - .Byte(0x00) - .Byte(0x42) - .Byte(0xFF); - const j = JSON.parse(b.json()); - assert.eq(j.section.length, 1); - assert.eq(j.section[0].name, "custom section"); - assert.eq(j.section[0].data.length, 3); - assert.eq(j.section[0].data[0], 0x00); - assert.eq(j.section[0].data[1], 0x42); - assert.eq(j.section[0].data[2], 0xFF); -})(); - -(function CustomSectionAllBytes() { - const b = new Builder(); - let u = b.Unknown("custom section"); - for (let i = 0; i !== 0xFF + 1; ++i) - u.Byte(i); - const j = JSON.parse(b.json()); - assert.eq(j.section[0].data.length, 256); - for (let i = 0; i !== 0xFF + 1; ++i) - assert.eq(j.section[0].data[i], i); -})(); - -(function CustomSectionInvalidByte() { - const u = (new Builder()).Unknown("custom section"); - assert.throws(() => u.Byte(0xFF + 1), Error, `Not the same: "0" and "256": Unknown section expected byte, got: "256"`); -})(); - -(function TwoCustomSections() { - const b = new Builder(); - b.Unknown("custom section") - .Byte(0x00) - .Byte(0x42) - .Byte(0xFF) - .End() - .Unknown("☃") - .Byte(0x11); - const j = JSON.parse(b.json()); - assert.eq(j.section.length, 2); - assert.eq(j.section[0].name, "custom section"); - assert.eq(j.section[0].data.length, 3); - assert.eq(j.section[1].name, "☃"); - assert.eq(j.section[1].data.length, 1); - assert.eq(j.section[1].data[0], 0x11); -})(); - -(function SectionsWithSameCustomName() { - const b = (new Builder()).Unknown("foo").Byte(42).End().Unknown("foo").Byte(100).End(); - const j = JSON.parse(b.json()); - assert.eq(j.section.length, 2); - assert.eq(j.section[0].name, "foo"); - assert.eq(j.section[0].data.length, 1); - assert.eq(j.section[0].data[0], 42); - assert.eq(j.section[1].name, "foo"); - assert.eq(j.section[1].data.length, 1); - assert.eq(j.section[1].data[0], 100); -})(); - -(function EmptyTypeSection() { - const b = (new Builder()).Type().End(); - const j = JSON.parse(b.json()); - assert.eq(j.section.length, 1); - assert.eq(j.section[0].name, "Type"); - assert.eq(j.section[0].data.length, 0); -})(); - -(function TwoTypeSections() { - const b = (new Builder()).Type().End(); - assert.throws(() => b.Type(), Error, `Expected falsy: Cannot have two sections with the same name "Type" and ID 1`); -})(); - -(function SimpleTypeSection() { - const b = (new Builder()).Type() - .Func([]) - .Func([], "void") - .Func([], "i32") - .Func([], "i64") - .Func([], "f32") - .Func([], "f64") - .Func(["i32", "i64", "f32", "f64"]) - .End(); - const j = JSON.parse(b.json()); - assert.eq(j.section[0].data.length, 7); - assert.eq(j.section[0].data[0].params, []); - assert.eq(j.section[0].data[0].ret, "void"); - assert.eq(j.section[0].data[1].params, []); - assert.eq(j.section[0].data[1].ret, "void"); - assert.eq(j.section[0].data[2].params, []); - assert.eq(j.section[0].data[2].ret, "i32"); - assert.eq(j.section[0].data[3].params, []); - assert.eq(j.section[0].data[3].ret, "i64"); - assert.eq(j.section[0].data[4].params, []); - assert.eq(j.section[0].data[4].ret, "f32"); - assert.eq(j.section[0].data[5].params, []); - assert.eq(j.section[0].data[5].ret, "f64"); - assert.eq(j.section[0].data[6].params, ["i32", "i64", "f32", "f64"]); - assert.eq(j.section[0].data[6].ret, "void"); -})(); - -(function EmptyImportSection() { - const b = (new Builder()).Import().End(); - const j = JSON.parse(b.json()); - assert.eq(j.section.length, 1); - assert.eq(j.section[0].name, "Import"); - assert.eq(j.section[0].data.length, 0); -})(); - -(function ImportBeforeTypeSections() { - const b = (new Builder()).Import().End(); - assert.throws(() => b.Type(), Error, `Expected: "2" > "1": Bad section ordering: "Import" cannot precede "Type"`); -})(); - -(function ImportFunctionWithoutTypeSection() { - const i = (new Builder()).Import(); - assert.throws(() => i.Function("foo", "bar", 0), Error, `Shouldn't be undefined: Can not use type 0 if a type section is not present`); -})(); - -(function ImportFunctionWithInvalidType() { - const i = (new Builder()).Type().End().Import(); - assert.throws(() => i.Function("foo", "bar", 0), Error, `Shouldn't be undefined: Type 0 does not exist in type section`); -})(); - -(function ImportFunction() { - const b = (new Builder()) - .Type().Func([]).End() - .Import() - .Function("foo", "bar", 0) - .End(); - const j = JSON.parse(b.json()); - assert.eq(j.section[1].data.length, 1); - assert.eq(j.section[1].data[0].module, "foo"); - assert.eq(j.section[1].data[0].field, "bar"); - assert.eq(j.section[1].data[0].type, 0); - assert.eq(j.section[1].data[0].kind, "Function"); -})(); - -(function ImportFunctionsWithExistingTypes() { - const b = (new Builder()) - .Type() - .Func([]) - .Func([], "i32") - .Func(["i64", "i32"]) - .Func(["i64", "i64"]) - .End() - .Import() - .Function("foo", "bar", { params: [] }) - .Function("foo", "baz", { params: [], ret: "i32" }) - .Function("foo", "boo", { params: ["i64", "i64"] }) - .End(); - const j = JSON.parse(b.json()); - assert.eq(j.section[0].data.length, 4); - assert.eq(j.section[1].data.length, 3); - assert.eq(j.section[1].data[0].type, 0); - assert.eq(j.section[1].data[1].type, 1); - assert.eq(j.section[1].data[2].type, 3); -})(); - -(function ImportFunctionWithNewType() { - const b = (new Builder()) - .Type().End() - .Import() - .Function("foo", "bar", { params: [] }) - .Function("foo", "baz", { params: [], ret: "i32" }) - .Function("foo", "boo", { params: ["i64", "i64"] }) - .End(); - const j = JSON.parse(b.json()); - assert.eq(j.section[0].data.length, 3); - assert.eq(j.section[0].data[0].ret, "void"); - assert.eq(j.section[0].data[0].params, []); - assert.eq(j.section[0].data[1].ret, "i32"); - assert.eq(j.section[0].data[1].params, []); - assert.eq(j.section[0].data[2].ret, "void"); - assert.eq(j.section[0].data[2].params, ["i64", "i64"]); -})(); - -(function EmptyExportSection() { - const b = (new Builder()).Export().End(); - const j = JSON.parse(b.json()); - assert.eq(j.section.length, 1); - assert.eq(j.section[0].name, "Export"); - assert.eq(j.section[0].data.length, 0); -})(); - -(function ExportFunctionWithoutTypeSection() { - const e = (new Builder()).Export(); - assert.throws(() => e.Function("foo", 0, 0), Error, `Shouldn't be undefined: Can not use type 0 if a type section is not present`); -})(); - -(function ExportFunctionWithInvalidType() { - const e = (new Builder()).Type().End().Export(); - assert.throws(() => e.Function("foo", 0, 0), Error, `Shouldn't be undefined: Type 0 does not exist in type section`); -})(); - -(function ExportAnImport() { - const b = (new Builder()) - .Type().End() - .Import().Function("foo", "bar", { params: [] }).End() - .Export().Function("ExportAnImport", { module: "foo", field: "bar" }).End(); - const j = JSON.parse(b.json()); - assert.eq(j.section[2].name, "Export"); - assert.eq(j.section[2].data.length, 1); - assert.eq(j.section[2].data[0].field, "ExportAnImport"); - assert.eq(j.section[2].data[0].type, 0); - assert.eq(j.section[2].data[0].index, 0); - assert.eq(j.section[2].data[0].kind, "Function"); -})(); - -(function ExportMismatchedImport() { - const e = (new Builder()) - .Type().End() - .Import().Function("foo", "bar", { params: [] }).End() - .Export(); - assert.throws(() => e.Function("foo", 0, { params: ["i32"] }), Error, `Not the same: "1" and "0": Re-exporting import "bar" as "foo" has mismatching type`); -})(); - -(function StartInvalidNumberedFunction() { - const b = (new Builder()) - .Type().End() - .Function().End() - .Start(0).End() - assert.throws(() => b.Code().End(), Error, `Start section refers to non-existant function '0'`); -})(); - -(function StartInvalidNamedFunction() { - const b = (new Builder()) - .Type().End() - .Function().End() - .Start("foo").End(); - assert.throws(() => b.Code().End(), Error, `Start section refers to non-existant function 'foo'`); -})(); - -(function StartNamedFunction() { - const b = (new Builder()) - .Type().End() - .Function().End() - .Start("foo").End() - .Code() - .Function("foo", { params: [] }).End() - .End(); - const j = JSON.parse(b.json()); - assert.eq(j.section.length, 4); - assert.eq(j.section[2].name, "Start"); - assert.eq(j.section[2].data.length, 1); - assert.eq(j.section[2].data[0], 0); -})(); - -/* FIXME implement checking of signature https://bugs.webkit.org/show_bug.cgi?id=165658 -(function StartInvalidTypeArg() { - const b = (new Builder()) - .Type().End() - .Function().End() - .Start("foo").End() - assert.throws(() => b.Code().Function("foo", { params: ["i32"] }).End(), Error, `???`); -})(); - -(function StartInvalidTypeReturn() { - const b = (new Builder()) - .Type().End() - .Function().End() - .Start("foo").End() - assert.throws(() => b.Code().Function("foo", { params: [], ret: "i32" }).I32Const(42).Ret().End(), Error, `???`); -})(); -*/ - -// FIXME test start of import or table. https://bugs.webkit.org/show_bug.cgi?id=165658 - -(function EmptyCodeSection() { - const b = new Builder(); - b.Code(); - const j = JSON.parse(b.json()); - assert.eq(j.section.length, 1); - assert.eq(j.section[0].name, "Code"); - assert.eq(j.section[0].data.length, 0); -})(); - -(function CodeSectionWithEmptyFunction() { - const b = new Builder(); - b.Type().End() - .Code() - .Function(); - const j = JSON.parse(b.json()); - assert.eq(j.section.length, 2); - assert.eq(j.section[0].name, "Type"); - assert.eq(j.section[0].data.length, 1); - assert.eq(j.section[0].data[0].params, []); - assert.eq(j.section[0].data[0].ret, "void"); - assert.eq(j.section[1].name, "Code"); - assert.eq(j.section[1].data.length, 1); - assert.eq(j.section[1].data[0].name, undefined); - assert.eq(j.section[1].data[0].type, 0); - assert.eq(j.section[1].data[0].parameterCount, 0); - assert.eq(j.section[1].data[0].locals.length, 0); - assert.eq(j.section[1].data[0].code.length, 0); -})(); - -(function CodeSectionWithEmptyFunctionWithParameters() { - const b = new Builder(); - b.Type().End() - .Code() - .Function({ params: ["i32", "i64", "f32", "f64"] }); - const j = JSON.parse(b.json()); - assert.eq(j.section.length, 2); - assert.eq(j.section[0].data.length, 1); - assert.eq(j.section[0].data[0].params, ["i32", "i64", "f32", "f64"]); - assert.eq(j.section[0].data[0].ret, "void"); - assert.eq(j.section[1].data.length, 1); - assert.eq(j.section[1].data[0].type, 0); - assert.eq(j.section[1].data[0].parameterCount, 4); - assert.eq(j.section[1].data[0].locals[0], "i32"); - assert.eq(j.section[1].data[0].locals[1], "i64"); - assert.eq(j.section[1].data[0].locals[2], "f32"); - assert.eq(j.section[1].data[0].locals[3], "f64"); - assert.eq(j.section[1].data[0].code.length, 0); -})(); - -(function InvalidFunctionParameters() { - for (let invalid of ["", "bool", "any", "struct", 0, 3.14, undefined, [], {}]) { - const c = (new Builder()).Code(); - assert.throws(() => c.Function({ params: [invalid] }), Error, `Expected truthy: Type parameter ${invalid} needs a valid value type`); - } -})(); - -(function SimpleFunction() { - const b = new Builder(); - b.Type().End() - .Code() - .Function() - .Nop() - .Nop() - .End(); - const j = JSON.parse(b.json()); - assert.eq(j.section[1].data.length, 1); - assert.eq(j.section[1].data[0].locals.length, 0); - assert.eq(j.section[1].data[0].code.length, 3); - assert.eq(j.section[1].data[0].code[0].name, "nop"); - assert.eq(j.section[1].data[0].code[1].name, "nop"); - assert.eq(j.section[1].data[0].code[2].name, "end"); -})(); - -(function TwoSimpleFunctions() { - const b = new Builder(); - b.Type().End() - .Code() - .Function() - .Nop() - .Nop() - .End() - .Function() - .Return() - .End(); - const j = JSON.parse(b.json()); - assert.eq(j.section[1].data.length, 2); - assert.eq(j.section[1].data[0].locals.length, 0); - assert.eq(j.section[1].data[0].code.length, 3); - assert.eq(j.section[1].data[0].code[0].name, "nop"); - assert.eq(j.section[1].data[0].code[1].name, "nop"); - assert.eq(j.section[1].data[0].code[2].name, "end"); - assert.eq(j.section[1].data[1].locals.length, 0); - assert.eq(j.section[1].data[1].code.length, 2); - assert.eq(j.section[1].data[1].code[0].name, "return"); - assert.eq(j.section[1].data[1].code[1].name, "end"); -})(); - -(function NamedFunctions() { - const b = new Builder().Type().End().Code() - .Function("hello").End() - .Function("world", { params: ["i32"] }).End() - .End(); - const j = JSON.parse(b.json()); - assert.eq(j.section[1].data[0].name, "hello"); - assert.eq(j.section[1].data[0].parameterCount, 0); - assert.eq(j.section[1].data[1].name, "world"); - assert.eq(j.section[1].data[1].parameterCount, 1); -})(); - -(function ExportSimpleFunctions() { - const b = (new Builder()) - .Type().End() - .Export() - .Function("foo", 0, { params: [] }) - .Function("bar") - .Function("betterNameForBar", "bar") - .End() - .Code() - .Function({ params: [] }).Nop().End() - .Function("bar", { params: [] }).Nop().End() - .End(); - const j = JSON.parse(b.json()); - assert.eq(j.section[0].data.length, 1); - assert.eq(j.section[0].data[0].ret, "void"); - assert.eq(j.section[0].data[0].params, []); - assert.eq(j.section[1].data.length, 3); - assert.eq(j.section[1].data[0].field, "foo"); - assert.eq(j.section[1].data[0].type, 0); - assert.eq(j.section[1].data[0].index, 0); - assert.eq(j.section[1].data[0].kind, "Function"); - assert.eq(j.section[1].data[1].field, "bar"); - assert.eq(j.section[1].data[1].type, 0); - assert.eq(j.section[1].data[1].index, 1); - assert.eq(j.section[1].data[1].kind, "Function"); - assert.eq(j.section[1].data[2].field, "betterNameForBar"); - assert.eq(j.section[1].data[2].type, 0); - assert.eq(j.section[1].data[2].index, 1); - assert.eq(j.section[1].data[2].kind, "Function"); -})(); - -(function ExportUndefinedFunction() { - const c = (new Builder()).Type().End().Export().Function("foo").End().Code(); - assert.throws(() => c.End(), Error, `Should be number, got undefined: Export section contains undefined function "foo"`); -})(); - -(function TwoBuildersAtTheSameTime() { - const b = [new Builder(), new Builder()]; - const f = b.map(builder => builder.Type().End().Code().Function()); - f[0].Nop(); - f[1].Return().End().End(); - f[0].Nop().End().End(); - const j = b.map(builder => JSON.parse(builder.json())); - assert.eq(j[0].section[1].data[0].code.length, 3); - assert.eq(j[0].section[1].data[0].code[0].name, "nop"); - assert.eq(j[0].section[1].data[0].code[1].name, "nop"); - assert.eq(j[0].section[1].data[0].code[2].name, "end"); - assert.eq(j[1].section[1].data[0].code.length, 2); - assert.eq(j[1].section[1].data[0].code[0].name, "return"); - assert.eq(j[1].section[1].data[0].code[1].name, "end"); -})(); - -(function CheckedOpcodeArgumentsTooMany() { - assertOpThrows(f => f.Nop("uh-oh!"), `Not the same: "1" and "0": "nop" expects exactly 0 immediates, got 1`); -})(); - -(function UncheckedOpcodeArgumentsTooMany() { - (new Builder()).setChecked(false).Type().End().Code().Function().Nop("This is fine.", "I'm OK with the events that are unfolding currently."); -})(); - -(function CheckedOpcodeArgumentsNotEnough() { - assertOpThrows(f => f.I32Const(), `Not the same: "0" and "1": "i32.const" expects exactly 1 immediate, got 0`); -})(); - -(function UncheckedOpcodeArgumentsNotEnough() { - (new Builder()).setChecked(false).Type().End().Code().Function().I32Const(); -})(); - -(function CallNoArguments() { - const b = (new Builder()).Type().End().Code().Function().Call(0).End().End(); - const j = JSON.parse(b.json()); - assert.eq(j.section[1].data[0].code.length, 2); - assert.eq(j.section[1].data[0].code[0].name, "call"); - assert.eq(j.section[1].data[0].code[0].arguments.length, 0); - assert.eq(j.section[1].data[0].code[0].immediates.length, 1); - assert.eq(j.section[1].data[0].code[0].immediates[0], 0); - assert.eq(j.section[1].data[0].code[1].name, "end"); -})(); - -(function CallInvalid() { - for (let c of [-1, 0x100000000, "0", {}, Infinity, -Infinity, NaN, -NaN, null]) - assertOpThrows(f => f.Call(c), `Expected truthy: Invalid value on call: got "${c}", expected non-negative i32`); -})(); - -(function I32ConstValid() { - for (let c of [-100, -1, 0, 1, 2, 42, 1337, 0xFF, 0xFFFF, 0x7FFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF]) { - const b = (new Builder()).Type().End().Code().Function().I32Const(c).Return().End().End(); - const j = JSON.parse(b.json()); - assert.eq(j.section[1].data[0].code[0].name, "i32.const"); - assert.eq(j.section[1].data[0].code[0].arguments.length, 0); - assert.eq(j.section[1].data[0].code[0].immediates.length, 1); - assert.eq(j.section[1].data[0].code[0].immediates[0], c); - } -})(); - -(function I32ConstInvalid() { - for (let c of [0x100000000, 0.1, -0.1, "0", {}, Infinity, null]) - assertOpThrows(f => f.I32Const(c), `Expected truthy: Invalid value on i32.const: got "${c}", expected i32`); -})(); - -// FIXME: test i64. https://bugs.webkit.org/show_bug.cgi?id=163420 - -(function F32ConstValid() { - for (let c of [0, -0., 0.2, Math.PI, 0x100000000]) { - const b = (new Builder()).Type().End().Code().Function().F32Const(c).Return().End().End(); - const j = JSON.parse(b.json()); - assert.eq(j.section[1].data[0].code[0].name, "f32.const"); - assert.eq(j.section[1].data[0].code[0].arguments.length, 0); - assert.eq(j.section[1].data[0].code[0].immediates.length, 1); - assert.eq(j.section[1].data[0].code[0].immediates[0] === "NEGATIVE_ZERO" ? -0.0 : j.section[1].data[0].code[0].immediates[0], c); - } -})(); - -(function F32ConstInvalid() { - for (let c of ["0", {}, Infinity, -Infinity, NaN, -NaN, null]) - assertOpThrows(f => f.F32Const(c), `Expected truthy: Invalid value on f32.const: got "${c}", expected f32`); -})(); - -(function F64ConstValid() { - for (let c of [0, -0., 0.2, Math.PI, 0x100000000]) { - const b = (new Builder()).Type().End().Code().Function().F64Const(c).Return().End().End(); - const j = JSON.parse(b.json()); - assert.eq(j.section[1].data[0].code[0].name, "f64.const"); - assert.eq(j.section[1].data[0].code[0].arguments.length, 0); - assert.eq(j.section[1].data[0].code[0].immediates.length, 1); - assert.eq(j.section[1].data[0].code[0].immediates[0] === "NEGATIVE_ZERO" ? -0.0 : j.section[1].data[0].code[0].immediates[0], c); - } -})(); - -(function F64ConstInvalid() { - for (let c of ["0", {}, Infinity, -Infinity, NaN, -NaN, null]) - assertOpThrows(f => f.F64Const(c), `Expected truthy: Invalid value on f64.const: got "${c}", expected f64`); -})(); - -(function CallOneFromStack() { - const b = (new Builder()).Type().End().Code() - .Function({ params: ["i32"] }) - .I32Const(42) - .Call(0) - .End() - .End(); - const j = JSON.parse(b.json()); - assert.eq(j.section[1].data[0].code.length, 3); - assert.eq(j.section[1].data[0].code[0].name, "i32.const"); - assert.eq(j.section[1].data[0].code[0].immediates[0], 42); - assert.eq(j.section[1].data[0].code[1].name, "call"); - // FIXME: assert.eq(j.section[1].data[0].code[1].arguments.length, 1); https://bugs.webkit.org/show_bug.cgi?id=163267 - assert.eq(j.section[1].data[0].code[1].immediates.length, 1); - assert.eq(j.section[1].data[0].code[1].immediates[0], 0); - assert.eq(j.section[1].data[0].code[2].name, "end"); -})(); - -// FIXME https://bugs.webkit.org/show_bug.cgi?id=163267 all of these: -// test too many pops. -// test not enough pops (function has non-empty stack at the end). -// test mismatched pop types. -// test mismatched function signature (calling with wrong arg types). -// test invalid function index. -// test function names (both setting and calling them). - -(function CallManyFromStack() { - const b = (new Builder()).Type().End().Code() - .Function({ params: ["i32", "i32", "i32", "i32"] }) - .I32Const(42).I32Const(1337).I32Const(0xBEEF).I32Const(0xFFFF) - .Call(0) - .End() - .End(); - const j = JSON.parse(b.json()); - assert.eq(j.section[1].data[0].code.length, 6); - assert.eq(j.section[1].data[0].code[4].name, "call"); - // FIXME: assert.eq(j.section[1].data[0].code[4].arguments.length, 4); https://bugs.webkit.org/show_bug.cgi?id=163267 - assert.eq(j.section[1].data[0].code[4].immediates.length, 1); - assert.eq(j.section[1].data[0].code[4].immediates[0], 0); -})(); - -(function OpcodeAdd() { - const b = (new Builder()).Type().End().Code() - .Function() - .I32Const(42).I32Const(1337) - .I32Add() - .Return() - .End() - .End(); - const j = JSON.parse(b.json()); - assert.eq(j.section[1].data[0].code.length, 5); - assert.eq(j.section[1].data[0].code[2].name, "i32.add"); - // FIXME: assert.eq(j.section[1].data[0].code[2].arguments.length, 2); https://bugs.webkit.org/show_bug.cgi?id=163267 - assert.eq(j.section[1].data[0].code[3].name, "return"); - // FIXME check return. https://bugs.webkit.org/show_bug.cgi?id=163267 -})(); - -(function OpcodeUnreachable() { - const b = (new Builder()).Type().End().Code().Function().Unreachable().End().End(); - const j = JSON.parse(b.json()); - assert.eq(j.section[1].data[0].code.length, 2); - assert.eq(j.section[1].data[0].code[0].name, "unreachable"); -})(); - -(function OpcodeUnreachableCombinations() { - (new Builder()).Type().End().Code().Function().Nop().Unreachable().End().End().json(); - (new Builder()).Type().End().Code().Function().Unreachable().Nop().End().End().json(); - (new Builder()).Type().End().Code().Function().Return().Unreachable().End().End().json(); - (new Builder()).Type().End().Code().Function().Unreachable().Return().End().End().json(); - (new Builder()).Type().End().Code().Function().Call(0).Unreachable().End().End().json(); - (new Builder()).Type().End().Code().Function().Unreachable().Call(0).End().End().json(); -})(); - -(function OpcodeSelect() { - const b = (new Builder()).Type().End().Code().Function() - .I32Const(1).I32Const(2).I32Const(0) - .Select() - .Return() - .End() - .End(); - const j = JSON.parse(b.json()); - assert.eq(j.section[1].data[0].code.length, 6); - assert.eq(j.section[1].data[0].code[3].name, "select"); -})(); -// FIXME test type mismatch with select. https://bugs.webkit.org/show_bug.cgi?id=163267 - -(function MemoryImport() { - const builder = (new Builder()) - .Type().End() - .Import() - .Memory("__module__", "__field__", {initial: 30, maximum: 31}) - .End() - .Code().End(); - - const json = JSON.parse(builder.json()); - assert.eq(json.section.length, 3); - assert.eq(json.section[1].name, "Import"); - assert.eq(json.section[1].data.length, 1); - assert.eq(json.section[1].data[0].module, "__module__"); - assert.eq(json.section[1].data[0].field, "__field__"); - assert.eq(json.section[1].data[0].kind, "Memory"); - assert.eq(json.section[1].data[0].memoryDescription.initial, 30); - assert.eq(json.section[1].data[0].memoryDescription.maximum, 31); -})(); - -(function DataSection() { - const builder = (new Builder()) - .Memory().InitialMaxPages(64, 64).End() - .Data() - .Segment([0xff, 0x2a]).Offset(4).End() - .Segment([0xde, 0xad, 0xbe, 0xef]).Index(0).Offset(24).End() - .End(); - const json = JSON.parse(builder.json()); - assert.eq(json.section.length, 2); - assert.eq(json.section[1].name, "Data"); - assert.eq(json.section[1].data.length, 2); - assert.eq(json.section[1].data[0].index, 0); - assert.eq(json.section[1].data[0].offset, 4); - assert.eq(json.section[1].data[0].data.length, 2); - assert.eq(json.section[1].data[0].data[0], 0xff); - assert.eq(json.section[1].data[0].data[1], 0x2a); - assert.eq(json.section[1].data[1].index, 0); - assert.eq(json.section[1].data[1].offset, 24); - assert.eq(json.section[1].data[1].data.length, 4); - assert.eq(json.section[1].data[1].data[0], 0xde); - assert.eq(json.section[1].data[1].data[1], 0xad); - assert.eq(json.section[1].data[1].data[2], 0xbe); - assert.eq(json.section[1].data[1].data[3], 0xef); -})(); diff --git a/implementation-contributed/javascriptcore/wasm/self-test/test_BuilderWebAssembly.js b/implementation-contributed/javascriptcore/wasm/self-test/test_BuilderWebAssembly.js deleted file mode 100644 index 9d6dc1baf266e80ba230e4a788c8219d04216df8..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/self-test/test_BuilderWebAssembly.js +++ /dev/null @@ -1,31 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -(function EmptyModule() { - const builder = new Builder(); - const bin = builder.WebAssembly(); - assert.eq(bin.hexdump().trim(), - "00000000 00 61 73 6d 01 00 00 00 |·asm···· |"); -})(); - -(function EmptyModule() { - const bin = (new Builder()) - .setPreamble({ "magic number": 0x45464F43, version: 0xFFFFFFFF }) - .WebAssembly(); - assert.eq(bin.hexdump().trim(), - "00000000 43 4f 46 45 ff ff ff ff |COFE···· |"); -})(); - -(function CustomSection() { - const bin = (new Builder()) - .Unknown("OHHAI") - .Byte(0xDE) - .Byte(0xAD) - .Byte(0xC0) - .Byte(0xFE) - .End() - .WebAssembly(); - assert.eq(bin.hexdump().trim(), - ["00000000 00 61 73 6d 01 00 00 00 00 0a 05 4f 48 48 41 49 |·asm·······OHHAI|", - "00000010 de ad c0 fe |···· |"].join("\n")); -})(); diff --git a/implementation-contributed/javascriptcore/wasm/spec-harness/index.js b/implementation-contributed/javascriptcore/wasm/spec-harness/index.js deleted file mode 100644 index bc298d200a07b1d569708adf80e04b3ab96a14cc..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/spec-harness/index.js +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright 2017 WebAssembly Community Group participants - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ - -'use strict'; - -let testNum = (function() { - let count = 1; - return function() { - return `#${count++} `; - } -})(); - -// WPT's assert_throw uses a list of predefined, hardcoded known errors. Since -// it is not aware of the WebAssembly error types (yet), implement our own -// version. -function assertThrows(func, err) { - let caught = false; - try { - func(); - } catch(e) { - assert_true(e instanceof err, `expected ${err.name}, observed ${e.constructor.name}`); - caught = true; - } - assert_true(caught, testNum() + "assertThrows must catch any error.") -} - -/****************************************************************************** -***************************** WAST HARNESS ************************************ -******************************************************************************/ - -// For assertions internal to our test harness. -function _assert(x) { - if (!x) { - throw new Error(`Assertion failure: ${x}`); - } -} - -// A simple sum type that can either be a valid Value or an Error. -function Result(type, maybeValue) { - this.value = maybeValue; - this.type = type; -}; - -Result.VALUE = 'VALUE'; -Result.ERROR = 'ERROR'; - -function ValueResult(val) { return new Result(Result.VALUE, val); } -function ErrorResult(err) { return new Result(Result.ERROR, err); } - -Result.prototype.isError = function() { return this.type === Result.ERROR; } - -const EXPECT_INVALID = false; - -/* DATA **********************************************************************/ - -let soft_validate = true; - -let $$; - -// Default imports. -var registry = {}; - -// Resets the registry between two different WPT tests. -function reinitializeRegistry() { - if (typeof WebAssembly === 'undefined') - return; - - registry = { - spectest: { - print: print, - global: 666, - table: new WebAssembly.Table({initial: 10, maximum: 20, element: 'anyfunc'}), - memory: new WebAssembly.Memory({initial: 1, maximum: 2}) - } - }; -} - -reinitializeRegistry(); - -/* WAST POLYFILL *************************************************************/ - -function binary(bytes) { - let buffer = new ArrayBuffer(bytes.length); - let view = new Uint8Array(buffer); - for (let i = 0; i < bytes.length; ++i) { - view[i] = bytes.charCodeAt(i); - } - return buffer; -} - -/** - * Returns a compiled module, or throws if there was an error at compilation. - */ -function module(bytes, valid = true) { - let buffer = binary(bytes); - let validated; - - try { - validated = WebAssembly.validate(buffer); - } catch (e) { - throw new Error(`WebAssembly.validate throws ${typeof e}: ${e}${e.stack}`); - } - - if (validated !== valid) { - // Try to get a more precise error message from the WebAssembly.CompileError. - let err = ''; - try { - new WebAssembly.Module(buffer); - } catch (e) { - if (e instanceof WebAssembly.CompileError) - throw new WebAssembly.CompileError(`WebAssembly.validate error: ${e.toString()}${e.stack}\n`); - else - throw new Error(`WebAssembly.validate throws ${typeof e}: ${e}${e.stack}`); - } - throw new Error(`WebAssembly.validate was expected to fail, but didn't`); - } - - let module; - try { - module = new WebAssembly.Module(buffer); - } catch(e) { - if (valid) - throw new Error('WebAssembly.Module ctor unexpectedly throws ${typeof e}: ${e}${e.stack}'); - throw e; - } - - return module; -} - -function uniqueTest(func, desc) { - test(func, testNum() + desc); -} - -function assert_invalid(bytes) { - uniqueTest(() => { - try { - module(bytes, /* valid */ false); - throw new Error('did not fail'); - } catch(e) { - assert_true(e instanceof WebAssembly.CompileError, "expected invalid failure:"); - } - }, "A wast module that should be invalid or malformed."); -} - -const assert_malformed = assert_invalid; - -function assert_soft_invalid(bytes) { - uniqueTest(() => { - try { - module(bytes, /* valid */ soft_validate); - if (soft_validate) - throw new Error('did not fail'); - } catch(e) { - if (soft_validate) - assert_true(e instanceof WebAssembly.CompileError, "expected soft invalid failure:"); - } - }, "A wast module that *could* be invalid under certain engines."); -} - -function instance(bytes, imports = registry, valid = true) { - if (imports instanceof Result) { - if (imports.isError()) - return imports; - imports = imports.value; - } - - let err = null; - - let m, i; - try { - let m = module(bytes); - i = new WebAssembly.Instance(m, imports); - } catch(e) { - err = e; - } - - if (valid) { - uniqueTest(() => { - let instantiated = err === null; - assert_true(instantiated, err); - }, "module successfully instantiated"); - } - - return err !== null ? ErrorResult(err) : ValueResult(i); -} - -function register(name, instance) { - _assert(instance instanceof Result); - - if (instance.isError()) - return; - - registry[name] = instance.value.exports; -} - -function call(instance, name, args) { - _assert(instance instanceof Result); - - if (instance.isError()) - return instance; - - let err = null; - let result; - try { - result = instance.value.exports[name](...args); - } catch(e) { - err = e; - } - - return err !== null ? ErrorResult(err) : ValueResult(result); -}; - -function get(instance, name) { - _assert(instance instanceof Result); - - if (instance.isError()) - return instance; - - return ValueResult(instance.value.exports[name]); -} - -function exports(name, instance) { - _assert(instance instanceof Result); - - if (instance.isError()) - return instance; - - return ValueResult({ [name]: instance.value.exports }); -} - -function run(action) { - let result = action(); - - _assert(result instanceof Result); - - uniqueTest(() => { - if (result.isError()) - throw result.value; - }, "A wast test that runs without any special assertion."); -} - -function assert_unlinkable(bytes) { - let result = instance(bytes, registry, EXPECT_INVALID); - - _assert(result instanceof Result); - - uniqueTest(() => { - assert_true(result.isError(), 'expected error result'); - if (result.isError()) { - let e = result.value; - assert_true(e instanceof WebAssembly.LinkError, `expected link error, observed ${e}:`); - } - }, "A wast module that is unlinkable."); -} - -function assert_uninstantiable(bytes) { - let result = instance(bytes, registry, EXPECT_INVALID); - - _assert(result instanceof Result); - - uniqueTest(() => { - assert_true(result.isError(), 'expected error result'); - if (result.isError()) { - let e = result.value; - assert_true(e instanceof WebAssembly.RuntimeError, `expected runtime error, observed ${e}:`); - } - }, "A wast module that is uninstantiable."); -} - -function assert_trap(action) { - let result = action(); - - _assert(result instanceof Result); - - uniqueTest(() => { - assert_true(result.isError(), 'expected error result'); - if (result.isError()) { - let e = result.value; - assert_true(e instanceof WebAssembly.RuntimeError, `expected runtime error, observed ${e}:`); - } - }, "A wast module that must trap at runtime."); -} - -let StackOverflow; -try { (function f() { 1 + f() })() } catch (e) { StackOverflow = e.constructor } - -function assert_exhaustion(action) { - let result = action(); - - _assert(result instanceof Result); - - uniqueTest(() => { - assert_true(result.isError(), 'expected error result'); - if (result.isError()) { - let e = result.value; - assert_true(e instanceof StackOverflow, `expected stack overflow error, observed ${e}:`); - } - }, "A wast module that must exhaust the stack space."); -} - -function assert_return(action, expected) { - if (expected instanceof Result) { - if (expected.isError()) - return; - expected = expected.value; - } - - let result = action(); - - _assert(result instanceof Result); - - uniqueTest(() => { - assert_true(!result.isError(), `expected success result, got: ${result.value}.`); - if (!result.isError()) { - assert_equals(result.value, expected); - }; - }, "A wast module that must return a particular value."); -}; - -function assert_return_nan(action) { - let result = action(); - - _assert(result instanceof Result); - - uniqueTest(() => { - assert_true(!result.isError(), 'expected success result'); - if (!result.isError()) { - assert_true(Number.isNaN(result.value), `expected NaN, observed ${result.value}.`); - }; - }, "A wast module that must return NaN."); -} diff --git a/implementation-contributed/javascriptcore/wasm/spec-harness/wasm-module-builder.js b/implementation-contributed/javascriptcore/wasm/spec-harness/wasm-module-builder.js deleted file mode 100644 index 68fab8985c76ed12f9455254d6536cc4ce669335..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/spec-harness/wasm-module-builder.js +++ /dev/null @@ -1,583 +0,0 @@ -// Copyright 2016 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Used for encoding f32 and double constants to bits. -let __buffer = new ArrayBuffer(8); -let byte_view = new Int8Array(__buffer); -let f32_view = new Float32Array(__buffer); -let f64_view = new Float64Array(__buffer); - -class Binary extends Array { - emit_u8(val) { - this.push(val); - } - - emit_u16(val) { - this.push(val & 0xff); - this.push((val >> 8) & 0xff); - } - - emit_u32(val) { - this.push(val & 0xff); - this.push((val >> 8) & 0xff); - this.push((val >> 16) & 0xff); - this.push((val >> 24) & 0xff); - } - - emit_u32v(val) { - while (true) { - let v = val & 0xff; - val = val >>> 7; - if (val == 0) { - this.push(v); - break; - } - this.push(v | 0x80); - } - } - - emit_bytes(data) { - for (let i = 0; i < data.length; i++) { - this.push(data[i] & 0xff); - } - } - - emit_string(string) { - // When testing illegal names, we pass a byte array directly. - if (string instanceof Array) { - this.emit_u32v(string.length); - this.emit_bytes(string); - return; - } - - // This is the hacky way to convert a JavaScript string to a UTF8 encoded - // string only containing single-byte characters. - let string_utf8 = unescape(encodeURIComponent(string)); - this.emit_u32v(string_utf8.length); - for (let i = 0; i < string_utf8.length; i++) { - this.emit_u8(string_utf8.charCodeAt(i)); - } - } - - emit_header() { - this.push(kWasmH0, kWasmH1, kWasmH2, kWasmH3, - kWasmV0, kWasmV1, kWasmV2, kWasmV3); - } - - emit_section(section_code, content_generator) { - // Emit section name. - this.emit_u8(section_code); - // Emit the section to a temporary buffer: its full length isn't know yet. - let section = new Binary; - content_generator(section); - // Emit section length. - this.emit_u32v(section.length); - // Copy the temporary buffer. - for (const sectionByte of section) { - this.push(sectionByte); - } - } -} - -class WasmFunctionBuilder { - constructor(module, name, type_index) { - this.module = module; - this.name = name; - this.type_index = type_index; - this.body = []; - } - - exportAs(name) { - this.module.addExport(name, this.index); - return this; - } - - exportFunc() { - this.exportAs(this.name); - return this; - } - - addBody(body) { - for (let b of body) { - if (typeof b != 'number') - throw new Error('invalid body (entries have to be numbers): ' + body); - } - this.body = body.slice(); - // Automatically add the end for the function block to the body. - this.body.push(kExprEnd); - return this; - } - - addLocals(locals) { - this.locals = locals; - return this; - } - - end() { - this.body.push(kExprEnd); - return this.module; - } -} - -class WasmGlobalBuilder { - constructor(module, type, mutable) { - this.module = module; - this.type = type; - this.mutable = mutable; - this.init = 0; - } - - exportAs(name) { - this.module.exports.push({name: name, kind: kExternalGlobal, - index: this.index}); - return this; - } -} - -class WasmModuleBuilder { - constructor() { - this.types = []; - this.imports = []; - this.exports = []; - this.globals = []; - this.functions = []; - this.function_table = []; - this.function_table_length = 0; - this.function_table_inits = []; - this.segments = []; - this.explicit = []; - this.num_imported_funcs = 0; - this.num_imported_globals = 0; - return this; - } - - addStart(start_index) { - this.start_index = start_index; - return this; - } - - addMemory(min, max, exp) { - this.memory = {min: min, max: max, exp: exp}; - return this; - } - - addExplicitSection(bytes) { - this.explicit.push(bytes); - return this; - } - - stringToBytes(name) { - var result = new Binary(); - result.emit_u32v(name.length); - for (var i = 0; i < name.length; i++) { - result.emit_u8(name.charCodeAt(i)); - } - return result; - } - - addCustomSection(name, bytes) { - name = this.stringToBytes(name); - var length = new Binary(); - length.emit_u32v(name.length + bytes.length); - this.explicit.push([0, ...length, ...name, ...bytes]); - } - - addType(type) { - // TODO: canonicalize types? - this.types.push(type); - return this.types.length - 1; - } - - addGlobal(local_type, mutable) { - let glob = new WasmGlobalBuilder(this, local_type, mutable); - glob.index = this.globals.length + this.num_imported_globals; - this.globals.push(glob); - return glob; - } - - addFunction(name, type) { - let type_index = (typeof type) == "number" ? type : this.addType(type); - let func = new WasmFunctionBuilder(this, name, type_index); - func.index = this.functions.length + this.num_imported_funcs; - this.functions.push(func); - return func; - } - - addImport(module = "", name, type) { - let type_index = (typeof type) == "number" ? type : this.addType(type); - this.imports.push({module: module, name: name, kind: kExternalFunction, - type: type_index}); - return this.num_imported_funcs++; - } - - addImportedGlobal(module = "", name, type) { - let o = {module: module, name: name, kind: kExternalGlobal, type: type, - mutable: false} - this.imports.push(o); - return this.num_imported_globals++; - } - - addImportedMemory(module = "", name, initial = 0, maximum) { - let o = {module: module, name: name, kind: kExternalMemory, - initial: initial, maximum: maximum}; - this.imports.push(o); - return this; - } - - addImportedTable(module = "", name, initial, maximum) { - let o = {module: module, name: name, kind: kExternalTable, initial: initial, - maximum: maximum}; - this.imports.push(o); - } - - addExport(name, index) { - this.exports.push({name: name, kind: kExternalFunction, index: index}); - return this; - } - - addExportOfKind(name, kind, index) { - this.exports.push({name: name, kind: kind, index: index}); - return this; - } - - addDataSegment(addr, data, is_global = false) { - this.segments.push({addr: addr, data: data, is_global: is_global}); - return this.segments.length - 1; - } - - exportMemoryAs(name) { - this.exports.push({name: name, kind: kExternalMemory, index: 0}); - } - - addFunctionTableInit(base, is_global, array, is_import = false) { - this.function_table_inits.push({base: base, is_global: is_global, - array: array}); - if (!is_global) { - var length = base + array.length; - if (length > this.function_table_length && !is_import) { - this.function_table_length = length; - } - } - return this; - } - - appendToTable(array) { - for (let n of array) { - if (typeof n != 'number') - throw new Error('invalid table (entries have to be numbers): ' + array); - } - return this.addFunctionTableInit(this.function_table.length, false, array); - } - - setFunctionTableLength(length) { - this.function_table_length = length; - return this; - } - - toArray(debug = false) { - let binary = new Binary; - let wasm = this; - - // Add header - binary.emit_header(); - - // Add type section - if (wasm.types.length > 0) { - if (debug) print("emitting types @ " + binary.length); - binary.emit_section(kTypeSectionCode, section => { - section.emit_u32v(wasm.types.length); - for (let type of wasm.types) { - section.emit_u8(kWasmFunctionTypeForm); - section.emit_u32v(type.params.length); - for (let param of type.params) { - section.emit_u8(param); - } - section.emit_u32v(type.results.length); - for (let result of type.results) { - section.emit_u8(result); - } - } - }); - } - - // Add imports section - if (wasm.imports.length > 0) { - if (debug) print("emitting imports @ " + binary.length); - binary.emit_section(kImportSectionCode, section => { - section.emit_u32v(wasm.imports.length); - for (let imp of wasm.imports) { - section.emit_string(imp.module); - section.emit_string(imp.name || ''); - section.emit_u8(imp.kind); - if (imp.kind == kExternalFunction) { - section.emit_u32v(imp.type); - } else if (imp.kind == kExternalGlobal) { - section.emit_u32v(imp.type); - section.emit_u8(imp.mutable); - } else if (imp.kind == kExternalMemory) { - var has_max = (typeof imp.maximum) != "undefined"; - section.emit_u8(has_max ? 1 : 0); // flags - section.emit_u32v(imp.initial); // initial - if (has_max) section.emit_u32v(imp.maximum); // maximum - } else if (imp.kind == kExternalTable) { - section.emit_u8(kWasmAnyFunctionTypeForm); - var has_max = (typeof imp.maximum) != "undefined"; - section.emit_u8(has_max ? 1 : 0); // flags - section.emit_u32v(imp.initial); // initial - if (has_max) section.emit_u32v(imp.maximum); // maximum - } else { - throw new Error("unknown/unsupported import kind " + imp.kind); - } - } - }); - } - - // Add functions declarations - let num_function_names = 0; - let names = false; - if (wasm.functions.length > 0) { - if (debug) print("emitting function decls @ " + binary.length); - binary.emit_section(kFunctionSectionCode, section => { - section.emit_u32v(wasm.functions.length); - for (let func of wasm.functions) { - if (func.name !== undefined) { - ++num_function_names; - } - section.emit_u32v(func.type_index); - } - }); - } - - // Add function_table. - if (wasm.function_table_length > 0) { - if (debug) print("emitting table @ " + binary.length); - binary.emit_section(kTableSectionCode, section => { - section.emit_u8(1); // one table entry - section.emit_u8(kWasmAnyFunctionTypeForm); - section.emit_u8(1); - section.emit_u32v(wasm.function_table_length); - section.emit_u32v(wasm.function_table_length); - }); - } - - // Add memory section - if (wasm.memory !== undefined) { - if (debug) print("emitting memory @ " + binary.length); - binary.emit_section(kMemorySectionCode, section => { - section.emit_u8(1); // one memory entry - const has_max = wasm.memory.max !== undefined; - section.emit_u32v(has_max ? kResizableMaximumFlag : 0); - section.emit_u32v(wasm.memory.min); - if (has_max) section.emit_u32v(wasm.memory.max); - }); - } - - // Add global section. - if (wasm.globals.length > 0) { - if (debug) print ("emitting globals @ " + binary.length); - binary.emit_section(kGlobalSectionCode, section => { - section.emit_u32v(wasm.globals.length); - for (let global of wasm.globals) { - section.emit_u8(global.type); - section.emit_u8(global.mutable); - if ((typeof global.init_index) == "undefined") { - // Emit a constant initializer. - switch (global.type) { - case kWasmI32: - section.emit_u8(kExprI32Const); - section.emit_u32v(global.init); - break; - case kWasmI64: - section.emit_u8(kExprI64Const); - section.emit_u32v(global.init); - break; - case kWasmF32: - section.emit_u8(kExprF32Const); - f32_view[0] = global.init; - section.emit_u8(byte_view[0]); - section.emit_u8(byte_view[1]); - section.emit_u8(byte_view[2]); - section.emit_u8(byte_view[3]); - break; - case kWasmF64: - section.emit_u8(kExprF64Const); - f64_view[0] = global.init; - section.emit_u8(byte_view[0]); - section.emit_u8(byte_view[1]); - section.emit_u8(byte_view[2]); - section.emit_u8(byte_view[3]); - section.emit_u8(byte_view[4]); - section.emit_u8(byte_view[5]); - section.emit_u8(byte_view[6]); - section.emit_u8(byte_view[7]); - break; - } - } else { - // Emit a global-index initializer. - section.emit_u8(kExprGetGlobal); - section.emit_u32v(global.init_index); - } - section.emit_u8(kExprEnd); // end of init expression - } - }); - } - - // Add export table. - var mem_export = (wasm.memory !== undefined && wasm.memory.exp); - var exports_count = wasm.exports.length + (mem_export ? 1 : 0); - if (exports_count > 0) { - if (debug) print("emitting exports @ " + binary.length); - binary.emit_section(kExportSectionCode, section => { - section.emit_u32v(exports_count); - for (let exp of wasm.exports) { - section.emit_string(exp.name); - section.emit_u8(exp.kind); - section.emit_u32v(exp.index); - } - if (mem_export) { - section.emit_string("memory"); - section.emit_u8(kExternalMemory); - section.emit_u8(0); - } - }); - } - - // Add start function section. - if (wasm.start_index !== undefined) { - if (debug) print("emitting start function @ " + binary.length); - binary.emit_section(kStartSectionCode, section => { - section.emit_u32v(wasm.start_index); - }); - } - - // Add table elements. - if (wasm.function_table_inits.length > 0) { - if (debug) print("emitting table @ " + binary.length); - binary.emit_section(kElementSectionCode, section => { - var inits = wasm.function_table_inits; - section.emit_u32v(inits.length); - - for (let init of inits) { - section.emit_u8(0); // table index - if (init.is_global) { - section.emit_u8(kExprGetGlobal); - } else { - section.emit_u8(kExprI32Const); - } - section.emit_u32v(init.base); - section.emit_u8(kExprEnd); - section.emit_u32v(init.array.length); - for (let index of init.array) { - section.emit_u32v(index); - } - } - }); - } - - // Add function bodies. - if (wasm.functions.length > 0) { - // emit function bodies - if (debug) print("emitting code @ " + binary.length); - binary.emit_section(kCodeSectionCode, section => { - section.emit_u32v(wasm.functions.length); - for (let func of wasm.functions) { - // Function body length will be patched later. - let local_decls = []; - let l = func.locals; - if (l !== undefined) { - let local_decls_count = 0; - if (l.i32_count > 0) { - local_decls.push({count: l.i32_count, type: kWasmI32}); - } - if (l.i64_count > 0) { - local_decls.push({count: l.i64_count, type: kWasmI64}); - } - if (l.f32_count > 0) { - local_decls.push({count: l.f32_count, type: kWasmF32}); - } - if (l.f64_count > 0) { - local_decls.push({count: l.f64_count, type: kWasmF64}); - } - } - - let header = new Binary; - header.emit_u32v(local_decls.length); - for (let decl of local_decls) { - header.emit_u32v(decl.count); - header.emit_u8(decl.type); - } - - section.emit_u32v(header.length + func.body.length); - section.emit_bytes(header); - section.emit_bytes(func.body); - } - }); - } - - // Add data segments. - if (wasm.segments.length > 0) { - if (debug) print("emitting data segments @ " + binary.length); - binary.emit_section(kDataSectionCode, section => { - section.emit_u32v(wasm.segments.length); - for (let seg of wasm.segments) { - section.emit_u8(0); // linear memory index 0 - if (seg.is_global) { - // initializer is a global variable - section.emit_u8(kExprGetGlobal); - section.emit_u32v(seg.addr); - } else { - // initializer is a constant - section.emit_u8(kExprI32Const); - section.emit_u32v(seg.addr); - } - section.emit_u8(kExprEnd); - section.emit_u32v(seg.data.length); - section.emit_bytes(seg.data); - } - }); - } - - // Add any explicitly added sections - for (let exp of wasm.explicit) { - if (debug) print("emitting explicit @ " + binary.length); - binary.emit_bytes(exp); - } - - // Add function names. - if (num_function_names > 0) { - if (debug) print('emitting names @ ' + binary.length); - binary.emit_section(kUnknownSectionCode, section => { - section.emit_string('name'); - section.emit_section(kFunctionNamesCode, name_section => { - name_section.emit_u32v(num_function_names); - for (let func of wasm.functions) { - if (func.name === undefined) continue; - name_section.emit_u32v(func.index); - name_section.emit_string(func.name); - } - }); - }); - } - - return binary; - } - - toBuffer(debug = false) { - let bytes = this.toArray(debug); - let buffer = new ArrayBuffer(bytes.length); - let view = new Uint8Array(buffer); - for (let i = 0; i < bytes.length; i++) { - let val = bytes[i]; - if ((typeof val) == "string") val = val.charCodeAt(0); - view[i] = val | 0; - } - return buffer; - } - - instantiate(ffi) { - let module = new WebAssembly.Module(this.toBuffer()); - let instance = new WebAssembly.Instance(module, ffi); - return instance; - } -} diff --git a/implementation-contributed/javascriptcore/wasm/spec-tests/jsapi.js b/implementation-contributed/javascriptcore/wasm/spec-tests/jsapi.js deleted file mode 100644 index 179e4fe975cdaae90852bd221ca7f7dcbd034fe6..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/spec-tests/jsapi.js +++ /dev/null @@ -1,792 +0,0 @@ -/* - * Copyright 2017 WebAssembly Community Group participants - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ - -(function testJSAPI() { - -const WasmPage = 64 * 1024; - -const emptyModuleBinary = new WasmModuleBuilder().toBuffer(); - -const importingModuleBinary = (() => { - let builder = new WasmModuleBuilder(); - - builder.addImport('', 'f', kSig_v_v); - - return builder.toBuffer(); -})(); - -const complexImportingModuleBinary = (() => { - let builder = new WasmModuleBuilder(); - - builder.addImport('a', 'b', kSig_v_v); - builder.addImportedMemory('c', 'd', 1); - builder.addImportedTable('e', 'f', 1); - builder.addImportedGlobal('g', 'âš¡', kWasmI32); - - return builder.toBuffer(); -})(); - -const exportingModuleBinary = (() => { - let builder = new WasmModuleBuilder(); - - builder - .addFunction('f', kSig_i_v) - .addBody([ - kExprI32Const, - 42 - ]) - .exportFunc(); - - return builder.toBuffer(); -})(); - -const complexExportingModuleBinary = (() => { - let builder = new WasmModuleBuilder(); - - builder - .addFunction('a', kSig_v_v) - .addBody([]) - .exportFunc(); - - builder.addMemory(1, 1, /* exported */ false); - builder.exportMemoryAs('b'); - - builder.setFunctionTableLength(1); - builder.addExportOfKind('c', kExternalTable, 0); - - // Default init for global values is 0. Keep that. - builder.addGlobal(kWasmI32, /* mutable */ false) - .exportAs("âš¡"); - - return builder.toBuffer(); -})(); - -const moduleBinaryImporting2Memories = (() => { - var builder = new WasmModuleBuilder(); - builder.addImportedMemory("", "memory1"); - builder.addImportedMemory("", "memory2"); - return builder.toBuffer(); -})(); - -const moduleBinaryWithMemSectionAndMemImport = (() => { - var builder = new WasmModuleBuilder(); - builder.addMemory(1, 1, false); - builder.addImportedMemory("", "memory1"); - return builder.toBuffer(); -})(); - -let Module; -let Instance; -let CompileError; -let LinkError; -let RuntimeError; -let Memory; -let instanceProto; -let memoryProto; -let mem1; -let Table; -let tbl1; -let tableProto; - -let emptyModule; -let exportingModule; -let exportingInstance; -let exportsObj; -let importingModule; - -// Start of tests. - -test(() => { - const wasmDesc = Object.getOwnPropertyDescriptor(this, 'WebAssembly'); - assert_equals(typeof wasmDesc.value, "object"); - assert_true(wasmDesc.writable); - assert_false(wasmDesc.enumerable); - assert_true(wasmDesc.configurable); -}, "'WebAssembly' data property on global object"); - -test(() => { - const wasmDesc = Object.getOwnPropertyDescriptor(this, 'WebAssembly'); - assert_equals(WebAssembly, wasmDesc.value); - assert_equals(String(WebAssembly), "[object WebAssembly]"); -}, "'WebAssembly' object"); - -test(() => { - const compileErrorDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'CompileError'); - const linkErrorDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'LinkError'); - const runtimeErrorDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'RuntimeError'); - assert_equals(typeof compileErrorDesc.value, "function"); - assert_equals(typeof linkErrorDesc.value, "function"); - assert_equals(typeof runtimeErrorDesc.value, "function"); - assert_equals(compileErrorDesc.writable, true); - assert_equals(linkErrorDesc.writable, true); - assert_equals(runtimeErrorDesc.writable, true); - assert_equals(compileErrorDesc.enumerable, false); - assert_equals(linkErrorDesc.enumerable, false); - assert_equals(runtimeErrorDesc.enumerable, false); - assert_equals(compileErrorDesc.configurable, true); - assert_equals(linkErrorDesc.configurable, true); - assert_equals(runtimeErrorDesc.configurable, true); - - CompileError = WebAssembly.CompileError; - LinkError = WebAssembly.LinkError; - RuntimeError = WebAssembly.RuntimeError; -}, "'WebAssembly.(Compile|Link|Runtime)Error' data property"); - -test(() => { - const compileErrorDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'CompileError'); - const linkErrorDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'LinkError'); - const runtimeErrorDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'RuntimeError'); - assert_equals(CompileError, compileErrorDesc.value); - assert_equals(LinkError, linkErrorDesc.value); - assert_equals(RuntimeError, runtimeErrorDesc.value); - assert_equals(CompileError.length, 1); - assert_equals(LinkError.length, 1); - assert_equals(RuntimeError.length, 1); - assert_equals(CompileError.name, "CompileError"); - assert_equals(LinkError.name, "LinkError"); - assert_equals(RuntimeError.name, "RuntimeError"); -}, "'WebAssembly.(Compile|Runtime)Error' constructor function"); - -test(() => { - const compileError = new CompileError; - const runtimeError = new RuntimeError; - assert_equals(compileError instanceof CompileError, true); - assert_equals(runtimeError instanceof RuntimeError, true); - assert_equals(compileError instanceof Error, true); - assert_equals(runtimeError instanceof Error, true); - assert_equals(compileError instanceof TypeError, false); - assert_equals(runtimeError instanceof TypeError, false); - assert_equals(compileError.message, ""); - assert_equals(runtimeError.message, ""); -// FIXME https://bugs.webkit.org/show_bug.cgi?id=173159 assert_equals(new CompileError("hi").message, "hi"); -// FIXME https://bugs.webkit.org/show_bug.cgi?id=173159 assert_equals(new RuntimeError("hi").message, "hi"); -}, "'WebAssembly.(Compile|Runtime)Error' instance objects"); - -test(() => { - const moduleDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Module'); - assert_equals(typeof moduleDesc.value, "function"); - assert_equals(moduleDesc.writable, true); - assert_equals(moduleDesc.enumerable, false); - assert_equals(moduleDesc.configurable, true); - Module = WebAssembly.Module; -}, "'WebAssembly.Module' data property"); - -test(() => { - const moduleDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Module'); - assert_equals(Module, moduleDesc.value); - assert_equals(Module.length, 1); - assert_equals(Module.name, "Module"); - assertThrows(() => Module(), TypeError); - assertThrows(() => new Module(), TypeError); - assertThrows(() => new Module(undefined), TypeError); - assertThrows(() => new Module(1), TypeError); - assertThrows(() => new Module({}), TypeError); - assertThrows(() => new Module(new Uint8Array()), CompileError); - assertThrows(() => new Module(new ArrayBuffer()), CompileError); - assert_equals(new Module(emptyModuleBinary) instanceof Module, true); - assert_equals(new Module(new Uint8Array(emptyModuleBinary)) instanceof Module, true); -}, "'WebAssembly.Module' constructor function"); - -test(() => { - const moduleProtoDesc = Object.getOwnPropertyDescriptor(Module, 'prototype'); - assert_equals(typeof moduleProtoDesc.value, "object"); - assert_equals(moduleProtoDesc.writable, false); - assert_equals(moduleProtoDesc.enumerable, false); - assert_equals(moduleProtoDesc.configurable, false); -}, "'WebAssembly.Module.prototype' data property"); - -test(() => { - const moduleProtoDesc = Object.getOwnPropertyDescriptor(Module, 'prototype'); - const moduleProto = Module.prototype; - assert_equals(moduleProto, moduleProtoDesc.value); - assert_equals(String(moduleProto), "[object WebAssembly.Module]"); - assert_equals(Object.getPrototypeOf(moduleProto), Object.prototype); -}, "'WebAssembly.Module.prototype' object"); - -test(() => { - const moduleProto = Module.prototype; - emptyModule = new Module(emptyModuleBinary); - exportingModule = new Module(exportingModuleBinary); - importingModule = new Module(importingModuleBinary); - assert_equals(typeof emptyModule, "object"); - assert_equals(String(emptyModule), "[object WebAssembly.Module]"); - assert_equals(Object.getPrototypeOf(emptyModule), moduleProto); -}, "'WebAssembly.Module' instance objects"); - -test(() => { - const moduleImportsDesc = Object.getOwnPropertyDescriptor(Module, 'imports'); - assert_equals(typeof moduleImportsDesc.value, "function"); - assert_equals(moduleImportsDesc.writable, true); - assert_equals(moduleImportsDesc.enumerable, false); - assert_equals(moduleImportsDesc.configurable, true); -}, "'WebAssembly.Module.imports' data property"); - -test(() => { - const moduleImportsDesc = Object.getOwnPropertyDescriptor(Module, 'imports'); - const moduleImports = moduleImportsDesc.value; - assert_equals(moduleImports.length, 1); - assertThrows(() => moduleImports(), TypeError); - assertThrows(() => moduleImports(undefined), TypeError); - assertThrows(() => moduleImports({}), TypeError); - var arr = moduleImports(emptyModule); - assert_equals(arr instanceof Array, true); - assert_equals(arr.length, 0); - var arr = moduleImports(new Module(complexImportingModuleBinary)); - assert_equals(arr instanceof Array, true); - assert_equals(arr.length, 4); - assert_equals(arr[0].kind, "function"); - assert_equals(arr[0].module, "a"); - assert_equals(arr[0].name, "b"); - assert_equals(arr[1].kind, "memory"); - assert_equals(arr[1].module, "c"); - assert_equals(arr[1].name, "d"); - assert_equals(arr[2].kind, "table"); - assert_equals(arr[2].module, "e"); - assert_equals(arr[2].name, "f"); - assert_equals(arr[3].kind, "global"); - assert_equals(arr[3].module, "g"); - assert_equals(arr[3].name, "âš¡"); -}, "'WebAssembly.Module.imports' method"); - -test(() => { - const moduleExportsDesc = Object.getOwnPropertyDescriptor(Module, 'exports'); - assert_equals(typeof moduleExportsDesc.value, "function"); - assert_equals(moduleExportsDesc.writable, true); - assert_equals(moduleExportsDesc.enumerable, false); - assert_equals(moduleExportsDesc.configurable, true); -}, "'WebAssembly.Module.exports' data property"); - -test(() => { - const moduleExportsDesc = Object.getOwnPropertyDescriptor(Module, 'exports'); - const moduleExports = moduleExportsDesc.value; - assert_equals(moduleExports.length, 1); - assertThrows(() => moduleExports(), TypeError); - assertThrows(() => moduleExports(undefined), TypeError); - assertThrows(() => moduleExports({}), TypeError); - var arr = moduleExports(emptyModule); - assert_equals(arr instanceof Array, true); - assert_equals(arr.length, 0); - var arr = moduleExports(new Module(complexExportingModuleBinary)); - assert_equals(arr instanceof Array, true); - assert_equals(arr.length, 4); - assert_equals(arr[0].kind, "function"); - assert_equals(arr[0].name, "a"); - assert_equals(arr[1].kind, "memory"); - assert_equals(arr[1].name, "b"); - assert_equals(arr[2].kind, "table"); - assert_equals(arr[2].name, "c"); - assert_equals(arr[3].kind, "global"); - assert_equals(arr[3].name, "âš¡"); -}, "'WebAssembly.Module.exports' method"); - -test(() => { - const customSectionsDesc = Object.getOwnPropertyDescriptor(Module, 'customSections'); - assert_equals(typeof customSectionsDesc.value, "function"); - assert_equals(customSectionsDesc.writable, true); - assert_equals(customSectionsDesc.enumerable, false); - assert_equals(customSectionsDesc.configurable, true); -}, "'WebAssembly.Module.customSections' data property"); - -test(() => { - const customSectionsDesc = Object.getOwnPropertyDescriptor(Module, 'customSections'); - const moduleCustomSections = customSectionsDesc.value; - assert_equals(moduleCustomSections.length, 2); - assertThrows(() => moduleCustomSections(), TypeError); - assertThrows(() => moduleCustomSections(undefined), TypeError); - assertThrows(() => moduleCustomSections({}), TypeError); - var arr = moduleCustomSections(emptyModule); - assert_equals(arr instanceof Array, true); - assert_equals(arr.length, 0); -}, "'WebAssembly.Module.customSections' method"); - -test(() => { - const instanceDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Instance'); - assert_equals(typeof instanceDesc.value, "function"); - assert_equals(instanceDesc.writable, true); - assert_equals(instanceDesc.enumerable, false); - assert_equals(instanceDesc.configurable, true); - Instance = WebAssembly.Instance; -}, "'WebAssembly.Instance' data property"); - -test(() => { - const instanceDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Instance'); - assert_equals(Instance, instanceDesc.value); - assert_equals(Instance.length, 1); - assert_equals(Instance.name, "Instance"); - assertThrows(() => Instance(), TypeError); - assertThrows(() => new Instance(1), TypeError); - assertThrows(() => new Instance({}), TypeError); - assertThrows(() => new Instance(emptyModule, null), TypeError); - assertThrows(() => new Instance(importingModule, null), TypeError); - assertThrows(() => new Instance(importingModule, undefined), TypeError); - assertThrows(() => new Instance(importingModule, {}), TypeError); - assertThrows(() => new Instance(importingModule, {"":{g:()=>{}}}), LinkError); - assertThrows(() => new Instance(importingModule, {t:{f:()=>{}}}), TypeError); - assert_equals(new Instance(emptyModule) instanceof Instance, true); - assert_equals(new Instance(emptyModule, {}) instanceof Instance, true); -}, "'WebAssembly.Instance' constructor function"); - -test(() => { - const instanceProtoDesc = Object.getOwnPropertyDescriptor(Instance, 'prototype'); - assert_equals(typeof instanceProtoDesc.value, "object"); - assert_equals(instanceProtoDesc.writable, false); - assert_equals(instanceProtoDesc.enumerable, false); - assert_equals(instanceProtoDesc.configurable, false); -}, "'WebAssembly.Instance.prototype' data property"); - -test(() => { - instanceProto = Instance.prototype; - const instanceProtoDesc = Object.getOwnPropertyDescriptor(Instance, 'prototype'); - assert_equals(instanceProto, instanceProtoDesc.value); - assert_equals(String(instanceProto), "[object WebAssembly.Instance]"); - assert_equals(Object.getPrototypeOf(instanceProto), Object.prototype); -}, "'WebAssembly.Instance.prototype' object"); - -test(() => { - const instanceProto = Instance.prototype; - exportingInstance = new Instance(exportingModule); - assert_equals(typeof exportingInstance, "object"); - assert_equals(String(exportingInstance), "[object WebAssembly.Instance]"); - assert_equals(Object.getPrototypeOf(exportingInstance), instanceProto); -}, "'WebAssembly.Instance' instance objects"); - -test(() => { - const exportsDesc = Object.getOwnPropertyDescriptor(instanceProto, 'exports'); - assert_equals(typeof exportsDesc.get, "function"); - assert_equals(exportsDesc.set, undefined); - assert_equals(exportsDesc.enumerable, false); - assert_equals(exportsDesc.configurable, true); - const exportsGetter = exportsDesc.get; - assertThrows(() => exportsGetter.call(), TypeError); - assertThrows(() => exportsGetter.call({}), TypeError); - assert_equals(typeof exportsGetter.call(exportingInstance), "object"); -}, "'WebAssembly.Instance.prototype.exports' accessor property"); - -test(() => { - exportsObj = exportingInstance.exports; - assert_equals(typeof exportsObj, "object"); - assert_equals(Object.isExtensible(exportsObj), false); - assert_equals(Object.getPrototypeOf(exportsObj), null); - assert_equals(Object.keys(exportsObj).join(), "f"); - exportsObj.g = 1; - assert_equals(Object.keys(exportsObj).join(), "f"); - assertThrows(() => Object.setPrototypeOf(exportsObj, {}), TypeError); - assert_equals(Object.getPrototypeOf(exportsObj), null); - assertThrows(() => Object.defineProperty(exportsObj, 'g', {}), TypeError); - assert_equals(Object.keys(exportsObj).join(), "f"); -}, "exports object"); - -test(() => { - const f = exportsObj.f; - assert_equals(f instanceof Function, true); - assert_equals(f.length, 0); - assert_equals('name' in f, true); - assert_equals(Function.prototype.call.call(f), 42); - assertThrows(() => new f(), TypeError); -}, "Exported WebAssembly functions"); - -test(() => { - const memoryDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Memory'); - assert_equals(typeof memoryDesc.value, "function"); - assert_equals(memoryDesc.writable, true); - assert_equals(memoryDesc.enumerable, false); - assert_equals(memoryDesc.configurable, true); - Memory = WebAssembly.Memory; -}, "'WebAssembly.Memory' data property"); - -test(() => { - const memoryDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Memory'); - assert_equals(Memory, memoryDesc.value); - assert_equals(Memory.length, 1); - assert_equals(Memory.name, "Memory"); - assertThrows(() => Memory(), TypeError); - assertThrows(() => new Memory(1), TypeError); - assertThrows(() => new Memory({initial:{valueOf() { throw new Error("here")}}}), Error); - assertThrows(() => new Memory({initial:-1}), RangeError); - assertThrows(() => new Memory({initial:Math.pow(2,32)}), RangeError); - assertThrows(() => new Memory({initial:1, maximum: Math.pow(2,32)/Math.pow(2,14) }), RangeError); - assertThrows(() => new Memory({initial:2, maximum:1 }), RangeError); - assertThrows(() => new Memory({maximum: -1 }), RangeError); - assert_equals(new Memory({initial:1}) instanceof Memory, true); - assert_equals(new Memory({initial:1.5}).buffer.byteLength, WasmPage); -}, "'WebAssembly.Memory' constructor function"); - -test(() => { - const memoryProtoDesc = Object.getOwnPropertyDescriptor(Memory, 'prototype'); - assert_equals(typeof memoryProtoDesc.value, "object"); - assert_equals(memoryProtoDesc.writable, false); - assert_equals(memoryProtoDesc.enumerable, false); - assert_equals(memoryProtoDesc.configurable, false); -}, "'WebAssembly.Memory.prototype' data property"); - -test(() => { - memoryProto = Memory.prototype; - const memoryProtoDesc = Object.getOwnPropertyDescriptor(Memory, 'prototype'); - assert_equals(memoryProto, memoryProtoDesc.value); - assert_equals(String(memoryProto), "[object WebAssembly.Memory]"); - assert_equals(Object.getPrototypeOf(memoryProto), Object.prototype); -}, "'WebAssembly.Memory.prototype' object"); - -test(() => { - mem1 = new Memory({initial:1}); - assert_equals(typeof mem1, "object"); - assert_equals(String(mem1), "[object WebAssembly.Memory]"); - assert_equals(Object.getPrototypeOf(mem1), memoryProto); -}, "'WebAssembly.Memory' instance objects"); - -test(() => { - const bufferDesc = Object.getOwnPropertyDescriptor(memoryProto, 'buffer'); - assert_equals(typeof bufferDesc.get, "function"); - assert_equals(bufferDesc.set, undefined); - assert_equals(bufferDesc.enumerable, false); - assert_equals(bufferDesc.configurable, true); -}, "'WebAssembly.Memory.prototype.buffer' accessor property"); - -test(() => { - const bufferDesc = Object.getOwnPropertyDescriptor(memoryProto, 'buffer'); - const bufferGetter = bufferDesc.get; - assertThrows(() => bufferGetter.call(), TypeError); - assertThrows(() => bufferGetter.call({}), TypeError); - assert_equals(bufferGetter.call(mem1) instanceof ArrayBuffer, true); - assert_equals(bufferGetter.call(mem1).byteLength, WasmPage); -}, "'WebAssembly.Memory.prototype.buffer' getter"); - -test(() => { - const memGrowDesc = Object.getOwnPropertyDescriptor(memoryProto, 'grow'); - assert_equals(typeof memGrowDesc.value, "function"); - assert_equals(memGrowDesc.enumerable, false); - assert_equals(memGrowDesc.configurable, true); -}, "'WebAssembly.Memory.prototype.grow' data property"); - -test(() => { - const memGrowDesc = Object.getOwnPropertyDescriptor(memoryProto, 'grow'); - const memGrow = memGrowDesc.value; - assert_equals(memGrow.length, 1); - assertThrows(() => memGrow.call(), TypeError); - assertThrows(() => memGrow.call({}), TypeError); - assertThrows(() => memGrow.call(mem1, -1), RangeError); - assertThrows(() => memGrow.call(mem1, Math.pow(2,32)), RangeError); - var mem = new Memory({initial:1, maximum:2}); - var buf = mem.buffer; - assert_equals(buf.byteLength, WasmPage); - assert_equals(mem.grow(0), 1); - assert_equals(buf !== mem.buffer, true); - assert_equals(buf.byteLength, 0); - buf = mem.buffer; - assert_equals(buf.byteLength, WasmPage); - assert_equals(mem.grow(1), 1); - assert_equals(buf !== mem.buffer, true); - assert_equals(buf.byteLength, 0); - buf = mem.buffer; - assert_equals(buf.byteLength, 2 * WasmPage); - assertThrows(() => mem.grow(1), Error); - assert_equals(buf, mem.buffer); -}, "'WebAssembly.Memory.prototype.grow' method"); - -test(() => { - const tableDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Table'); - assert_equals(typeof tableDesc.value, "function"); - assert_equals(tableDesc.writable, true); - assert_equals(tableDesc.enumerable, false); - assert_equals(tableDesc.configurable, true); - Table = WebAssembly.Table; -}, "'WebAssembly.Table' data property"); - -test(() => { - const tableDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'Table'); - assert_equals(Table, tableDesc.value); - assert_equals(Table.length, 1); - assert_equals(Table.name, "Table"); - assertThrows(() => Table(), TypeError); - assertThrows(() => new Table(1), TypeError); - assertThrows(() => new Table({initial:1, element:1}), TypeError); - assertThrows(() => new Table({initial:1, element:"any"}), TypeError); - assertThrows(() => new Table({initial:1, element:{valueOf() { return "anyfunc" }}}), TypeError); - assertThrows(() => new Table({initial:{valueOf() { throw new Error("here")}}, element:"anyfunc"}), Error); - assertThrows(() => new Table({initial:-1, element:"anyfunc"}), RangeError); - assertThrows(() => new Table({initial:Math.pow(2,32), element:"anyfunc"}), RangeError); - assertThrows(() => new Table({initial:2, maximum:1, element:"anyfunc"}), RangeError); - assertThrows(() => new Table({initial:2, maximum:Math.pow(2,32), element:"anyfunc"}), RangeError); - assert_equals(new Table({initial:1, element:"anyfunc"}) instanceof Table, true); - assert_equals(new Table({initial:1.5, element:"anyfunc"}) instanceof Table, true); - assert_equals(new Table({initial:1, maximum:1.5, element:"anyfunc"}) instanceof Table, true); - assert_equals(new Table({initial:1, maximum:Math.pow(2,32)-1, element:"anyfunc"}) instanceof Table, true); -}, "'WebAssembly.Table' constructor function"); - -test(() => { - const tableProtoDesc = Object.getOwnPropertyDescriptor(Table, 'prototype'); - assert_equals(typeof tableProtoDesc.value, "object"); - assert_equals(tableProtoDesc.writable, false); - assert_equals(tableProtoDesc.enumerable, false); - assert_equals(tableProtoDesc.configurable, false); -}, "'WebAssembly.Table.prototype' data property"); - -test(() => { - const tableProtoDesc = Object.getOwnPropertyDescriptor(Table, 'prototype'); - tableProto = Table.prototype; - assert_equals(tableProto, tableProtoDesc.value); - assert_equals(String(tableProto), "[object WebAssembly.Table]"); - assert_equals(Object.getPrototypeOf(tableProto), Object.prototype); -}, "'WebAssembly.Table.prototype' object"); - -test(() => { - tbl1 = new Table({initial:2, element:"anyfunc"}); - assert_equals(typeof tbl1, "object"); - assert_equals(String(tbl1), "[object WebAssembly.Table]"); - assert_equals(Object.getPrototypeOf(tbl1), tableProto); -}, "'WebAssembly.Table' instance objects"); - -test(() => { - const lengthDesc = Object.getOwnPropertyDescriptor(tableProto, 'length'); - assert_equals(typeof lengthDesc.get, "function"); - assert_equals(lengthDesc.set, undefined); - assert_equals(lengthDesc.enumerable, false); - assert_equals(lengthDesc.configurable, true); -}, "'WebAssembly.Table.prototype.length' accessor data property"); - -test(() => { - const lengthDesc = Object.getOwnPropertyDescriptor(tableProto, 'length'); - const lengthGetter = lengthDesc.get; - assert_equals(lengthGetter.length, 0); - assertThrows(() => lengthGetter.call(), TypeError); - assertThrows(() => lengthGetter.call({}), TypeError); - assert_equals(typeof lengthGetter.call(tbl1), "number"); - assert_equals(lengthGetter.call(tbl1), 2); -}, "'WebAssembly.Table.prototype.length' getter"); - -test(() => { - const getDesc = Object.getOwnPropertyDescriptor(tableProto, 'get'); - assert_equals(typeof getDesc.value, "function"); - assert_equals(getDesc.enumerable, false); - assert_equals(getDesc.configurable, true); -}, "'WebAssembly.Table.prototype.get' data property"); - -test(() => { - const getDesc = Object.getOwnPropertyDescriptor(tableProto, 'get'); - const get = getDesc.value; - assert_equals(get.length, 1); - assertThrows(() => get.call(), TypeError); - assertThrows(() => get.call({}), TypeError); - assert_equals(get.call(tbl1, 0), null); - assert_equals(get.call(tbl1, 1), null); - assert_equals(get.call(tbl1, 1.5), null); - assertThrows(() => get.call(tbl1, 2), RangeError); - assertThrows(() => get.call(tbl1, 2.5), RangeError); - assertThrows(() => get.call(tbl1, -1), RangeError); - assertThrows(() => get.call(tbl1, Math.pow(2,33)), RangeError); - assertThrows(() => get.call(tbl1, {valueOf() { throw new Error("hi") }}), Error); -}, "'WebAssembly.Table.prototype.get' method"); - -test(() => { - const setDesc = Object.getOwnPropertyDescriptor(tableProto, 'set'); - assert_equals(typeof setDesc.value, "function"); - assert_equals(setDesc.enumerable, false); - assert_equals(setDesc.configurable, true); -}, "'WebAssembly.Table.prototype.set' data property"); - -test(() => { - const setDesc = Object.getOwnPropertyDescriptor(tableProto, 'set'); - const set = setDesc.value; - assert_equals(set.length, 2); - assertThrows(() => set.call(), TypeError); - assertThrows(() => set.call({}), TypeError); - assertThrows(() => set.call(tbl1, 0), TypeError); - assertThrows(() => set.call(tbl1, 2, null), RangeError); - assertThrows(() => set.call(tbl1, -1, null), RangeError); - assertThrows(() => set.call(tbl1, Math.pow(2,33), null), RangeError); - assertThrows(() => set.call(tbl1, 0, undefined), TypeError); - assertThrows(() => set.call(tbl1, 0, {}), TypeError); - assertThrows(() => set.call(tbl1, 0, function() {}), TypeError); - assertThrows(() => set.call(tbl1, 0, Math.sin), TypeError); - assertThrows(() => set.call(tbl1, {valueOf() { throw Error("hai") }}, null), Error); - assert_equals(set.call(tbl1, 0, null), undefined); - assert_equals(set.call(tbl1, 1, null), undefined); -}, "'WebAssembly.Table.prototype.set' method"); - -test(() => { - const tblGrowDesc = Object.getOwnPropertyDescriptor(tableProto, 'grow'); - assert_equals(typeof tblGrowDesc.value, "function"); - assert_equals(tblGrowDesc.enumerable, false); - assert_equals(tblGrowDesc.configurable, true); -}, "'WebAssembly.Table.prototype.grow' data property"); - -test(() => { - const tblGrowDesc = Object.getOwnPropertyDescriptor(tableProto, 'grow'); - const tblGrow = tblGrowDesc.value; - assert_equals(tblGrow.length, 1); - assertThrows(() => tblGrow.call(), TypeError); - assertThrows(() => tblGrow.call({}), TypeError); - assertThrows(() => tblGrow.call(tbl1, -1), RangeError); - assertThrows(() => tblGrow.call(tbl1, Math.pow(2,32)), RangeError); - var tbl = new Table({element:"anyfunc", initial:1, maximum:2}); - assert_equals(tbl.length, 1); - assert_equals(tbl.grow(0), 1); - assert_equals(tbl.length, 1); - assert_equals(tbl.grow(1), 1); - assert_equals(tbl.length, 2); - assertThrows(() => tbl.grow(1), Error); -}, "'WebAssembly.Table.prototype.grow' method"); - -test(() => { - assertThrows(() => WebAssembly.validate(), TypeError); - assertThrows(() => WebAssembly.validate("hi"), TypeError); - assert_true(WebAssembly.validate(emptyModuleBinary)); - assert_true(WebAssembly.validate(complexImportingModuleBinary)); - assert_false(WebAssembly.validate(moduleBinaryImporting2Memories)); - assert_false(WebAssembly.validate(moduleBinaryWithMemSectionAndMemImport)); -}, "'WebAssembly.validate' method"); - -/* FIXME https://bugs.webkit.org/show_bug.cgi?id=173180 -test(() => { - const compileDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'compile'); - assert_equals(typeof compileDesc.value, "function"); - assert_equals(compileDesc.writable, true); - assert_equals(compileDesc.enumerable, false); - assert_equals(compileDesc.configurable, true); -}, "'WebAssembly.compile' data property"); - -test(() => { - const compile = WebAssembly.compile; - const compileDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'compile'); - - assert_equals(compile, compileDesc.value); - assert_equals(compile.length, 1); - assert_equals(compile.name, "compile"); -}, "'WebAssembly.compile' function"); */ - -var num_tests = 1; -function assertCompileError(args, err) { - promise_test(() => { - return WebAssembly.compile(...args) - .then(_ => { - throw null; - }) - .catch(error => { - assert_equals(error instanceof err, true); - return Promise.resolve() - }); - }, `assertCompileError ${num_tests++}`); -} - -assertCompileError([], TypeError); -assertCompileError([undefined], TypeError); -assertCompileError([1], TypeError); -assertCompileError([{}], TypeError); -assertCompileError([new Uint8Array()], CompileError); -assertCompileError([new ArrayBuffer()], CompileError); -// FIXME: https://github.com/WebAssembly/spec/pull/503 -//assertCompileError([new Uint8Array("hi!")], CompileError); -//assertCompileError([new ArrayBuffer("hi!")], CompileError); - -num_tests = 1; -function assertCompileSuccess(bytes) { - promise_test(() => { - return WebAssembly.compile(bytes) - .then(module => { - assert_equals(module instanceof Module, true); - }); - }, `assertCompileSuccess ${num_tests++}`); -} - -assertCompileSuccess(emptyModuleBinary); -assertCompileSuccess(new Uint8Array(emptyModuleBinary)); - -/* FIXME https://bugs.webkit.org/show_bug.cgi?id=173180 -test(() => { - const instantiateDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'instantiate'); - assert_equals(typeof instantiateDesc.value, "function"); - assert_equals(instantiateDesc.writable, true); - assert_equals(instantiateDesc.enumerable, false); - assert_equals(instantiateDesc.configurable, true); -}, "'WebAssembly.instantiate' data property");*/ - -test(() => { - const instantiateDesc = Object.getOwnPropertyDescriptor(WebAssembly, 'instantiate'); - const instantiate = WebAssembly.instantiate; -/* FIXME https://bugs.webkit.org/show_bug.cgi?id=173180 - assert_equals(instantiate, instantiateDesc.value); - assert_equals(instantiate.length, 1); - assert_equals(instantiate.name, "instantiate");*/ - function assertInstantiateError(args, err) { - promise_test(() => { - return instantiate(...args) - .then(m => { - throw null; - }) - .catch(error => { - assert_equals(error instanceof err, true); - }) - }, 'unexpected success in assertInstantiateError'); - } - var scratch_memory = new WebAssembly.Memory({initial:1}); - var scratch_table = new WebAssembly.Table({element:"anyfunc", initial:1, maximum:1}); - assertInstantiateError([], TypeError); - assertInstantiateError([undefined], TypeError); - assertInstantiateError([1], TypeError); - assertInstantiateError([{}], TypeError); - assertInstantiateError([new Uint8Array()], CompileError); - assertInstantiateError([new ArrayBuffer()], CompileError); -// FIXME: https://github.com/WebAssembly/spec/pull/503 -// assertInstantiateError([new Uint8Array("hi!")], CompileError); -// assertInstantiateError([new ArrayBuffer("hi!")], CompileError); - assertInstantiateError([importingModule], TypeError); - assertInstantiateError([importingModule, null], TypeError); - assertInstantiateError([importingModuleBinary, null], TypeError); - assertInstantiateError([emptyModule, null], TypeError); - assertInstantiateError([importingModuleBinary, null], TypeError); - assertInstantiateError([importingModuleBinary, undefined], TypeError); - assertInstantiateError([importingModuleBinary, {}], TypeError); - assertInstantiateError([importingModuleBinary, {"":{g:()=>{}}}], LinkError); - assertInstantiateError([importingModuleBinary, {t:{f:()=>{}}}], TypeError); - assertInstantiateError([complexImportingModuleBinary, null], TypeError); - assertInstantiateError([complexImportingModuleBinary, undefined], TypeError); - assertInstantiateError([complexImportingModuleBinary, {}], TypeError); - assertInstantiateError([complexImportingModuleBinary, {"c": {"d": scratch_memory}}], TypeError); - - function assertInstantiateSuccess(module, imports) { - promise_test(()=> { - return instantiate(module, imports) - .then(result => { - if (module instanceof Module) { - assert_equals(result instanceof Instance, true); - } else { - assert_equals(result.module instanceof Module, true); - assert_equals(result.instance instanceof Instance, true); - var desc = Object.getOwnPropertyDescriptor(result, 'module'); - assert_equals(desc.writable, true); - assert_equals(desc.enumerable, true); - assert_equals(desc.configurable, true); - desc = Object.getOwnPropertyDescriptor(result, 'instance'); - assert_equals(desc.writable, true); - assert_equals(desc.enumerable, true); - assert_equals(desc.configurable, true); - } - })}, 'unexpected failure in assertInstantiateSuccess'); - } - assertInstantiateSuccess(emptyModule); - assertInstantiateSuccess(emptyModuleBinary); - assertInstantiateSuccess(new Uint8Array(emptyModuleBinary)); - assertInstantiateSuccess(importingModule, {"":{f:()=>{}}}); - assertInstantiateSuccess(importingModuleBinary, {"":{f:()=>{}}}); - assertInstantiateSuccess(new Uint8Array(importingModuleBinary), {"":{f:()=>{}}}); - assertInstantiateSuccess(complexImportingModuleBinary, { - a:{b:()=>{}}, - c:{d:scratch_memory}, - e:{f:scratch_table}, - g:{'âš¡':1}}); -}, "'WebAssembly.instantiate' function"); - -})(); diff --git a/implementation-contributed/javascriptcore/wasm/stress/oom.js b/implementation-contributed/javascriptcore/wasm/stress/oom.js deleted file mode 100644 index c00bc653e1460a0bafe31094752552216b95feba..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/stress/oom.js +++ /dev/null @@ -1,25 +0,0 @@ -// We don't need N versions of this simultaneously filling up RAM. -//@ skip - -const verbose = false; - -// Use a full 4GiB so that exhaustion is likely to occur faster. We're not -// guaranteed that we'll get that much virtually allocated to the memory so we -// can't actually check that exhaustion occurs at a particular number of -// memories. -const maximumPages = 65536; - -let memories = []; -try { - while (true) { - let m = new WebAssembly.Memory({ initial: 64, maximum: maximumPages }); - memories.push(m); - if (verbose) - print(`${WebAssemblyMemoryMode(m)} ${memories.length}`); - } -} catch (e) { - if (verbose) - print(`Caught: ${e}`); - if (e.message !== "Out of memory") - throw new Error(`Expected an out of memory error, got ${e} of type ${typeof e}`); -} diff --git a/implementation-contributed/javascriptcore/wasm/tier-up/js-to-wasm.js b/implementation-contributed/javascriptcore/wasm/tier-up/js-to-wasm.js deleted file mode 100644 index a93913970a4a50d2626ec1ba625dd20df8c32de6..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/tier-up/js-to-wasm.js +++ /dev/null @@ -1,25 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -async function test() { - let builder = (new Builder()) - .Type().End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", { params: [], ret: "i32" }) - .I32Const(42) - .Return() - .End() - .End(); - - const bin = builder.WebAssembly().get(); - const {instance} = await WebAssembly.instantiate(bin, {}); - - for (let i = 0; i < 1000000; i++) - assert.eq(instance.exports.foo(), 42); -} - -assert.asyncTest(test()); diff --git a/implementation-contributed/javascriptcore/wasm/tier-up/wasm-to-wasm.js b/implementation-contributed/javascriptcore/wasm/tier-up/wasm-to-wasm.js deleted file mode 100644 index 227d90d7f94584450ba24017313522d487d8cbd4..0000000000000000000000000000000000000000 --- a/implementation-contributed/javascriptcore/wasm/tier-up/wasm-to-wasm.js +++ /dev/null @@ -1,47 +0,0 @@ -import * as assert from '../assert.js'; -import Builder from '../Builder.js'; - -async function test() { - let builder = (new Builder()) - .Type().End() - .Function().End() - .Export() - .Function("foo") - .End() - .Code() - .Function("foo", { params: ["i32"], ret: "i32" }, ["i32"]) - .Block("i32") - .Loop("i32", b => - b.GetLocal(1) - .GetLocal(0) - .I32Eqz() - .BrIf(1) - - .Call(1) - .GetLocal(1) - .I32Add() - .SetLocal(1) - .GetLocal(0) - .I32Const(1) - .I32Sub() - .SetLocal(0) - .Br(0) - - ) - .End() - .End() - .Function("bar", { params: [], ret: "i32" }) - .I32Const(42) - .Return() - .End() - .End() - - const bin = builder.WebAssembly().get(); - const {instance} = await WebAssembly.instantiate(bin, {}); - - const iters = 100000 - for (let i = 0; i < 100; i++) - assert.eq(instance.exports.foo(iters), 42 * iters); -} - -assert.asyncTest(test());