From 1254b564b2d36cbf96ef8b8fe0c17fa2fa668ae3 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Thu, 18 Feb 2021 04:36:56 +0900 Subject: [EH] Make rethrow's target a try label (#3568) I was previously mistaken about `rethrow`'s argument rule and thought it only counted `catch`'s depth. But it turns out it follows the same rule `delegate`'s label: the immediate argument follows the same rule as when computing branch labels, but it only can target `try` labels (semantically it targets that `try`'s corresponding `catch`); otherwise it will be a validation failure. Unlike `delegate`, `rethrow`'s label denotes not where to rethrow, but which exception to rethrow. For example, ```wasm try $l0 catch ($l0) try $l1 catch ($l1) rethrow $l0 ;; rethrow the exception caught by 'catch ($l0)' end end ``` Refer to this comment for the more detailed informal semantics: https://github.com/WebAssembly/exception-handling/issues/146#issuecomment-777714491 --- This also reverts some of `delegateTarget` -> `exceptionTarget` changes done in #3562 in the validator. Label validation rules apply differently for `delegate` and `rethrow` for try-catch. For example, this is valid: ```wasm try $l0 try delegate $l0 catch ($l0) end ``` But this is NOT valid: ```wasm try $l0 catch ($l0) try delegate $l0 end ``` So `try`'s label should be used within try-catch range (not catch-end range) for `delegate`s. But for the `rethrow` the rule is different. For example, this is valid: ```wasm try $l0 catch ($l0) rethrow $l0 end ``` But this is NOT valid: ```wasm try $l0 rethrow $l0 catch ($l0) end ``` So the `try`'s label should be used within catch-end range instead. --- test/exception-handling.wast.fromBinary | 119 ++++++++++++++++++++++++++++---- 1 file changed, 106 insertions(+), 13 deletions(-) (limited to 'test/exception-handling.wast.fromBinary') diff --git a/test/exception-handling.wast.fromBinary b/test/exception-handling.wast.fromBinary index d6dd331b1..89d0bb7fb 100644 --- a/test/exception-handling.wast.fromBinary +++ b/test/exception-handling.wast.fromBinary @@ -194,19 +194,6 @@ ) ) ) - (try $label$37 - (do - (throw $event$0 - (i32.const 0) - ) - ) - (catch $event$0 - (drop - (pop i32) - ) - (rethrow 0) - ) - ) ) (func $delegate-test (try $label$9 @@ -269,5 +256,111 @@ (delegate 0) ) ) + (func $rethrow-test + (try $label$3 + (do + (call $foo) + ) + (catch $event$0 + (drop + (pop i32) + ) + (rethrow $label$3) + ) + (catch_all + (rethrow $label$3) + ) + ) + (block $label$4 + (try $label$7 + (do + (call $foo) + ) + (catch $event$0 + (drop + (pop i32) + ) + (rethrow $label$7) + ) + (catch_all + (br $label$4) + ) + ) + ) + (try $label$13 + (do + (call $foo) + ) + (catch_all + (try $label$12 + (do + (call $foo) + ) + (catch $event$0 + (drop + (pop i32) + ) + (rethrow $label$13) + ) + (catch_all + (rethrow $label$13) + ) + ) + ) + ) + (try $label$20 + (do + (call $foo) + ) + (catch_all + (try $label$19 + (do + (call $foo) + ) + (catch $event$0 + (drop + (pop i32) + ) + (block $label$18 + (rethrow $label$20) + ) + ) + (catch_all + (rethrow $label$20) + ) + ) + ) + ) + (try $label$26 + (do + (call $foo) + ) + (catch_all + (try $label$25 + (do + (rethrow $label$26) + ) + (catch_all + (nop) + ) + ) + ) + ) + (try $label$32 + (do + (call $foo) + ) + (catch_all + (try $label$31 + (do + (rethrow $label$32) + ) + (catch_all + (nop) + ) + ) + ) + ) + ) ) -- cgit v1.2.3