Commit 159e440d authored by Thibaud Michaud's avatar Thibaud Michaud Committed by V8 LUCI CQ

[wasm][eh] Fix interpreter delegate in catch block

The recent change in the delegate semantics was incorrectly implemented
in the interpreter. It only checked that the first opcode of the target
block is a 'try': we also need to skip try blocks when we are already in
their 'catch' or 'catch_all' sub-block.
Use the exception_stack instead, since it already only contains indices
of try blocks that haven't reached their handlers yet.

R=clemensb@chromium.org

Bug: chromium:1249306
Change-Id: I15746b4bfabf3dcf04cfe0f2ad438c573cce65e7
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3168622
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/main@{#76919}
parent 325077dc
......@@ -522,6 +522,14 @@ TEST(Regress1246712) {
CHECK_EQ(kExpected, r.Call());
}
TEST(Regress1249306) {
WasmRunner<uint32_t> r(TestExecutionTier::kInterpreter);
TestSignatures sigs;
BUILD(r, kExprTry, kVoid, kExprCatchAll, kExprTry, kVoid, kExprDelegate, 0,
kExprEnd, kExprI32Const, 0);
r.Call();
}
} // namespace test_run_wasm_interpreter
} // namespace wasm
} // namespace internal
......
......@@ -970,17 +970,20 @@ class SideTable : public ZoneObject {
Control* c = &control_stack.back();
const size_t new_stack_size = control_stack.size() - 1;
const size_t max_depth = new_stack_size - 1;
size_t target_depth = imm.depth;
while (target_depth < max_depth &&
*control_stack[max_depth - target_depth].pc != kExprTry) {
target_depth++;
// Find the first try block that is equal to or encloses the target
// block, i.e. has a lower than or equal index in the control stack.
int try_index = static_cast<int>(exception_stack.size()) - 1;
while (try_index >= 0 &&
exception_stack[try_index] > max_depth - imm.depth) {
try_index--;
}
if (target_depth < max_depth) {
if (try_index >= 0) {
size_t target_depth = exception_stack[try_index];
constexpr int kUnusedControlIndex = -1;
c->else_label->Bind(i.pc(), kRethrowOrDelegateExceptionIndex,
kUnusedControlIndex);
c->else_label->Finish(&map_, code->start);
Control* target = &control_stack[max_depth - target_depth];
Control* target = &control_stack[target_depth];
DCHECK_EQ(*target->pc, kExprTry);
DCHECK_NOT_NULL(target->else_label);
if (!control_parent().unreachable) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment