diff --git a/tests/local/legacy-exceptions.wat b/tests/local/legacy-exceptions/legacy-exceptions.wat similarity index 100% rename from tests/local/legacy-exceptions.wat rename to tests/local/legacy-exceptions/legacy-exceptions.wat diff --git a/tests/local/legacy-exceptions/rethrow.wast b/tests/local/legacy-exceptions/rethrow.wast new file mode 100644 index 0000000000..5a7b320c5d --- /dev/null +++ b/tests/local/legacy-exceptions/rethrow.wast @@ -0,0 +1,124 @@ +;; Test rethrow instruction. + +(module + (tag $e0) + (tag $e1) + + (func (export "catch-rethrow-0") + try + throw $e0 + catch $e0 + rethrow 0 + end + ) + + (func (export "catch-rethrow-1") (param i32) (result i32) + try (result i32) + throw $e0 + catch $e0 + local.get 0 + i32.eqz + if + rethrow 1 + end + i32.const 23 + end + ) + + (func (export "catchall-rethrow-0") + try + throw $e0 + catch_all + rethrow 0 + end + ) + + (func (export "catchall-rethrow-1") (param i32) (result i32) + try (result i32) + throw $e0 + catch_all + local.get 0 + i32.eqz + if + rethrow 1 + end + i32.const 23 + end + ) + + (func (export "rethrow-nested") (param i32) (result i32) + try (result i32) + throw $e1 + catch $e1 + try (result i32) + throw $e0 + catch $e0 + local.get 0 + i32.const 0 + i32.eq + if + rethrow 1 + end + local.get 0 + i32.const 1 + i32.eq + if + rethrow 2 + end + i32.const 23 + end + end + ) + + (func (export "rethrow-recatch") (param i32) (result i32) + try (result i32) + throw $e0 + catch $e0 + try (result i32) + local.get 0 + i32.eqz + if + rethrow 2 + end + i32.const 42 + catch $e0 + i32.const 23 + end + end + ) + + (func (export "rethrow-stack-polymorphism") + try + throw $e0 + catch $e0 + i32.const 1 + rethrow 0 + end + ) +) + +(assert_exception (invoke "catch-rethrow-0")) + +(assert_exception (invoke "catch-rethrow-1" (i32.const 0))) +(assert_return (invoke "catch-rethrow-1" (i32.const 1)) (i32.const 23)) + +(assert_exception (invoke "catchall-rethrow-0")) + +(assert_exception (invoke "catchall-rethrow-1" (i32.const 0))) +(assert_return (invoke "catchall-rethrow-1" (i32.const 1)) (i32.const 23)) +(assert_exception (invoke "rethrow-nested" (i32.const 0))) +(assert_exception (invoke "rethrow-nested" (i32.const 1))) +(assert_return (invoke "rethrow-nested" (i32.const 2)) (i32.const 23)) + +(assert_return (invoke "rethrow-recatch" (i32.const 0)) (i32.const 23)) +(assert_return (invoke "rethrow-recatch" (i32.const 1)) (i32.const 42)) + +(assert_exception (invoke "rethrow-stack-polymorphism")) + +(assert_invalid (module (func (rethrow 0))) "invalid rethrow label") +(assert_invalid (module (func (block (rethrow 0)))) "invalid rethrow label") +(assert_invalid (module (func + try + rethrow 0 + delegate 0)) + "invalid rethrow label") diff --git a/tests/local/legacy-exceptions/throw.wast b/tests/local/legacy-exceptions/throw.wast new file mode 100644 index 0000000000..2ab9f2f330 --- /dev/null +++ b/tests/local/legacy-exceptions/throw.wast @@ -0,0 +1,56 @@ +;; Test throw instruction. + +(module + (tag $e0) + (tag $e-i32 (param i32)) + (tag $e-f32 (param f32)) + (tag $e-i64 (param i64)) + (tag $e-f64 (param f64)) + (tag $e-i32-i32 (param i32 i32)) + + (func $throw-if (export "throw-if") (param i32) (result i32) + (local.get 0) + (i32.const 0) (if (i32.ne) (then (throw $e0))) + (i32.const 0) + ) + + (func (export "throw-param-f32") (param f32) (local.get 0) (throw $e-f32)) + + (func (export "throw-param-i64") (param i64) (local.get 0) (throw $e-i64)) + + (func (export "throw-param-f64") (param f64) (local.get 0) (throw $e-f64)) + + (func $throw-1-2 (i32.const 1) (i32.const 2) (throw $e-i32-i32)) + (func (export "test-throw-1-2") + try + call $throw-1-2 + catch $e-i32-i32 + i32.const 2 + i32.ne + if + unreachable + end + i32.const 1 + i32.ne + if + unreachable + end + end + ) +) + +(assert_return (invoke "throw-if" (i32.const 0)) (i32.const 0)) +(assert_exception (invoke "throw-if" (i32.const 10))) +(assert_exception (invoke "throw-if" (i32.const -1))) + +(assert_exception (invoke "throw-param-f32" (f32.const 5.0))) +(assert_exception (invoke "throw-param-i64" (i64.const 5))) +(assert_exception (invoke "throw-param-f64" (f64.const 5.0))) + +(assert_return (invoke "test-throw-1-2")) + +(assert_invalid (module (func (throw 0))) "unknown tag 0") +(assert_invalid (module (tag (param i32)) (func (throw 0))) + "type mismatch: instruction requires [i32] but stack has []") +(assert_invalid (module (tag (param i32)) (func (i64.const 5) (throw 0))) + "type mismatch: instruction requires [i32] but stack has [i64]") diff --git a/tests/local/legacy-exceptions/try_catch.wast b/tests/local/legacy-exceptions/try_catch.wast new file mode 100644 index 0000000000..8819e82487 --- /dev/null +++ b/tests/local/legacy-exceptions/try_catch.wast @@ -0,0 +1,309 @@ +;; Test try-catch blocks. + +(module + (tag $e0 (export "e0")) + (func (export "throw") (throw $e0)) +) + +(register "test") + +(module + (tag $imported-e0 (import "test" "e0")) + (func $imported-throw (import "test" "throw")) + (tag $e0) + (tag $e1) + (tag $e2) + (tag $e-i32 (param i32)) + (tag $e-f32 (param f32)) + (tag $e-i64 (param i64)) + (tag $e-f64 (param f64)) + + (func $throw-if (param i32) (result i32) + (local.get 0) + (i32.const 0) (if (i32.ne) (then (throw $e0))) + (i32.const 0) + ) + + (func (export "empty-catch") + try + catch $e0 + end + ) + + (func (export "simple-throw-catch") (param i32) (result i32) + try (result i32) + local.get 0 + i32.eqz + if + throw 1 + end + i32.const 42 + catch 1 + i32.const 23 + end + ) + + (func (export "unreachable-not-caught") try unreachable catch_all end) + + (func $div (param i32 i32) (result i32) + (local.get 0) (local.get 1) (i32.div_u) + ) + (func (export "trap-in-callee") (param i32 i32) (result i32) + try (result i32) + local.get 0 + local.get 1 + call 5 + catch_all + i32.const 11 + end + ) + + (func (export "catch-complex-1") (param i32) (result i32) + try (result i32) + try (result i32) + local.get 0 + i32.eqz + if + throw 1 + else + local.get 0 + i32.const 1 + i32.eq + if + throw 2 + else + throw 3 + end + end + i32.const 2 + catch 1 + i32.const 3 + end + catch 2 + i32.const 4 + end + ) + + (func (export "catch-complex-2") (param i32) (result i32) + try (result i32) + local.get 0 + i32.eqz + if + throw 1 + else + local.get 0 + i32.const 1 + i32.eq + if + throw 2 + else + throw 3 + end + end + i32.const 2 + catch 1 + i32.const 3 + catch 2 + i32.const 4 + end + ) + + (func (export "throw-catch-param-i32") (param i32) (result i32) + try (result i32) + local.get 0 + throw 4 + i32.const 2 + catch 4 + return + end + ) + + (func (export "throw-catch-param-f32") (param f32) (result f32) + try (result f32) + local.get 0 + throw 5 + f32.const 0 + catch 5 + return + end + ) + + (func (export "throw-catch-param-i64") (param i64) (result i64) + try (result i64) + local.get 0 + throw 6 + i64.const 2 + catch 6 + return + end + ) + + (func (export "throw-catch-param-f64") (param f64) (result f64) + try (result f64) + local.get 0 + throw 7 + f64.const 0 + catch 7 + return + end + ) + + (func $throw-param-i32 (param i32) (local.get 0) (throw $e-i32)) + (func (export "catch-param-i32") (param i32) (result i32) + try (result i32) + i32.const 0 + local.get 0 + call 13 + catch 4 + end + ) + + (func (export "catch-imported") (result i32) + try (result i32) + i32.const 1 + call 0 + catch 0 + i32.const 2 + end + ) + + (func (export "catchless-try") (param i32) (result i32) + try (result i32) + try (result i32) + local.get 0 + call 1 + end + catch 1 + i32.const 1 + end + ) + + (func $throw-void (throw $e0)) + (func (export "return-call-in-try-catch") + try + return_call 17 + catch 1 + end + ) + + (table funcref (elem $throw-void)) + (func (export "return-call-indirect-in-try-catch") + try + i32.const 0 + return_call_indirect (type 0) + catch 1 + end + ) + + (func (export "break-try-catch") + try + br 0 + catch 1 + end + ) + + (func (export "break-try-catch_all") + try + br 0 + catch_all + end + ) +) + +(assert_return (invoke "empty-catch")) + +(assert_return (invoke "simple-throw-catch" (i32.const 0)) (i32.const 23)) +(assert_return (invoke "simple-throw-catch" (i32.const 1)) (i32.const 42)) + +(assert_trap (invoke "unreachable-not-caught") "unreachable") + +(assert_return (invoke "trap-in-callee" (i32.const 7) (i32.const 2)) (i32.const 3)) +(assert_trap (invoke "trap-in-callee" (i32.const 1) (i32.const 0)) "integer divide by zero") + +(assert_return (invoke "catch-complex-1" (i32.const 0)) (i32.const 3)) +(assert_return (invoke "catch-complex-1" (i32.const 1)) (i32.const 4)) +(assert_exception (invoke "catch-complex-1" (i32.const 2))) + +(assert_return (invoke "catch-complex-2" (i32.const 0)) (i32.const 3)) +(assert_return (invoke "catch-complex-2" (i32.const 1)) (i32.const 4)) +(assert_exception (invoke "catch-complex-2" (i32.const 2))) + +(assert_return (invoke "throw-catch-param-i32" (i32.const 0)) (i32.const 0)) +(assert_return (invoke "throw-catch-param-i32" (i32.const 1)) (i32.const 1)) +(assert_return (invoke "throw-catch-param-i32" (i32.const 10)) (i32.const 10)) + +(assert_return (invoke "throw-catch-param-f32" (f32.const 5.0)) (f32.const 5.0)) +(assert_return (invoke "throw-catch-param-f32" (f32.const 10.5)) (f32.const 10.5)) + +(assert_return (invoke "throw-catch-param-i64" (i64.const 5)) (i64.const 5)) +(assert_return (invoke "throw-catch-param-i64" (i64.const 0)) (i64.const 0)) +(assert_return (invoke "throw-catch-param-i64" (i64.const -1)) (i64.const -1)) + +(assert_return (invoke "throw-catch-param-f64" (f64.const 5.0)) (f64.const 5.0)) +(assert_return (invoke "throw-catch-param-f64" (f64.const 10.5)) (f64.const 10.5)) + +(assert_return (invoke "catch-param-i32" (i32.const 5)) (i32.const 5)) + +(assert_return (invoke "catch-imported") (i32.const 2)) + +(assert_return (invoke "catchless-try" (i32.const 0)) (i32.const 0)) +(assert_return (invoke "catchless-try" (i32.const 1)) (i32.const 1)) + +(assert_exception (invoke "return-call-in-try-catch")) +(assert_exception (invoke "return-call-indirect-in-try-catch")) + +(assert_return (invoke "break-try-catch")) +(assert_return (invoke "break-try-catch_all")) + +(module + (func $imported-throw (import "test" "throw")) + (tag $e0) + + (func (export "imported-mismatch") (result i32) + try (result i32) ;; label = @1 + try (result i32) ;; label = @2 + i32.const 1 + call 0 + catch 0 + i32.const 2 + end + catch_all + i32.const 3 + end + ) +) + +(assert_return (invoke "imported-mismatch") (i32.const 3)) + +;; Ignore per https://github.com/bytecodealliance/wasm-tools/issues/1671 +;; +;; (assert_malformed +;; (module quote "(module (func (catch_all)))") +;; "unexpected token" +;; ) + +;; (assert_malformed +;; (module quote "(module (tag $e) (func (catch $e)))") +;; "unexpected token" +;; ) + +;; (assert_malformed +;; (module quote +;; "(module (func try catch_all catch_all end))" +;; ) +;; "unexpected token" +;; ) + +(assert_invalid (module (func (result i32) try (result i32) end)) + "type mismatch: instruction requires [i32] but stack has []") +(assert_invalid (module (func (result i32) try (result i32) i64.const 42 end)) + "type mismatch: instruction requires [i32] but stack has [i64]") +(assert_invalid (module (tag) (func try catch 0 i32.const 42 end)) + "type mismatch: block requires [] but stack has [i32]") +(assert_invalid (module + (tag (param i64)) + (func (result i32) + try (result i32) i32.const 42 catch 0 end)) + "type mismatch: instruction requires [i32] but stack has [i64]") +(assert_invalid (module (func try catch_all i32.const 32 end)) + "type mismatch: block requires [] but stack has [i32]") diff --git a/tests/local/legacy-exceptions/try_delegate.wast b/tests/local/legacy-exceptions/try_delegate.wast new file mode 100644 index 0000000000..8f115268d9 --- /dev/null +++ b/tests/local/legacy-exceptions/try_delegate.wast @@ -0,0 +1,275 @@ +;; Test try-delegate blocks. + +(module + (tag $e0) + (tag $e1) + + (func (export "delegate-no-throw") (result i32) + try (result i32) ;; label = @1 + try (result i32) ;; label = @2 + i32.const 1 + delegate 0 + catch 0 + i32.const 2 + end + ) + + (func $throw-if (param i32) + (local.get 0) + (if (then (throw $e0)) (else)) + ) + + (func (export "delegate-throw") (param i32) (result i32) + try (result i32) ;; label = @1 + try (result i32) ;; label = @2 + local.get 0 + call 1 + i32.const 1 + delegate 0 + catch 0 + i32.const 2 + end + ) + + (func (export "delegate-skip") (result i32) + try (result i32) ;; label = @1 + try (result i32) ;; label = @2 + try (result i32) ;; label = @3 + throw 0 + i32.const 1 + delegate 1 + catch 0 + i32.const 2 + end + catch 0 + i32.const 3 + end + ) + + (func (export "delegate-to-block") (result i32) + try (result i32) ;; label = @1 + block ;; label = @2 + try ;; label = @3 + throw 0 + delegate 0 + end + i32.const 0 + catch_all + i32.const 1 + end + ) + + (func (export "delegate-to-catch") (result i32) + try (result i32) ;; label = @1 + try ;; label = @2 + throw 0 + catch 0 + try ;; label = @3 + rethrow 1 (;@2;) + delegate 0 + end + i32.const 0 + catch_all + i32.const 1 + end + ) + + (func (export "delegate-to-caller-trivial") + try ;; label = @1 + throw 0 + delegate 0) + + (func (export "delegate-to-caller-skipping") + try ;; label = @1 + try ;; label = @2 + throw 0 + delegate 1 + catch_all + end + ) + + (func $select-tag (param i32) + block ;; label = @1 + block ;; label = @2 + block ;; label = @3 + local.get 0 + br_table 0 (;@3;) 1 (;@2;) 2 (;@1;) + end + return + end + throw 0 + end + throw 1 + ) + + (func (export "delegate-merge") (param i32 i32) (result i32) + try (result i32) ;; label = @1 + local.get 0 + call 8 + try (result i32) ;; label = @2 + local.get 1 + call 8 + i32.const 1 + delegate 0 + catch 0 + i32.const 2 + end + ) + + (func (export "delegate-throw-no-catch") (result i32) + try (result i32) ;; label = @1 + try (result i32) ;; label = @2 + throw 0 + i32.const 1 + delegate 0 + catch 1 + i32.const 2 + end + ) + + (func (export "delegate-correct-targets") (result i32) + try (result i32) ;; label = @1 + try ;; label = @2 + try ;; label = @3 + try ;; label = @4 + try ;; label = @5 + try ;; label = @6 + throw 0 + delegate 1 + catch_all + unreachable + end + delegate 1 + catch_all + unreachable + end + catch_all + try ;; label = @3 + throw 0 + delegate 0 + end + unreachable + catch_all + i32.const 1 + end) + + (func $throw-void (throw $e0)) + (func (export "return-call-in-try-delegate") + try ;; label = @1 + try ;; label = @2 + return_call 12 + delegate 0 + catch 0 + end + ) + + (table funcref (elem $throw-void)) + (func (export "return-call-indirect-in-try-delegate") + try ;; label = @1 + try ;; label = @2 + i32.const 0 + return_call_indirect (type 0) + delegate 0 + catch 0 + end + ) + + (func (export "break-try-delegate") + try ;; label = @1 + br 0 (;@1;) + delegate 0) + + (func (export "break-and-call-throw") (result i32) + try (result i32) ;; label = @1 + try (result i32) ;; label = @2 + block ;; label = @3 + try ;; label = @4 + br 1 (;@3;) + delegate 2 + end + call 12 + i32.const 0 + catch 0 + i32.const 1 + end + catch 0 + i32.const 2 + end + ) + + (func (export "break-and-throw") (result i32) + try (result i32) ;; label = @1 + try (result i32) ;; label = @2 + block ;; label = @3 + try ;; label = @4 + br 1 (;@3;) + delegate 2 + end + throw 0 + i32.const 0 + catch 0 + i32.const 1 + end + catch 0 + i32.const 2 + end + ) +) + +(assert_return (invoke "delegate-no-throw") (i32.const 1)) + +(assert_return (invoke "delegate-throw" (i32.const 0)) (i32.const 1)) +(assert_return (invoke "delegate-throw" (i32.const 1)) (i32.const 2)) + +(assert_exception (invoke "delegate-throw-no-catch")) + +(assert_return (invoke "delegate-merge" (i32.const 1) (i32.const 0)) (i32.const 2)) +(assert_exception (invoke "delegate-merge" (i32.const 2) (i32.const 0))) +(assert_return (invoke "delegate-merge" (i32.const 0) (i32.const 1)) (i32.const 2)) +(assert_exception (invoke "delegate-merge" (i32.const 0) (i32.const 2))) +(assert_return (invoke "delegate-merge" (i32.const 0) (i32.const 0)) (i32.const 1)) + +(assert_return (invoke "delegate-skip") (i32.const 3)) + +(assert_return (invoke "delegate-to-block") (i32.const 1)) +(assert_return (invoke "delegate-to-catch") (i32.const 1)) + +(assert_exception (invoke "delegate-to-caller-trivial")) +(assert_exception (invoke "delegate-to-caller-skipping")) + +(assert_return (invoke "delegate-correct-targets") (i32.const 1)) + +(assert_exception (invoke "return-call-in-try-delegate")) +(assert_exception (invoke "return-call-indirect-in-try-delegate")) + +(assert_return (invoke "break-try-delegate")) + +(assert_return (invoke "break-and-call-throw") (i32.const 1)) +(assert_return (invoke "break-and-throw") (i32.const 1)) + +;; Ignore per https://github.com/bytecodealliance/wasm-tools/issues/1671 +;; +;; (assert_malformed +;; (module quote "(module (func (delegate 0)))") +;; "unexpected token" +;; ) + +;; (assert_malformed +;; (module quote "(module (tag $e) (func try catch $e delegate 0))") +;; "unexpected token" +;; ) + +;; (assert_malformed +;; (module quote "(module (func try catch_all delegate 0))") +;; "unexpected token" +;; ) + +;; (assert_malformed +;; (module quote "(module (func try delegate delegate 0))") +;; "unexpected token" +;; ) + +(assert_invalid + (module (func try delegate 1)) + "unknown label" +) diff --git a/tests/roundtrip.rs b/tests/roundtrip.rs index 4a8e4f2b6a..b788a81f3f 100644 --- a/tests/roundtrip.rs +++ b/tests/roundtrip.rs @@ -605,7 +605,7 @@ impl TestState { } "simd" => features.insert(WasmFeatures::SIMD), "exception-handling" => features.insert(WasmFeatures::EXCEPTIONS), - "legacy-exceptions.wat" => features.insert(WasmFeatures::LEGACY_EXCEPTIONS), + "legacy-exceptions" => features.insert(WasmFeatures::LEGACY_EXCEPTIONS), "tail-call" => features.insert(WasmFeatures::TAIL_CALL), "memory64" => features.insert(WasmFeatures::MEMORY64), "component-model" => features.insert(WasmFeatures::COMPONENT_MODEL), diff --git a/tests/snapshots/local/legacy-exceptions.wat.print b/tests/snapshots/local/legacy-exceptions/legacy-exceptions.wat.print similarity index 100% rename from tests/snapshots/local/legacy-exceptions.wat.print rename to tests/snapshots/local/legacy-exceptions/legacy-exceptions.wat.print diff --git a/tests/snapshots/local/legacy-exceptions/rethrow.wast.json b/tests/snapshots/local/legacy-exceptions/rethrow.wast.json new file mode 100644 index 0000000000..40a67982c1 --- /dev/null +++ b/tests/snapshots/local/legacy-exceptions/rethrow.wast.json @@ -0,0 +1,214 @@ +{ + "source_filename": "tests/local/legacy-exceptions/rethrow.wast", + "commands": [ + { + "type": "module", + "line": 3, + "filename": "rethrow.0.wasm" + }, + { + "type": "assert_exception", + "line": 100, + "action": { + "type": "invoke", + "field": "catch-rethrow-0", + "args": [] + } + }, + { + "type": "assert_exception", + "line": 102, + "action": { + "type": "invoke", + "field": "catch-rethrow-1", + "args": [ + { + "type": "i32", + "value": "0" + } + ] + } + }, + { + "type": "assert_return", + "line": 103, + "action": { + "type": "invoke", + "field": "catch-rethrow-1", + "args": [ + { + "type": "i32", + "value": "1" + } + ] + }, + "expected": [ + { + "type": "i32", + "value": "23" + } + ] + }, + { + "type": "assert_exception", + "line": 105, + "action": { + "type": "invoke", + "field": "catchall-rethrow-0", + "args": [] + } + }, + { + "type": "assert_exception", + "line": 107, + "action": { + "type": "invoke", + "field": "catchall-rethrow-1", + "args": [ + { + "type": "i32", + "value": "0" + } + ] + } + }, + { + "type": "assert_return", + "line": 108, + "action": { + "type": "invoke", + "field": "catchall-rethrow-1", + "args": [ + { + "type": "i32", + "value": "1" + } + ] + }, + "expected": [ + { + "type": "i32", + "value": "23" + } + ] + }, + { + "type": "assert_exception", + "line": 109, + "action": { + "type": "invoke", + "field": "rethrow-nested", + "args": [ + { + "type": "i32", + "value": "0" + } + ] + } + }, + { + "type": "assert_exception", + "line": 110, + "action": { + "type": "invoke", + "field": "rethrow-nested", + "args": [ + { + "type": "i32", + "value": "1" + } + ] + } + }, + { + "type": "assert_return", + "line": 111, + "action": { + "type": "invoke", + "field": "rethrow-nested", + "args": [ + { + "type": "i32", + "value": "2" + } + ] + }, + "expected": [ + { + "type": "i32", + "value": "23" + } + ] + }, + { + "type": "assert_return", + "line": 113, + "action": { + "type": "invoke", + "field": "rethrow-recatch", + "args": [ + { + "type": "i32", + "value": "0" + } + ] + }, + "expected": [ + { + "type": "i32", + "value": "23" + } + ] + }, + { + "type": "assert_return", + "line": 114, + "action": { + "type": "invoke", + "field": "rethrow-recatch", + "args": [ + { + "type": "i32", + "value": "1" + } + ] + }, + "expected": [ + { + "type": "i32", + "value": "42" + } + ] + }, + { + "type": "assert_exception", + "line": 116, + "action": { + "type": "invoke", + "field": "rethrow-stack-polymorphism", + "args": [] + } + }, + { + "type": "assert_invalid", + "line": 118, + "filename": "rethrow.1.wasm", + "text": "invalid rethrow label", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 119, + "filename": "rethrow.2.wasm", + "text": "invalid rethrow label", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 120, + "filename": "rethrow.3.wasm", + "text": "invalid rethrow label", + "module_type": "binary" + } + ] +} \ No newline at end of file diff --git a/tests/snapshots/local/legacy-exceptions/rethrow.wast/0.print b/tests/snapshots/local/legacy-exceptions/rethrow.wast/0.print new file mode 100644 index 0000000000..998341854e --- /dev/null +++ b/tests/snapshots/local/legacy-exceptions/rethrow.wast/0.print @@ -0,0 +1,98 @@ +(module + (type (;0;) (func)) + (type (;1;) (func (param i32) (result i32))) + (func (;0;) (type 0) + try ;; label = @1 + throw $e0 + catch $e0 + rethrow 0 (;@1;) + end + ) + (func (;1;) (type 1) (param i32) (result i32) + try (result i32) ;; label = @1 + throw $e0 + catch $e0 + local.get 0 + i32.eqz + if ;; label = @2 + rethrow 1 (;@1;) + end + i32.const 23 + end + ) + (func (;2;) (type 0) + try ;; label = @1 + throw $e0 + catch_all + rethrow 0 (;@1;) + end + ) + (func (;3;) (type 1) (param i32) (result i32) + try (result i32) ;; label = @1 + throw $e0 + catch_all + local.get 0 + i32.eqz + if ;; label = @2 + rethrow 1 (;@1;) + end + i32.const 23 + end + ) + (func (;4;) (type 1) (param i32) (result i32) + try (result i32) ;; label = @1 + throw $e1 + catch $e1 + try (result i32) ;; label = @2 + throw $e0 + catch $e0 + local.get 0 + i32.const 0 + i32.eq + if ;; label = @3 + rethrow 1 (;@2;) + end + local.get 0 + i32.const 1 + i32.eq + if ;; label = @3 + rethrow 2 (;@1;) + end + i32.const 23 + end + end + ) + (func (;5;) (type 1) (param i32) (result i32) + try (result i32) ;; label = @1 + throw $e0 + catch $e0 + try (result i32) ;; label = @2 + local.get 0 + i32.eqz + if ;; label = @3 + rethrow 2 (;@1;) + end + i32.const 42 + catch $e0 + i32.const 23 + end + end + ) + (func (;6;) (type 0) + try ;; label = @1 + throw $e0 + catch $e0 + i32.const 1 + rethrow 0 (;@1;) + end + ) + (tag $e0 (;0;) (type 0)) + (tag $e1 (;1;) (type 0)) + (export "catch-rethrow-0" (func 0)) + (export "catch-rethrow-1" (func 1)) + (export "catchall-rethrow-0" (func 2)) + (export "catchall-rethrow-1" (func 3)) + (export "rethrow-nested" (func 4)) + (export "rethrow-recatch" (func 5)) + (export "rethrow-stack-polymorphism" (func 6)) +) diff --git a/tests/snapshots/local/legacy-exceptions/throw.wast.json b/tests/snapshots/local/legacy-exceptions/throw.wast.json new file mode 100644 index 0000000000..bbffce788a --- /dev/null +++ b/tests/snapshots/local/legacy-exceptions/throw.wast.json @@ -0,0 +1,131 @@ +{ + "source_filename": "tests/local/legacy-exceptions/throw.wast", + "commands": [ + { + "type": "module", + "line": 3, + "filename": "throw.0.wasm" + }, + { + "type": "assert_return", + "line": 42, + "action": { + "type": "invoke", + "field": "throw-if", + "args": [ + { + "type": "i32", + "value": "0" + } + ] + }, + "expected": [ + { + "type": "i32", + "value": "0" + } + ] + }, + { + "type": "assert_exception", + "line": 43, + "action": { + "type": "invoke", + "field": "throw-if", + "args": [ + { + "type": "i32", + "value": "10" + } + ] + } + }, + { + "type": "assert_exception", + "line": 44, + "action": { + "type": "invoke", + "field": "throw-if", + "args": [ + { + "type": "i32", + "value": "-1" + } + ] + } + }, + { + "type": "assert_exception", + "line": 46, + "action": { + "type": "invoke", + "field": "throw-param-f32", + "args": [ + { + "type": "f32", + "value": "1084227584" + } + ] + } + }, + { + "type": "assert_exception", + "line": 47, + "action": { + "type": "invoke", + "field": "throw-param-i64", + "args": [ + { + "type": "i64", + "value": "5" + } + ] + } + }, + { + "type": "assert_exception", + "line": 48, + "action": { + "type": "invoke", + "field": "throw-param-f64", + "args": [ + { + "type": "f64", + "value": "4617315517961601024" + } + ] + } + }, + { + "type": "assert_return", + "line": 50, + "action": { + "type": "invoke", + "field": "test-throw-1-2", + "args": [] + }, + "expected": [] + }, + { + "type": "assert_invalid", + "line": 52, + "filename": "throw.1.wasm", + "text": "unknown tag 0", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 53, + "filename": "throw.2.wasm", + "text": "type mismatch: instruction requires [i32] but stack has []", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 55, + "filename": "throw.3.wasm", + "text": "type mismatch: instruction requires [i32] but stack has [i64]", + "module_type": "binary" + } + ] +} \ No newline at end of file diff --git a/tests/snapshots/local/legacy-exceptions/throw.wast/0.print b/tests/snapshots/local/legacy-exceptions/throw.wast/0.print new file mode 100644 index 0000000000..afaf56a81e --- /dev/null +++ b/tests/snapshots/local/legacy-exceptions/throw.wast/0.print @@ -0,0 +1,62 @@ +(module + (type (;0;) (func)) + (type (;1;) (func (param i32))) + (type (;2;) (func (param f32))) + (type (;3;) (func (param i64))) + (type (;4;) (func (param f64))) + (type (;5;) (func (param i32 i32))) + (type (;6;) (func (param i32) (result i32))) + (func $throw-if (;0;) (type 6) (param i32) (result i32) + local.get 0 + i32.const 0 + i32.ne + if ;; label = @1 + throw $e0 + end + i32.const 0 + ) + (func (;1;) (type 2) (param f32) + local.get 0 + throw $e-f32 + ) + (func (;2;) (type 3) (param i64) + local.get 0 + throw $e-i64 + ) + (func (;3;) (type 4) (param f64) + local.get 0 + throw $e-f64 + ) + (func $throw-1-2 (;4;) (type 0) + i32.const 1 + i32.const 2 + throw $e-i32-i32 + ) + (func (;5;) (type 0) + try ;; label = @1 + call $throw-1-2 + catch $e-i32-i32 + i32.const 2 + i32.ne + if ;; label = @2 + unreachable + end + i32.const 1 + i32.ne + if ;; label = @2 + unreachable + end + end + ) + (tag $e0 (;0;) (type 0)) + (tag $e-i32 (;1;) (type 1) (param i32)) + (tag $e-f32 (;2;) (type 2) (param f32)) + (tag $e-i64 (;3;) (type 3) (param i64)) + (tag $e-f64 (;4;) (type 4) (param f64)) + (tag $e-i32-i32 (;5;) (type 5) (param i32 i32)) + (export "throw-if" (func $throw-if)) + (export "throw-param-f32" (func 1)) + (export "throw-param-i64" (func 2)) + (export "throw-param-f64" (func 3)) + (export "test-throw-1-2" (func 5)) +) diff --git a/tests/snapshots/local/legacy-exceptions/try_catch.wast.json b/tests/snapshots/local/legacy-exceptions/try_catch.wast.json new file mode 100644 index 0000000000..8b256d189b --- /dev/null +++ b/tests/snapshots/local/legacy-exceptions/try_catch.wast.json @@ -0,0 +1,599 @@ +{ + "source_filename": "tests/local/legacy-exceptions/try_catch.wast", + "commands": [ + { + "type": "module", + "line": 3, + "filename": "try_catch.0.wasm" + }, + { + "type": "register", + "line": 8, + "as": "test" + }, + { + "type": "module", + "line": 10, + "filename": "try_catch.1.wasm" + }, + { + "type": "assert_return", + "line": 213, + "action": { + "type": "invoke", + "field": "empty-catch", + "args": [] + }, + "expected": [] + }, + { + "type": "assert_return", + "line": 215, + "action": { + "type": "invoke", + "field": "simple-throw-catch", + "args": [ + { + "type": "i32", + "value": "0" + } + ] + }, + "expected": [ + { + "type": "i32", + "value": "23" + } + ] + }, + { + "type": "assert_return", + "line": 216, + "action": { + "type": "invoke", + "field": "simple-throw-catch", + "args": [ + { + "type": "i32", + "value": "1" + } + ] + }, + "expected": [ + { + "type": "i32", + "value": "42" + } + ] + }, + { + "type": "assert_trap", + "line": 218, + "action": { + "type": "invoke", + "field": "unreachable-not-caught", + "args": [] + }, + "text": "unreachable" + }, + { + "type": "assert_return", + "line": 220, + "action": { + "type": "invoke", + "field": "trap-in-callee", + "args": [ + { + "type": "i32", + "value": "7" + }, + { + "type": "i32", + "value": "2" + } + ] + }, + "expected": [ + { + "type": "i32", + "value": "3" + } + ] + }, + { + "type": "assert_trap", + "line": 221, + "action": { + "type": "invoke", + "field": "trap-in-callee", + "args": [ + { + "type": "i32", + "value": "1" + }, + { + "type": "i32", + "value": "0" + } + ] + }, + "text": "integer divide by zero" + }, + { + "type": "assert_return", + "line": 223, + "action": { + "type": "invoke", + "field": "catch-complex-1", + "args": [ + { + "type": "i32", + "value": "0" + } + ] + }, + "expected": [ + { + "type": "i32", + "value": "3" + } + ] + }, + { + "type": "assert_return", + "line": 224, + "action": { + "type": "invoke", + "field": "catch-complex-1", + "args": [ + { + "type": "i32", + "value": "1" + } + ] + }, + "expected": [ + { + "type": "i32", + "value": "4" + } + ] + }, + { + "type": "assert_exception", + "line": 225, + "action": { + "type": "invoke", + "field": "catch-complex-1", + "args": [ + { + "type": "i32", + "value": "2" + } + ] + } + }, + { + "type": "assert_return", + "line": 227, + "action": { + "type": "invoke", + "field": "catch-complex-2", + "args": [ + { + "type": "i32", + "value": "0" + } + ] + }, + "expected": [ + { + "type": "i32", + "value": "3" + } + ] + }, + { + "type": "assert_return", + "line": 228, + "action": { + "type": "invoke", + "field": "catch-complex-2", + "args": [ + { + "type": "i32", + "value": "1" + } + ] + }, + "expected": [ + { + "type": "i32", + "value": "4" + } + ] + }, + { + "type": "assert_exception", + "line": 229, + "action": { + "type": "invoke", + "field": "catch-complex-2", + "args": [ + { + "type": "i32", + "value": "2" + } + ] + } + }, + { + "type": "assert_return", + "line": 231, + "action": { + "type": "invoke", + "field": "throw-catch-param-i32", + "args": [ + { + "type": "i32", + "value": "0" + } + ] + }, + "expected": [ + { + "type": "i32", + "value": "0" + } + ] + }, + { + "type": "assert_return", + "line": 232, + "action": { + "type": "invoke", + "field": "throw-catch-param-i32", + "args": [ + { + "type": "i32", + "value": "1" + } + ] + }, + "expected": [ + { + "type": "i32", + "value": "1" + } + ] + }, + { + "type": "assert_return", + "line": 233, + "action": { + "type": "invoke", + "field": "throw-catch-param-i32", + "args": [ + { + "type": "i32", + "value": "10" + } + ] + }, + "expected": [ + { + "type": "i32", + "value": "10" + } + ] + }, + { + "type": "assert_return", + "line": 235, + "action": { + "type": "invoke", + "field": "throw-catch-param-f32", + "args": [ + { + "type": "f32", + "value": "1084227584" + } + ] + }, + "expected": [ + { + "type": "f32", + "value": "1084227584" + } + ] + }, + { + "type": "assert_return", + "line": 236, + "action": { + "type": "invoke", + "field": "throw-catch-param-f32", + "args": [ + { + "type": "f32", + "value": "1093140480" + } + ] + }, + "expected": [ + { + "type": "f32", + "value": "1093140480" + } + ] + }, + { + "type": "assert_return", + "line": 238, + "action": { + "type": "invoke", + "field": "throw-catch-param-i64", + "args": [ + { + "type": "i64", + "value": "5" + } + ] + }, + "expected": [ + { + "type": "i64", + "value": "5" + } + ] + }, + { + "type": "assert_return", + "line": 239, + "action": { + "type": "invoke", + "field": "throw-catch-param-i64", + "args": [ + { + "type": "i64", + "value": "0" + } + ] + }, + "expected": [ + { + "type": "i64", + "value": "0" + } + ] + }, + { + "type": "assert_return", + "line": 240, + "action": { + "type": "invoke", + "field": "throw-catch-param-i64", + "args": [ + { + "type": "i64", + "value": "-1" + } + ] + }, + "expected": [ + { + "type": "i64", + "value": "-1" + } + ] + }, + { + "type": "assert_return", + "line": 242, + "action": { + "type": "invoke", + "field": "throw-catch-param-f64", + "args": [ + { + "type": "f64", + "value": "4617315517961601024" + } + ] + }, + "expected": [ + { + "type": "f64", + "value": "4617315517961601024" + } + ] + }, + { + "type": "assert_return", + "line": 243, + "action": { + "type": "invoke", + "field": "throw-catch-param-f64", + "args": [ + { + "type": "f64", + "value": "4622100592565682176" + } + ] + }, + "expected": [ + { + "type": "f64", + "value": "4622100592565682176" + } + ] + }, + { + "type": "assert_return", + "line": 245, + "action": { + "type": "invoke", + "field": "catch-param-i32", + "args": [ + { + "type": "i32", + "value": "5" + } + ] + }, + "expected": [ + { + "type": "i32", + "value": "5" + } + ] + }, + { + "type": "assert_return", + "line": 247, + "action": { + "type": "invoke", + "field": "catch-imported", + "args": [] + }, + "expected": [ + { + "type": "i32", + "value": "2" + } + ] + }, + { + "type": "assert_return", + "line": 249, + "action": { + "type": "invoke", + "field": "catchless-try", + "args": [ + { + "type": "i32", + "value": "0" + } + ] + }, + "expected": [ + { + "type": "i32", + "value": "0" + } + ] + }, + { + "type": "assert_return", + "line": 250, + "action": { + "type": "invoke", + "field": "catchless-try", + "args": [ + { + "type": "i32", + "value": "1" + } + ] + }, + "expected": [ + { + "type": "i32", + "value": "1" + } + ] + }, + { + "type": "assert_exception", + "line": 252, + "action": { + "type": "invoke", + "field": "return-call-in-try-catch", + "args": [] + } + }, + { + "type": "assert_exception", + "line": 253, + "action": { + "type": "invoke", + "field": "return-call-indirect-in-try-catch", + "args": [] + } + }, + { + "type": "assert_return", + "line": 255, + "action": { + "type": "invoke", + "field": "break-try-catch", + "args": [] + }, + "expected": [] + }, + { + "type": "assert_return", + "line": 256, + "action": { + "type": "invoke", + "field": "break-try-catch_all", + "args": [] + }, + "expected": [] + }, + { + "type": "module", + "line": 258, + "filename": "try_catch.2.wasm" + }, + { + "type": "assert_return", + "line": 276, + "action": { + "type": "invoke", + "field": "imported-mismatch", + "args": [] + }, + "expected": [ + { + "type": "i32", + "value": "3" + } + ] + }, + { + "type": "assert_invalid", + "line": 297, + "filename": "try_catch.3.wasm", + "text": "type mismatch: instruction requires [i32] but stack has []", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 299, + "filename": "try_catch.4.wasm", + "text": "type mismatch: instruction requires [i32] but stack has [i64]", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 301, + "filename": "try_catch.5.wasm", + "text": "type mismatch: block requires [] but stack has [i32]", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 303, + "filename": "try_catch.6.wasm", + "text": "type mismatch: instruction requires [i32] but stack has [i64]", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 308, + "filename": "try_catch.7.wasm", + "text": "type mismatch: block requires [] but stack has [i32]", + "module_type": "binary" + } + ] +} \ No newline at end of file diff --git a/tests/snapshots/local/legacy-exceptions/try_catch.wast/0.print b/tests/snapshots/local/legacy-exceptions/try_catch.wast/0.print new file mode 100644 index 0000000000..121840d85f --- /dev/null +++ b/tests/snapshots/local/legacy-exceptions/try_catch.wast/0.print @@ -0,0 +1,9 @@ +(module + (type (;0;) (func)) + (func (;0;) (type 0) + throw $e0 + ) + (tag $e0 (;0;) (type 0)) + (export "e0" (tag 0)) + (export "throw" (func 0)) +) diff --git a/tests/snapshots/local/legacy-exceptions/try_catch.wast/2.print b/tests/snapshots/local/legacy-exceptions/try_catch.wast/2.print new file mode 100644 index 0000000000..dc973cca06 --- /dev/null +++ b/tests/snapshots/local/legacy-exceptions/try_catch.wast/2.print @@ -0,0 +1,229 @@ +(module + (type (;0;) (func)) + (type (;1;) (func (param i32))) + (type (;2;) (func (param f32))) + (type (;3;) (func (param i64))) + (type (;4;) (func (param f64))) + (type (;5;) (func (param i32) (result i32))) + (type (;6;) (func (param i32 i32) (result i32))) + (type (;7;) (func (param f32) (result f32))) + (type (;8;) (func (param i64) (result i64))) + (type (;9;) (func (param f64) (result f64))) + (type (;10;) (func (result i32))) + (import "test" "e0" (tag $imported-e0 (;0;) (type 0))) + (import "test" "throw" (func $imported-throw (;0;) (type 0))) + (func $throw-if (;1;) (type 5) (param i32) (result i32) + local.get 0 + i32.const 0 + i32.ne + if ;; label = @1 + throw $e0 + end + i32.const 0 + ) + (func (;2;) (type 0) + try ;; label = @1 + catch $e0 + end + ) + (func (;3;) (type 5) (param i32) (result i32) + try (result i32) ;; label = @1 + local.get 0 + i32.eqz + if ;; label = @2 + throw $e0 + end + i32.const 42 + catch $e0 + i32.const 23 + end + ) + (func (;4;) (type 0) + try ;; label = @1 + unreachable + catch_all + end + ) + (func $div (;5;) (type 6) (param i32 i32) (result i32) + local.get 0 + local.get 1 + i32.div_u + ) + (func (;6;) (type 6) (param i32 i32) (result i32) + try (result i32) ;; label = @1 + local.get 0 + local.get 1 + call $div + catch_all + i32.const 11 + end + ) + (func (;7;) (type 5) (param i32) (result i32) + try (result i32) ;; label = @1 + try (result i32) ;; label = @2 + local.get 0 + i32.eqz + if ;; label = @3 + throw $e0 + else + local.get 0 + i32.const 1 + i32.eq + if ;; label = @4 + throw $e1 + else + throw $e2 + end + end + i32.const 2 + catch $e0 + i32.const 3 + end + catch $e1 + i32.const 4 + end + ) + (func (;8;) (type 5) (param i32) (result i32) + try (result i32) ;; label = @1 + local.get 0 + i32.eqz + if ;; label = @2 + throw $e0 + else + local.get 0 + i32.const 1 + i32.eq + if ;; label = @3 + throw $e1 + else + throw $e2 + end + end + i32.const 2 + catch $e0 + i32.const 3 + catch $e1 + i32.const 4 + end + ) + (func (;9;) (type 5) (param i32) (result i32) + try (result i32) ;; label = @1 + local.get 0 + throw $e-i32 + i32.const 2 + catch $e-i32 + return + end + ) + (func (;10;) (type 7) (param f32) (result f32) + try (result f32) ;; label = @1 + local.get 0 + throw $e-f32 + f32.const 0x0p+0 (;=0;) + catch $e-f32 + return + end + ) + (func (;11;) (type 8) (param i64) (result i64) + try (result i64) ;; label = @1 + local.get 0 + throw $e-i64 + i64.const 2 + catch $e-i64 + return + end + ) + (func (;12;) (type 9) (param f64) (result f64) + try (result f64) ;; label = @1 + local.get 0 + throw $e-f64 + f64.const 0x0p+0 (;=0;) + catch $e-f64 + return + end + ) + (func $throw-param-i32 (;13;) (type 1) (param i32) + local.get 0 + throw $e-i32 + ) + (func (;14;) (type 5) (param i32) (result i32) + try (result i32) ;; label = @1 + i32.const 0 + local.get 0 + call $throw-param-i32 + catch $e-i32 + end + ) + (func (;15;) (type 10) (result i32) + try (result i32) ;; label = @1 + i32.const 1 + call $imported-throw + catch $imported-e0 + i32.const 2 + end + ) + (func (;16;) (type 5) (param i32) (result i32) + try (result i32) ;; label = @1 + try (result i32) ;; label = @2 + local.get 0 + call $throw-if + end + catch $e0 + i32.const 1 + end + ) + (func $throw-void (;17;) (type 0) + throw $e0 + ) + (func (;18;) (type 0) + try ;; label = @1 + return_call $throw-void + catch $e0 + end + ) + (func (;19;) (type 0) + try ;; label = @1 + i32.const 0 + return_call_indirect (type 0) + catch $e0 + end + ) + (func (;20;) (type 0) + try ;; label = @1 + br 0 (;@1;) + catch $e0 + end + ) + (func (;21;) (type 0) + try ;; label = @1 + br 0 (;@1;) + catch_all + end + ) + (table (;0;) 1 1 funcref) + (tag $e0 (;1;) (type 0)) + (tag $e1 (;2;) (type 0)) + (tag $e2 (;3;) (type 0)) + (tag $e-i32 (;4;) (type 1) (param i32)) + (tag $e-f32 (;5;) (type 2) (param f32)) + (tag $e-i64 (;6;) (type 3) (param i64)) + (tag $e-f64 (;7;) (type 4) (param f64)) + (export "empty-catch" (func 2)) + (export "simple-throw-catch" (func 3)) + (export "unreachable-not-caught" (func 4)) + (export "trap-in-callee" (func 6)) + (export "catch-complex-1" (func 7)) + (export "catch-complex-2" (func 8)) + (export "throw-catch-param-i32" (func 9)) + (export "throw-catch-param-f32" (func 10)) + (export "throw-catch-param-i64" (func 11)) + (export "throw-catch-param-f64" (func 12)) + (export "catch-param-i32" (func 14)) + (export "catch-imported" (func 15)) + (export "catchless-try" (func 16)) + (export "return-call-in-try-catch" (func 18)) + (export "return-call-indirect-in-try-catch" (func 19)) + (export "break-try-catch" (func 20)) + (export "break-try-catch_all" (func 21)) + (elem (;0;) (i32.const 0) func $throw-void) +) diff --git a/tests/snapshots/local/legacy-exceptions/try_catch.wast/33.print b/tests/snapshots/local/legacy-exceptions/try_catch.wast/33.print new file mode 100644 index 0000000000..8210510b56 --- /dev/null +++ b/tests/snapshots/local/legacy-exceptions/try_catch.wast/33.print @@ -0,0 +1,19 @@ +(module + (type (;0;) (func)) + (type (;1;) (func (result i32))) + (import "test" "throw" (func $imported-throw (;0;) (type 0))) + (func (;1;) (type 1) (result i32) + try (result i32) ;; label = @1 + try (result i32) ;; label = @2 + i32.const 1 + call $imported-throw + catch $e0 + i32.const 2 + end + catch_all + i32.const 3 + end + ) + (tag $e0 (;0;) (type 0)) + (export "imported-mismatch" (func 1)) +) diff --git a/tests/snapshots/local/legacy-exceptions/try_delegate.wast.json b/tests/snapshots/local/legacy-exceptions/try_delegate.wast.json new file mode 100644 index 0000000000..2ba6f88788 --- /dev/null +++ b/tests/snapshots/local/legacy-exceptions/try_delegate.wast.json @@ -0,0 +1,325 @@ +{ + "source_filename": "tests/local/legacy-exceptions/try_delegate.wast", + "commands": [ + { + "type": "module", + "line": 3, + "filename": "try_delegate.0.wasm" + }, + { + "type": "assert_return", + "line": 219, + "action": { + "type": "invoke", + "field": "delegate-no-throw", + "args": [] + }, + "expected": [ + { + "type": "i32", + "value": "1" + } + ] + }, + { + "type": "assert_return", + "line": 221, + "action": { + "type": "invoke", + "field": "delegate-throw", + "args": [ + { + "type": "i32", + "value": "0" + } + ] + }, + "expected": [ + { + "type": "i32", + "value": "1" + } + ] + }, + { + "type": "assert_return", + "line": 222, + "action": { + "type": "invoke", + "field": "delegate-throw", + "args": [ + { + "type": "i32", + "value": "1" + } + ] + }, + "expected": [ + { + "type": "i32", + "value": "2" + } + ] + }, + { + "type": "assert_exception", + "line": 224, + "action": { + "type": "invoke", + "field": "delegate-throw-no-catch", + "args": [] + } + }, + { + "type": "assert_return", + "line": 226, + "action": { + "type": "invoke", + "field": "delegate-merge", + "args": [ + { + "type": "i32", + "value": "1" + }, + { + "type": "i32", + "value": "0" + } + ] + }, + "expected": [ + { + "type": "i32", + "value": "2" + } + ] + }, + { + "type": "assert_exception", + "line": 227, + "action": { + "type": "invoke", + "field": "delegate-merge", + "args": [ + { + "type": "i32", + "value": "2" + }, + { + "type": "i32", + "value": "0" + } + ] + } + }, + { + "type": "assert_return", + "line": 228, + "action": { + "type": "invoke", + "field": "delegate-merge", + "args": [ + { + "type": "i32", + "value": "0" + }, + { + "type": "i32", + "value": "1" + } + ] + }, + "expected": [ + { + "type": "i32", + "value": "2" + } + ] + }, + { + "type": "assert_exception", + "line": 229, + "action": { + "type": "invoke", + "field": "delegate-merge", + "args": [ + { + "type": "i32", + "value": "0" + }, + { + "type": "i32", + "value": "2" + } + ] + } + }, + { + "type": "assert_return", + "line": 230, + "action": { + "type": "invoke", + "field": "delegate-merge", + "args": [ + { + "type": "i32", + "value": "0" + }, + { + "type": "i32", + "value": "0" + } + ] + }, + "expected": [ + { + "type": "i32", + "value": "1" + } + ] + }, + { + "type": "assert_return", + "line": 232, + "action": { + "type": "invoke", + "field": "delegate-skip", + "args": [] + }, + "expected": [ + { + "type": "i32", + "value": "3" + } + ] + }, + { + "type": "assert_return", + "line": 234, + "action": { + "type": "invoke", + "field": "delegate-to-block", + "args": [] + }, + "expected": [ + { + "type": "i32", + "value": "1" + } + ] + }, + { + "type": "assert_return", + "line": 235, + "action": { + "type": "invoke", + "field": "delegate-to-catch", + "args": [] + }, + "expected": [ + { + "type": "i32", + "value": "1" + } + ] + }, + { + "type": "assert_exception", + "line": 237, + "action": { + "type": "invoke", + "field": "delegate-to-caller-trivial", + "args": [] + } + }, + { + "type": "assert_exception", + "line": 238, + "action": { + "type": "invoke", + "field": "delegate-to-caller-skipping", + "args": [] + } + }, + { + "type": "assert_return", + "line": 240, + "action": { + "type": "invoke", + "field": "delegate-correct-targets", + "args": [] + }, + "expected": [ + { + "type": "i32", + "value": "1" + } + ] + }, + { + "type": "assert_exception", + "line": 242, + "action": { + "type": "invoke", + "field": "return-call-in-try-delegate", + "args": [] + } + }, + { + "type": "assert_exception", + "line": 243, + "action": { + "type": "invoke", + "field": "return-call-indirect-in-try-delegate", + "args": [] + } + }, + { + "type": "assert_return", + "line": 245, + "action": { + "type": "invoke", + "field": "break-try-delegate", + "args": [] + }, + "expected": [] + }, + { + "type": "assert_return", + "line": 247, + "action": { + "type": "invoke", + "field": "break-and-call-throw", + "args": [] + }, + "expected": [ + { + "type": "i32", + "value": "1" + } + ] + }, + { + "type": "assert_return", + "line": 248, + "action": { + "type": "invoke", + "field": "break-and-throw", + "args": [] + }, + "expected": [ + { + "type": "i32", + "value": "1" + } + ] + }, + { + "type": "assert_invalid", + "line": 273, + "filename": "try_delegate.1.wasm", + "text": "unknown label", + "module_type": "binary" + } + ] +} \ No newline at end of file diff --git a/tests/snapshots/local/legacy-exceptions/try_delegate.wast/0.print b/tests/snapshots/local/legacy-exceptions/try_delegate.wast/0.print new file mode 100644 index 0000000000..7144255ea7 --- /dev/null +++ b/tests/snapshots/local/legacy-exceptions/try_delegate.wast/0.print @@ -0,0 +1,227 @@ +(module + (type (;0;) (func)) + (type (;1;) (func (result i32))) + (type (;2;) (func (param i32))) + (type (;3;) (func (param i32) (result i32))) + (type (;4;) (func (param i32 i32) (result i32))) + (func (;0;) (type 1) (result i32) + try (result i32) ;; label = @1 + try (result i32) ;; label = @2 + i32.const 1 + delegate 0 (;@1;) + catch $e0 + i32.const 2 + end + ) + (func $throw-if (;1;) (type 2) (param i32) + local.get 0 + if ;; label = @1 + throw $e0 + else + end + ) + (func (;2;) (type 3) (param i32) (result i32) + try (result i32) ;; label = @1 + try (result i32) ;; label = @2 + local.get 0 + call $throw-if + i32.const 1 + delegate 0 (;@1;) + catch $e0 + i32.const 2 + end + ) + (func (;3;) (type 1) (result i32) + try (result i32) ;; label = @1 + try (result i32) ;; label = @2 + try (result i32) ;; label = @3 + throw $e0 + i32.const 1 + delegate 1 (;@1;) + catch $e0 + i32.const 2 + end + catch $e0 + i32.const 3 + end + ) + (func (;4;) (type 1) (result i32) + try (result i32) ;; label = @1 + block ;; label = @2 + try ;; label = @3 + throw $e0 + delegate 0 (;@2;) + end + i32.const 0 + catch_all + i32.const 1 + end + ) + (func (;5;) (type 1) (result i32) + try (result i32) ;; label = @1 + try ;; label = @2 + throw $e0 + catch $e0 + try ;; label = @3 + rethrow 1 (;@2;) + delegate 0 (;@2;) + end + i32.const 0 + catch_all + i32.const 1 + end + ) + (func (;6;) (type 0) + try ;; label = @1 + throw $e0 + delegate 0 + ) + (func (;7;) (type 0) + try ;; label = @1 + try ;; label = @2 + throw $e0 + delegate 1 + catch_all + end + ) + (func $select-tag (;8;) (type 2) (param i32) + block ;; label = @1 + block ;; label = @2 + block ;; label = @3 + local.get 0 + br_table 0 (;@3;) 1 (;@2;) 2 (;@1;) + end + return + end + throw $e0 + end + throw $e1 + ) + (func (;9;) (type 4) (param i32 i32) (result i32) + try (result i32) ;; label = @1 + local.get 0 + call $select-tag + try (result i32) ;; label = @2 + local.get 1 + call $select-tag + i32.const 1 + delegate 0 (;@1;) + catch $e0 + i32.const 2 + end + ) + (func (;10;) (type 1) (result i32) + try (result i32) ;; label = @1 + try (result i32) ;; label = @2 + throw $e0 + i32.const 1 + delegate 0 (;@1;) + catch $e1 + i32.const 2 + end + ) + (func (;11;) (type 1) (result i32) + try (result i32) ;; label = @1 + try ;; label = @2 + try ;; label = @3 + try ;; label = @4 + try ;; label = @5 + try ;; label = @6 + throw $e0 + delegate 1 (;@4;) + catch_all + unreachable + end + delegate 1 (;@2;) + catch_all + unreachable + end + catch_all + try ;; label = @3 + throw $e0 + delegate 0 (;@2;) + end + unreachable + catch_all + i32.const 1 + end + ) + (func $throw-void (;12;) (type 0) + throw $e0 + ) + (func (;13;) (type 0) + try ;; label = @1 + try ;; label = @2 + return_call $throw-void + delegate 0 (;@1;) + catch $e0 + end + ) + (func (;14;) (type 0) + try ;; label = @1 + try ;; label = @2 + i32.const 0 + return_call_indirect (type 0) + delegate 0 (;@1;) + catch $e0 + end + ) + (func (;15;) (type 0) + try ;; label = @1 + br 0 (;@1;) + delegate 0 + ) + (func (;16;) (type 1) (result i32) + try (result i32) ;; label = @1 + try (result i32) ;; label = @2 + block ;; label = @3 + try ;; label = @4 + br 1 (;@3;) + delegate 2 (;@1;) + end + call $throw-void + i32.const 0 + catch $e0 + i32.const 1 + end + catch $e0 + i32.const 2 + end + ) + (func (;17;) (type 1) (result i32) + try (result i32) ;; label = @1 + try (result i32) ;; label = @2 + block ;; label = @3 + try ;; label = @4 + br 1 (;@3;) + delegate 2 (;@1;) + end + throw $e0 + i32.const 0 + catch $e0 + i32.const 1 + end + catch $e0 + i32.const 2 + end + ) + (table (;0;) 1 1 funcref) + (tag $e0 (;0;) (type 0)) + (tag $e1 (;1;) (type 0)) + (export "delegate-no-throw" (func 0)) + (export "delegate-throw" (func 2)) + (export "delegate-skip" (func 3)) + (export "delegate-to-block" (func 4)) + (export "delegate-to-catch" (func 5)) + (export "delegate-to-caller-trivial" (func 6)) + (export "delegate-to-caller-skipping" (func 7)) + (export "delegate-merge" (func 9)) + (export "delegate-throw-no-catch" (func 10)) + (export "delegate-correct-targets" (func 11)) + (export "return-call-in-try-delegate" (func 13)) + (export "return-call-indirect-in-try-delegate" (func 14)) + (export "break-try-delegate" (func 15)) + (export "break-and-call-throw" (func 16)) + (export "break-and-throw" (func 17)) + (elem (;0;) (i32.const 0) func $throw-void) +)