summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/wasm/tail-calls/return_call_indirect.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/wasm/tail-calls/return_call_indirect.js')
-rw-r--r--js/src/jit-test/tests/wasm/tail-calls/return_call_indirect.js156
1 files changed, 156 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/wasm/tail-calls/return_call_indirect.js b/js/src/jit-test/tests/wasm/tail-calls/return_call_indirect.js
new file mode 100644
index 0000000000..f9639902fe
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/tail-calls/return_call_indirect.js
@@ -0,0 +1,156 @@
+var ins0 = wasmEvalText(`(module
+ (func $fac-acc (export "fac-acc") (param i64 i64) (result i64)
+ (if (result i64) (i64.eqz (local.get 0))
+ (then (local.get 1))
+ (else
+ (return_call $fac-acc
+ (i64.sub (local.get 0) (i64.const 1))
+ (i64.mul (local.get 0) (local.get 1))
+ )
+ )
+ )
+ )
+)`);
+
+var ins = wasmEvalText(`(module
+ (import "" "fac-acc" (func $fac-acc (param i64 i64) (result i64)))
+ (type $ty (func (param i64 i64) (result i64)))
+ (table $t 1 1 funcref)
+ (func $f (export "fac") (param i64) (result i64)
+ local.get 0
+ i64.const 1
+ i32.const 0
+ return_call_indirect $t (type $ty)
+ )
+ (elem $t (i32.const 0) $fac-acc)
+
+ (func (export "main") (result i64)
+ i64.const 5
+ call $f
+ )
+)`, {"": {"fac-acc": ins0.exports["fac-acc"]}});
+
+// Check return call via wasm function
+assertEq(ins.exports.main(5n), 120n);
+
+// Check return call directly via interpreter stub
+const fac = ins.exports["fac"];
+assertEq(fac(4n, 1n), 24n);
+
+// Check return call directly via jit stub
+check_stub1: {
+ let options = getJitCompilerOptions();
+ if (!options["baseline.enable"]) break check_stub1;
+ const check = function() {
+ fac(4n, 1n);
+ };
+ for (let i = options["baseline.warmup.trigger"] + 1; i--;)
+ check();
+}
+
+// Invalid func type
+var ins = wasmEvalText(`(module
+ (import "" "fac-acc" (func $fac-acc (param i64 i64) (result i64)))
+ (type $ty (func (param i64 i64) (result i64)))
+ (type $tz (func (param i64) (result i64)))
+ (table $t 1 1 funcref)
+ (func $f (export "fac") (param i64) (result i64)
+ local.get 0
+ i64.const 1
+ i32.const 0
+ return_call_indirect $t (type $tz)
+ )
+ (elem $t (i32.const 0) $fac-acc)
+
+ (func (export "main") (result i64)
+ i64.const 5
+ call $f
+ )
+)`, {"": {"fac-acc": ins0.exports["fac-acc"]}});
+
+assertErrorMessage(() => ins.exports.main(), WebAssembly.RuntimeError, /indirect call signature mismatch/);
+assertErrorMessage(() => ins.exports.fac(6n), WebAssembly.RuntimeError, /indirect call signature mismatch/);
+
+// Invalid func type, but testing when entry directly does invalid return_call_indirect.
+var wasm = wasmTextToBinary(`(module
+ (global $g (export "g") (mut i32) (i32.const 0))
+ (table 1 1 funcref)
+ (type $ft (func (param f64)))
+ (func $f (export "f")
+ unreachable
+ )
+ (func $test (export "test")
+ global.get $g
+ br_if 0
+ f64.const 0.0
+ i32.const 0
+ return_call_indirect (type $ft)
+ )
+ (elem (i32.const 0) $f)
+)`);
+
+var ins = new WebAssembly.Instance(new WebAssembly.Module(wasm));
+function check_err() { ins.exports.test(); }
+assertErrorMessage(check_err, WebAssembly.RuntimeError, /indirect call signature mismatch/);
+
+var ins = new WebAssembly.Instance(new WebAssembly.Module(wasm));
+check_stub2: {
+ let options = getJitCompilerOptions();
+ if (!options["baseline.enable"]) break check_stub2;
+ ins.exports.g.value = 1;
+ for (let i = options["baseline.warmup.trigger"] + 1; i--;)
+ check_err();
+ ins.exports.g.value = 0;
+ assertErrorMessage(check_err, WebAssembly.RuntimeError, /indirect call signature mismatch/);
+}
+
+var ins = new WebAssembly.Instance(new WebAssembly.Module(wasm));
+check_stub3: {
+ let options = getJitCompilerOptions();
+ if (!options["ion.enable"]) break check_stub3;
+ ins.exports.g.value = 1;
+ var check_err2 = function() { for (var i = 0; i < 5; i++) ins.exports.test(); };
+ for (let i = options["ion.warmup.trigger"]+2; i--;)
+ check_err2();
+ ins.exports.g.value = 0;
+ assertErrorMessage(() => check_err2(), WebAssembly.RuntimeError, /indirect call signature mismatch/);
+}
+
+// Performance and stack growth: calculating sum of numbers 1..40000000
+var ins = wasmEvalText(`(module
+ (table 1 1 funcref)
+ (type $rec (func (param i32 i64) (result i64)))
+ (func $sum (param i32 i64) (result i64)
+ local.get 0
+ i32.eqz
+ if
+ local.get 1
+ return
+ else
+ local.get 0
+ i32.const 1
+ i32.sub
+ local.get 1
+ local.get 0
+ i64.extend_i32_s
+ i64.add
+ i32.const 0
+ return_call_indirect (type $rec)
+ end
+ unreachable
+ )
+ (elem (i32.const 0) $sum)
+
+ (func (export "main") (param i32) (result i64)
+ local.get 0
+ i64.const 0
+ i32.const 0
+ return_call_indirect (type $rec)
+ )
+)`);
+
+if (getBuildConfiguration("simulator")) {
+ assertEq(ins.exports.main(400000), 80000200000n);
+} else {
+ assertEq(ins.exports.main(40000000), 800000020000000n);
+}