summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/wasm/exceptions/bug-1744663-extended.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/wasm/exceptions/bug-1744663-extended.js')
-rw-r--r--js/src/jit-test/tests/wasm/exceptions/bug-1744663-extended.js224
1 files changed, 224 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/wasm/exceptions/bug-1744663-extended.js b/js/src/jit-test/tests/wasm/exceptions/bug-1744663-extended.js
new file mode 100644
index 0000000000..6efd8f0bb1
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/exceptions/bug-1744663-extended.js
@@ -0,0 +1,224 @@
+load(libdir + "eqArrayHelper.js");
+
+// These tests ensure that the gc related errors in bug 1744663 are resolved.
+
+{
+ let catchlessTry = `
+ (try
+ (do (call $gc)
+ (throw $exn)))`;
+ let rethrow0 = `
+ (try
+ (do (call $gc)
+ (throw $exn))
+ (catch $exn (rethrow 0)))`;
+ let rethrow1 = `
+ (try
+ (do (throw $exn))
+ (catch_all
+ (try
+ (do (throw $exn))
+ (catch $exn (rethrow 1)))))`;
+ let delegate0 = `
+ (try
+ (do (call $gc)
+ (throw $exn))
+ (delegate 0))`;
+ let delegate1 = `
+ (block
+ (try
+ (do (call $gc)
+ (throw $exn))
+ (delegate 1)))`;
+ let delegate0InCatch = `
+ (try
+ (do (throw $exn))
+ (catch_all
+ (try
+ (do (call $gc)
+ (throw $exn))
+ (delegate 0))))`;
+ let delegate1InCatch = `
+ (try
+ (do (throw $exn))
+ (catch_all
+ (try
+ (do (call $gc)
+ (throw $exn))
+ (delegate 1))))`;
+
+ let rethrowingBodies = [catchlessTry, rethrow0, delegate0, delegate1,
+ rethrow1, delegate0InCatch, delegate1InCatch];
+
+ function rethrowingIndirectly(rethrowingBody) {
+ let exports = wasmEvalText(
+ `(module
+ (tag $exn (export "exn"))
+ (import "js" "gc" (func $gc))
+ (func $throwExn (export "throwExn") ${rethrowingBody}))`,
+ {js: {gc: () => { gc(); }}}
+ ).exports;
+
+ let mod =
+ `(module
+ (type $exnType (func))
+ (type $indirectFunctype (func))
+ (import "m" "exn" (tag $exn (type $exnType)))
+ (import "m" "throwExn" (func $throwExn (type $indirectFunctype)))
+ (table funcref (elem $throwExn))
+ (func (export "testFunc") (result i32)
+ (try (result i32)
+ (do (call_indirect (type $indirectFunctype) (i32.const 0))
+ (i32.const 0))
+ (catch $exn (i32.const 1)))))`;
+
+ let testFunction = wasmEvalText(mod, { m : exports}).exports.testFunc;
+ assertEq(testFunction(), 1);
+ };
+
+ for (let rethrowingBody of rethrowingBodies) {
+ //console.log("Calling rethrowingIndirectly with rethrowingBody = " + rethrowingBody);
+ rethrowingIndirectly(rethrowingBody);
+ }
+}
+
+// The full test case that caused the original failure.
+
+{
+ gczeal(2,1); // Collect after every allocation.
+
+ let v128Type = " i32";
+ let wrongV128 = "(i32.const 0)";
+ let correctV128 = "(i32.const 1)";
+ let checkV128Value = "";
+
+ if (wasmSimdEnabled()) {
+ v128Type = " v128";
+ wrongV128 = "(v128.const i32x4 11 22 33 44)";
+ correctV128 = "(v128.const i32x4 55 66 77 88)";
+ checkV128Value = `;; Check the V128 value
+ (v128.const i32x4 55 66 77 88)
+ (i32x4.eq)
+ (i32x4.all_true)`;
+ }
+
+ let exports = wasmEvalText(
+ `(module
+ (type $exnType (func (param i32 i64 f32 f64 externref ${v128Type})))
+ (type $indirectFunctype (func (param i32 i64 f32 f64 externref ${v128Type})
+ (result i32 i64 f32 f64 externref ${v128Type})))
+ (tag $exn (export "exn") (type $exnType))
+ (tag $emptyExn (export "emptyExn"))
+ (func $throwExn (export "throwExn") (param i32 i64 f32 f64 externref ${v128Type})
+ (result i32 i64 f32 f64 externref ${v128Type})
+ (local $ifPredicate i32)
+ (local.get 0) ;; i32
+ (local.get 1) ;; i64
+ (local.get 2) ;; f32
+ (local.get 3) ;; f64
+ (local.get 4) ;; ref
+ (local.get 5) ;; v128 or i32
+ (try (param i32 i64 f32 f64 externref ${v128Type})
+ (do
+ (if (param i32 i64 f32 f64 externref ${v128Type})
+ (local.get $ifPredicate)
+ (then (throw $exn))
+ (else (throw $exn))))
+ (catch $exn
+ (try (param i32 i64 f32 f64 externref ${v128Type})
+ (do (throw $exn))
+ (catch_all (rethrow 1))))
+ (catch_all))
+ unreachable)
+ (func $throwEmptyExn (export "throwEmptyExn")
+ (param i32 i64 f32 f64 externref ${v128Type})
+ (result i32 i64 f32 f64 externref ${v128Type})
+ (throw $emptyExn)
+ unreachable)
+ (func $returnArgs (export "returnArgs")
+ (param i32 i64 f32 f64 externref ${v128Type})
+ (result i32 i64 f32 f64 externref ${v128Type})
+ (local.get 0) ;; i32
+ (local.get 1) ;; i64
+ (local.get 2) ;; f32
+ (local.get 3) ;; f64
+ (local.get 4) ;; ref
+ (local.get 5))
+ (table (export "tab") funcref (elem $throwExn ;; 0
+ $throwEmptyExn ;; 1
+ $returnArgs)) ;; 2
+ )`).exports;
+
+ var mod =
+ `(module
+ (type $exnType (func (param i32 i64 f32 f64 externref ${v128Type})))
+ (type $indirectFunctype (func (param i32 i64 f32 f64 externref ${v128Type})
+ (result i32 i64 f32 f64 externref ${v128Type})))
+ (import "m" "exn" (tag $exn (type $exnType)))
+ (import "m" "emptyExn" (tag $emptyExn))
+ (import "m" "throwExn" (func $throwExn (type $indirectFunctype)))
+ (import "m" "throwEmptyExn"
+ (func $throwEmptyExn (type $indirectFunctype)))
+ (import "m" "returnArgs"
+ (func $returnArgs (type $indirectFunctype)))
+ (import "m" "tab" (table 3 funcref))
+ (func (export "testFunc") (param $correctRef externref)
+ (param $wrongRef externref)
+ ;; The last i32 result is the v128 check.
+ (result i32 i64 f32 f64 externref i32)
+ (local $ifPredicate i32)
+ (try (result i32 i64 f32 f64 externref i32)
+ (do
+ ;; Wrong values
+ (i32.const 5)
+ (i64.const 6)
+ (f32.const 0.1)
+ (f64.const 0.6437)
+ (local.get $wrongRef)
+ ${wrongV128}
+ ;; throwEmptyExn
+ (call_indirect (type $indirectFunctype) (i32.const 1))
+ drop ;; Drop the last v128 value.
+ (i32.const 0))
+ (catch_all
+ (try (result i32 i64 f32 f64 externref ${v128Type})
+ (do ;; Values to throw.
+ (i32.const 2)
+ (i64.const 3)
+ (f32.const 4)
+ (f64.const 13.37)
+ (local.get $correctRef)
+ ${correctV128}
+ (call_indirect (type $indirectFunctype) (i32.const 2)) ;; returnArgs
+ (call_indirect (type $indirectFunctype) (i32.const 0)) ;; throwExn
+ drop drop ;; Drop v128 and externref to do trivial and irrelevant ops.
+ (f64.const 5)
+ (f64.add)
+ (local.get $wrongRef)
+ ${wrongV128}
+ ;; throwEmptyExn
+ (call_indirect (type $indirectFunctype) (i32.const 1))
+ unreachable)
+ (catch $emptyExn
+ ;; Wrong values
+ (i32.const 5)
+ (i64.const 6)
+ (f32.const 0.1)
+ (f64.const 0.6437)
+ (local.get $wrongRef)
+ ${wrongV128})
+ (catch $exn)
+ (catch_all
+ ;; Wrong values
+ (i32.const 5)
+ (i64.const 6)
+ (f32.const 0.1)
+ (f64.const 0.6437)
+ (local.get $wrongRef)
+ ${wrongV128}))
+ ${checkV128Value}))))`;
+
+ let testAllValtypes = wasmEvalText(mod, { m : exports}).exports.testFunc;
+ assertEqArray(testAllValtypes("foo", "bar"),
+ [2, 3n, 4, 13.37, "foo", 1]);
+}