summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/wasm/exceptions/reftypes.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/wasm/exceptions/reftypes.js')
-rw-r--r--js/src/jit-test/tests/wasm/exceptions/reftypes.js141
1 files changed, 141 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/wasm/exceptions/reftypes.js b/js/src/jit-test/tests/wasm/exceptions/reftypes.js
new file mode 100644
index 0000000000..efd577dec8
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/exceptions/reftypes.js
@@ -0,0 +1,141 @@
+// Exception tests that use reference types.
+
+load(libdir + "eqArrayHelper.js");
+
+assertEq(
+ wasmEvalText(
+ `(module
+ (tag $exn (param externref))
+ (func (export "f") (result externref)
+ try (result externref)
+ ref.null extern
+ throw $exn
+ catch $exn
+ end))`
+ ).exports.f(),
+ null
+);
+
+{
+ let f = wasmEvalText(
+ `(module
+ (tag $exn (param funcref))
+ (func $f (export "f") (result funcref)
+ try (result funcref)
+ ref.func $f
+ throw $exn
+ catch $exn
+ end))`
+ ).exports.f;
+ assertEq(f(), f);
+}
+
+{
+ let f = wasmEvalText(
+ `(module
+ (tag $exn (param externref))
+ (func (export "f") (param externref) (result externref)
+ try (result externref)
+ local.get 0
+ throw $exn
+ catch $exn
+ end))`
+ ).exports.f;
+
+ for (v of WasmExternrefValues) {
+ assertEq(f(v), v);
+ }
+}
+
+assertEqArray(
+ wasmEvalText(
+ `(module
+ (tag $exn (param externref externref))
+ (func (export "f") (param externref externref)
+ (result externref externref)
+ try (result externref externref)
+ local.get 0
+ local.get 1
+ throw $exn
+ catch $exn
+ end))`
+ ).exports.f("foo", "bar"),
+ ["foo", "bar"]
+);
+
+assertEqArray(
+ wasmEvalText(
+ `(module
+ (tag $exn (param i32 i32 externref f32))
+ (func (export "f") (param externref)
+ (result i32 i32 externref f32)
+ try (result i32 i32 externref f32)
+ i32.const 0
+ i32.const 1
+ local.get 0
+ f32.const 2.0
+ throw $exn
+ catch $exn
+ end))`
+ ).exports.f("foo"),
+ [0, 1, "foo", 2.0]
+);
+
+assertEqArray(
+ wasmEvalText(
+ `(module
+ (tag $exn (param i32 i32 externref f32 externref f64))
+ (func (export "f") (param externref externref)
+ (result i32 i32 externref f32 externref f64)
+ try (result i32 i32 externref f32 externref f64)
+ i32.const 0
+ i32.const 1
+ local.get 0
+ f32.const 2.0
+ local.get 1
+ f64.const 3.0
+ throw $exn
+ catch $exn
+ end))`
+ ).exports.f("foo", "bar"),
+ [0, 1, "foo", 2.0, "bar", 3.0]
+);
+
+// Test to ensure that reference typed values are tracked correctly by
+// the GC within exception objects.
+{
+ gczeal(2, 1); // Collect on every allocation.
+
+ var thrower;
+ let exports = wasmEvalText(
+ `(module
+ (tag $exn (param externref))
+ (import "m" "f" (func $f (result externref)))
+ (func (export "thrower") (param externref)
+ (local.get 0)
+ (throw $exn))
+ (func (export "catcher") (result externref)
+ try (result externref)
+ (call $f)
+ catch $exn
+ end))`,
+ {
+ m: {
+ f: () => {
+ // The purpose of this intermediate try-catch in JS is to force
+ // some allocation to occur after Wasm's `throw`, triggering GC, and
+ // then rethrow back to Wasm to observe any errors.
+ try {
+ thrower("foo");
+ } catch (e) {
+ let v = { x: 5 };
+ throw e;
+ }
+ },
+ },
+ }
+ ).exports;
+
+ thrower = exports.thrower;
+ assertEq(exports.catcher(), "foo");
+}