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. --- src/js/binaryen.js-post.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src/js/binaryen.js-post.js') diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js index 63be4d446..7c53298ad 100644 --- a/src/js/binaryen.js-post.js +++ b/src/js/binaryen.js-post.js @@ -2154,8 +2154,8 @@ function wrapModule(module, self = {}) { self['throw'] = function(event_, operands) { return preserveStack(() => Module['_BinaryenThrow'](module, strToStack(event_), i32sToStack(operands), operands.length)); }; - self['rethrow'] = function(depth) { - return Module['_BinaryenRethrow'](module, depth); + self['rethrow'] = function(target) { + return Module['_BinaryenRethrow'](module, strToStack(target)); }; self['tuple'] = { @@ -2916,7 +2916,7 @@ Module['getExpressionInfo'] = function(expr) { return { 'id': id, 'type': type, - 'depth': Module['_BinaryenRethrowGetDepth'](expr) + 'target': UTF8ToString(Module['_BinaryenRethrowGetTarget'](expr)) }; case Module['TupleMakeId']: return { @@ -4287,11 +4287,12 @@ Module['Throw'] = makeExpressionWrapper({ }); Module['Rethrow'] = makeExpressionWrapper({ - 'getDepth'(expr) { - return Module['_BinaryenRethrowGetDepth'](expr); + 'getTarget'(expr) { + const target = Module['_BinaryenRethrowGetTarget'](expr); + return target ? UTF8ToString(target) : null; }, - 'setDepth'(expr, depthExpr) { - Module['_BinaryenRethrowSetDepth'](expr, depthExpr); + 'setTarget'(expr, target) { + preserveStack(() => { Module['_BinaryenRethrowSetTarget'](expr, strToStack(target)) }); } }); -- cgit v1.2.3