[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:
parent
079b50e5ec
commit
d4ecac6bc3
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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());
|
||||
})();
|
||||
|
@ -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},
|
||||
|
Loading…
Reference in New Issue
Block a user