summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/wasm/tail-calls/return-call-indirect-validate.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/wasm/tail-calls/return-call-indirect-validate.js')
-rw-r--r--js/src/jit-test/tests/wasm/tail-calls/return-call-indirect-validate.js243
1 files changed, 243 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/wasm/tail-calls/return-call-indirect-validate.js b/js/src/jit-test/tests/wasm/tail-calls/return-call-indirect-validate.js
new file mode 100644
index 0000000000..15c2142a55
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/tail-calls/return-call-indirect-validate.js
@@ -0,0 +1,243 @@
+// |jit-test| skip-if: !wasmTailCallsEnabled()
+
+wasmValidateText(
+ `(module
+ (type (func))
+ (table 0 funcref)
+ (func $arity-1-vs-0
+ (return_call_indirect (type 0)
+ (i32.const 1) (i32.const 0))))`);
+
+wasmValidateText(
+ `(module
+ (type (func))
+ (table 0 funcref)
+ (func $arity-1-vs-0
+ (return_call_indirect (type 0)
+ (f64.const 2) (i32.const 1) (i32.const 0))))`);
+
+const constants = [{'type': 'i32', 'value': '0x132'},
+ {'type': 'i64', 'value': '0x164'},
+ {'type': 'f32', 'value': '0xf32'},
+ {'type': 'f64', 'value': '0xf64'}];
+
+function validateConst(type, value) {
+ wasmValidateText(
+ `(module
+ (type $out-${type} (func (result ${type})))
+ (func $type-${type} (result ${type})
+ (return_call_indirect (type $out-${type}) (i32.const 0)))
+ (func $const-${type} (result ${type})
+ (${type}.const ${value}))
+ (func $t (result ${type})
+ (return_call $type-${type}))
+ (table funcref (elem $const-${type})))`);
+}
+for (let {type, value} of constants) {
+ validateConst(type, value);
+}
+
+function validateOneArg(type, value) {
+ wasmValidateText(
+ `(module
+ (type $f-${type} (func (param ${type}) (result ${type})))
+ (func $id-${type} (param ${type}) (result ${type})
+ (local.get 0))
+ (func $t (result ${type})
+ (return_call_indirect (type $f-${type}) (${type}.const ${value})
+ (i32.const 0)))
+ (table funcref (elem $id-${type})))`);
+}
+for (let {type, value} of constants) {
+ validateOneArg(type, value);
+}
+
+function validateTwoArgs(t0, v0, t1, v1) {
+ wasmValidateText(
+ `(module
+ (type $f (func (param ${t0} ${t1}) (result ${t1})))
+ (func $second-${t0}-${t1} (param ${t0} ${t1}) (result ${t1})
+ (local.get 1))
+ (func $t (result ${t1})
+ (return_call_indirect (type $f)
+ (${t0}.const ${v0}) (${t1}.const ${v1})
+ (i32.const 0)))
+ (table funcref (elem $second-${t0}-${t1})))`);
+}
+for (let {type: t0, value: v0} of constants) {
+ for (let {type: t1, value: v1} of constants) {
+ validateTwoArgs(t0, v0, t1, v1);
+ }
+}
+
+wasmValidateText(
+ `(module
+ (type $f (func (param i64) (result i64)))
+ (func $id-i64 (param i64) (result i64)
+ (local.get 0))
+ (func $dispatch1 (param i32 i64) (result i64)
+ (return_call_indirect (type $f) (local.get 1) (local.get 0)))
+ (func $dispatch2 (param i32) (result i64)
+ (return_call_indirect (type $f) (i64.const 42) (local.get 0)))
+ (func $t1 (result i64)
+ (return_call $dispatch1 (i32.const 0) (i64.const 1)))
+ (func $t2 (result i64)
+ (return_call $dispatch2 (i32.const 100)))
+ (table funcref (elem $id-i64)))`);
+
+wasmValidateText(
+ `(module
+ (type $i64-i64 (func (param i64 i64) (result i64)))
+ (func $fac (type $i64-i64)
+ (return_call_indirect (type $i64-i64)
+ (local.get 0) (i64.const 1) (i32.const 0)))
+
+ (func $fac-acc (param i64 i64) (result i64)
+ (if (result i64) (i64.eqz (local.get 0))
+ (then (local.get 1))
+ (else
+ (return_call_indirect (type $i64-i64)
+ (i64.sub (local.get 0) (i64.const 1))
+ (i64.mul (local.get 0) (local.get 1))
+ (i32.const 0)))))
+
+ (table funcref (elem $fac-acc)))`);
+
+wasmValidateText(
+ `(module
+ (type $t (func (param i32) (result i32)))
+ (func $even (param i32) (result i32)
+ (if (result i32) (i32.eqz (local.get 0))
+ (then (i32.const 44))
+ (else
+ (return_call_indirect (type $t)
+ (i32.sub (local.get 0) (i32.const 1))
+ (i32.const 1)))))
+ (func $odd (param i32) (result i32)
+ (if (result i32) (i32.eqz (local.get 0))
+ (then (i32.const 99))
+ (else
+ (return_call_indirect (type $t)
+ (i32.sub (local.get 0) (i32.const 1))
+ (i32.const 0)))))
+ (table funcref (elem $even $odd)))`);
+
+wasmFailValidateText(
+ `(module
+ (type (func))
+ (func $no-table
+ (return_call_indirect (type 0) (i32.const 0))))`,
+ /call_indirect without a table/);
+
+wasmFailValidateText(
+ `(module
+ (type (func))
+ (table 0 funcref)
+ (func $type-void-vs-num
+ (i32.eqz (return_call_indirect (type 0) (i32.const 0)))))`,
+ /unused values not explicitly dropped/);
+
+wasmFailValidateText(
+ `(module
+ (type (func))
+ (table 0 funcref)
+ (func $type-void-vs-num (result i32)
+ (i32.eqz (return_call_indirect (type 0) (i32.const 0)))))`,
+ /type mismatch: expected 1 values, got 0 values/);
+
+wasmFailValidateText(
+ `(module
+ (type (func (result i64)))
+ (table 0 funcref)
+ (func $type-num-vs-num
+ (i32.eqz (return_call_indirect (type 0) (i32.const 0)))))`,
+ /type mismatch: expected 0 values, got 1 values/);
+
+wasmFailValidateText(
+ `(module
+ (type (func (result i64)))
+ (table 0 funcref)
+ (func $type-num-vs-num (result i32)
+ (i32.eqz (return_call_indirect (type 0) (i32.const 0)))))`,
+ /expression has type i64 but expected i32/);
+
+wasmFailValidateText(
+ `(module
+ (type (func (param i32)))
+ (table 0 funcref)
+ (func $arity-0-vs-1
+ (return_call_indirect (type 0) (i32.const 0))))`,
+ /popping value from empty stack/);
+
+wasmFailValidateText(
+ `(module
+ (type (func (param f64 i32)))
+ (table 0 funcref)
+ (func $arity-0-vs-2
+ (return_call_indirect (type 0) (i32.const 0))))`,
+ /popping value from empty stack/);
+
+wasmFailValidateText(
+ `(module
+ (type (func (param i32)))
+ (table 0 funcref)
+ (func $type-func-void-vs-i32
+ (return_call_indirect (type 0) (i32.const 1) (nop))))`,
+ /popping value from empty stack/);
+
+wasmFailValidateText(
+ `(module
+ (type (func (param i32)))
+ (table 0 funcref)
+ (func $type-func-num-vs-i32
+ (return_call_indirect (type 0) (i32.const 0) (i64.const 1))))`,
+ /expression has type i64 but expected i32/);
+
+wasmFailValidateText(
+ `(module
+ (type (func (param i32 i32)))
+ (table 0 funcref)
+ (func $type-first-void-vs-num
+ (return_call_indirect (type 0) (nop) (i32.const 1) (i32.const 0))
+ ))`,
+ /popping value from empty stack/);
+
+wasmFailValidateText(
+ `(module
+ (type (func (param i32 i32)))
+ (table 0 funcref)
+ (func $type-second-void-vs-num
+ (return_call_indirect (type 0) (i32.const 1) (nop) (i32.const 0))))`,
+ /popping value from empty stack/);
+
+wasmFailValidateText(
+ `(module
+ (type (func (param i32 f64)))
+ (table 0 funcref)
+ (func $type-first-num-vs-num
+ (return_call_indirect (type 0)
+ (f64.const 1) (i32.const 1) (i32.const 0))))`,
+ /expression has type i32 but expected f64/);
+
+wasmFailValidateText(
+ `(module
+ (type (func (param f64 i32)))
+ (table 0 funcref)
+ (func $type-second-num-vs-num
+ (return_call_indirect (type 0)
+ (i32.const 1) (f64.const 1) (i32.const 0))))`,
+ /expression has type f64 but expected i32/);
+
+wasmFailValidateText(
+ `(module
+ (table 0 funcref)
+ (func $unbound-type
+ (return_call_indirect (type 1) (i32.const 0))))`,
+ /signature index out of range/);
+
+wasmFailValidateText(
+ `(module
+ (table 0 funcref)
+ (func $large-type
+ (return_call_indirect (type 1012321300) (i32.const 0))))`,
+ /signature index out of range/);