summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/wasm/exceptions/memory.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/wasm/exceptions/memory.js')
-rw-r--r--js/src/jit-test/tests/wasm/exceptions/memory.js78
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);
+ }
+}