[wasm][eh] Update delegate behavior
Update the behavior of 'delegate' according to: https://github.com/WebAssembly/exception-handling/issues/176 Summary: delegate can target any block, which just rethrows to the next outer try/catch. R=clemensb@chromium.org Bug: v8:8091 Change-Id: I967db9ab1cbb1a15b2c5e0a1a20f64fa19a3f769 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3140603 Commit-Queue: Thibaud Michaud <thibaudm@chromium.org> Reviewed-by: Clemens Backes <clemensb@chromium.org> Cr-Commit-Position: refs/heads/main@{#76677}
This commit is contained in:
parent
f7d65d5069
commit
7c67bc1928
@ -2635,19 +2635,15 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
|
||||
return 0;
|
||||
}
|
||||
// +1 because the current try block is not included in the count.
|
||||
Control* target = control_at(imm.depth + 1);
|
||||
if (imm.depth + 1 < control_depth() - 1 && !target->is_try()) {
|
||||
this->DecodeError(
|
||||
"delegate target must be a try block or the function block");
|
||||
return 0;
|
||||
}
|
||||
if (target->is_try_catch() || target->is_try_catchall()) {
|
||||
this->DecodeError(
|
||||
"cannot delegate inside the catch handler of the target");
|
||||
return 0;
|
||||
uint32_t target_depth = imm.depth + 1;
|
||||
while (target_depth < control_depth() - 1 &&
|
||||
(!control_at(target_depth)->is_try() ||
|
||||
control_at(target_depth)->is_try_catch() ||
|
||||
control_at(target_depth)->is_try_catchall())) {
|
||||
target_depth++;
|
||||
}
|
||||
FallThrough();
|
||||
CALL_INTERFACE_IF_OK_AND_PARENT_REACHABLE(Delegate, imm.depth + 1, c);
|
||||
CALL_INTERFACE_IF_OK_AND_PARENT_REACHABLE(Delegate, target_depth, c);
|
||||
current_catch_ = c->previous_catch;
|
||||
EndControl();
|
||||
PopControl();
|
||||
|
@ -1073,3 +1073,41 @@ d8.file.execute("test/mjsunit/wasm/exceptions-utils.js");
|
||||
assertDoesNotThrow(() => instance.exports.catchless_try(0));
|
||||
assertWasmThrows(instance, except, [], () => instance.exports.catchless_try(1));
|
||||
})();
|
||||
|
||||
// Delegate to a regular block inside a try block.
|
||||
(function TestDelegateToBlock() {
|
||||
print(arguments.callee.name);
|
||||
let builder = new WasmModuleBuilder();
|
||||
let except = builder.addTag(kSig_v_v);
|
||||
builder.addFunction('test', kSig_i_v)
|
||||
.addBody([
|
||||
kExprTry, kWasmI32,
|
||||
kExprBlock, kWasmI32,
|
||||
kExprTry, kWasmI32,
|
||||
kExprThrow, except,
|
||||
kExprDelegate, 0,
|
||||
kExprEnd,
|
||||
kExprCatch, except,
|
||||
kExprI32Const, 2,
|
||||
kExprEnd,
|
||||
]).exportFunc();
|
||||
instance = builder.instantiate();
|
||||
assertEquals(2, instance.exports.test());
|
||||
})();
|
||||
|
||||
// Delegate to a regular block with no outer try (delegate to caller).
|
||||
(function TestDelegateToCallerWithBlock() {
|
||||
print(arguments.callee.name);
|
||||
let builder = new WasmModuleBuilder();
|
||||
let except = builder.addTag(kSig_v_v);
|
||||
builder.addFunction('test', kSig_v_v)
|
||||
.addBody([
|
||||
kExprBlock, kWasmVoid,
|
||||
kExprTry, kWasmVoid,
|
||||
kExprThrow, except,
|
||||
kExprDelegate, 0,
|
||||
kExprEnd
|
||||
]).exportFunc();
|
||||
instance = builder.instantiate();
|
||||
assertThrows(() => instance.exports.test(), WebAssembly.Exception);
|
||||
})();
|
||||
|
@ -2990,18 +2990,16 @@ TEST_F(FunctionBodyDecoderTest, TryDelegate) {
|
||||
sigs.v_v(),
|
||||
{WASM_BLOCK(WASM_TRY_OP, WASM_TRY_DELEGATE(WASM_STMTS(kExprThrow, ex), 2),
|
||||
kExprCatch, ex, kExprEnd)});
|
||||
ExpectValidates(sigs.v_v(),
|
||||
{WASM_TRY_OP, kExprCatch, ex,
|
||||
WASM_TRY_DELEGATE(WASM_STMTS(kExprThrow, ex), 0), kExprEnd},
|
||||
kAppendEnd);
|
||||
ExpectValidates(sigs.v_v(),
|
||||
{WASM_TRY_OP,
|
||||
WASM_BLOCK(WASM_TRY_DELEGATE(WASM_STMTS(kExprThrow, ex), 0)),
|
||||
kExprCatch, ex, kExprEnd},
|
||||
kAppendEnd);
|
||||
|
||||
ExpectFailure(sigs.v_v(),
|
||||
{WASM_TRY_OP,
|
||||
WASM_BLOCK(WASM_TRY_DELEGATE(WASM_STMTS(kExprThrow, ex), 0)),
|
||||
kExprCatch, ex, kExprEnd},
|
||||
kAppendEnd,
|
||||
"delegate target must be a try block or the function block");
|
||||
ExpectFailure(sigs.v_v(),
|
||||
{WASM_TRY_OP, kExprCatch, ex,
|
||||
WASM_TRY_DELEGATE(WASM_STMTS(kExprThrow, ex), 0), kExprEnd},
|
||||
kAppendEnd,
|
||||
"cannot delegate inside the catch handler of the target");
|
||||
ExpectFailure(
|
||||
sigs.v_v(),
|
||||
{WASM_BLOCK(WASM_TRY_OP, WASM_TRY_DELEGATE(WASM_STMTS(kExprThrow, ex), 3),
|
||||
|
Loading…
Reference in New Issue
Block a user