[wasm][eh] Allow delegating to the caller

Delegating to the current control depth is valid and rethrows the
exception to the caller. See
https://github.com/WebAssembly/exception-handling/pull/143.

R=clemensb@chromium.org
CC=​aheejin@chromium.org

Bug: v8:8091
Change-Id: I6f14663751736ec6de29eefebfccdf5eb9e955e2
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2617081
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Reviewed-by: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71974}
This commit is contained in:
Thibaud Michaud 2021-01-08 14:07:11 +01:00 committed by Commit Bot
parent 079b50e5ec
commit d4ecac6bc3
4 changed files with 29 additions and 9 deletions

View File

@ -2484,16 +2484,11 @@ class WasmFullDecoder : public WasmDecoder<validate> {
while (next_try < control_depth() && !control_at(next_try)->is_try()) {
next_try++;
}
if (next_try == control_depth()) {
this->DecodeError("delegate does not target a try-catch");
return 0;
}
FallThruTo(c);
CALL_INTERFACE_IF_PARENT_REACHABLE(Delegate, next_try, c);
current_code_reachable_ = this->ok() && control_.back().reachable();
EndControl();
PopControl(c);
c->reachability = control_at(1)->innerReachability();
return 1 + imm.length;
}

View File

@ -629,6 +629,12 @@ class WasmGraphBuildingInterface {
if (block->try_info->might_throw()) {
// Merge the current env into the target handler's env.
SetEnv(block->try_info->catch_env);
if (depth == decoder->control_depth()) {
builder_->Rethrow(block->try_info->exception);
builder_->TerminateThrow(effect(), control());
return;
}
DCHECK(decoder->control_at(depth)->is_try());
TryInfo* target_try = decoder->control_at(depth)->try_info;
Goto(decoder, target_try->catch_env);

View File

@ -1039,3 +1039,20 @@ load("test/mjsunit/wasm/exceptions-utils.js");
instance = builder.instantiate();
assertEquals(2, instance.exports.test());
})();
(function TestDelegateToCaller() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let except = builder.addException(kSig_v_v);
builder.addFunction('test', kSig_v_v)
.addBody([
kExprTry, kWasmStmt,
kExprTry, kWasmStmt,
kExprThrow, except,
kExprDelegate, 1,
kExprCatchAll,
kExprEnd
]).exportFunc();
instance = builder.instantiate();
assertTraps(WebAssembly.RuntimeError, () => instance.exports.test());
})();

View File

@ -2900,14 +2900,16 @@ TEST_F(FunctionBodyDecoderTest, TryDelegate) {
{WASM_TRY_OP,
WASM_BLOCK(WASM_TRY_DELEGATE(WASM_STMTS(kExprThrow, ex), 0)),
kExprCatch, ex, kExprEnd});
ExpectValidates(
sigs.v_v(),
{WASM_BLOCK(WASM_TRY_OP, WASM_TRY_DELEGATE(WASM_STMTS(kExprThrow, ex), 2),
kExprCatch, ex, kExprEnd)});
// delegate after catch.
// delegate after catch_all.
ExpectFailure(
sigs.v_v(),
{WASM_BLOCK(WASM_TRY_OP, WASM_TRY_DELEGATE(WASM_STMTS(kExprThrow, ex), 1),
{WASM_BLOCK(WASM_TRY_OP, WASM_TRY_DELEGATE(WASM_STMTS(kExprThrow, ex), 3),
kExprCatch, ex, kExprEnd)},
kAppendEnd, "delegate does not target a try-catch");
kAppendEnd, "invalid branch depth: 3");
ExpectFailure(
sigs.v_v(),
{WASM_TRY_OP, WASM_TRY_OP, kExprCatch, ex, kExprDelegate, 0, kExprEnd},