summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/wasm/regress
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /js/src/jit-test/tests/wasm/regress
parentInitial commit. (diff)
downloadfirefox-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 'js/src/jit-test/tests/wasm/regress')
-rw-r--r--js/src/jit-test/tests/wasm/regress/baseline-arm64-chunk-pop.js31
-rw-r--r--js/src/jit-test/tests/wasm/regress/baseline-builtin-abi.js20
-rw-r--r--js/src/jit-test/tests/wasm/regress/baseline-bytereg.js34
-rw-r--r--js/src/jit-test/tests/wasm/regress/baseline-extend8.js34
-rw-r--r--js/src/jit-test/tests/wasm/regress/baseline-getglobal-scratch.js58
-rw-r--r--js/src/jit-test/tests/wasm/regress/baseline-i64-opt-cmp.js16
-rw-r--r--js/src/jit-test/tests/wasm/regress/baseline-joinreg.js16
-rw-r--r--js/src/jit-test/tests/wasm/regress/baseline-many-results.js63
-rw-r--r--js/src/jit-test/tests/wasm/regress/baseline-nops-jumptable.js12
-rw-r--r--js/src/jit-test/tests/wasm/regress/baseline-pop-along-edge.js66
-rw-r--r--js/src/jit-test/tests/wasm/regress/baseline-pop-before-capture.js12
-rw-r--r--js/src/jit-test/tests/wasm/regress/baseline-stack-height.js1
-rw-r--r--js/src/jit-test/tests/wasm/regress/baseline-stack-height.wasmbin0 -> 67032 bytes
-rw-r--r--js/src/jit-test/tests/wasm/regress/brtable-conditionblock-folding.js17
-rw-r--r--js/src/jit-test/tests/wasm/regress/bug1300546.js28
-rw-r--r--js/src/jit-test/tests/wasm/regress/bug1311019.js9
-rw-r--r--js/src/jit-test/tests/wasm/regress/bug1392105.js8
-rw-r--r--js/src/jit-test/tests/wasm/regress/bug1440512.js216
-rw-r--r--js/src/jit-test/tests/wasm/regress/bug1450800.js27
-rw-r--r--js/src/jit-test/tests/wasm/regress/bug1467415.js29
-rw-r--r--js/src/jit-test/tests/wasm/regress/bug1491322.js35
-rw-r--r--js/src/jit-test/tests/wasm/regress/bug1502886.js30
-rw-r--r--js/src/jit-test/tests/wasm/regress/bug1507314.js6
-rw-r--r--js/src/jit-test/tests/wasm/regress/bug1533204.js10
-rw-r--r--js/src/jit-test/tests/wasm/regress/bug1566992.js14
-rw-r--r--js/src/jit-test/tests/wasm/regress/bug1569137.js65
-rw-r--r--js/src/jit-test/tests/wasm/regress/bug1590920.js11
-rw-r--r--js/src/jit-test/tests/wasm/regress/bug1678542.js11
-rw-r--r--js/src/jit-test/tests/wasm/regress/bug1678785.js20
-rw-r--r--js/src/jit-test/tests/wasm/regress/bug1684861.js54
-rw-r--r--js/src/jit-test/tests/wasm/regress/bug1699647.js10
-rw-r--r--js/src/jit-test/tests/wasm/regress/bug1700610.js8
-rw-r--r--js/src/jit-test/tests/wasm/regress/bug1708124.js10
-rw-r--r--js/src/jit-test/tests/wasm/regress/bug1713581.js13
-rw-r--r--js/src/jit-test/tests/wasm/regress/bug1727284/directives.txt1
-rw-r--r--js/src/jit-test/tests/wasm/regress/bug1727284/test.js12
-rw-r--r--js/src/jit-test/tests/wasm/regress/bug1747870.js19
-rw-r--r--js/src/jit-test/tests/wasm/regress/bug1761850.js79
-rw-r--r--js/src/jit-test/tests/wasm/regress/bug1762899.js34
-rw-r--r--js/src/jit-test/tests/wasm/regress/bug1770335.js33
-rw-r--r--js/src/jit-test/tests/wasm/regress/bug1836708.js19
-rw-r--r--js/src/jit-test/tests/wasm/regress/builtin-import-sigs.js15
-rw-r--r--js/src/jit-test/tests/wasm/regress/caller-property.js7
-rw-r--r--js/src/jit-test/tests/wasm/regress/current-memory-tls.js95
-rw-r--r--js/src/jit-test/tests/wasm/regress/debug-clone-segment.js36
-rw-r--r--js/src/jit-test/tests/wasm/regress/debug-exception-in-fast-import.js21
-rw-r--r--js/src/jit-test/tests/wasm/regress/debug-osr.js16
-rw-r--r--js/src/jit-test/tests/wasm/regress/directives.txt1
-rw-r--r--js/src/jit-test/tests/wasm/regress/enable-profiling-in-import.js9
-rw-r--r--js/src/jit-test/tests/wasm/regress/frame-offset-stack-arg.js38
-rw-r--r--js/src/jit-test/tests/wasm/regress/fuzzsafe-bug1645610.js15
-rw-r--r--js/src/jit-test/tests/wasm/regress/gvn-unremovable-phi.js20
-rw-r--r--js/src/jit-test/tests/wasm/regress/imul64-ion-negative-power-of-two.js11
-rw-r--r--js/src/jit-test/tests/wasm/regress/ion-callerfp-tag.js28
-rw-r--r--js/src/jit-test/tests/wasm/regress/ion-error-gc-fakeexitframe.js81
-rw-r--r--js/src/jit-test/tests/wasm/regress/ion-inlinedcall-resumepoint.js50
-rw-r--r--js/src/jit-test/tests/wasm/regress/ion-lazy-stubs-jit.js13
-rw-r--r--js/src/jit-test/tests/wasm/regress/ion-many-results.js17
-rw-r--r--js/src/jit-test/tests/wasm/regress/jit-updatepcquad.js31
-rw-r--r--js/src/jit-test/tests/wasm/regress/lazy-table-nan.js10
-rw-r--r--js/src/jit-test/tests/wasm/regress/load-lane-oob.js14
-rw-r--r--js/src/jit-test/tests/wasm/regress/long-select.js38
-rw-r--r--js/src/jit-test/tests/wasm/regress/misc-control-flow.js227
-rw-r--r--js/src/jit-test/tests/wasm/regress/movable-traps.js38
-rw-r--r--js/src/jit-test/tests/wasm/regress/no-directives/debugger-no-script.js19
-rw-r--r--js/src/jit-test/tests/wasm/regress/nop-fill-jit-exit.js28
-rw-r--r--js/src/jit-test/tests/wasm/regress/null-call.js14
-rw-r--r--js/src/jit-test/tests/wasm/regress/null-metadata-filename.js20
-rw-r--r--js/src/jit-test/tests/wasm/regress/onlyjsiter-while-wasm.js13
-rw-r--r--js/src/jit-test/tests/wasm/regress/oom-eval.js7
-rw-r--r--js/src/jit-test/tests/wasm/regress/oom-init.js21
-rw-r--r--js/src/jit-test/tests/wasm/regress/oom-masm-baseline.js31
-rw-r--r--js/src/jit-test/tests/wasm/regress/oom-wasm-streaming.js14
-rw-r--r--js/src/jit-test/tests/wasm/regress/oom-wasmtexttobinary-block.js7
-rw-r--r--js/src/jit-test/tests/wasm/regress/pass-stack-int64.js15
-rw-r--r--js/src/jit-test/tests/wasm/regress/proxy-get-trap-table.js14
-rw-r--r--js/src/jit-test/tests/wasm/regress/regalloc-i64-load-store-global.js20
-rw-r--r--js/src/jit-test/tests/wasm/regress/regalloc-muli64.js14
-rw-r--r--js/src/jit-test/tests/wasm/regress/reserve-enough.js13
-rw-r--r--js/src/jit-test/tests/wasm/regress/reserve-joinreg.js22
-rw-r--r--js/src/jit-test/tests/wasm/regress/savedframe-lookup-in-wasm.js17
-rw-r--r--js/src/jit-test/tests/wasm/regress/select-any.js41
-rw-r--r--js/src/jit-test/tests/wasm/regress/shift-counts.js8
-rw-r--r--js/src/jit-test/tests/wasm/regress/signed-unsigned-div-mod.js75
-rw-r--r--js/src/jit-test/tests/wasm/regress/startfunc-in-table.js6
-rw-r--r--js/src/jit-test/tests/wasm/regress/table-of-anyref.js9
-rw-r--r--js/src/jit-test/tests/wasm/regress/teavm-bugs.js53
-rw-r--r--js/src/jit-test/tests/wasm/regress/too-large-frame.js27
-rw-r--r--js/src/jit-test/tests/wasm/regress/unaligned-store64.js35
-rw-r--r--js/src/jit-test/tests/wasm/regress/upper-maximum-memory.js4
90 files changed, 2569 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/wasm/regress/baseline-arm64-chunk-pop.js b/js/src/jit-test/tests/wasm/regress/baseline-arm64-chunk-pop.js
new file mode 100644
index 0000000000..23aa5934a4
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/baseline-arm64-chunk-pop.js
@@ -0,0 +1,31 @@
+var bin = wasmTextToBinary(
+ `(module
+ (func (export "f4786") (result i32)
+ (local i32 i64 i64 i64 f32)
+ i32.const 1
+ tee_local 0
+ local.get 0
+ local.get 0
+ local.get 0
+ local.get 0
+ local.get 0
+ local.get 0
+ local.get 0
+ if (result i32)
+ local.get 0
+ else
+ local.get 0
+ tee_local 0
+ local.get 0
+ br_if 1
+ end
+ drop
+ drop
+ drop
+ drop
+ drop
+ drop
+ drop))`);
+var ins = new WebAssembly.Instance(new WebAssembly.Module(bin));
+ins.exports.f4786();
+
diff --git a/js/src/jit-test/tests/wasm/regress/baseline-builtin-abi.js b/js/src/jit-test/tests/wasm/regress/baseline-builtin-abi.js
new file mode 100644
index 0000000000..16de2dc400
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/baseline-builtin-abi.js
@@ -0,0 +1,20 @@
+// Bug 1488515 - ABI issues on Android because both the baseline compiler and
+// the builtin thunks converted between hardFP and softFP.
+
+var prog = wasmEvalText(
+ `(module
+ (func $f64div (export "test") (param $a f64) (param $b f64) (result f64)
+ (local $dummy0 i32)
+ (local $dummy1 i32)
+ (local $dummy2 i32)
+ (local $dummy3 i32)
+ (local $dummy4 i32)
+ (local $x f64)
+ (local $y f64)
+ (local $z f64)
+ (local.set $x (local.get $a))
+ (local.set $y (local.get $b))
+ (local.set $z (f64.floor (f64.div (local.get $x) (local.get $y))))
+ (local.get $z)))`);
+
+assertEq(prog.exports.test(16096, 32), 503);
diff --git a/js/src/jit-test/tests/wasm/regress/baseline-bytereg.js b/js/src/jit-test/tests/wasm/regress/baseline-bytereg.js
new file mode 100644
index 0000000000..8bdcc32618
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/baseline-bytereg.js
@@ -0,0 +1,34 @@
+// Bug 1322450 is about the baseline compiler not properly handling a byte store
+// from a wider datum on 32-bit x86 because it does not move the value to be
+// stored to a valid byte register if it is in a 32-bit register that does not
+// have a byte part (EDI/ESI/EBP).
+//
+// This test is white-box because it knows about the register allocation order:
+// the two values pushed onto the stack occupy EAX and ECX, and the i64.store8
+// will use EDX for the index and (EDI or ESI or EBP) for the low register of
+// the value to be stored. The i64.store8 instruction will then assert in the
+// assembler.
+//
+// If the baseline compiler starts allocating registers in a different order
+// then this test will be ineffective.
+
+wasmEvalText(`(module
+ (memory 1)
+ (func $run (param i64) (param i32) (param i32)
+ local.get 1
+ local.get 2
+ i32.add
+
+ local.get 1
+ local.get 2
+ i32.add
+
+ i32.const 0
+ local.get 0
+ i64.store8
+
+ drop
+ drop
+ )
+ (export "run" (func $run))
+)`);
diff --git a/js/src/jit-test/tests/wasm/regress/baseline-extend8.js b/js/src/jit-test/tests/wasm/regress/baseline-extend8.js
new file mode 100644
index 0000000000..6e637e97c9
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/baseline-extend8.js
@@ -0,0 +1,34 @@
+// This attempts to test that we can do an 8-bit sign extend no matter what the
+// source register. This test is arguably somewhat tied to the baseline
+// compiler's register allocator, but is still appropriate for most simple
+// register allocators. It works by filling an increasing number of registers
+// with values so as eventually to force the source operand for extend8_s into a
+// register that does not have a byte personality.
+
+for ( let i=0; i < 8; i++) {
+ let txt =
+ `(module
+ (func (export "f") (param i32) (result i32)
+ ${adds(i)}
+ (local.set 0 (i32.extend8_s (i32.add (local.get 0) (i32.const 1))))
+ ${drops(i)}
+ (local.get 0)))`;
+ let ins = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(txt)));
+ assertEq(ins.exports.f(254), -1);
+}
+
+function adds(n) {
+ let s = ""
+ for ( let i=0; i < n; i++ )
+ s += "(i32.add (local.get 0) (i32.const 1))\n";
+ return s;
+}
+
+function drops(n) {
+ let s = "";
+ for ( let i=0; i < n; i++ )
+ s += "drop\n";
+ return s;
+}
+
+
diff --git a/js/src/jit-test/tests/wasm/regress/baseline-getglobal-scratch.js b/js/src/jit-test/tests/wasm/regress/baseline-getglobal-scratch.js
new file mode 100644
index 0000000000..2f4d74b912
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/baseline-getglobal-scratch.js
@@ -0,0 +1,58 @@
+new WebAssembly.Module(wasmTextToBinary(`
+(module
+ (global $g (mut i32) (i32.const 42))
+ (func (param $i i32)
+ local.get $i
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ unreachable
+ )
+)
+`));
+
+new WebAssembly.Module(wasmTextToBinary(`
+(module
+ (global $g (mut i32) (i32.const 42))
+ (func (param $i i32)
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ global.get $g
+ local.get $i
+ global.set $g
+ unreachable
+ )
+)
+`));
diff --git a/js/src/jit-test/tests/wasm/regress/baseline-i64-opt-cmp.js b/js/src/jit-test/tests/wasm/regress/baseline-i64-opt-cmp.js
new file mode 100644
index 0000000000..eb6cafb8f0
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/baseline-i64-opt-cmp.js
@@ -0,0 +1,16 @@
+// Bug 1404760: Optimized compare-and-branch with a preserved value would fail
+// the baseline compiler on x86 debug builds (and would just generate bad code
+// on non-debug builds) because of register starvation.
+
+wasmEvalText(
+ `(module
+ (func $run (param i64) (param i64) (result i64)
+ block (result i64)
+ i64.const 1
+ (i64.lt_s (local.get 0) (local.get 1))
+ br_if 0
+ drop
+ i64.const 2
+ end)
+ (export "run" (func $run)))`
+);
diff --git a/js/src/jit-test/tests/wasm/regress/baseline-joinreg.js b/js/src/jit-test/tests/wasm/regress/baseline-joinreg.js
new file mode 100644
index 0000000000..01bc3d5bbc
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/baseline-joinreg.js
@@ -0,0 +1,16 @@
+// Bug 1322288 is about the floating join register not being reserved properly
+// in the presence of boolean evaluation for control. The situation is that a
+// conditional branch passes a floating point value to the join point; the join register
+// must be available when it does that, but could have been allocated to the operands of
+// the conditional expression of the control flow.
+//
+// This test is white-box: it depends on the floating join reg being among the first
+// floating registers to be allocated.
+
+wasmEvalText(`
+(module
+ (func $run
+ (drop (block (result f64)
+ (drop (br_if 0 (f64.const 1) (f64.eq (f64.const 1) (f64.const 0))))
+ (drop (br 0 (f64.const 2))))))
+ (export "run" (func $run)))`);
diff --git a/js/src/jit-test/tests/wasm/regress/baseline-many-results.js b/js/src/jit-test/tests/wasm/regress/baseline-many-results.js
new file mode 100644
index 0000000000..ff4d9c35dd
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/baseline-many-results.js
@@ -0,0 +1,63 @@
+// This provokes a crash in baseline if its Stk reservation logic is not up to
+// snuff, bug 1675844.
+
+var txt = `
+(module
+ (type (;0;) (func (result f32 f32 i32)))
+ (func $main (type 0) (result f32 f32 i32)
+ call $main
+ call $main
+ call $main
+ call $main
+ call $main
+ call $main
+ call $main
+ call $main
+ call $main
+ call $main
+ call $main
+ call $main
+ call $main
+ call $main
+ call $main
+ call $main
+ call $main
+ call $main
+ call $main
+ memory.size
+ call $main
+ call $main
+ call $main
+ call_indirect (type 0)
+ call $main
+ call $main
+ call $main
+ call $main
+ call $main
+ call $main
+ memory.size
+ call $main
+ call $main
+ call $main
+ call_indirect (type 0)
+ call $main
+ call $main
+ call $main
+ call $main
+ call $main
+ call $main
+ call $main
+ call $main
+ call $main
+ call $main
+ call $main
+ call $main
+ memory.size)
+ (table (;0;) 62 255 funcref)
+ (memory (;0;) 15 18)
+ (export "t1" (table 0))
+ (export "memory" (memory 0)))`;
+assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(txt)),
+ WebAssembly.CompileError,
+ /(unused values not explicitly dropped)|(expected f32, found i32)/);
+
diff --git a/js/src/jit-test/tests/wasm/regress/baseline-nops-jumptable.js b/js/src/jit-test/tests/wasm/regress/baseline-nops-jumptable.js
new file mode 100644
index 0000000000..e4388296fb
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/baseline-nops-jumptable.js
@@ -0,0 +1,12 @@
+// |jit-test| --arm-asm-nop-fill=1
+var f = wasmEvalText(`(module (func (param i32) (result i32)
+ (block $0
+ (block $1
+ (block $2
+ (block $default
+ (br_table $0 $1 $2 $default (local.get 0))))))
+ (return (i32.const 0)))
+ (export "" (func 0))
+)`).exports[""];
+
+f(0);
diff --git a/js/src/jit-test/tests/wasm/regress/baseline-pop-along-edge.js b/js/src/jit-test/tests/wasm/regress/baseline-pop-along-edge.js
new file mode 100644
index 0000000000..650931c99a
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/baseline-pop-along-edge.js
@@ -0,0 +1,66 @@
+// Bug 1316181
+
+// There are locals with different values here to ensure that the
+// local.get at the end picks up the right one even if the stack might
+// have become unbalanced by a failure to adjust SP along the branch
+// edge. The logic is that we use SP-relative addressing, and if the
+// actual SP is not what the compiler thinks it is we will read
+// something other than the expected value.
+
+var o = wasmEvalText(
+ `(module
+ (func (result i32)
+ (local $v0 i32)
+ (local $v1 i32)
+ (local $v2 i32)
+ (local $v3 i32)
+ (local $v4 i32)
+ (local $v5 i32)
+ (local $v6 i32)
+ (local $v7 i32)
+ (local $res i32)
+ (local.set $v0 (i32.const 0xDEADBEEF))
+ (local.set $v1 (i32.const 0xFDEADBEE))
+ (local.set $v2 (i32.const 0xEFDEADBE))
+ (local.set $v3 (i32.const 0xEEFDEADB))
+ (local.set $v4 (i32.const 0xBEEFDEAD))
+ (local.set $v5 (i32.const 0xDBEEFDEA))
+ (local.set $v6 (i32.const 0xADBEEFDE))
+ (local.set $v7 (i32.const 0xEADBEEFD))
+ (block $b
+ (local.set $res
+ (i32.add
+ (i32.add (i32.const 1) (i32.const 2))
+ (i32.add
+ (i32.add (i32.const 3) (i32.const 4))
+ (i32.add
+ (i32.add (i32.const 5) (i32.const 6))
+ (i32.add
+ (i32.add (i32.const 7) (i32.const 8))
+ (i32.add
+ (i32.add (i32.const 9) (i32.const 10))
+ (i32.add
+ (i32.add (i32.const 11) (i32.const 12))
+ (i32.add
+ (i32.add (i32.const 13) (i32.const 14))
+ (i32.add
+ (i32.add (i32.const 15) (i32.const 16))
+ (i32.add
+ (i32.add (i32.const 17) (i32.const 18))
+ (i32.add
+ (i32.add (i32.const 19) (i32.const 20))
+ (i32.add
+ (i32.add (i32.const 21) (i32.const 22))
+ (i32.add
+ (i32.add (i32.const 23) (i32.const 24))
+ (i32.add
+ (i32.add (i32.const 25) (i32.const 26))
+ (i32.add
+ (i32.add (i32.const 27) (i32.const 28))
+ (i32.add
+ (i32.add (i32.const 29) (i32.const 30))
+ (br_if $b (i32.const 31) (i32.const 1)))))))))))))))))))
+ (return (local.get $v3)))
+ (export "a" (func 0)))`).exports;
+
+assertEq(o["a"](), 0xEEFDEADB|0);
diff --git a/js/src/jit-test/tests/wasm/regress/baseline-pop-before-capture.js b/js/src/jit-test/tests/wasm/regress/baseline-pop-before-capture.js
new file mode 100644
index 0000000000..b3a41f6949
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/baseline-pop-before-capture.js
@@ -0,0 +1,12 @@
+// Bug 1319415
+
+var src =
+`(module
+ (func (result i32)
+ i32.const 0
+ i32.const 1
+ br_if 0
+ unreachable)
+ (export "run" (func 0)))`;
+
+wasmFullPass(src, 0);
diff --git a/js/src/jit-test/tests/wasm/regress/baseline-stack-height.js b/js/src/jit-test/tests/wasm/regress/baseline-stack-height.js
new file mode 100644
index 0000000000..185a7c3069
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/baseline-stack-height.js
@@ -0,0 +1 @@
+new WebAssembly.Module(os.file.readFile(scriptdir + "/baseline-stack-height.wasm", 'binary'));
diff --git a/js/src/jit-test/tests/wasm/regress/baseline-stack-height.wasm b/js/src/jit-test/tests/wasm/regress/baseline-stack-height.wasm
new file mode 100644
index 0000000000..cc25a1dac8
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/baseline-stack-height.wasm
Binary files differ
diff --git a/js/src/jit-test/tests/wasm/regress/brtable-conditionblock-folding.js b/js/src/jit-test/tests/wasm/regress/brtable-conditionblock-folding.js
new file mode 100644
index 0000000000..6692a7473b
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/brtable-conditionblock-folding.js
@@ -0,0 +1,17 @@
+assertEq(wasmEvalText(`
+(module
+ (func $f (param $p i32)
+ block $out
+ i32.const 0
+ if
+ i32.const 1
+ tee_local $p
+ br_table $out $out
+ end
+ end
+ local.get $p
+ br_if 0
+ )
+ (export "f" (func $f))
+)
+`).exports.f(42), undefined);
diff --git a/js/src/jit-test/tests/wasm/regress/bug1300546.js b/js/src/jit-test/tests/wasm/regress/bug1300546.js
new file mode 100644
index 0000000000..2897995deb
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/bug1300546.js
@@ -0,0 +1,28 @@
+try {
+ wasmEvalText(`
+ (module
+ (type $type0 (func))
+ (func $func0
+ (nop)
+ (f64.load offset=59 align=1 (i32.const 0))
+ (memory.size)
+ (memory.size)
+ (memory.size)
+ (memory.size)
+ (memory.size)
+ (memory.size)
+ (memory.size)
+ (memory.size)
+ (i64.rem_s (i64.const 17) (i64.xor (i64.const 17) (i64.xor (i64.const 17) (i64.xor (i64.xor (i64.const 17) (i64.const 17)) (i64.xor (i64.const 17) (i64.const 17))))))
+
+ (i64.rem_s
+ (i64.const 17)
+ (i64.xor
+ (i64.rem_s (i64.const 17) (i64.const 17))
+ (i64.xor (i64.rem_s (i64.const 17) (i64.const 17)) (i64.xor (i64.const 17) (i64.const 17)))))
+ )
+ (memory 1 1)
+ )
+ `);
+} catch(e) {
+}
diff --git a/js/src/jit-test/tests/wasm/regress/bug1311019.js b/js/src/jit-test/tests/wasm/regress/bug1311019.js
new file mode 100644
index 0000000000..3c5c39e352
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/bug1311019.js
@@ -0,0 +1,9 @@
+new WebAssembly.Module(wasmTextToBinary(`(module
+ (memory 1)
+ (func
+ (i64.trunc_s/f32 (f32.const 6.96875))
+ (i32.load8_s (i32.const 0))
+ (f32.const -7.66028056e-31)
+ (unreachable)
+ )
+)`));
diff --git a/js/src/jit-test/tests/wasm/regress/bug1392105.js b/js/src/jit-test/tests/wasm/regress/bug1392105.js
new file mode 100644
index 0000000000..4752da8ddf
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/bug1392105.js
@@ -0,0 +1,8 @@
+// |jit-test| --arm-asm-nop-fill=1
+
+var code = "(module ";
+for (var i = 0; i < 100; i++)
+ code += "(func (param i32) (result i32) (i32.add (i32.const 1) (local.get 0))) ";
+code += ")";
+var buf = wasmTextToBinary(code);
+WebAssembly.compile(buf);
diff --git a/js/src/jit-test/tests/wasm/regress/bug1440512.js b/js/src/jit-test/tests/wasm/regress/bug1440512.js
new file mode 100644
index 0000000000..1997b34f7f
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/bug1440512.js
@@ -0,0 +1,216 @@
+// |jit-test| skip-if: !wasmDebuggingEnabled()
+var g = newGlobal({newCompartment: true});
+var dbg = new g.Debugger(this);
+var dbg = new Debugger;
+var kWasmH0 = 0;
+var kWasmH1 = 0x61;
+var kWasmH2 = 0x73;
+var kWasmH3 = 0x6d;
+var kWasmV0 = 0x1;
+var kWasmV1 = 0;
+var kWasmV2 = 0;
+var kWasmV3 = 0;
+let kTypeSectionCode = 1; // Function signature declarations
+let kImportSectionCode = 2; // Import declarations
+let kFunctionSectionCode = 3; // Function declarations
+let kExportSectionCode = 7; // Exports
+let kCodeSectionCode = 10; // Function code
+let kWasmFunctionTypeForm = 0x60;
+let kWasmI32 = 0x7f;
+let kExternalFunction = 0;
+let kSig_i_i = makeSig([kWasmI32], [kWasmI32]);
+function makeSig(params, results) {
+ return {
+ params: params,
+ results: results
+ };
+}
+let kExprEnd = 0x0b;
+let kExprGetLocal = 0x20;
+class Binary extends Array {
+ emit_u8(val) {
+ this.push(val);
+ }
+ emit_u32v(val) {
+ while (true) {
+ let v = val & 0xff;
+ val = val >>> 7;
+ this.push(v);
+ break;
+ }
+ }
+ emit_bytes(data) {
+ for (let i = 0; i < data.length; i++) {
+ this.push(data[i] & 0xff);
+ }
+ }
+ emit_string(string) {
+ 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) {
+ this.emit_u8(section_code);
+ let section = new Binary;
+ content_generator(section);
+ this.emit_u32v(section.length);
+ for (var i = 0; i < section.length; i++) this.push(section[i]);
+ }
+}
+class WasmFunctionBuilder {
+ constructor(module, name, type_index) {
+ this.module = module;
+ }
+ exportAs(name) {
+ this.module.addExport(name, this.index);
+ }
+ addBody(body) {
+ this.body = body.slice();
+ this.body.push(kExprEnd);
+ return this;
+ }
+}
+class WasmModuleBuilder {
+ constructor() {
+ this.types = [];
+ this.imports = [];
+ this.exports = [];
+ this.functions = [];
+ }
+ addType(type) {
+ this.types.push(type);
+ }
+ addFunction(name, type) {
+ let type_index = (typeof type) == "number" ? type : this.addType(type);
+ let func = new WasmFunctionBuilder(this, name, type_index);
+ this.functions.push(func);
+ return func;
+ }
+ addImport(module = "", name, type) {
+ this.imports.push({
+ module: module,
+ name: name,
+ kind: kExternalFunction,
+ });
+ }
+ addExport(name, index) {
+ this.exports.push({
+ name: name,
+ });
+ }
+ toArray(debug = false) {
+ let binary = new Binary;
+ let wasm = this;
+ binary.emit_header();
+ if (wasm.types.length > 0) {
+ 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);
+ }
+ }
+ });
+ 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);
+ }
+ }
+ });
+ binary.emit_section(kFunctionSectionCode, section => {
+ section.emit_u32v(wasm.functions.length);
+ for (let func of wasm.functions) {
+ section.emit_u32v(func.type_index);
+ }
+ });
+ }
+ var mem_export = (wasm.memory !== undefined && wasm.memory.exp);
+ var exports_count = wasm.exports.length + (mem_export ? 1 : 0);
+ if (exports_count > 0) {
+ 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_u8(0);
+ }
+ });
+ }
+ if (wasm.start_index !== undefined) {
+ }
+ if (wasm.functions.length > 0) {
+ binary.emit_section(kCodeSectionCode, section => {
+ section.emit_u32v(wasm.functions.length);
+ for (let func of wasm.functions) {
+ let local_decls = [];
+ let header = new Binary;
+ header.emit_u32v(local_decls.length);
+ section.emit_u32v(header.length + func.body.length);
+ section.emit_bytes(header);
+ section.emit_bytes(func.body);
+ }
+ });
+ }
+ let num_function_names = 0;
+ let num_functions_with_local_names = 0;
+ if (num_function_names > 0 || num_functions_with_local_names > 0 || wasm.name !== undefined) {
+ binary.emit_section(kUnknownSectionCode, section => {
+ if (num_function_names > 0) {
+ }
+ });
+ }
+ 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];
+ view[i] = val | 0;
+ }
+ return buffer;
+ }
+ toModule(debug = false) {
+ return new WebAssembly.Module(this.toBuffer(debug));
+ }
+}
+const verifyHeap = gc;
+function testProperties(obj) {
+ for (let i = 0; i < 3; i++) {
+ verifyHeap();
+ }
+}
+(function ExportedFunctionTest() {
+ var builder = new WasmModuleBuilder();
+ builder.addFunction("exp", kSig_i_i).addBody([
+ kExprGetLocal, 0,
+ ]).exportAs("exp");
+ let module1 = builder.toModule();
+ let instance1 = new WebAssembly.Instance(module1);
+ let g = instance1.exports.exp;
+ testProperties(g);
+ builder.addImport("imp", "func", kSig_i_i);
+ let module2 = builder.toModule();
+ let instance2 = new WebAssembly.Instance(module2, {
+ imp: {
+ func: g
+ }
+ });
+})();
diff --git a/js/src/jit-test/tests/wasm/regress/bug1450800.js b/js/src/jit-test/tests/wasm/regress/bug1450800.js
new file mode 100644
index 0000000000..fb8493c102
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/bug1450800.js
@@ -0,0 +1,27 @@
+// |jit-test| skip-if: !this.gczeal || !WebAssembly.Global
+
+gczeal(9, 10);
+function wasmEvalText(str, imports) {
+ let binary = wasmTextToBinary(str);
+ m = new WebAssembly.Module(binary);
+ return new WebAssembly.Instance(m, imports);
+}
+assertEq(wasmEvalText(`(module
+ (global (import "a" "b") i32)
+ (export "g" (global 0))
+ (func (export "get") (result i32) global.get 0))`,
+ { a: { b: 42 }}).exports.get(),
+ 42);
+for (let v of []) {}
+function testInitExpr(type, initialValue, nextValue, coercion, assertFunc = assertEq) {
+ var module = wasmEvalText(`(module
+ (import "globals" "a" (global ${type}))
+ (global $glob_imm ${type} (global.get 0))
+ (export "global_imm" (global $glob_imm))
+ )`, {
+ globals: {
+ a: coercion(initialValue)
+ }
+ }).exports;
+}
+testInitExpr('i32', 13, 37, x => x | 0);
diff --git a/js/src/jit-test/tests/wasm/regress/bug1467415.js b/js/src/jit-test/tests/wasm/regress/bug1467415.js
new file mode 100644
index 0000000000..177e67ba08
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/bug1467415.js
@@ -0,0 +1,29 @@
+
+// This exposed an alias analysis bug in the Wasm Ion machinery. It should
+// compute 125 (88 + 37) but with the bug would compute 176 (88 + 88) instead.
+// See bug 1467415.
+
+let mt = `
+(module
+ (import "m" "g" (global (mut i32)))
+ (import "m" "h" (global (mut i32)))
+ (memory 1 1)
+ (data (i32.const 0) "\\01\\00\\00\\00\\01\\00\\00\\00\\01\\00\\00\\00")
+ (func (export "f") (result i32)
+ (local i32)
+ (local i32)
+ (block (result i32)
+ (local.set 0 (global.get 0))
+ (block (result i32)
+ (global.set 1 (i32.const 37))
+ (block (result i32)
+ (local.set 1 (global.get 0))
+ (i32.add (local.get 0) (local.get 1)))))))
+`;
+
+let glob = new WebAssembly.Global({value:'i32', mutable:true}, 88);
+let module = new WebAssembly.Module(wasmTextToBinary(mt));
+let ins = new WebAssembly.Instance(module, {m:{g:glob, h:glob}});
+
+let shouldBe125 = ins.exports.f();
+assertEq(shouldBe125, 125);
diff --git a/js/src/jit-test/tests/wasm/regress/bug1491322.js b/js/src/jit-test/tests/wasm/regress/bug1491322.js
new file mode 100644
index 0000000000..ae3d6a0e73
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/bug1491322.js
@@ -0,0 +1,35 @@
+// |jit-test| skip-if: !wasmDebuggingEnabled()
+var evalInFrame = (function(global) {
+ var dbgGlobal = newGlobal({newCompartment: true});
+ var dbg = new dbgGlobal.Debugger();
+ dbg.addDebuggee(global);
+})(this);
+const Module = WebAssembly.Module;
+const Instance = WebAssembly.Instance;
+var m = new Module(wasmTextToBinary(`(module
+ (import "" "foo" (func $foo (result i32)))
+ (import "" "bar" (func $bar (result i32)))
+ (table 3 funcref)
+ (func $baz (result i32) (i32.const 13))
+ (elem (i32.const 0) $foo $bar $baz)
+ (export "tbl" (table 0))
+)`));
+var jsFun = () => 83;
+var wasmFun = new Instance(
+ new Module(
+ wasmTextToBinary('(module (func (result i32) (i32.const 42)) (export "foo" (func 0)))')
+ )
+).exports.foo;
+var e1 = new Instance(m, {
+ "": {
+ foo: jsFun,
+ bar: wasmFun
+ }
+}).exports;
+var e2 = new Instance(m, {
+ "": {
+ foo: jsFun,
+ bar: jsFun
+ }
+}).exports;
+e2.tbl.get(0);
diff --git a/js/src/jit-test/tests/wasm/regress/bug1502886.js b/js/src/jit-test/tests/wasm/regress/bug1502886.js
new file mode 100644
index 0000000000..a45bf774a4
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/bug1502886.js
@@ -0,0 +1,30 @@
+newGlobal({newCompartment: true});
+g = newGlobal({newCompartment: true});
+var dbg = Debugger(g);
+gczeal(2, 100);
+function f(x, initFunc) {
+ newGlobal({newCompartment: true});
+ g.eval(`
+ var binary = wasmTextToBinary('${x}');
+ new WebAssembly.Instance(new WebAssembly.Module(binary));
+ `);
+ var wasmScript = dbg.findScripts().filter(s => s.format == 'wasm')[0];
+ var offsets = wasmScript.getPossibleBreakpointOffsets();
+ initFunc({
+ wasmScript,
+ breakpoints: offsets
+ })
+};
+try {
+ f('(module (func nop nop) (export "" (func 0)))',
+ function({
+ wasmScript,
+ breakpoints
+ }) {
+ breakpoints.forEach(function(offset) {
+ wasmScript.setBreakpoint(offset, s = {});
+ });
+ }
+ );
+ f();
+} catch (e) {}
diff --git a/js/src/jit-test/tests/wasm/regress/bug1507314.js b/js/src/jit-test/tests/wasm/regress/bug1507314.js
new file mode 100644
index 0000000000..db07593d87
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/bug1507314.js
@@ -0,0 +1,6 @@
+// |jit-test| --no-sse4
+if (!wasmCachingEnabled())
+ quit(0);
+
+var m = wasmCompileInSeparateProcess(wasmTextToBinary('(module (func (export "run") (result i32) (i32.const 42)))'));
+assertEq(new WebAssembly.Instance(m).exports.run(), 42);
diff --git a/js/src/jit-test/tests/wasm/regress/bug1533204.js b/js/src/jit-test/tests/wasm/regress/bug1533204.js
new file mode 100644
index 0000000000..e901fd066b
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/bug1533204.js
@@ -0,0 +1,10 @@
+// |jit-test| skip-if: helperThreadCount() === 0
+enableOsiPointRegisterChecks();
+evalInWorker(`
+function DiagModule(stdlib, foreign) {
+ "use asm";
+ function diag() {
+ while(1) {}
+ }
+ return {};
+`);
diff --git a/js/src/jit-test/tests/wasm/regress/bug1566992.js b/js/src/jit-test/tests/wasm/regress/bug1566992.js
new file mode 100644
index 0000000000..52d2c0710c
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/bug1566992.js
@@ -0,0 +1,14 @@
+let { exports: { f } } = wasmEvalText(`
+(module
+ (func (export "f")
+ (block
+ i64.const 0xfffffffe00000000
+ i32.wrap_i64
+ br_table 0 1
+ )
+ unreachable
+ )
+)
+`);
+
+assertErrorMessage(f, WebAssembly.RuntimeError, /unreachable/);
diff --git a/js/src/jit-test/tests/wasm/regress/bug1569137.js b/js/src/jit-test/tests/wasm/regress/bug1569137.js
new file mode 100644
index 0000000000..fc0a4a3c39
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/bug1569137.js
@@ -0,0 +1,65 @@
+let { exports: { f } } = wasmEvalText(`
+(module
+ (memory $0 1 1)
+
+ (func (export "f") (result f32)
+ (local $0 i32) (local $1 f64) (local $2 i32)
+
+ (set_local 0 (i32.const 134219779))
+ (set_local 1 (f64.const 3810600700439633677210579e165))
+
+ (f32.floor
+ (loop $label$2 (result f32)
+ (br_if $label$2
+ (i32.load offset=3 align=2
+ (block $label$4 (result i32)
+ (drop
+ (if (result f64)
+ (br_if $label$4
+ (i32.const 4883)
+ (i32.const -124)
+ )
+ (f64.const 77)
+ (block (result f64)
+ (drop
+ (br_if $label$4
+ (i32.const 4194304)
+ (i32.const -8192)
+ )
+ )
+ (return
+ (f32.const 4294967296)
+ )
+ )
+ )
+ )
+ (br_if $label$4
+ (br_if $label$4
+ (i32.const -90)
+ (br_if $label$4
+ (br_if $label$4
+ (local.get $2)
+ (i32.const -16)
+ )
+ (i32.const 15656)
+ )
+ )
+ (block $label$18 (result i32)
+ (i32.eqz
+ (br_if $label$4
+ (i32.const -1)
+ (i32.const 15)
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ (f32.const 23)
+ )
+ )
+ )
+)`);
+
+f();
diff --git a/js/src/jit-test/tests/wasm/regress/bug1590920.js b/js/src/jit-test/tests/wasm/regress/bug1590920.js
new file mode 100644
index 0000000000..1f92db1129
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/bug1590920.js
@@ -0,0 +1,11 @@
+let { exports } = new WebAssembly.Instance(new WebAssembly.Module(
+ wasmTextToBinary(`
+ (module
+ (func (export "g")
+ (drop
+ (block (result i32)
+ (i32.clz (i32.const 1))
+ (if
+ (i32.const 1)
+ (return))))))`)));
+exports.g();
diff --git a/js/src/jit-test/tests/wasm/regress/bug1678542.js b/js/src/jit-test/tests/wasm/regress/bug1678542.js
new file mode 100644
index 0000000000..8c3f44fa6d
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/bug1678542.js
@@ -0,0 +1,11 @@
+var ins = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(`
+(module
+ (global $g (export "g") (mut f64) (f64.const 0))
+ (func $p (param f64) (result f64) (local.get 0))
+ (func (export "f") (param f64) (result f64)
+ (global.set $g (f64.neg (local.get 0)))
+ (call $p (local.get 0))))`)));
+assertEq(ins.exports.f(3), 3);
+assertEq(ins.exports.g.value, -3);
+
+
diff --git a/js/src/jit-test/tests/wasm/regress/bug1678785.js b/js/src/jit-test/tests/wasm/regress/bug1678785.js
new file mode 100644
index 0000000000..b04ac8480b
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/bug1678785.js
@@ -0,0 +1,20 @@
+
+// This exposed a bug in CL's aarch64 isel, in which the -4098 was
+// incorrectly sign-extended out to 64 bits.
+
+let { exports } = new WebAssembly.Instance(new WebAssembly.Module(
+ wasmTextToBinary(`
+ (module
+ (type (;0;) (func))
+ (type (;1;) (func (result i32)))
+ (type (;2;) (func (result i64)))
+ (func (;0;) (type 0)
+ i32.const -4098
+ i32.load16_s offset=1
+ drop)
+ (memory (;0;) 1)
+ (export "g" (func 0)))` )));
+try {
+ exports.g();
+} catch (e) {}
+
diff --git a/js/src/jit-test/tests/wasm/regress/bug1684861.js b/js/src/jit-test/tests/wasm/regress/bug1684861.js
new file mode 100644
index 0000000000..4cb9bb2383
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/bug1684861.js
@@ -0,0 +1,54 @@
+const oob = /index out of bounds/;
+const unaligned = /unaligned memory access/;
+const RuntimeError = WebAssembly.RuntimeError;
+
+// Test memory.atomic.notify unaligned access.
+const module = new WebAssembly.Module(wasmTextToBinary(`(module
+ (type (;0;) (func))
+ (func $main (type 0)
+ i32.const -64
+ i32.const -63
+ memory.atomic.notify offset=1
+ unreachable)
+ (memory (;0;) 4 4)
+ (export "main" (func $main)))`));
+
+const instance = new WebAssembly.Instance(module);
+assertErrorMessage(() => instance.exports.main(), RuntimeError, unaligned);
+
+// Test memory.atomic.notify oob access.
+const module2 = new WebAssembly.Module(wasmTextToBinary(`(module
+ (type (;0;) (func))
+ (func $main (type 0)
+ i32.const -64
+ i32.const -63
+ memory.atomic.notify offset=65536
+ unreachable)
+ (memory (;0;) 4 4)
+ (export "main" (func $main)))`));
+
+const instance2 = new WebAssembly.Instance(module2);
+assertErrorMessage(() => instance2.exports.main(), RuntimeError, oob);
+
+// Test memory.atomic.wait32 and .wait64 unaligned access.
+const module3 = new WebAssembly.Module(wasmTextToBinary(`(module
+ (type (;0;) (func))
+ (func $wait32 (type 0)
+ i32.const -64
+ i32.const 42
+ i64.const 0
+ memory.atomic.wait32 offset=1
+ unreachable)
+ (func $wait64 (type 0)
+ i32.const -64
+ i64.const 43
+ i64.const 0
+ memory.atomic.wait64 offset=3
+ unreachable)
+ (memory (;0;) 4 4 shared)
+ (export "wait32" (func $wait32))
+ (export "wait64" (func $wait64)))`));
+
+const instance3 = new WebAssembly.Instance(module3);
+assertErrorMessage(() => instance3.exports.wait32(), RuntimeError, unaligned);
+assertErrorMessage(() => instance3.exports.wait64(), RuntimeError, unaligned);
diff --git a/js/src/jit-test/tests/wasm/regress/bug1699647.js b/js/src/jit-test/tests/wasm/regress/bug1699647.js
new file mode 100644
index 0000000000..499b88b36d
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/bug1699647.js
@@ -0,0 +1,10 @@
+// |jit-test| skip-if: !wasmSimdEnabled() || !getBuildConfiguration().x86
+
+const module = new Uint8Array([
+ 0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,
+ 5,4,1,1,0,0,7,10,1,6,109,101,109,111,114,121,2,0,10,49,
+ 1,47,0,65,16,253,1,1,1,253,253,1,253,131,1,65,158,232,
+ 68,253,1,1,1,253,100,65,16,253,1,1,1,253,11,0,0,253,1,1,
+ 1,65,158,232,68,253,1,1,0,0,11,0,14,4,110,97,109,101,1,
+ 7,1,0,4,109,97,105,110]);
+new WebAssembly.Module(module)
diff --git a/js/src/jit-test/tests/wasm/regress/bug1700610.js b/js/src/jit-test/tests/wasm/regress/bug1700610.js
new file mode 100644
index 0000000000..ce8b032074
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/bug1700610.js
@@ -0,0 +1,8 @@
+// |jit-test| skip-if: !wasmSimdEnabled() || !getBuildConfiguration().x86
+
+const module = new Uint8Array([
+ 0,97,115,109,1,0,0,0,1,6,1,96,1,127,1,111,3,2,1,0,5,4,1,1,0,0,10,38,1,36,
+ 0,65,1,253,4,0,81,253,21,1,253,4,0,81,253,21,0,253,1,0,81,253,21,1,253,4,
+ 0,81,253,21,0,50,0,0,0,11,0,14,4,110,97,109,101,1,7,1,0,4,109,97,105,110
+]);
+new WebAssembly.Module(module)
diff --git a/js/src/jit-test/tests/wasm/regress/bug1708124.js b/js/src/jit-test/tests/wasm/regress/bug1708124.js
new file mode 100644
index 0000000000..dc035b02e5
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/bug1708124.js
@@ -0,0 +1,10 @@
+// |jit-test| skip-if: !('oomTest' in this)
+// Ensure that trap reporting mechanism doesn't crash under OOM conditions.
+
+oomTest(
+ wasmEvalText(
+ `(module
+ (func (export "f") (result)
+ unreachable))`
+ ).exports.f
+);
diff --git a/js/src/jit-test/tests/wasm/regress/bug1713581.js b/js/src/jit-test/tests/wasm/regress/bug1713581.js
new file mode 100644
index 0000000000..a7201ccb22
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/bug1713581.js
@@ -0,0 +1,13 @@
+function wasmEvalText(str, imports, options) {
+ let binary = wasmTextToBinary(str);
+ m = new WebAssembly.Module(binary, options);
+ return new WebAssembly.Instance(m, imports);
+}
+let ins = wasmEvalText(`
+ (module
+ (func (export "fill0") (param $r externref))
+ )
+`);
+for (let i53 = 0; i53 < 1000; i53++) {
+ ins.exports.fill0("hello")
+}
diff --git a/js/src/jit-test/tests/wasm/regress/bug1727284/directives.txt b/js/src/jit-test/tests/wasm/regress/bug1727284/directives.txt
new file mode 100644
index 0000000000..82e51d5a01
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/bug1727284/directives.txt
@@ -0,0 +1 @@
+|jit-test| --fast-warmup; --ion-warmup-threshold=0; --wasm-compiler=optimizing; include:wasm.js
diff --git a/js/src/jit-test/tests/wasm/regress/bug1727284/test.js b/js/src/jit-test/tests/wasm/regress/bug1727284/test.js
new file mode 100644
index 0000000000..54d7350be9
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/bug1727284/test.js
@@ -0,0 +1,12 @@
+function test() {
+ let instance = wasmEvalText(`
+ (module
+ (global $g (mut externref) (ref.null extern))
+ (func (export "set") (param externref) local.get 0 global.set $g)
+ )
+ `).exports;
+ let obj = { field: null };
+ instance.set(obj);
+ for (var v4 = 0; v4 < 10; v4++) {}
+}
+test();
diff --git a/js/src/jit-test/tests/wasm/regress/bug1747870.js b/js/src/jit-test/tests/wasm/regress/bug1747870.js
new file mode 100644
index 0000000000..2625e965fb
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/bug1747870.js
@@ -0,0 +1,19 @@
+// |jit-test| skip-if: !wasmSimdEnabled()
+
+// This should not release-assert, which it could previously do on some 32-bit
+// platforms due to the too-limited size of a bitfield.
+
+const MaxParams = 1000; // Per spec
+
+var params = '';
+for ( var i=0 ; i < MaxParams-1; i++ ) {
+ params += '(param v128) '
+}
+params += '(param externref)'
+
+new WebAssembly.Module(wasmTextToBinary(`
+(module
+ (func $f)
+ (func ${params} (result externref)
+ (call $f)
+ (local.get ${MaxParams-1})))`));
diff --git a/js/src/jit-test/tests/wasm/regress/bug1761850.js b/js/src/jit-test/tests/wasm/regress/bug1761850.js
new file mode 100644
index 0000000000..609991bde4
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/bug1761850.js
@@ -0,0 +1,79 @@
+// Testing runtime execution of select + comparison operations.
+// Normally they are folded into shorter/faster sequence than select alone.
+
+const floatOps = {
+ lt(a, b) { return a < b ? 0 : 1; },
+ le(a, b) { return a <= b ? 0 : 1; },
+ gt(a, b) { return a > b ? 0 : 1; },
+ ge(a, b) { return a >= b ? 0 : 1; },
+ eq(a, b) { return a === b ? 0 : 1; },
+ ne(a, b) { return a !== b ? 0 : 1; },
+}
+
+for (let ty of ['f32', 'f64']) {
+ for (let op of ['lt', 'le', 'gt', 'ge', 'eq', 'ne']) {
+ const module = new WebAssembly.Module(wasmTextToBinary(`(module
+ (memory (export "memory") 1 1)
+ (func (export "test") (result i32)
+ i32.const 128
+ i32.load8_u
+ i32.const 129
+ i32.load8_u
+ i32.const 0
+ ${ty}.load
+ i32.const ${ty == 'f32' ? 4 : 8}
+ ${ty}.load
+ ${ty}.${op}
+ select
+ )
+ (data (i32.const 128) "\\00\\01"))`));
+ const instance = new WebAssembly.Instance(module);
+ const arr = new (ty == 'f32' ? Float32Array : Float64Array)(instance.exports.memory.buffer);
+ for (let [a, b] of cross(
+ [0, 1, -1e100, Infinity, -Infinity, 1e100, -1e-10, 1/-Infinity, NaN]
+ )) {
+ arr[0] = a; arr[1] = b;
+ assertEq(instance.exports.test(), floatOps[op](arr[0], arr[1]))
+ }
+ }
+}
+
+const intOps = {
+ lt(a, b) { return a < b ? 0 : 1; },
+ le(a, b) { return a <= b ? 0 : 1; },
+ gt(a, b) { return a > b ? 0 : 1; },
+ ge(a, b) { return a >= b ? 0 : 1; },
+ eq(a, b) { return a === b ? 0 : 1; },
+ ne(a, b) { return a !== b ? 0 : 1; },
+}
+
+for (let [ty, signed] of [['i32', true], ['i32', false], ['i64', true], ['i64', false]]) {
+ for (let op of ['lt', 'le', 'gt', 'ge', 'eq', 'ne']) {
+ const module = new WebAssembly.Module(wasmTextToBinary(`(module
+ (memory (export "memory") 1 1)
+ (func (export "test") (result i32)
+ i32.const 128
+ i32.load8_u
+ i32.const 129
+ i32.load8_u
+ i32.const 0
+ ${ty}.load
+ i32.const ${ty == 'i32' ? 4 : 8}
+ ${ty}.load
+ ${ty}.${op}${op[0] == 'l' || op[0] == 'g' ? (signed ? '_s' : '_u') : ''}
+ select
+ )
+ (data (i32.const 128) "\\00\\01"))`));
+ const instance = new WebAssembly.Instance(module);
+ const arr = new (ty == 'i32' ? (signed ? Int32Array : Uint32Array) :
+ (signed ? BigInt64Array : BigUint64Array))
+ (instance.exports.memory.buffer);
+ const c = ty == 'i32' ? (a => a|0) : BigInt;
+ for (let [a, b] of cross(
+ [c(0), ~c(0), c(1), ~c(1), c(1) << c(8), ~c(1) << c(12)]
+ )) {
+ arr[0] = a; arr[1] = b;
+ assertEq(instance.exports.test(), intOps[op](arr[0], arr[1]))
+ }
+ }
+}
diff --git a/js/src/jit-test/tests/wasm/regress/bug1762899.js b/js/src/jit-test/tests/wasm/regress/bug1762899.js
new file mode 100644
index 0000000000..3938c93a02
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/bug1762899.js
@@ -0,0 +1,34 @@
+var ins = wasmEvalText(`
+(module
+ (func (export "copysign_f64") (param f64 f64) (result f64)
+ f64.const 0x1.921fb54442d18p+0 (;=1.5708;)
+ local.get 0
+ f64.copysign
+ )
+ (func (export "copysign_f32") (param f32 f32) (result f32)
+ f32.const 0x1.921fb54442d18p+0 (;=1.5708;)
+ local.get 0
+ f32.copysign
+ )
+ (func (export "copysign_f64_2") (param f64 f64) (result f64)
+ local.get 1
+ f64.const 0x1.921fb54442d18p+0 (;=1.5708;)
+ f64.copysign
+ )
+ (func (export "copysign_f32_2") (param f32 f32) (result f32)
+ local.get 1
+ f32.const -0x1.921fb54442d18p+0 (;=1.5708;)
+ f32.copysign
+ )
+
+)
+`);
+
+assertEq(ins.exports.copysign_f64(1, 0), 1.5707963267948966);
+assertEq(ins.exports.copysign_f64(-1, 0), -1.5707963267948966);
+assertEq(ins.exports.copysign_f32(1, 0), 1.5707963705062866);
+assertEq(ins.exports.copysign_f32(-1, 0), -1.5707963705062866);
+assertEq(ins.exports.copysign_f64_2(0, 1), 1);
+assertEq(ins.exports.copysign_f64_2(0, -1), 1);
+assertEq(ins.exports.copysign_f32_2(0, 1), -1);
+assertEq(ins.exports.copysign_f32_2(0, -1), -1);
diff --git a/js/src/jit-test/tests/wasm/regress/bug1770335.js b/js/src/jit-test/tests/wasm/regress/bug1770335.js
new file mode 100644
index 0000000000..569d7bd35e
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/bug1770335.js
@@ -0,0 +1,33 @@
+// |jit-test| skip-if: !wasmSimdEnabled()
+
+// Check if GVN indentifies two non-indentical shuffles. During value numbering
+// the control field/data might look the same. Shuffle or permute kind, and
+// operands order have to be taking into account during value numbering.
+// If GVN fails to recognize the following shuffles as different, the v128.xor
+// produces zero output.
+var ins = wasmEvalText(`(module
+ (memory (export "memory") 1 1)
+ (func $test (param v128) (result v128)
+ local.get 0
+ v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000
+ i8x16.shuffle 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
+ v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000
+ local.get 0
+ i8x16.shuffle 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
+ v128.xor
+ )
+ (func (export "run")
+ i32.const 16
+ i32.const 0
+ v128.load
+ call $test
+ v128.store
+ )
+)`);
+
+const mem64 = new BigInt64Array(ins.exports.memory.buffer, 0, 4);
+mem64[0] = 0x123456789n;
+mem64[1] = -0xFDCBA000n;
+ins.exports.run();
+assertEq(mem64[2], -0xFDCBA000n);
+assertEq(mem64[3], 0x123456789n);
diff --git a/js/src/jit-test/tests/wasm/regress/bug1836708.js b/js/src/jit-test/tests/wasm/regress/bug1836708.js
new file mode 100644
index 0000000000..87b7483bd6
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/bug1836708.js
@@ -0,0 +1,19 @@
+// Testing i64.mul in wasm with a 2 ** n +- 1 value as operand, which may
+// be optimized in code generation.
+var mulImmOperands = [];
+
+for (let i = 0n; i < 64n; i++) {
+ mulImmOperands.push(2n ** i - 1n);
+ mulImmOperands.push(2n ** i + 1n);
+}
+
+for (const immVal of mulImmOperands) {
+ const ins = wasmEvalText(`(module
+ (func (export "mul_i64") (param i64) (result i64)
+ local.get 0
+ i64.const ${immVal}
+ i64.mul
+ ))`);
+
+ assertEq(ins.exports.mul_i64(42n), BigInt.asIntN(64, 42n * immVal));
+}
diff --git a/js/src/jit-test/tests/wasm/regress/builtin-import-sigs.js b/js/src/jit-test/tests/wasm/regress/builtin-import-sigs.js
new file mode 100644
index 0000000000..50aa2a41d1
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/builtin-import-sigs.js
@@ -0,0 +1,15 @@
+var code = wasmTextToBinary(`(module
+ (import "" "builtin" (func $one))
+ (import "" "builtin" (func $two (param i32)))
+ (import "" "builtin" (func $three (result i32)))
+ (import "" "builtin" (func $four (param f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32) (result f32)))
+ (func (export "run")
+ (call $one)
+ (call $two (i32.const 0))
+ (drop (call $three))
+ (drop (call $four (f32.const 0) (f32.const 0) (f32.const 0) (f32.const 0) (f32.const 0) (f32.const 0) (f32.const 0) (f32.const 0) (f32.const 0) (f32.const 0) (f32.const 0) (f32.const 0)))
+ )
+)`);
+var m = new WebAssembly.Module(code);
+var i = new WebAssembly.Instance(m, {'':{builtin:Math.sin}});
+i.exports.run();
diff --git a/js/src/jit-test/tests/wasm/regress/caller-property.js b/js/src/jit-test/tests/wasm/regress/caller-property.js
new file mode 100644
index 0000000000..8b9a95a989
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/caller-property.js
@@ -0,0 +1,7 @@
+const { g } = wasmEvalText(`(module (func $f) (export "g" (func $f)))`).exports;
+
+function testCaller() {
+ return g.caller;
+}
+
+assertErrorMessage(testCaller, TypeError, /caller/);
diff --git a/js/src/jit-test/tests/wasm/regress/current-memory-tls.js b/js/src/jit-test/tests/wasm/regress/current-memory-tls.js
new file mode 100644
index 0000000000..6bd46b2b5f
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/current-memory-tls.js
@@ -0,0 +1,95 @@
+// Bug 1341650:
+// - when compiled with Ion, pass the TLS register to memory.size;
+// - when compiled with Baseline, don't clobber the last stack slot when
+// calling into memory.size/memory.grow;
+
+// This toy module starts with an empty memory, then tries to set values at different
+// indexes, automatically growing memory when that would trigger an out of
+// bounds access, for the exact right amount of pages. Note it's not made for
+// efficiency, but optimizing it doesn't trigger the bugs mentioned above.
+
+let i = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(`
+(module
+ (memory $mem (export "mem") 0 65535)
+
+ (func (export "cur_mem") (result i32) (memory.size))
+
+ (func $maybeGrow (param $i i32) (local $smem i32)
+ ;; get memory.size in number of bytes, not pages.
+ memory.size
+ i64.extend_u/i32
+ i64.const 65536
+ i64.mul
+
+ ;; get the last byte index accessed by an int32 access.
+ local.get $i
+ i32.const 3
+ i32.add
+ tee_local $i
+ i64.extend_u/i32
+
+ ;; if the memory is too small, grow it.
+ i64.le_u
+ if
+ ;; get the floor of the accessed *page* index.
+ local.get $i
+ i64.extend_u/i32
+ i64.const 65536
+ i64.div_u
+
+ ;; subtract to that the size of the current memory in pages;
+ ;; that's the amount of pages we want to grow, minus one.
+ memory.size
+ i64.extend_u/i32
+
+ i64.sub
+
+ ;; add 1 to that amount.
+ i64.const 1
+ i64.add
+
+ ;; get back to i32 and grow memory.
+ i32.wrap/i64
+ memory.grow
+ drop
+ end
+ )
+
+ (func (export "set") (param $i i32) (param $v i32)
+ local.get $i
+ call $maybeGrow
+ local.get $i
+ local.get $v
+ i32.store
+ )
+
+ (func (export "get") (param $i i32) (result i32)
+ local.get $i
+ i32.load
+ )
+)
+`))).exports;
+
+assertEq(i.cur_mem(), 0);
+
+i.set(0, 1);
+assertEq(i.get(0), 1);
+
+assertEq(i.cur_mem(), 1);
+
+i.set(1234, 1);
+assertEq(i.get(1234), 1);
+
+assertEq(i.cur_mem(), 1);
+
+i.set(65532, 1);
+assertEq(i.get(65532), 1);
+
+assertErrorMessage(() => i.get(65533), WebAssembly.RuntimeError, /index out of bounds/);
+
+assertEq(i.cur_mem(), 1);
+
+i.set(65533, 1);
+assertEq(i.get(65533), 1);
+
+assertEq(i.cur_mem(), 2);
diff --git a/js/src/jit-test/tests/wasm/regress/debug-clone-segment.js b/js/src/jit-test/tests/wasm/regress/debug-clone-segment.js
new file mode 100644
index 0000000000..f91f62df32
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/debug-clone-segment.js
@@ -0,0 +1,36 @@
+// |jit-test| skip-if: !wasmDebuggingEnabled()
+//
+var mod = new WebAssembly.Module(wasmTextToBinary(`
+ (module
+ (func (export "func_0") (result i32)
+ call 0
+ )
+ )
+`));
+
+var g = newGlobal({newCompartment: true});
+g.parent = this;
+g.eval("(" + function() {
+ var dbg = Debugger(parent);
+ dbg.onEnterFrame = function(frame) {}
+} + ")()");
+
+processModule(mod);
+processModule(mod);
+processModule(mod);
+processModule(mod);
+
+mod = new WebAssembly.Module(wasmTextToBinary(`
+(module (export "func_0" (func $func1)) (func $func1))
+`));
+
+processModule(mod);
+processModule(mod);
+processModule(mod);
+processModule(mod);
+
+function processModule(module) {
+ try {
+ new WebAssembly.Instance(module).exports.func_0();
+ } catch(ex) {}
+}
diff --git a/js/src/jit-test/tests/wasm/regress/debug-exception-in-fast-import.js b/js/src/jit-test/tests/wasm/regress/debug-exception-in-fast-import.js
new file mode 100644
index 0000000000..bba37b38b0
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/debug-exception-in-fast-import.js
@@ -0,0 +1,21 @@
+// |jit-test| skip-if: !wasmDebuggingEnabled()
+g = newGlobal({newCompartment: true});
+g.parent = this;
+g.eval("(" + function() {
+ Debugger(parent).onExceptionUnwind = function(frame) {}
+} + ")()")
+
+o = {};
+
+let { exports } = wasmEvalText(`
+ (module (import "" "inc" (func $imp)) (func) (func $start (call $imp)) (start $start) (export "" (func $start)))
+`, {
+ "": {
+ inc: function() { o = o.p; }
+ }
+});
+
+// after instanciation, the start function has been executed and o is undefined.
+// This second call will throw in the imported function:
+
+assertErrorMessage(exports[""], TypeError, /undefined/);
diff --git a/js/src/jit-test/tests/wasm/regress/debug-osr.js b/js/src/jit-test/tests/wasm/regress/debug-osr.js
new file mode 100644
index 0000000000..e8d3285ed4
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/debug-osr.js
@@ -0,0 +1,16 @@
+// |jit-test| skip-if: !wasmDebuggingEnabled()
+g = newGlobal({newCompartment: true});
+g.parent = this;
+g.eval("(" + function() {
+ Debugger(parent).onExceptionUnwind = function(frame) {
+ frame.older
+ }
+} + ")()");
+
+let o = {};
+
+let func = wasmEvalText(`
+ (module (import "" "inc" (func $imp)) (func) (func $start (call $imp)) (start $start) (export "" (func $start)))
+`, { "": { inc: function() { o = o.set; } } }).exports[""];
+
+assertErrorMessage(func, TypeError, /(is|of) undefined/);
diff --git a/js/src/jit-test/tests/wasm/regress/directives.txt b/js/src/jit-test/tests/wasm/regress/directives.txt
new file mode 100644
index 0000000000..8bb976be49
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/directives.txt
@@ -0,0 +1 @@
+|jit-test| test-also=--wasm-compiler=optimizing; test-also=--wasm-compiler=baseline; 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/regress/enable-profiling-in-import.js b/js/src/jit-test/tests/wasm/regress/enable-profiling-in-import.js
new file mode 100644
index 0000000000..dd17b2089f
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/enable-profiling-in-import.js
@@ -0,0 +1,9 @@
+var module = new WebAssembly.Module(wasmTextToBinary(`
+ (module
+ (import "global" "func" (func))
+ (func (export "f")
+ call 0
+ )
+ )
+`));
+new WebAssembly.Instance(module, { global: { func: enableGeckoProfiling } }).exports.f();
diff --git a/js/src/jit-test/tests/wasm/regress/frame-offset-stack-arg.js b/js/src/jit-test/tests/wasm/regress/frame-offset-stack-arg.js
new file mode 100644
index 0000000000..6ab2834d79
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/frame-offset-stack-arg.js
@@ -0,0 +1,38 @@
+// We have some register args and the rest are on the stack in the wasm->js
+// call. This tests a case where the wrong frame offset was used (on ARM64,
+// which is weird in this regard) to read the stack arg in an optimized callout
+// stub.
+
+var loop_counter = 0;
+
+function f(a,b,c,d,e,f,g,h,i,j) {
+ assertEq(a, loop_counter);
+ assertEq(b, a+1);
+ assertEq(c, b+1);
+ assertEq(d, c+1);
+ assertEq(e, d+1);
+ assertEq(f, e+1);
+ assertEq(g, f+1);
+ assertEq(h, g+1);
+ assertEq(i, h+1);
+ assertEq(j, i+1);
+}
+
+var bin = wasmTextToBinary(
+ `(module
+ (import "m" "f" (func $f (param i32) (param i32) (param i32) (param i32) (param i32)
+ (param i32) (param i32) (param i32) (param i32) (param i32)))
+ (func (export "test") (param $a i32) (param $b i32) (param $c i32) (param $d i32) (param $e i32)
+ (param $f i32) (param $g i32) (param $h i32) (param $i i32) (param $j i32)
+ (call $f (local.get $a) (local.get $b) (local.get $c) (local.get $d) (local.get $e)
+ (local.get $f) (local.get $g) (local.get $h) (local.get $i) (local.get $j))))`);
+
+var mod = new WebAssembly.Module(bin);
+var ins = new WebAssembly.Instance(mod, {m:{f}});
+
+// Enough iterations for the jit to kick in and the stub to become optimized.
+
+for ( let i=0; i < 100; i++ ) {
+ loop_counter = i;
+ ins.exports.test(i, i+1, i+2, i+3, i+4, i+5, i+6, i+7, i+8, i+9);
+}
diff --git a/js/src/jit-test/tests/wasm/regress/fuzzsafe-bug1645610.js b/js/src/jit-test/tests/wasm/regress/fuzzsafe-bug1645610.js
new file mode 100644
index 0000000000..6bd88e95bc
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/fuzzsafe-bug1645610.js
@@ -0,0 +1,15 @@
+// |jit-test| --fuzzing-safe; skip-if: this.getErrorNotes
+//
+// The meaning of the line above is that the test case is to be run only with
+// --fuzzing-safe and only if that setting (or similar settings) is effectful.
+
+WebAssembly.Module.exports(new WebAssembly.Module(wasmTextToBinary(`
+(module
+ (func (;0;))
+ (func (;1;))
+ (func (;2;))
+ (func (;3;) (result i32)
+ i32.const 42)
+ (export "memo" (func 3))
+ (export "main" (func 3)))
+`)));
diff --git a/js/src/jit-test/tests/wasm/regress/gvn-unremovable-phi.js b/js/src/jit-test/tests/wasm/regress/gvn-unremovable-phi.js
new file mode 100644
index 0000000000..832215f4e6
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/gvn-unremovable-phi.js
@@ -0,0 +1,20 @@
+wasmEvalText(`(module
+ (type $type0 (func (param i32)))
+ (func $f (param $p i32)
+ (local $x i32) (local $y i32)
+ loop $top
+ local.get $x
+ local.get $p
+ local.get $x
+ br_if $top
+ i32.const 1
+ tee_local $p
+ local.get $y
+ local.set $x
+ i32.add
+ call $f
+ br_if $top
+ return
+ end
+ )
+)`);
diff --git a/js/src/jit-test/tests/wasm/regress/imul64-ion-negative-power-of-two.js b/js/src/jit-test/tests/wasm/regress/imul64-ion-negative-power-of-two.js
new file mode 100644
index 0000000000..0fe59546d7
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/imul64-ion-negative-power-of-two.js
@@ -0,0 +1,11 @@
+new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(`
+(module
+ (func (param i64))
+ (func (export "f")
+ i64.const 2
+ i64.const -9223372036854775808
+ i64.mul
+ call 0
+ )
+)
+`))).exports.f();
diff --git a/js/src/jit-test/tests/wasm/regress/ion-callerfp-tag.js b/js/src/jit-test/tests/wasm/regress/ion-callerfp-tag.js
new file mode 100644
index 0000000000..936fba24fd
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/ion-callerfp-tag.js
@@ -0,0 +1,28 @@
+var lfModule = new WebAssembly.Module(wasmTextToBinary(`
+ (module
+ (import "global" "func" (func (result i32)))
+ (func (export "func_0") (result i32)
+ call 0 ;; calls the import, which is func #0
+ )
+ )
+`));
+
+enableGeckoProfiling();
+WasmHelpers.startProfiling();
+setJitCompilerOption("ion.warmup.trigger", 20);
+
+Object.prototype[3] = 3;
+
+var imports = {
+ global: {
+ func: function() {}
+ }
+}
+
+for (let i = 0; i < 100; ++i) {
+ for (dmod in imports)
+ for (dname in imports[dmod])
+ if (imports[dmod][dname] == undefined) {}
+ instance = new WebAssembly.Instance(lfModule, imports);
+ print(i, instance.exports.func_0());
+}
diff --git a/js/src/jit-test/tests/wasm/regress/ion-error-gc-fakeexitframe.js b/js/src/jit-test/tests/wasm/regress/ion-error-gc-fakeexitframe.js
new file mode 100644
index 0000000000..5b184611d7
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/ion-error-gc-fakeexitframe.js
@@ -0,0 +1,81 @@
+var lfLogBuffer = `
+//corefuzz-dcd-endofdata
+for (var i = 0; gczeal(4,10); g(buffer))
+ assertEq(assignParameterGetElement(42), 17);
+//corefuzz-dcd-endofdata
+//corefuzz-dcd-endofdata
+//corefuzz-dcd-endofdata
+g = newGlobal({newCompartment: true});
+g.parent = this
+g.eval("Debugger(parent).onExceptionUnwind=(function(){})")
+`;
+lfLogBuffer = lfLogBuffer.split('\n');
+
+gcPreserveCode();
+
+var letext =`(module
+ (type $type0 (func (param i32 i64)))
+ (type $type1 (func (param i32) (result i64)))
+ (type $type2 (func (result i32)))
+ (memory 1)
+ (export "store" (func $func0))
+ (export "load" (func $func1))
+ (export "assert_0" (func $func2))
+ (func $func0 (param $var0 i32) (param $var1 i64)
+ local.get $var0
+ local.get $var1
+ i64.store16 offset=16
+ )
+ (func $func1 (param $var0 i32) (result i64)
+ local.get $var0
+ i64.load16_s offset=16
+ )
+ (func $func2 (result i32)
+ i32.const 65519
+ i64.const -32768
+ call $func0
+ i32.const 1
+ )
+ (data (i32.const 0)
+ "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\t\\n\\0b\\0c\\0d\\0e\\0f"
+ )
+ (data (i32.const 16)
+ "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff"
+ )
+)`;
+
+var binary = wasmTextToBinary(letext);
+var module = new WebAssembly.Module(binary);
+
+var lfCodeBuffer = "";
+while (true) {
+ var line = lfLogBuffer.shift();
+ if (line == null) {
+ break;
+ } else if (line == "//corefuzz-dcd-endofdata") {
+ processCode(lfCodeBuffer);
+ } else {
+ lfCodeBuffer += line + "\n";
+ }
+}
+
+if (lfCodeBuffer) processCode(lfCodeBuffer);
+
+function processCode(code) {
+ evaluate(code);
+ while (true) {
+ imports = {}
+ try {
+ instance = new WebAssembly.Instance(module, imports);
+ break;
+ } catch (exc) {}
+ }
+ for (let descriptor of WebAssembly.Module.exports(module)) {
+ switch (descriptor.kind) {
+ case "function":
+ try {
+ print(instance.exports[descriptor.name]())
+ } catch (exc1) {}
+ }
+ }
+}
diff --git a/js/src/jit-test/tests/wasm/regress/ion-inlinedcall-resumepoint.js b/js/src/jit-test/tests/wasm/regress/ion-inlinedcall-resumepoint.js
new file mode 100644
index 0000000000..9b9c8209bc
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/ion-inlinedcall-resumepoint.js
@@ -0,0 +1,50 @@
+var invalidatedFunction = function() { return false; }
+
+var counter = 0;
+
+function maybeInvalidate(iplusk) {
+ if (iplusk === 0) {
+ // This should happen only once; it will invalidate the call frame of
+ // the ion() function, which should rewind to just after the wasm call
+ // (if it got its own resume point).
+ // Before the patch, the wasm call doesn't get its resume point, so
+ // it's repeated and the importedFunc() is called once too many.
+ counter++;
+ invalidatedFunction = function () { return true; };
+ }
+}
+
+function importedFunc(k) {
+ for (let i = 100; i --> 0 ;) {
+ maybeInvalidate(i + k);
+ }
+}
+
+let { exports } = new WebAssembly.Instance(
+ new WebAssembly.Module(
+ wasmTextToBinary(`
+ (module
+ (func $imp (import "env" "importedFunc") (param i32))
+ (func (export "exp") (param i32)
+ local.get 0
+ call $imp
+ )
+ )
+ `)
+ ), {
+ env: {
+ importedFunc
+ }
+ }
+);
+
+function ion(k) {
+ exports.exp(k);
+ invalidatedFunction();
+}
+
+for (let k = 100; k --> 0 ;) {
+ ion(k);
+}
+
+assertEq(counter, 1);
diff --git a/js/src/jit-test/tests/wasm/regress/ion-lazy-stubs-jit.js b/js/src/jit-test/tests/wasm/regress/ion-lazy-stubs-jit.js
new file mode 100644
index 0000000000..f7592b14fb
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/ion-lazy-stubs-jit.js
@@ -0,0 +1,13 @@
+(function coerceinplace() {
+ var { table } = wasmEvalText(`(module
+ (func $add (param i32) (param i32) (result i32)
+ local.get 0
+ )
+ (table (export "table") 10 funcref)
+ (elem (i32.const 0) $add)
+ )`).exports;
+
+ for (var i = 0; i < 100; i++) {
+ table.get(0)((true).get++, i*2+1);
+ }
+})();
diff --git a/js/src/jit-test/tests/wasm/regress/ion-many-results.js b/js/src/jit-test/tests/wasm/regress/ion-many-results.js
new file mode 100644
index 0000000000..bc4df59e20
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/ion-many-results.js
@@ -0,0 +1,17 @@
+// This provokes a crash in ion if its tempalloc reservation logic is not
+// up to snuff, bug 1675844.
+
+for ( let i=100; i < 300; i++ ) {
+ let xs = new Array(i).fill(1);
+
+ // Should not crash the compiler but should fail validation
+ assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(`
+(module
+ (func $f (result ${xs.map(_ => 'i32 ').join(' ')})
+ ${xs.map((_) => '(i32.const 1)').join(' ')})
+ (func $g
+ (call $f)))`)),
+ WebAssembly.CompileError,
+ /(unused values not explicitly dropped)|(values remaining on stack)/);
+
+}
diff --git a/js/src/jit-test/tests/wasm/regress/jit-updatepcquad.js b/js/src/jit-test/tests/wasm/regress/jit-updatepcquad.js
new file mode 100644
index 0000000000..69f9371b84
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/jit-updatepcquad.js
@@ -0,0 +1,31 @@
+var evalInFrame = (function (global) {
+ var dbgGlobal = newGlobal({newCompartment: true});
+ var dbg = new dbgGlobal.Debugger();
+ return function evalInFrame(code) {
+ dbg.addDebuggee(global);
+ var frame = dbg.getNewestFrame().older;
+ frame = frame.older || frame;
+ let completion = frame.eval(code);
+ return completion.return;
+ };
+})(this);
+
+const { exports } = wasmEvalText(`
+ (module
+ (import "global" "func" (func (param i32) (result i32)))
+ (func (export "func_0") (param i32)(result i32)
+ local.get 0
+ call 0
+ )
+ )
+`, {
+ global: {
+ func: function jscode(i) {
+ return evalInFrame(`a = ${i}`);
+ }
+ }
+});
+
+for (i = 0; i < 20; ++i) {
+ assertEq(exports.func_0(i), i);
+}
diff --git a/js/src/jit-test/tests/wasm/regress/lazy-table-nan.js b/js/src/jit-test/tests/wasm/regress/lazy-table-nan.js
new file mode 100644
index 0000000000..aa7bda7485
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/lazy-table-nan.js
@@ -0,0 +1,10 @@
+let i = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(`
+(module
+ (func $f (result f32)
+ f32.const nan:0x42
+ )
+ (table (export "table") 10 funcref)
+ (elem (i32.const 0) $f)
+)
+`))).exports;
+i.table.get(0)();
diff --git a/js/src/jit-test/tests/wasm/regress/load-lane-oob.js b/js/src/jit-test/tests/wasm/regress/load-lane-oob.js
new file mode 100644
index 0000000000..02fea77daf
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/load-lane-oob.js
@@ -0,0 +1,14 @@
+// |jit-test| skip-if: !wasmSimdEnabled()
+
+// Bug 1735128 - useless load should not be eliminated by Ion
+
+var ins = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(
+`(module
+ (memory 0)
+ (func (export "f") (param i32)
+ (v128.load64_lane 1 (local.get 0) (v128.const i32x4 0 0 0 0))
+ drop))`)));
+assertErrorMessage(() => ins.exports.f(100),
+ WebAssembly.RuntimeError,
+ /out of bounds/);
+
diff --git a/js/src/jit-test/tests/wasm/regress/long-select.js b/js/src/jit-test/tests/wasm/regress/long-select.js
new file mode 100644
index 0000000000..dfda4e6799
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/long-select.js
@@ -0,0 +1,38 @@
+// Bug 1337060 causes too much register pressure on x86 by requiring four int64
+// values in registers at the same time.
+
+wasmFullPassI64(`
+(module
+ (func $run (result i64)
+ i64.const 0x2800000033
+ i64.const 0x9900000044
+ i64.const 0x1000000012
+ i64.const 0x1000000013
+ i64.lt_s
+ select))`, "0x2800000033");
+
+wasmFullPassI64(`
+(module
+ (func $run (result i64)
+ i64.const 0x2800000033
+ i64.const 0x9900000044
+ i64.const 0x1000000013
+ i64.const 0x1000000012
+ i64.lt_s
+ select))`, "0x9900000044");
+
+wasmFullPassI64(`
+(module
+ (func $run (param f32) (result i64)
+ i64.const 0x13100000001
+ i64.const 0x23370000002
+ i64.const 0x34480000003
+ i32.const 1
+ select
+ i32.const 1
+ select
+ i64.const 0x45590000004
+ i32.const 1
+ select
+ )
+)`, "0x13100000001", {}, 'f32.const 0');
diff --git a/js/src/jit-test/tests/wasm/regress/misc-control-flow.js b/js/src/jit-test/tests/wasm/regress/misc-control-flow.js
new file mode 100644
index 0000000000..6feafcee1b
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/misc-control-flow.js
@@ -0,0 +1,227 @@
+wasmFailValidateText(`(module
+ (func (param i32) (result i32)
+ (loop (if (i32.const 0) (br 0)) (local.get 0)))
+ (export "" (func 0))
+)`, /(unused values not explicitly dropped by end of block)|(values remaining on stack at end of block)/);
+
+wasmFailValidateText(`(module
+ (func (param i32)
+ (loop (if (i32.const 0) (br 0)) (local.get 0)))
+ (export "" (func 0))
+)`, /(unused values not explicitly dropped by end of block)|(values remaining on stack at end of block)/);
+
+wasmFailValidateText(`(module
+ (func (param i32) (result i32)
+ (loop (if (i32.const 0) (br 0)) (drop (local.get 0))))
+ (export "" (func 0))
+)`, emptyStackError);
+
+assertEq(wasmEvalText(`(module
+ (func (param i32) (result i32)
+ (loop (if (i32.const 0) (br 0))) (local.get 0))
+ (export "" (func 0))
+)`).exports[""](42), 42);
+
+wasmEvalText(`(module (func $func$0
+ (block (if (i32.const 1) (loop (br_table 0 (br 0)))))
+ )
+)`);
+
+wasmEvalText(`(module (func
+ (block $out (loop $in (br_table $out $out $in (i32.const 0))))
+ )
+)`);
+
+wasmEvalText(`(module (func (result i32)
+ (select
+ (block (result i32)
+ (drop (block (result i32)
+ (br_table
+ 1
+ 0
+ (i32.const 1)
+ (i32.const 0)
+ )
+ ))
+ (i32.const 2)
+ )
+ (i32.const 3)
+ (i32.const 4)
+ )
+))
+`);
+
+wasmEvalText(`(module
+ (func (param i32) (param i32) (result i32) (i32.const 0))
+ (func (result i32)
+ (call 0 (i32.const 1) (call 0 (i32.const 2) (i32.const 3)))
+ (call 0 (unreachable) (i32.const 4))
+ )
+)`);
+
+wasmEvalText(`
+(module
+
+ (func
+ (param i32) (param i32) (param i32) (param i32)
+ (result i32)
+ (i32.const 0)
+ )
+
+ (func (result i32)
+ (call 0
+ (i32.const 42)
+ (i32.const 53)
+ (call 0 (i32.const 100) (i32.const 13) (i32.const 37) (i32.const 128))
+ (return (i32.const 42))
+ )
+ )
+
+ (export "" (func 1))
+)
+`).exports[""]();
+
+wasmEvalText(`
+(module
+ (import "check" "one" (func (param i32)))
+ (import "check" "two" (func (param i32) (param i32)))
+ (func (param i32) (call 0 (local.get 0)))
+ (func (param i32) (param i32) (call 1 (local.get 0) (local.get 1)))
+ (func
+ (call 1
+ (i32.const 43)
+ (block $b (result i32)
+ (if (i32.const 1)
+ (call 0
+ (block (result i32)
+ (call 0 (i32.const 42))
+ (br $b (i32.const 10)))))
+ (i32.const 44))))
+ (export "foo" (func 4)))
+`, {
+ check: {
+ one(x) {
+ assertEq(x, 42);
+ },
+ two(x, y) {
+ assertEq(x, 43);
+ assertEq(y, 10);
+ }
+ }
+}).exports.foo();
+
+assertEq(wasmEvalText(`(module (func
+ return
+ (select
+ (loop (result i32) (i32.const 1))
+ (loop (result i32) (i32.const 2))
+ (i32.const 3)
+ )
+ drop
+) (export "" (func 0)))`).exports[""](), undefined);
+
+wasmEvalText(`(module (func (result i32)
+ (return (i32.const 0))
+ (select
+ (loop (result i32) (i32.const 1))
+ (loop (result i32) (i32.const 2))
+ (i32.const 3)
+ )
+))`);
+
+wasmEvalText(`(module (func
+ (block $return
+ (block $beforeReturn
+ (block $out
+ (loop $in
+ (block $otherTable
+ (br_table
+ $return
+ $return
+ $otherTable
+ $beforeReturn
+ (i32.const 0)
+ )
+ )
+ (block $backTop
+ (br_table
+ $backTop
+ $backTop
+ $beforeReturn
+ (i32.const 0)
+ )
+ )
+ (br $in)
+ )
+ )
+ )
+ )
+))`);
+
+wasmFailValidateText(
+`(module
+ (func $func$0
+ (select
+ (if (result f32)
+ (i32.const 0)
+ (f32.const 0)
+ (i32.const 0)
+ )
+ (if (result f32)
+ (i32.const 0)
+ (f32.const 0)
+ (i32.const 0)
+ )
+ (i32.const 0)
+ )
+ )
+)`, mismatchError("i32", "f32"));
+
+wasmEvalText(`
+(module
+ (func (result i32)
+ (i32.add
+ (block $outer (result i32)
+ (drop (block $middle (result i32)
+ (block $inner (result i32)
+ (br_table $middle $outer $inner (i32.const 42) (i32.const 1))
+ )
+ (nop)
+ ))
+ (i32.const 0)
+ )
+ (i32.const 13)
+ )
+ )
+)
+`);
+
+wasmFailValidateText(`
+(module
+ (func (result i32)
+ (loop
+ (i32.const 0)
+ (br_table 1 0 (i32.const 15))
+ )
+ )
+)`, /(br_table targets must all have the same arity)|(br_table target labels have different types)/);
+
+wasmFailValidateText(`
+(module
+ (func (result i32)
+ (loop (result i32)
+ (i32.const 0)
+ (br_table 1 0 (i32.const 15))
+ )
+ )
+)`, /(br_table targets must all have the same arity)|(br_table target labels have different types)/);
+
+wasmValidateText(`
+(module
+ (func
+ (loop
+ (i32.const 0)
+ (br_table 1 0 (i32.const 15))
+ )
+ )
+)`);
diff --git a/js/src/jit-test/tests/wasm/regress/movable-traps.js b/js/src/jit-test/tests/wasm/regress/movable-traps.js
new file mode 100644
index 0000000000..ac5577032b
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/movable-traps.js
@@ -0,0 +1,38 @@
+let bodies = [
+ `
+ i32.const 1
+ i32.const 0
+ i32.div_s
+ `,
+ `
+ i32.const 1
+ i32.const 0
+ i32.rem_s
+ `,
+ `
+ f64.const 1.7976931348623157e+308
+ i64.trunc_s/f64
+ `,
+ `
+ f32.const 3.40282347e+38
+ i32.trunc_s/f32
+ `
+];
+
+for (let body of bodies) {
+ wasmFullPass(`
+ (module
+ (func $f (param $x i32) (result i32)
+ loop $top (result i32)
+ local.get $x
+ if
+ local.get $x
+ br 2
+ end
+ ${body}
+ br $top
+ end
+ )
+ (export "run" (func $f))
+ )`, 42, {}, 42);
+}
diff --git a/js/src/jit-test/tests/wasm/regress/no-directives/debugger-no-script.js b/js/src/jit-test/tests/wasm/regress/no-directives/debugger-no-script.js
new file mode 100644
index 0000000000..1072e9268e
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/no-directives/debugger-no-script.js
@@ -0,0 +1,19 @@
+// |jit-test| skip-if: !wasmDebuggingEnabled(); exitstatus:3
+
+function userError() {};
+
+let g = newGlobal({newCompartment: true});
+let dbg = new Debugger(g);
+
+g.eval(`
+ var wasm = wasmTextToBinary('(module (func (export "test") (nop)))');
+ var m = new WebAssembly.Instance(new WebAssembly.Module(wasm));
+`);
+
+dbg.onEnterFrame = function(frame) {
+ if (frame.type == "wasmcall") {
+ throw new userError()
+ }
+}
+
+result = g.eval("m.exports.test()");
diff --git a/js/src/jit-test/tests/wasm/regress/nop-fill-jit-exit.js b/js/src/jit-test/tests/wasm/regress/nop-fill-jit-exit.js
new file mode 100644
index 0000000000..0aadbc22a5
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/nop-fill-jit-exit.js
@@ -0,0 +1,28 @@
+// |jit-test| --arm-asm-nop-fill=1
+//
+try {
+ enableSingleStepProfiling();
+ disableSingleStepProfiling();
+} catch (e) {
+ // Early quit on platforms not supporting single step profiling.
+ quit();
+}
+
+load(libdir + "asm.js");
+
+var ffi = function(enable) {
+ enableGeckoProfiling();
+ enableSingleStepProfiling();
+}
+var f = asmLink(asmCompile('global', 'ffis',
+ USE_ASM + `
+ var ffi=ffis.ffi;
+ function f(i) {
+ i=i|0;
+ ffi(i|0);
+ } return f
+ `), null, {
+ ffi
+});
+f(0);
+f(+1);
diff --git a/js/src/jit-test/tests/wasm/regress/null-call.js b/js/src/jit-test/tests/wasm/regress/null-call.js
new file mode 100644
index 0000000000..b7ed4b46e3
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/null-call.js
@@ -0,0 +1,14 @@
+// Bug 1747540 - two trap descriptors at the same address led to some confusion.
+
+var ins = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(`
+ (table 1 funcref)
+ (memory 1)
+ (func $test (export "test") (result i32)
+ (call_indirect (i32.const 0))
+ (i32.load (i32.const 0))
+)
+`)))
+assertErrorMessage(() => ins.exports.test(),
+ WebAssembly.RuntimeError,
+ /indirect call to null/);
+
diff --git a/js/src/jit-test/tests/wasm/regress/null-metadata-filename.js b/js/src/jit-test/tests/wasm/regress/null-metadata-filename.js
new file mode 100644
index 0000000000..638fef6c40
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/null-metadata-filename.js
@@ -0,0 +1,20 @@
+// |jit-test| skip-if: !isAsmJSCompilationAvailable()
+
+enableGeckoProfiling();
+var code = evaluate("(function() { 'use asm'; function g() { return 43 } return g })", {
+ fileName: null
+});
+
+assertEq(code()(), 43);
+
+evaluate(`
+let f = evalReturningScope.bind(null, '');
+
+(function(glob, stdlib) {
+ "use asm";
+ var f = stdlib.f;
+ function _() { f(); }
+ return _;
+})(this, { f })();
+`, { fileName: null });
+
diff --git a/js/src/jit-test/tests/wasm/regress/onlyjsiter-while-wasm.js b/js/src/jit-test/tests/wasm/regress/onlyjsiter-while-wasm.js
new file mode 100644
index 0000000000..f67b6d27b8
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/onlyjsiter-while-wasm.js
@@ -0,0 +1,13 @@
+// |jit-test| skip-if: typeof evalInCooperativeThread === 'undefined'
+
+try {
+ evalInCooperativeThread(`
+ var { f } = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(\`
+ (module
+ (func $f (export "f") call $f)
+ )
+ \`))).exports;
+ gczeal(9);
+ f();
+ `);
+} catch(e) {}
diff --git a/js/src/jit-test/tests/wasm/regress/oom-eval.js b/js/src/jit-test/tests/wasm/regress/oom-eval.js
new file mode 100644
index 0000000000..1ce7c26df1
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/oom-eval.js
@@ -0,0 +1,7 @@
+// |jit-test| slow; allow-oom; skip-if: !wasmIsSupported() || !('oomTest' in this)
+
+function foo() {
+ var g = newGlobal({sameZoneAs: this});
+ g.eval(`o = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary('(module (func) (export "" (func 0)))')));`);
+}
+oomTest(foo);
diff --git a/js/src/jit-test/tests/wasm/regress/oom-init.js b/js/src/jit-test/tests/wasm/regress/oom-init.js
new file mode 100644
index 0000000000..f08b088107
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/oom-init.js
@@ -0,0 +1,21 @@
+// |jit-test| slow; allow-oom; skip-if: !wasmIsSupported() || !('oomTest' in this)
+
+Object.getOwnPropertyNames(this);
+s = newGlobal();
+evalcx("\
+ /x/;\
+ oomTest(function() {\
+ this[\"\"];\
+ void 0;\
+ Object.freeze(this);\
+ l(undefined)();\
+ O;\
+ t;\
+ 0;\
+ ({e});\
+ i;\
+ 0;\
+ ({ z: p ? 0 : 0});\
+ s;\
+ });\
+", s);
diff --git a/js/src/jit-test/tests/wasm/regress/oom-masm-baseline.js b/js/src/jit-test/tests/wasm/regress/oom-masm-baseline.js
new file mode 100644
index 0000000000..cda1b54584
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/oom-masm-baseline.js
@@ -0,0 +1,31 @@
+// |jit-test| slow; skip-if: !('oomTest' in this)
+
+// Test baseline compiler only.
+if (typeof wasmCompileMode === 'undefined' || wasmCompileMode() != 'baseline')
+ quit();
+
+try {
+ var bin = wasmTextToBinary(
+ `(module (func (result i32) (param f64) (param f32)
+ i64.const 0
+ local.get 0
+ drop
+ i32.wrap/i64
+ f64.const 0
+ f64.const 0
+ i32.const 0
+ select
+ f32.const 0
+ f32.const 0
+ f32.const 0
+ i32.const 0
+ select
+ i32.const 0
+ i32.const 0
+ i32.const 0
+ select
+ select
+ drop
+ drop))`);
+ oomTest(() => new WebAssembly.Module(bin));
+} catch(e) { }
diff --git a/js/src/jit-test/tests/wasm/regress/oom-wasm-streaming.js b/js/src/jit-test/tests/wasm/regress/oom-wasm-streaming.js
new file mode 100644
index 0000000000..5d7e719912
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/oom-wasm-streaming.js
@@ -0,0 +1,14 @@
+// |jit-test| skip-if: !('oomAfterAllocations' in this)
+
+ignoreUnhandledRejections();
+
+try {
+ WebAssembly.compileStreaming();
+} catch (err) {
+ assertEq(String(err).indexOf("not supported with --no-threads") !== -1, true);
+ quit();
+}
+oomAfterAllocations(1, 2);
+var x = wasmTextToBinary('(module (func (export "run") (result i32) i32.const 42))');
+WebAssembly.compileStreaming(x);
+drainJobQueue();
diff --git a/js/src/jit-test/tests/wasm/regress/oom-wasmtexttobinary-block.js b/js/src/jit-test/tests/wasm/regress/oom-wasmtexttobinary-block.js
new file mode 100644
index 0000000000..6f3b666873
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/oom-wasmtexttobinary-block.js
@@ -0,0 +1,7 @@
+// |jit-test| skip-if: !('oomTest' in this)
+
+try {
+ oomTest((function () {
+ wasmTextToBinary("(module(func(loop $label1 $label0)))");
+ }));
+} catch(e) { }
diff --git a/js/src/jit-test/tests/wasm/regress/pass-stack-int64.js b/js/src/jit-test/tests/wasm/regress/pass-stack-int64.js
new file mode 100644
index 0000000000..94497f35de
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/pass-stack-int64.js
@@ -0,0 +1,15 @@
+var params = '';
+var locals = '';
+for (let i = 0; i < 20; i++) {
+ params += '(param i64) ';
+ locals += `(local.get ${i}) `;
+}
+
+wasmEvalText(`
+(module
+ (func
+ ${params}
+ (call 0 ${locals})
+ )
+)
+`);
diff --git a/js/src/jit-test/tests/wasm/regress/proxy-get-trap-table.js b/js/src/jit-test/tests/wasm/regress/proxy-get-trap-table.js
new file mode 100644
index 0000000000..56158e7b15
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/proxy-get-trap-table.js
@@ -0,0 +1,14 @@
+// The 'get' handler should be invoked directly when reading fields of the
+// descriptor.
+
+assertErrorMessage(() => {
+ var desc = {
+ element: "anyfunc",
+ initial: 1
+ };
+ var proxy = new Proxy({}, {
+ get: true
+ });
+ Object.setPrototypeOf(desc, proxy);
+ let table = new WebAssembly.Table(desc);
+}, TypeError, /proxy handler's get trap/);
diff --git a/js/src/jit-test/tests/wasm/regress/regalloc-i64-load-store-global.js b/js/src/jit-test/tests/wasm/regress/regalloc-i64-load-store-global.js
new file mode 100644
index 0000000000..da971d1aa2
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/regalloc-i64-load-store-global.js
@@ -0,0 +1,20 @@
+wasmFullPassI64(`
+ (module
+ (global (mut i64) (i64.const 9970292656026947164))
+ (func (export "global.get_0") (result i64) global.get 0)
+
+ (func $run (param i32) (result i64)
+ i64.const 8692897571457488645
+ i64.const 1028567229461950342
+ i64.mul
+ global.get 0
+ f32.const 3.141592653
+ f32.floor
+ f32.const -13.37
+ f32.floor
+ f32.copysign
+ drop
+ i64.div_u
+ )
+ )
+`, 1, {}, 'i32.const 0');
diff --git a/js/src/jit-test/tests/wasm/regress/regalloc-muli64.js b/js/src/jit-test/tests/wasm/regress/regalloc-muli64.js
new file mode 100644
index 0000000000..b9ad31dca9
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/regalloc-muli64.js
@@ -0,0 +1,14 @@
+// Bug 1298808.
+assertEq(wasmEvalText(`(module
+ (func
+ (result i32)
+ (i32.wrap/i64
+ (i64.mul
+ ;; Conditions: rhs == lhs, rhs is not a constant.
+ (i64.add (i64.const 1) (i64.const 10))
+ (i64.add (i64.const 1) (i64.const 10))
+ )
+ )
+ )
+ (export "" (func 0))
+)`).exports[""](), 121);
diff --git a/js/src/jit-test/tests/wasm/regress/reserve-enough.js b/js/src/jit-test/tests/wasm/regress/reserve-enough.js
new file mode 100644
index 0000000000..c591fa3153
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/reserve-enough.js
@@ -0,0 +1,13 @@
+// Bug 1281131 - be sure to reserve enough stack space
+
+wasmEvalText(
+`(module
+ (func $func0
+ ${loopy(100)}
+ (nop)))`);
+
+function loopy(n) {
+ if (n == 0)
+ return "(nop)";
+ return `(block $out${n} (loop $in${n} ${loopy(n-1)}))`;
+}
diff --git a/js/src/jit-test/tests/wasm/regress/reserve-joinreg.js b/js/src/jit-test/tests/wasm/regress/reserve-joinreg.js
new file mode 100644
index 0000000000..7121914651
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/reserve-joinreg.js
@@ -0,0 +1,22 @@
+// Bug 1280933, excerpted from binary test case provided there.
+
+wasmEvalText(
+`(module
+ (func $func0 (param $arg0 i32) (result i32) (local $var0 i64)
+ (local.set $var0 (i64.extend_u/i32 (local.get $arg0)))
+ (i32.wrap/i64
+ (i64.add
+ (block (result i64)
+ (block $label1
+ (loop $label0
+ (drop
+ (block $label2 (result i64)
+ (br_table $label2 (i64.const 0) (local.get $arg0))
+ )
+ )
+ (local.set $var0 (i64.mul (i64.const 2) (local.get $var0)))
+ )
+ )
+ (tee_local $var0 (i64.add (i64.const 4) (local.get $var0))))
+ (i64.const 1))))
+ (export "" (func 0)))`);
diff --git a/js/src/jit-test/tests/wasm/regress/savedframe-lookup-in-wasm.js b/js/src/jit-test/tests/wasm/regress/savedframe-lookup-in-wasm.js
new file mode 100644
index 0000000000..6527c78efa
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/savedframe-lookup-in-wasm.js
@@ -0,0 +1,17 @@
+g = newGlobal({newCompartment: true});
+g.parent = this;
+g.eval(`(function() {
+ Debugger(parent).onExceptionUnwind = function(frame) { return frame.eval(""); }
+})()`);
+
+var module = new WebAssembly.Module(wasmTextToBinary(`
+ (module (import $imp "" "inc") (func) (func $start (call $imp)) (start $start) (export "" (func $start)))
+`));
+
+var imports = {
+ "": {
+ inc: function() { undefined_function(); }
+ }
+};
+
+new WebAssembly.Instance(module, imports).exports['']();
diff --git a/js/src/jit-test/tests/wasm/regress/select-any.js b/js/src/jit-test/tests/wasm/regress/select-any.js
new file mode 100644
index 0000000000..9e85d33897
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/select-any.js
@@ -0,0 +1,41 @@
+// Bug 1280921
+
+var m1 = wasmEvalText(
+`(module
+ (type $type0 (func))
+ (func $func0
+ (select
+ (unreachable)
+ (return (nop))
+ (loop (result i32) (i32.const 1))
+ )
+ drop
+ )
+ (export "" (func 0)))`).exports[""];
+
+try {
+ m1();
+} catch (e) {
+ if (!(e instanceof Error && e.message.match(/unreachable executed/)))
+ throw e;
+}
+
+var m2 = wasmEvalText(
+`(module
+ (type $type0 (func))
+ (func $func0
+ (select
+ (i32.const 26)
+ (unreachable)
+ (i32.const 3)
+ )
+ drop
+ )
+ (export "" (func 0)))`).exports[""];
+
+try {
+ m2();
+} catch (e) {
+ if (!(e instanceof Error && e.message.match(/unreachable executed/)))
+ throw e;
+}
diff --git a/js/src/jit-test/tests/wasm/regress/shift-counts.js b/js/src/jit-test/tests/wasm/regress/shift-counts.js
new file mode 100644
index 0000000000..aadc9e5d76
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/shift-counts.js
@@ -0,0 +1,8 @@
+// Bug 1280926, extracted from binary
+
+wasmEvalText(
+`(module
+ (type $type0 (func (result i32)))
+ (export "" (func $func0))
+ (func $func0 (result i32)
+ (i32.shr_s (i32.const -40) (i32.const 34))))`);
diff --git a/js/src/jit-test/tests/wasm/regress/signed-unsigned-div-mod.js b/js/src/jit-test/tests/wasm/regress/signed-unsigned-div-mod.js
new file mode 100644
index 0000000000..370676d2c4
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/signed-unsigned-div-mod.js
@@ -0,0 +1,75 @@
+// The result should be -1 because it is (i32.rem_s -1 10000) and the spec
+// stipulates "result has the sign of the dividend". This test uncovers a bug
+// in SpiderMonkey wherein the shape of the lhs (it looks like an unsigned
+// value) causes an unsigned modulo to be emitted.
+
+assertEq(wasmEvalText(
+ `(module
+ (func (result i32)
+ (i32.const -1)
+ (i32.const 0)
+ i32.shr_u
+ (i32.const 10000)
+ i32.rem_s)
+ (export "f" (func 0)))`).exports.f(), -1);
+
+// Ditto for int64
+
+wasmAssert(
+ `(module
+ (func $run (result i64)
+ (i64.const -1)
+ (i64.const 0)
+ i64.shr_u
+ (i64.const 10000)
+ i64.rem_s)
+ )`, [{type:'i64', expected:'0xffffffffffffffff', func:'$run'}]);
+
+// Despite the signed shift this is 0x80000000 % 10000 (rem_u)
+// and the result is positive.
+
+assertEq(wasmEvalText(
+ `(module
+ (func (result i32)
+ (i32.const -1)
+ (i32.const 0)
+ i32.shl
+ (i32.const 10000)
+ i32.rem_u)
+ (export "f" (func 0)))`).exports.f(), 7295);
+
+// 0x80000000 is really -0x80000000 so the result of signed division shall be
+// negative.
+
+assertEq(wasmEvalText(
+ `(module
+ (func (result i32)
+ (i32.const 0x80000000)
+ (i32.const 0)
+ i32.shr_u
+ (i32.const 10000)
+ i32.div_s)
+ (export "f" (func 0)))`).exports.f(), -214748);
+
+assertEq(wasmEvalText(
+ `(module
+ (func (result i32)
+ (i32.const 0x80000000)
+ (i32.const 0)
+ i32.shr_u
+ (i32.const -10000)
+ i32.div_s)
+ (export "f" (func 0)))`).exports.f(), 214748);
+
+// And the result of unsigned division shall be positive.
+
+assertEq(wasmEvalText(
+ `(module
+ (func (result i32)
+ (i32.const 0x80000000)
+ (i32.const 0)
+ i32.shr_u
+ (i32.const 10000)
+ i32.div_u)
+ (export "f" (func 0)))`).exports.f(), 214748);
+
diff --git a/js/src/jit-test/tests/wasm/regress/startfunc-in-table.js b/js/src/jit-test/tests/wasm/regress/startfunc-in-table.js
new file mode 100644
index 0000000000..12ebfe64ab
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/startfunc-in-table.js
@@ -0,0 +1,6 @@
+wasmEvalText(`(module
+ (func)
+ (start 0)
+ (table $0 1 anyfunc)
+ (elem 0 (i32.const 0) func 0)
+)`);
diff --git a/js/src/jit-test/tests/wasm/regress/table-of-anyref.js b/js/src/jit-test/tests/wasm/regress/table-of-anyref.js
new file mode 100644
index 0000000000..a19ec95be5
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/table-of-anyref.js
@@ -0,0 +1,9 @@
+// Faulty prebarrier for tables.
+gczeal(4, 8);
+let ins = wasmEvalText(
+ `(module
+ (table (export "t") 10 externref)
+ (func (export "set_externref") (param i32) (param externref)
+ (table.set (get_local 0) (get_local 1))))`);
+ins.exports.set_externref(3, {});
+ins.exports.set_externref(3, null);
diff --git a/js/src/jit-test/tests/wasm/regress/teavm-bugs.js b/js/src/jit-test/tests/wasm/regress/teavm-bugs.js
new file mode 100644
index 0000000000..c526dbd7bb
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/teavm-bugs.js
@@ -0,0 +1,53 @@
+// Register allocation issue with LCompareI64AndBranch.
+let params = '';
+let locals = '';
+let tests = '(i64.const 0)';
+
+for (let i = 15; i --> 0;) {
+ params += `\n(param i64)`;
+ locals += `\n(local i64)`;
+ tests = `
+ (if (result i64)
+ (i64.eq
+ (local.get ${i + 8})
+ (local.get ${i})
+ )
+ (local.get ${i + 8})
+ ${tests}
+ )`;
+}
+
+let code = `(module
+ (func $i64
+ ${params} (result i64) ${locals}
+ ${tests}
+ )
+)`
+
+wasmEvalText(code);
+
+// Bounds check elimination.
+assertEq(wasmEvalText(`(module
+ (memory 1)
+ (func (param $p i32) (result i32) (local $l i32)
+ (local.set $l (i32.const 0))
+ (if
+ (local.get $p)
+ (local.set $l
+ (i32.add
+ (local.get $l)
+ (i32.load8_s (local.get $p))
+ )
+ )
+ )
+ (local.set $l
+ (i32.add
+ (local.get $l)
+ (i32.load8_s (local.get $p))
+ )
+ )
+ (local.get $l)
+ )
+ (data (i32.const 0) "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
+ (export "test" (func 0))
+)`).exports["test"](3), 6);
diff --git a/js/src/jit-test/tests/wasm/regress/too-large-frame.js b/js/src/jit-test/tests/wasm/regress/too-large-frame.js
new file mode 100644
index 0000000000..b91f8f6381
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/too-large-frame.js
@@ -0,0 +1,27 @@
+// Bug 1280934, equivalent test case.
+
+try {
+
+wasmEvalText(
+`(module
+ (func $func0 (result i32) ${locals()}
+ (i32.const 0))
+ (export "" (func 0)))`);
+
+} catch (e) {
+ // The wasm baseline compiler throws OOM on too-large frames, so
+ // handle that.
+ if (!String(e).match(/out of memory/))
+ throw e;
+}
+
+// The wasm baseline compiler cuts off frames at 256KB at the moment;
+// the test case for bug 1280934 constructed a frame around 512KB so
+// duplicate that here.
+
+function locals() {
+ var s = "";
+ for ( var i=0 ; i < 50000 ; i++ )
+ s += "(local f64)\n";
+ return s;
+}
diff --git a/js/src/jit-test/tests/wasm/regress/unaligned-store64.js b/js/src/jit-test/tests/wasm/regress/unaligned-store64.js
new file mode 100644
index 0000000000..b878093451
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/unaligned-store64.js
@@ -0,0 +1,35 @@
+var ins = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(
+ `(module
+ (memory (export "mem") 1 1)
+ (func (export "store_32_1") (param $ptr i32)
+ (i64.store32 align=1 (local.get $ptr) (i64.const 0xabba1337)))
+ (func (export "store_32_2") (param $ptr i32)
+ (i64.store32 align=2 (local.get $ptr) (i64.const 0xabba1337)))
+ (func (export "store_16") (param $ptr i32)
+ (i64.store16 align=1 (local.get $ptr) (i64.const 0x1337))))`))).exports;
+
+var mem = new Uint8Array(ins.mem.buffer);
+
+ins.store_16(1);
+assertEq(mem[1], 0x37);
+assertEq(mem[2], 0x13);
+
+ins.store_32_1(11);
+assertEq(mem[11], 0x37);
+assertEq(mem[12], 0x13);
+assertEq(mem[13], 0xba);
+assertEq(mem[14], 0xab);
+
+ins.store_32_2(18);
+assertEq(mem[18], 0x37);
+assertEq(mem[19], 0x13);
+assertEq(mem[20], 0xba);
+assertEq(mem[21], 0xab);
+
+// This must also work on all platforms even though we're lying about the
+// alignment.
+ins.store_32_2(29);
+assertEq(mem[29], 0x37);
+assertEq(mem[30], 0x13);
+assertEq(mem[31], 0xba);
+assertEq(mem[32], 0xab);
diff --git a/js/src/jit-test/tests/wasm/regress/upper-maximum-memory.js b/js/src/jit-test/tests/wasm/regress/upper-maximum-memory.js
new file mode 100644
index 0000000000..d2d099f4fe
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/upper-maximum-memory.js
@@ -0,0 +1,4 @@
+new WebAssembly.Memory({
+ initial: 1,
+ maximum: 65536
+});