diff options
Diffstat (limited to 'js/src/jit-test/tests/wasm/exceptions/memory.js')
-rw-r--r-- | js/src/jit-test/tests/wasm/exceptions/memory.js | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/wasm/exceptions/memory.js b/js/src/jit-test/tests/wasm/exceptions/memory.js new file mode 100644 index 0000000000..fef249ddf5 --- /dev/null +++ b/js/src/jit-test/tests/wasm/exceptions/memory.js @@ -0,0 +1,78 @@ +// Ensure memory operations work after a throw coming from a function call. +// These are also testing that the InstanceReg/HeapReg are set correctly after +// catching an exception. There are some variations to the kind of calls here; +// we test for direct/indirect calls of local/imported functions, and the +// indirect calls may come from a local table or an imported table. + +// Throw from a direct/indirect call of a local/imported function. +{ + let exports = wasmEvalText( + `(module $m + (memory $mem (data "bar")) + (tag $exn (export "exn")) + (tag $dummyExn (export "dummyExn")) + (func $throwsExn (export "throwsExn") + (throw $exn)) + (func $anotherThrowsExn + (throw $exn)) + (func $throwsDummyExn (export "throwsDummyExn") + (throw $dummyExn)) + (table (export "tab") funcref (elem $anotherThrowsExn $throwsDummyExn)))` + ).exports; + + function testMemoryAfterCall(callInstruction) { + assertEq( + wasmEvalText( + `(module + (import "m" "exn" (tag $exn)) + (tag $localExn (param i32)) + (type $t (func)) + (import "m" "tab" (table $importTable 2 funcref)) + (import "m" "throwsExn" (func $importFuncThrowsExn)) + (memory $mem (data "foo")) + (func $localFuncThrowsExn + (throw $exn)) + (table $localTable funcref + (elem $localFuncThrowsExn $importFuncThrowsExn)) + (func $anotherLocalFuncThrowsExn + (throw $exn)) + (func $throwsLocalExn + (throw $localExn + (i32.const 9))) + (func (export "testFunc") (result i32) + (try (result i32) + (do + ${callInstruction} + ;; All the rest should not be reachable. + (call $anotherLocalFuncThrowsExn) + (throw $exn) + (call $throwsLocalExn) + unreachable) + (catch $localExn) + (catch $exn + (i32.load8_u + (i32.const 0))) + (catch $exn + ;; This should be ignored. + unreachable))))`, + { m: exports } + ).exports.testFunc(), + 'foo'.charCodeAt(0) + ); + }; + + // Run test for various calls. + let callInstructions = + ["(call $anotherLocalFuncThrowsExn)", + "(call $importFuncThrowsExn)", + // Calls $localFuncThrowsExn. + "(call_indirect $localTable (type $t) (i32.const 0))", + // Calls $importFuncThrowsExn. + "(call_indirect $localTable (type $t) (i32.const 1))", + // Calls non exported function of the exports module $anotherThrowsExn. + "(call_indirect $importTable (type $t) (i32.const 0))"]; + + for (let callInstruction of callInstructions) { + testMemoryAfterCall(callInstruction); + } +} |