From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- js/src/jit-test/tests/wasm/ref-types/funcref.js | 135 ++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 js/src/jit-test/tests/wasm/ref-types/funcref.js (limited to 'js/src/jit-test/tests/wasm/ref-types/funcref.js') diff --git a/js/src/jit-test/tests/wasm/ref-types/funcref.js b/js/src/jit-test/tests/wasm/ref-types/funcref.js new file mode 100644 index 0000000000..21ce95c0cb --- /dev/null +++ b/js/src/jit-test/tests/wasm/ref-types/funcref.js @@ -0,0 +1,135 @@ +const {Module,Instance,Global,RuntimeError} = WebAssembly; + +const badWasmFunc = /can only pass WebAssembly exported functions to funcref/; +const typeErr = /type mismatch/; + + +// Validation: + +wasmFailValidateText(`(module (func (local externref funcref) (local.set 0 (local.get 1))))`, typeErr); +wasmEvalText(`(module (func (local funcref funcref) (local.set 0 (local.get 1))))`); +wasmEvalText(`(module (func (local funcref) (local.set 0 (ref.null func))))`); +wasmFailValidateText(`(module (func (local funcref externref) (local.set 0 (local.get 1))))`, typeErr); +wasmEvalText(`(module (global (mut funcref) (ref.null func)) (func (param funcref) (global.set 0 (local.get 0))))`); +wasmFailValidateText(`(module (global (mut externref) (ref.null extern)) (func (param funcref) (global.set 0 (local.get 0))))`, typeErr); +wasmFailValidateText(`(module (global (mut funcref) (ref.null func)) (func (param externref) (global.set 0 (local.get 0))))`, typeErr); +wasmEvalText(`(module (func (param funcref)) (func (param funcref) (call 0 (local.get 0))))`); +wasmFailValidateText(`(module (func (param externref)) (func (param funcref) (call 0 (local.get 0))))`, typeErr); +wasmFailValidateText(`(module (func (param funcref)) (func (param externref) (call 0 (local.get 0))))`, typeErr); +wasmEvalText(`(module (func (param funcref) (result funcref) (block (result funcref) (local.get 0) (br 0))))`); +wasmFailValidateText(`(module (func (param funcref) (result externref) (block (result externref) (local.get 0) (br 0))))`, typeErr); +wasmFailValidateText(`(module (func (param externref) (result externref) (block (result funcref) (local.get 0) (br 0))))`, typeErr); +wasmEvalText(`(module (func (param funcref funcref) (result funcref) (select (result funcref) (local.get 0) (local.get 1) (i32.const 0))))`); +wasmFailValidateText(`(module (func (param externref funcref) (result externref) (select (result externref) (local.get 0) (local.get 1) (i32.const 0))))`, typeErr); +wasmFailValidateText(`(module (func (param funcref externref) (result externref) (select (result externref)(local.get 0) (local.get 1) (i32.const 0))))`, typeErr); +wasmFailValidateText(`(module (func (param externref funcref) (result funcref) (select (result funcref) (local.get 0) (local.get 1) (i32.const 0))))`, typeErr); +wasmFailValidateText(`(module (func (param funcref externref) (result funcref) (select (result funcref) (local.get 0) (local.get 1) (i32.const 0))))`, typeErr); + + +// Runtime: + +var m = new Module(wasmTextToBinary(`(module (func (export "wasmFun")))`)); +const wasmFun1 = new Instance(m).exports.wasmFun; +const wasmFun2 = new Instance(m).exports.wasmFun; +const wasmFun3 = new Instance(m).exports.wasmFun; + +var run = wasmEvalText(`(module + (global (mut funcref) (ref.null func)) + (func (param $x funcref) (param $test i32) (result funcref) + local.get $x + global.get 0 + local.get $test + select (result funcref) + ) + (func (export "run") (param $a funcref) (param $b funcref) (param $c funcref) (param $test1 i32) (param $test2 i32) (result funcref) + local.get $a + global.set 0 + block (result funcref) + local.get $b + local.get $test1 + br_if 0 + drop + local.get $c + end + local.get $test2 + call 0 + ) +)`).exports.run; +assertEq(run(wasmFun1, wasmFun2, wasmFun3, false, false), wasmFun1); +assertEq(run(wasmFun1, wasmFun2, wasmFun3, true, false), wasmFun1); +assertEq(run(wasmFun1, wasmFun2, wasmFun3, true, true), wasmFun2); +assertEq(run(wasmFun1, wasmFun2, wasmFun3, false, true), wasmFun3); + +var run = wasmEvalText(`(module + (type $t0 (func (param externref) (result externref))) + (type $t1 (func (param funcref) (result externref))) + (type $t2 (func (param funcref funcref) (result externref))) + (func $f0 (type $t0) ref.null extern) + (func $f1 (type $t1) ref.null extern) + (func $f2 (type $t2) ref.null extern) + (table funcref (elem $f0 $f1 $f2)) + (func (export "run") (param i32 i32) (result externref) + block $b2 block $b1 block $b0 + local.get 0 + br_table $b0 $b1 $b2 + end $b0 + ref.null extern + local.get 1 + call_indirect (type $t0) + return + end $b1 + ref.null func + local.get 1 + call_indirect (type $t1) + return + end $b2 + ref.null func + ref.null func + local.get 1 + call_indirect (type $t2) + return + ) +)`).exports.run; + +for (var i = 0; i < 3; i++) { + for (var j = 0; j < 3; j++) { + if (i == j) + assertEq(run(i, j), null); + else + assertErrorMessage(() => run(i, j), RuntimeError, /indirect call signature mismatch/); + } +} + + +// JS API: + +const wasmFun = wasmEvalText(`(module (func (export "x")))`).exports.x; + +var run = wasmEvalText(`(module (func (export "run") (param funcref) (result funcref) (local.get 0)))`).exports.run; +assertEq(run(wasmFun), wasmFun); +assertEq(run(null), null); +assertErrorMessage(() => run(() => {}), TypeError, badWasmFunc); + +var importReturnValue; +var importFun = () => importReturnValue; +var run = wasmEvalText(`(module (func (import "" "i") (result funcref)) (func (export "run") (result funcref) (call 0)))`, {'':{i:importFun}}).exports.run; +importReturnValue = wasmFun; +assertEq(run(), wasmFun); +importReturnValue = null; +assertEq(run(), null); +importReturnValue = undefined; +assertErrorMessage(() => run(), TypeError, badWasmFunc); +importReturnValue = () => {}; +assertErrorMessage(() => run(), TypeError, badWasmFunc); + +var g = new Global({value:'anyfunc', mutable:true}, wasmFun); +assertEq(g.value, wasmFun); +g.value = null; +assertEq(g.value, null); +Math.sin(); +assertErrorMessage(() => g.value = () => {}, TypeError, badWasmFunc); +var g = new Global({value:'anyfunc', mutable:true}, null); +assertEq(g.value, null); +g.value = wasmFun; +assertEq(g.value, wasmFun); +assertErrorMessage(() => new Global({value:'anyfunc'}, () => {}), TypeError, badWasmFunc); -- cgit v1.2.3