diff options
Diffstat (limited to 'js/src/jit-test/tests/wasm/function-references/non-nullable.js')
-rw-r--r-- | js/src/jit-test/tests/wasm/function-references/non-nullable.js | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/wasm/function-references/non-nullable.js b/js/src/jit-test/tests/wasm/function-references/non-nullable.js new file mode 100644 index 0000000000..b8fd20fd83 --- /dev/null +++ b/js/src/jit-test/tests/wasm/function-references/non-nullable.js @@ -0,0 +1,176 @@ +// |jit-test| skip-if: !wasmFunctionReferencesEnabled() + +// non-null values are subtype of null values +wasmValidateText(`(module + (func (param $a (ref extern)) + local.get $a + (block (param (ref null extern)) + drop + ) + ) +)`); + +// null values are not subtype of non-null values +wasmFailValidateText(`(module + (func (param $a (ref null extern)) + local.get $a + (block (param (ref extern)) + drop + ) + ) +)`, /expression has type externref but expected \(ref extern\)/); + +// can have non-defaultable local, but not use/get if unset. +wasmValidateText(`(module + (func (local (ref extern))) +)`); +wasmFailValidateText(`(module + (func (local (ref extern)) + local.get 0 + drop + ) +)`, /local\.get read from unset local/); +wasmFailValidateText(`(module + (func + (local (ref extern)) + unreachable + block + local.get 0 + drop + end + ) +)`, /local\.get read from unset local/); +wasmFailValidateText(`(module + (func (param funcref) (result funcref) (local (ref func)) + block + local.get 0 + ref.as_non_null + local.set 1 + end + local.get 1 + ) +)`, /local\.get read from unset local/); +wasmValidateText(`(module + (func (param $r (ref extern)) + (local $var (ref extern)) + local.get $r + ref.as_non_null + local.set $var + block block block + local.get $var + drop + end end end + ) + (func + (param (ref null func) (ref null func) (ref func)) + (result funcref) + (local (ref func) i32 (ref func) (ref null func)) + local.get 0 + ref.as_non_null + local.tee 3 + block + local.get 6 + ref.as_non_null + local.set 5 + end + local.get 2 + drop + local.tee 5 + ) +)`); +wasmFailValidateText(`(module + (elem declare 0) + (func + (local (ref func)) + i32.const 0 + if + ref.func 0 + local.set 0 + else + local.get 0 + drop + end + ) +)`, /local\.get read from unset local/); +wasmValidateText(`(module + (elem declare 0) + (func (result funcref) + (local (ref func) (ref func)) + i32.const 0 + if (result funcref) + ref.func 0 + local.set 0 + local.get 0 + else + ref.func 0 + local.tee 1 + local.get 1 + drop + end + ) +)`); + +// exported funcs can't take null in non-nullable params +let {a} = wasmEvalText(`(module + (func (export "a") (param (ref extern))) +)`).exports; +assertErrorMessage(() => a(null), TypeError, /cannot pass null to non-nullable/); +for (let val of WasmNonNullExternrefValues) { + a(val); +} + +// imported funcs can't return null in non-nullable results +function returnNull() { + return null; +} +function returnMultiNullReg() { + return [null, null]; +} +function returnMultiNullStack() { + return [1, 2, 3, 4, 5, 6, 7, 8, null]; +} +let {runNull, runMultiNullReg, runMultiNullStack} = wasmEvalText(`(module + (func $returnNull (import "" "returnNull") (result (ref extern))) + (func $returnMultiNullReg (import "" "returnMultiNullReg") (result (ref extern) (ref extern))) + (func $returnMultiNullStack (import "" "returnMultiNullStack") (result (ref extern) (ref extern) (ref extern) (ref extern) (ref extern) (ref extern) (ref extern) (ref extern) (ref extern))) + (func (export "runNull") + call $returnNull + unreachable + ) + (func (export "runMultiNullReg") + call $returnMultiNullReg + unreachable + ) + (func (export "runMultiNullStack") + call $returnMultiNullStack + unreachable + ) +)`, { "": { returnNull, returnMultiNullReg, returnMultiNullStack } }).exports; +assertErrorMessage(() => runNull(), TypeError, /cannot pass null to non-nullable/); +assertErrorMessage(() => runMultiNullReg(), TypeError, /cannot pass null to non-nullable/); +assertErrorMessage(() => runMultiNullStack(), TypeError, /cannot pass null to non-nullable/); + +{ + // can have non-nullable globals + wasmEvalText(`(module + (func $f) + (elem declare $f) + (global (ref func) ref.func $f) + )`); +} + +// cannot have non-nullable tables without initializer +wasmFailValidateText(`(module + (table (ref extern) (elem)) +)`, /table with non-nullable references requires initializer/); + +// Testing internal wasmLosslessInvoke to pass non-nullable as params and arguments. +let {t} = wasmEvalText(`(module + (func (export "t") (param (ref extern)) (result (ref extern)) + (local (ref extern)) + (local.set 1 (local.get 0)) + (local.get 1) + ) +)`).exports; +const ret = wasmLosslessInvoke(t, {test: 1}); +assertEq(ret.value.test, 1); |