diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /js/src/jit-test/tests/wasm/multi-value | |
parent | Initial commit. (diff) | |
download | firefox-esr-upstream.tar.xz firefox-esr-upstream.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
18 files changed, 1112 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/wasm/multi-value/block-run.js b/js/src/jit-test/tests/wasm/multi-value/block-run.js new file mode 100644 index 0000000000..3b6689d2f9 --- /dev/null +++ b/js/src/jit-test/tests/wasm/multi-value/block-run.js @@ -0,0 +1,268 @@ +wasmFullPass(` + (module + (func (export "run") (result i32) + (i32.add + (block (result i32 i32) + (i32.const 32) + (i32.const 10)))))`, + 42); + +wasmFullPass(` + (module + (func (export "run") (result i32) + (i32.const 32) (i32.const 10) + (block (param i32 i32) (result i32 i32)) + (i32.add)))`, + 42); + +wasmFullPass(` + (module + (func (export "run") (result i32) + (i32.const 32) + (block (param i32) (result i32 i32) + (i32.const 10)) + (i32.add)))`, + 42); + +wasmFullPass(` + (module + (func (export "run") (result i32) + (i32.add + (loop (result i32 i32) + (i32.const 32) + (i32.const 10)))))`, + 42); + +wasmFullPass(` + (module + (func (export "run") (result i32) + (i32.const 32) (i32.const 10) + (loop (param i32 i32) (result i32 i32)) + (i32.add)))`, + 42); + +wasmFullPass(` + (module + (func (export "run") (result i32) + (i32.const 32) + (loop (param i32) (result i32 i32) + (i32.const 10)) + (i32.add)))`, + 42); + +wasmFullPass(` + (module + (func (export "run") (result i32) + (i32.add + (block (result i32 i32) + (i32.const 32) + (i32.const 10) + (br 0)))))`, + 42); + +wasmFullPass(` + (module + (func (export "run") (result i32) + (i32.const 32) + (i32.const 10) + (block (param i32 i32) (result i32 i32) + (br 0)) + (i32.add)))`, + 42); + +wasmFullPass(` + (module + (func (export "run") (result i32) + (i32.const 32) + (block (param i32) (result i32 i32) + (i32.const 10) + (br 0)) + (i32.add)))`, + 42); + +wasmFullPass(` + (module + (func (export "run") (result i32) + (i32.add + (block (result i32 i32) + (i32.const 32) + (i32.const 10) + (block (param i32 i32) (result i32 i32) + (br 1))))))`, + 42); + +wasmFullPass(` + (module + (func (export "run") (result i32) + (i32.const 32) + (i32.const 10) + (block (param i32 i32) (result i32 i32) + (block (param i32 i32) (result i32 i32) + (br 1))) + (i32.add)))`, + 42); + +wasmFullPass(` + (module + (func (export "run") (result i32) + (i32.const 32) + (i32.const 10) + (block (param i32 i32) (result i32 i32) + (block (param i32 i32) (result i32 i32) + (br 0))) + (i32.add)))`, + 42); + +wasmFullPass(` + (module + (func (export "run") (result i32) + (i32.const 32) + (block (param i32) (result i32 i32) + (i32.const 10) + (block (param i32 i32) (result i32 i32) + (br 1))) + (i32.add)))`, + 42); + +wasmFullPass(` + (module + (func (export "run") (result i32) + (i32.const 32) + (i32.const 10) + (i32.const 1) + (if (param i32 i32) (result i32) + (then (i32.add)) + (else (i32.sub)))))`, + 42); + +wasmFullPass(` + (module + (func (export "run") (result i32) + (i32.const 32) + (i32.const 10) + (i32.const 1) + (if (param i32 i32) (result i32 i32) + (then + (drop) + (drop) + (i32.const 10) + (i32.const 32))) + (i32.sub)))`, + -22); + +wasmFullPass(` + (module + (func (export "run") (result i32) + (i32.const 32) + (i32.const 10) + (i32.const 0) + (if (param i32 i32) (result i32 i32) + (then + (drop) + (drop) + (i32.const 10) + (i32.const 32))) + (i32.sub)))`, + 22); + +wasmFullPass(` + (module + (func (export "run") (result i32) + (i32.const 32) + (i32.const 10) + (i32.const 1) + (if (param i32 i32) (result i32 i32) + (then (return))) + (i32.sub)))`, + 10); + +wasmFullPass(` + (module + (func (export "run") (result i32) + (i32.const 32) + (i32.const 10) + (i32.const 0) + (if (param i32 i32) (result i32 i32) + (then (return))) + (i32.sub)))`, + 22); + +wasmFullPass(` + (module + (func (export "run") (result i32) + (i32.const 32) + (i32.const 10) + (i32.const 1) + (if (param i32 i32) (result i32 i32) + (then) + (else (return))) + (i32.sub)))`, + 22); + +wasmFullPass(` + (module + (func (export "run") (result i32) + (i32.const 32) + (i32.const 10) + (i32.const 0) + (if (param i32 i32) (result i32 i32) + (then) + (else (return))) + (i32.sub)))`, + 10); + +wasmFullPass(` + (module + (func (export "run") (result i32) + (local $i i32) + (i32.const 0) ;; sum + (i32.const 10) ;; i + (loop $loop (param i32 i32) (result i32) + (local.tee $i) + (i32.add) ;; sum = i + sum + (i32.sub (local.get $i) (i32.const 1)) + (i32.eqz (local.tee $i)) + (if (param i32) (result i32) + (then) + (else (local.get $i) (br $loop))))))`, + 55); + +wasmFullPass(` + (module + (func (export "run") (result i32) + (local i32) + i32.const 42 + local.get 0 + local.get 0 + loop (param i32 i32 i32) (result i32) + drop + drop + end))`, + 42); + +wasmFullPass(` + (module + (func (export "run") (result i32) + (block (result i32 i32) + (i32.popcnt (i32.const 1)) + (i32.popcnt (i32.const 3)) + (block (param i32 i32) + (i32.const 6) + (i32.const 7) + (br 1)) + (unreachable)) + i32.add))`, + 13); + +wasmFullPass(` + (module + (func (export "run") (result i32) + (block (result i32 i32) + (i32.popcnt (i32.const 1)) + (i32.popcnt (i32.const 3)) + (block) ;; sync() + (i32.const 6) + (i32.const 7) + (br 0)) + i32.add))`, + 13); diff --git a/js/src/jit-test/tests/wasm/multi-value/block-validate.js b/js/src/jit-test/tests/wasm/multi-value/block-validate.js new file mode 100644 index 0000000000..7845c016e3 --- /dev/null +++ b/js/src/jit-test/tests/wasm/multi-value/block-validate.js @@ -0,0 +1,266 @@ +wasmValidateText(` + (module + (func (result i32) + (i32.add + (block (result i32 i32) + (i32.const 32) + (i32.const 10)))))`); + +wasmValidateText(` + (module + (func (result i32) + (i32.const 32) (i32.const 10) + (block (param i32 i32) (result i32 i32)) + (i32.add)))`); + +wasmValidateText(` + (module + (func (result i32) + (i32.const 32) + (block (param i32) (result i32 i32) + (i32.const 10)) + (i32.add)))`); + +wasmValidateText(` + (module + (func (result i32) + (i32.add + (loop (result i32 i32) + (i32.const 32) + (i32.const 10)))))`); + +wasmValidateText(` + (module + (func (result i32) + (i32.const 32) (i32.const 10) + (loop (param i32 i32) (result i32 i32)) + (i32.add)))`); + +wasmValidateText(` + (module + (func (result i32) + (i32.const 32) + (loop (param i32) (result i32 i32) + (i32.const 10)) + (i32.add)))`); + +wasmValidateText(` + (module + (func (result i32) + (i32.add + (block (result i32 i32) + (i32.const 32) + (i32.const 10) + (br 0)))))`); + +wasmValidateText(` + (module + (func (result i32) + (i32.const 32) + (i32.const 10) + (block (param i32 i32) (result i32 i32) + (br 0)) + (i32.add)))`); + +wasmValidateText(` + (module + (func (result i32) + (i32.const 32) + (block (param i32) (result i32 i32) + (i32.const 10) + (br 0)) + (i32.add)))`); + +wasmValidateText(` + (module + (func (result i32) + (i32.add + (block (result i32 i32) + (i32.const 32) + (i32.const 10) + (block (param i32 i32) (result i32 i32) + (br 1))))))`); + +wasmValidateText(` + (module + (func (result i32) + (i32.const 32) + (i32.const 10) + (block (param i32 i32) (result i32 i32) + (block (param i32 i32) (result i32 i32) + (br 1))) + (i32.add)))`); + +wasmValidateText(` + (module + (func (result i32) + (i32.const 32) + (i32.const 10) + (block (param i32 i32) (result i32 i32) + (block (param i32 i32) (result i32 i32) + (br 0))) + (i32.add)))`); + +wasmValidateText(` + (module + (func (result i32) + (i32.const 32) + (block (param i32) (result i32 i32) + (i32.const 10) + (block (param i32 i32) (result i32 i32) + (br 1))) + (i32.add)))`); + +wasmValidateText(` + (module + (func (result i32) + (i32.const 32) + (i32.const 10) + (i32.const 1) + (if (param i32 i32) (result i32) + (then (i32.add)) + (else (i32.sub)))))`); + +wasmValidateText(` + (module + (func (result i32) + (i32.const 32) + (i32.const 10) + (i32.const 1) + (if (param i32 i32) (result i32 i32) + (then + (drop) + (drop) + (i32.const 10) + (i32.const 32))) + (i32.sub)))`); + +wasmValidateText(` + (module + (func (result i32) + (i32.const 32) + (i32.const 10) + (i32.const 1) + (if (param i32 i32) (result i32 i32) + (then (return))) + (i32.sub)))`); + +wasmValidateText(` + (module + (func (result i32) + (i32.const 32) + (i32.const 10) + (i32.const 1) + (if (param i32 i32) (result i32 i32) + (then) + (else (return))) + (i32.sub)))`); + +wasmValidateText(` + (module + (func (result i32) + (local $i i32) + (i32.const 0) ;; sum + (i32.const 10) ;; i + (loop $loop (param i32 i32) (result i32) + (local.tee $i) + (i32.add) ;; sum = i + sum + (i32.sub (local.get $i) (i32.const 1)) + (local.tee $i) + (local.get $i) + (br_if $loop (i32.eqz)) + (drop))))`); + +// Tests the encoding: with more than 64 function types, the block type encoded +// as an uleb will create a confusion with the valtype; an sleb is required. + +wasmValidateText(` + (module + ${(function () { + s = ""; + for ( let i=0; i < 64; i++ ) { + let t = []; + for ( let j=0; j < 6; j++ ) + t.push(i & (1 << j) ? "i32" : "f32"); + s += "(func (param " + t.join(" ") + "))\n"; + } + return s; + })()} + (func (result i32) + (i32.add + (block (result i32 i32) + (i32.const 32) + (i32.const 10)))))`); + +wasmValidateText(` + (module + (func (result i32) + (block $B (result i32 i32) + (br $B (i32.const 1) (i32.const 2)) + (i32.const 0x1337)) + (drop)))`); + +wasmValidateText(` + (module + (func (result i32) + (block $B (result i32 i32) + (i32.const 1) + (br $B (i32.const 2)) + (i32.const 0x1337)) + (drop)))`); + +wasmValidateText(` + (module + (func (result i32) + (block $B (result i32 i32) + (i32.const 1) + (i32.const 2) + (br $B) + (i32.const 0x1337)) + (drop)))`); + +wasmValidateText(` + (module + (func (param $cond i32) (result i32) + (block $B (result i32 i32) + (br_if $B (i32.const 1) (i32.const 2) (local.get $cond))) + (drop)))`); + +wasmValidateText(` + (module + (func (param $cond i32) (result i32) + (block $B (result i32 i32) + (i32.const 1) + (br_if $B (i32.const 2) (local.get $cond))) + (drop)))`); + +wasmValidateText(` + (module + (func (param $cond i32) (result i32) + (block $B (result i32 i32) + (i32.const 1) + (i32.const 2) + (br_if $B (local.get $cond))) + (drop)))`); + +wasmValidateText(` + (module + (func (param $cond i32) (result i32) + (block $B (result i32 i32) + (i32.const 1) + (i32.const 2) + (local.get $cond) + (br_if $B)) + (drop)))`); + +wasmValidateText(` + (module + (func (param $index i32) (result i32) + (block $OUT (result i32) + (block $B1 (result i32 i32) + (block $B2 (result i32 i32) + (block $B3 (result i32 i32) + (br_table $B1 $B2 $B3 (i32.const 1) (i32.const 2) (local.get $index))) + (br $OUT (i32.add))) + (br $OUT (i32.sub))) + (br $OUT (i32.mul)))))`); diff --git a/js/src/jit-test/tests/wasm/multi-value/call-js.js b/js/src/jit-test/tests/wasm/multi-value/call-js.js new file mode 100644 index 0000000000..7af031e5f0 --- /dev/null +++ b/js/src/jit-test/tests/wasm/multi-value/call-js.js @@ -0,0 +1,138 @@ + +wasmFullPass(` + (module + (import "env" "f" (func $f (result i32 i32 i32))) + (func (export "run") (result i32) + (call $f) + i32.sub + i32.sub))`, + 42, + { env: { f: () => [52, 10, 0] } }); + +wasmFullPass(` + (module + (import "env" "f" (func $f (result i64 i64 i64))) + (func (export "run") (result i64) + (call $f) + i64.sub + i64.sub))`, + 42n, + { env: { f: () => [52n, 10n, 0n] } }); + +wasmFullPass(` + (module + (import "env" "f" (func $f (result f32 f32 f32))) + (func (export "run") (result i32) + (call $f) + f32.sub + f32.sub + i32.trunc_f32_s))`, + 42, + { env: { f: () => [52.25, 10.5, 0.25] } }); + +wasmFullPass(` + (module + (import "env" "f" (func $f (result f64 f64 f64))) + (func (export "run") (result i32) + (call $f) + f64.sub + f64.sub + i32.trunc_f64_s))`, + 42, + { env: { f: () => [52.25, 10.5, 0.25] } }); + +// Multiple values are returned as an iterable; it doesn't have to be an array. +function expectMultiValuePass(f) { + wasmFullPass(` + (module + (import "env" "f" (func $f (result i32 i32 i32))) + (func (export "run") (result i32) + (call $f) + i32.sub + i32.sub))`, + 42, + { env: { f } }); +} +function expectMultiValueError(f, type, pattern) { + let module = new WebAssembly.Module(wasmTextToBinary(` + (module + (import "env" "f" (func $f (result i32 i32 i32))) + (func (export "run") (result i32) + (call $f) + i32.sub + i32.sub))`)); + + let instance = new WebAssembly.Instance(module, { env: { f } } ); + assertErrorMessage(() => instance.exports.run(), type, pattern); +} + +expectMultiValuePass(() => [52, 10, 0]); +expectMultiValuePass(() => [32, -10, 0]); +expectMultiValuePass(() => [52.75, 10, 0.5]); // Values converted to i32 via ToInt32. +expectMultiValuePass(() => [42, undefined, undefined]); +expectMultiValuePass(() => (function*() { yield 52; yield 10; yield 0; })()); +expectMultiValuePass(() => (function*() { yield '52'; yield '10'; yield 0; })()); + +// Multi-value result must be iterable. +expectMultiValueError(() => 1, TypeError, /iterable/); +expectMultiValueError(() => 1n, TypeError, /iterable/); + +// Check that the iterator's values are collected first, and that the +// length of the result is correct. +expectMultiValueError(() => [1], TypeError, /expected 3, got 1/); +expectMultiValueError(() => [1n], TypeError, /expected 3, got 1/); +expectMultiValueError(() => [52, 10, 0, 0], TypeError, /expected 3, got 4/); +expectMultiValueError(() => (function*() { yield 52; yield 10; yield 0; yield 0; })(), + TypeError, /expected 3, got 4/); + +// Check that side effects from conversions are done in order. +{ + let calls = []; + function log(x) { calls.push(x); return x; } + function logged(x) { return { valueOf: () => log(x) } } + expectMultiValuePass(() => [logged(52), logged(10), logged(0)]); + assertEq(calls.join(','), '52,10,0'); +} + +function expectMultiValueResult(text, expected) { + let instance = wasmEvalText(text); + assertDeepEq(instance.exports.run(), expected); +} + +expectMultiValueResult(` + (module + (func (export "run") (result i32 i32 i32) + (i32.const 0) + (i32.const 52) + (i32.const 10)))`, [0, 52, 10]); +expectMultiValueResult(` + (module + (func (export "run") (result f32 f32 f32) + (f32.const 0.5) + (f32.const 52.5) + (f32.const 10.5)))`, [0.5, 52.5, 10.5]); +expectMultiValueResult(` + (module + (func (export "run") (result f64 f64 f64) + (f64.const 0.5) + (f64.const 52.5) + (f64.const 10.5)))`, [0.5, 52.5, 10.5]); + +expectMultiValueResult(` + (module + (func (export "run") (result i32 i64 i32) + (i32.const 0) + (i64.const 52) + (i32.const 10)))`, [0, 52n, 10]); +expectMultiValueResult(` + (module + (func (export "run") (result i64 i32 i64) + (i64.const 0) + (i32.const 52) + (i64.const 10)))`, [0n, 52, 10n]); +expectMultiValueResult(` + (module + (func (export "run") (result i64 i64 i64) + (i64.const 0) + (i64.const 52) + (i64.const 10)))`, [0n, 52n, 10n]); diff --git a/js/src/jit-test/tests/wasm/multi-value/call-ref.js b/js/src/jit-test/tests/wasm/multi-value/call-ref.js new file mode 100644 index 0000000000..63b7eb271b --- /dev/null +++ b/js/src/jit-test/tests/wasm/multi-value/call-ref.js @@ -0,0 +1,81 @@ +let counter; +function resetCounter() { counter = 0; } + +function boxNextInt() { return {val: counter++}; } +function unboxInt(box) { return box.val; } +function boxNextThreeInts() { + return [boxNextInt(), boxNextInt(), boxNextInt()]; +} +function unboxThreeInts(x, y, z) { + return [unboxInt(x), unboxInt(y), unboxInt(z)]; +} + +function testAddNextThreeIntsInner(addNextThreeInts) { + resetCounter(); + for (let n = 0; n < 100000; n += 3) { + assertEq(addNextThreeInts(), n * 3 + 3); + } +} + +function testAddNextThreeInts(text, imports) { + let i = new WebAssembly.Instance( + new WebAssembly.Module(wasmTextToBinary(text)), { imports }); + + testAddNextThreeIntsInner(() => i.exports.addNextThreeInts()); +} + +testAddNextThreeInts(` + (module + (func $boxNextInt (import "imports" "boxNextInt") + (result externref)) + (func $unboxInt (import "imports" "unboxInt") + (param externref) (result i32)) + + (func $boxNextThreeInts (result externref externref externref) + call $boxNextInt + call $boxNextInt + call $boxNextInt) + + (func $unboxThreeInts (param externref externref externref) (result i32 i32 i32) + local.get 0 + call $unboxInt + local.get 1 + call $unboxInt + local.get 2 + call $unboxInt) + + (func $addNextThreeInts (export "addNextThreeInts") (result i32) + call $boxNextThreeInts + call $unboxThreeInts + i32.add + i32.add))`, + {boxNextInt, unboxInt}); + +testAddNextThreeInts(` + (module + (func $boxNextThreeInts (import "imports" "boxNextThreeInts") + (result externref externref externref)) + (func $unboxThreeInts (import "imports" "unboxThreeInts") + (param externref externref externref) (result i32 i32 i32)) + + (func $addNextThreeInts (export "addNextThreeInts") (result i32) + call $boxNextThreeInts + call $unboxThreeInts + i32.add + i32.add))`, + {boxNextThreeInts, unboxThreeInts}); + +{ + let i = wasmEvalText(` + (module + (func $boxNextThreeInts (import "imports" "boxNextThreeInts") + (result externref externref externref)) + + (func (export "boxNextThreeInts") (result externref externref externref) + call $boxNextThreeInts))`, + {imports: {boxNextThreeInts}}); + testAddNextThreeIntsInner(() => { + let [a, b, c] = i.exports.boxNextThreeInts(); + return unboxInt(a) + unboxInt(b) + unboxInt(c); + }); +} diff --git a/js/src/jit-test/tests/wasm/multi-value/call-run.js b/js/src/jit-test/tests/wasm/multi-value/call-run.js new file mode 100644 index 0000000000..67662a4af5 --- /dev/null +++ b/js/src/jit-test/tests/wasm/multi-value/call-run.js @@ -0,0 +1,120 @@ +wasmFullPass(` + (module + (func (result i32 i32) + (i32.const 52) + (i32.const 10)) + (func (export "run") (result i32) + (call 0) + i32.sub))`, + 42); + +wasmFullPass(` + (module + (func (param i32 i32) (result i32 i32) + (local.get 0) + (local.get 1)) + (func (export "run") (result i32) + (i32.const 52) + (i32.const 10) + (call 0) + i32.sub))`, + 42); + +wasmFullPass(` + (module + (func (param i32 i32 i32 i32 i32 + i32 i32 i32 i32 i32) + (result i32 i32) + (local.get 8) + (local.get 9)) + (func (export "run") (result i32) + (i32.const 0) + (i32.const 1) + (i32.const 2) + (i32.const 3) + (i32.const 4) + (i32.const 5) + (i32.const 6) + (i32.const 7) + (i32.const 52) + (i32.const 10) + (call 0) + i32.sub))`, + 42); + +wasmFullPass(` + (module + (func (param i32 i32 i32 i32 i32 + i32 i32 i32 i32 i32) + (result i32 i32) + (local i32 i32 i32 i32) + (local.get 8) + (local.get 9)) + (func (export "run") (result i32) + (i32.const 0) + (i32.const 1) + (i32.const 2) + (i32.const 3) + (i32.const 4) + (i32.const 5) + (i32.const 6) + (i32.const 7) + (i32.const 52) + (i32.const 10) + (call 0) + i32.sub))`, + 42); + +wasmFullPass(` + (module + (func (param i32 i32 i32 i32 i32 + i32 i32 i32 i32 i32) + (result i32 i32 i32) + (local i32 i32 i32 i32) + (local.get 7) + (local.get 8) + (local.get 9)) + (func (export "run") (result i32) + (i32.const 0) + (i32.const 1) + (i32.const 2) + (i32.const 3) + (i32.const 4) + (i32.const 5) + (i32.const 6) + (i32.const 7) + (i32.const 52) + (i32.const 10) + (call 0) + i32.sub + i32.sub))`, + -35); + +wasmFullPass(` + (module + (func (param i32 i64 i32 i64 i32 + i64 i32 i64 i32 i64) + (result i64 i32 i64) + (local i32 i64 i32 i64) + (local.get 7) + (local.get 8) + (local.get 9)) + (func (export "run") (result i32) + (i32.const 0) + (i64.const 1) + (i32.const 2) + (i64.const 3) + (i32.const 4) + (i64.const 5) + (i32.const 6) + (i64.const 7) + (i32.const 52) + (i64.const 10) + (call 0) + i32.wrap_i64 + i32.sub + i64.extend_i32_s + i64.sub + i32.wrap_i64))`, + -35); + diff --git a/js/src/jit-test/tests/wasm/multi-value/call-validate.js b/js/src/jit-test/tests/wasm/multi-value/call-validate.js new file mode 100644 index 0000000000..513e11bc6e --- /dev/null +++ b/js/src/jit-test/tests/wasm/multi-value/call-validate.js @@ -0,0 +1,47 @@ +wasmValidateText(` + (module + (func (result i32 i32) + (i32.const 32) + (i32.const 10)))`); + +wasmValidateText(` + (module + (type $t (func (result i32 i32))) + (func (type $t) + (i32.const 32) + (i32.const 10)))`); + +wasmValidateText(` + (module + (func (result i32 i32) + (block (result i32 i32) + (i32.const 32) + (i32.const 10))))`); + +wasmValidateText(` + (module + (func $return-2 (result i32 i32) + (i32.const 32) + (i32.const 10)) + (func $tail-call (result i32 i32) + (call 0)))`); + +wasmValidateText(` + (module + (func $return-2 (result i32 i32) + (i32.const 32) + (i32.const 10)) + (func $add (result i32) + (call 0) + i32.add))`); + +wasmValidateText(` + (module + (func $return-2 (param i32 i32) (result i32 i32) + (local.get 0) + (local.get 1)) + (func (export "run") (result i32) + (i32.const 32) + (i32.const 10) + (call 0) + i32.add))`); diff --git a/js/src/jit-test/tests/wasm/multi-value/directives.txt b/js/src/jit-test/tests/wasm/multi-value/directives.txt new file mode 100644 index 0000000000..f636e648ec --- /dev/null +++ b/js/src/jit-test/tests/wasm/multi-value/directives.txt @@ -0,0 +1 @@ +|jit-test| test-also=--wasm-compiler=optimizing; test-also=--wasm-compiler=baseline; test-also=--wasm-test-serialization; test-also=--test-wasm-await-tier2; test-also=--disable-wasm-huge-memory; skip-variant-if: --disable-wasm-huge-memory, !wasmHugeMemorySupported(); include:wasm.js diff --git a/js/src/jit-test/tests/wasm/multi-value/ion-inlining.js b/js/src/jit-test/tests/wasm/multi-value/ion-inlining.js new file mode 100644 index 0000000000..0d9a05214e --- /dev/null +++ b/js/src/jit-test/tests/wasm/multi-value/ion-inlining.js @@ -0,0 +1,14 @@ + +let instance = wasmEvalText(` + (module + (func $f (export "f") (result i32 i32 i32) + (i32.const 0) + (i32.const 32) + (i32.const 10)))`); + +const options = getJitCompilerOptions(); +const jitThreshold = options['ion.warmup.trigger'] * 2 + 2; + +for (let i = 0; i < jitThreshold; i++) { + assertDeepEq(instance.exports.f(), [0, 32, 10]); +} diff --git a/js/src/jit-test/tests/wasm/multi-value/regress-1597200.js b/js/src/jit-test/tests/wasm/multi-value/regress-1597200.js new file mode 100644 index 0000000000..542bd542ab --- /dev/null +++ b/js/src/jit-test/tests/wasm/multi-value/regress-1597200.js @@ -0,0 +1,41 @@ +new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(` +(module + (func (export "main") (result i32) + (i32.const 1) + (i32.const 2) + (i32.const 3) + (loop (param i32 i32 i32) + (i32.popcnt) + (i32.const -63) + (br 0)) + (unreachable)))`))); + +wasmFullPass(` +(module + (func (export "run") (result i32) + (block (result i32 i32 i32) + (i32.const 41) + (i32.const 42) + (i32.const 43) + (loop (param i32 i32 i32) + (i32.eqz) + (i32.const -63) + (br 1)) + (unreachable)) + (drop) + (drop)))`, + 42); + +wasmFullPass(` +(module + (func (export "run") (result i32) + (block (result i32 i32 i32) + (i32.popcnt (i32.const 0x0)) + (i32.popcnt (i32.const 0xf)) + (i32.popcnt (i32.const 0xff)) + (i32.popcnt (i32.const 0xfff)) + (block) ;; Force a sync(). + (br 0)) + (drop) + (drop)))`, + 4); diff --git a/js/src/jit-test/tests/wasm/multi-value/regress-1621645-2.js b/js/src/jit-test/tests/wasm/multi-value/regress-1621645-2.js new file mode 100644 index 0000000000..4ba4b3b116 --- /dev/null +++ b/js/src/jit-test/tests/wasm/multi-value/regress-1621645-2.js @@ -0,0 +1,19 @@ +wasmFullPass(` + ;; Iterative factorial without locals. + (func $pick0 (param i64) (result i64 i64) + (local.get 0) (local.get 0) + ) + (func $pick1 (param i64 i64) (result i64 i64 i64) + (local.get 0) (local.get 1) (local.get 0) + ) + (func (export "run") (param i64) (result i64) + (i64.const 1) (local.get 0) + (loop $l (param i64 i64) (result i64) + (call $pick1) (call $pick1) (i64.mul) + (call $pick1) (i64.const 1) (i64.sub) + (call $pick0) (i64.const 0) (i64.gt_u) + (br_if $l) + (drop) (return) + ) + )`, + 7034535277573963776n, {}, 25n); diff --git a/js/src/jit-test/tests/wasm/multi-value/regress-1621645.js b/js/src/jit-test/tests/wasm/multi-value/regress-1621645.js new file mode 100644 index 0000000000..dc9aaf264c --- /dev/null +++ b/js/src/jit-test/tests/wasm/multi-value/regress-1621645.js @@ -0,0 +1,20 @@ +wasmFullPass(` +(module + (func $f (result i64 i64 i64 i64 i64 + i64 i64 i64 i64 i64) + (i64.const 0) + (i64.const 1) + (i64.const 2) + (i64.const 3) + (i64.const 4) + (i64.const 5) + (i64.const 6) + (i64.const 7) + (i64.const 8) + (i64.const 9)) + (func (export "run") (result i32) + (call $f) + (i64.add) (i64.add) (i64.add) (i64.add) (i64.add) + (i64.add) (i64.add) (i64.add) (i64.add) + (i32.wrap_i64)))`, + 45); diff --git a/js/src/jit-test/tests/wasm/multi-value/regress-1628417.js b/js/src/jit-test/tests/wasm/multi-value/regress-1628417.js new file mode 100644 index 0000000000..eb97b2116f --- /dev/null +++ b/js/src/jit-test/tests/wasm/multi-value/regress-1628417.js @@ -0,0 +1,11 @@ +let bytes = wasmTextToBinary(` + (module + (func $main (export "main") (result i32 i32) + (i32.const 1) + (i32.const 2) + (i32.const 0) + (br_table 0 0)))`); + +let instance = new WebAssembly.Instance(new WebAssembly.Module(bytes)); + +instance.exports.main(); diff --git a/js/src/jit-test/tests/wasm/multi-value/regress-1628426.js b/js/src/jit-test/tests/wasm/multi-value/regress-1628426.js new file mode 100644 index 0000000000..ffb13333c4 --- /dev/null +++ b/js/src/jit-test/tests/wasm/multi-value/regress-1628426.js @@ -0,0 +1,22 @@ +// |jit-test| skip-if: !wasmDebuggingEnabled() +var g20 = newGlobal({ + newCompartment: true +}); +g20.parent = this; +g20.eval("Debugger(parent).onEnterFrame = function() {};"); + +let bytes = wasmTextToBinary(` + (module + (func $dup (param i32) (result i32 i32) + (local.get 0) + (local.get 0) + (i32.const 2) + (i32.mul)) + (func $main (export "main") (param i32 i32) (result i32) + (local.get 1) + (call $dup) + (i32.sub)))`); + +let instance = new WebAssembly.Instance(new WebAssembly.Module(bytes)); + +assertEq(instance.exports.main(0, 1), -1) diff --git a/js/src/jit-test/tests/wasm/multi-value/regress-1628429.js b/js/src/jit-test/tests/wasm/multi-value/regress-1628429.js new file mode 100644 index 0000000000..3446e0bc8b --- /dev/null +++ b/js/src/jit-test/tests/wasm/multi-value/regress-1628429.js @@ -0,0 +1,6 @@ +let bytes = wasmTextToBinary(` + (module + (func $f (import "imports" "f") (param i32 i32) (result i32 i32)))`); + +new WebAssembly.Instance(new WebAssembly.Module(bytes), + { 'imports': { 'f': Uint16Array } }); diff --git a/js/src/jit-test/tests/wasm/multi-value/regress-1628499.js b/js/src/jit-test/tests/wasm/multi-value/regress-1628499.js new file mode 100644 index 0000000000..e4360fcb9c --- /dev/null +++ b/js/src/jit-test/tests/wasm/multi-value/regress-1628499.js @@ -0,0 +1,11 @@ +let instance = wasmEvalText(` + (func $twoRefs (result externref externref) + (ref.null extern) + (ref.null extern)) + (func $fourRefs (export "run") (result externref externref externref externref externref externref) + call $twoRefs + call $twoRefs + call $twoRefs) +`); + +assertDeepEq(instance.exports.run(), [null, null, null, null, null, null]) diff --git a/js/src/jit-test/tests/wasm/multi-value/regress-1629496.js b/js/src/jit-test/tests/wasm/multi-value/regress-1629496.js new file mode 100644 index 0000000000..220fcf8d3d --- /dev/null +++ b/js/src/jit-test/tests/wasm/multi-value/regress-1629496.js @@ -0,0 +1,9 @@ +let bytes = wasmTextToBinary(` + (module + (func $f (param) (result i32 i32) + (local i32) + (loop) + (i32.const 0) + (i32.const 1)))`); + +new WebAssembly.Instance(new WebAssembly.Module(bytes)); diff --git a/js/src/jit-test/tests/wasm/multi-value/regress-1631423.js b/js/src/jit-test/tests/wasm/multi-value/regress-1631423.js new file mode 100644 index 0000000000..2460830dfd --- /dev/null +++ b/js/src/jit-test/tests/wasm/multi-value/regress-1631423.js @@ -0,0 +1,15 @@ +wasmEvalText(` + (module + (func $main (export "main") + (local i32) + i32.const 1 + i32.const 2 + i32.const 3 + (loop (param i32 i32 i32) + local.get 0 + i32.const 4 + i32.const 5 + i32.const 6 + i32.const 7 + br_if 0 + unreachable)))`); diff --git a/js/src/jit-test/tests/wasm/multi-value/regress-1661723.js b/js/src/jit-test/tests/wasm/multi-value/regress-1661723.js new file mode 100644 index 0000000000..3248c13444 --- /dev/null +++ b/js/src/jit-test/tests/wasm/multi-value/regress-1661723.js @@ -0,0 +1,23 @@ +let { exports } = new WebAssembly.Instance( + new WebAssembly.Module(wasmTextToBinary(` + (module + (func (import "module" "fn") (param f64 i32) (result i32 f64)) + (func (export "f") (result i32) + f64.const 4.2 + i32.const 7 + call 0 + drop + ) + ) + `)), + { + "module": { + fn(f32, i32) { + assertEq(f32, 4.2); + assertEq(i32, 7); + return [2, 7.3]; + }, + } + }); + +assertEq(exports.f(), 2); |