Commit 0df0d7ab authored by Thibaud Michaud's avatar Thibaud Michaud Committed by Commit Bot

[wasm][interpreter][eh] Add implicit rethrow

If the exception tag does not match any of the catch blocks and there is
no catch_all block, it should be rethrown.

R=clemensb@chromium.org

Bug: v8:8091
Change-Id: I8df80f51340fc6265f5ef4308ee3b0f892ee3a90
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2690599
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72713}
parent 203a0605
......@@ -127,6 +127,37 @@ WASM_EXEC_TEST(TryCatchAllThrow) {
}
}
WASM_EXEC_TEST(TryImplicitRethrow) {
TestSignatures sigs;
EXPERIMENTAL_FLAG_SCOPE(eh);
WasmRunner<uint32_t, uint32_t> r(execution_tier);
uint32_t except1 = r.builder().AddException(sigs.v_v());
uint32_t except2 = r.builder().AddException(sigs.v_v());
constexpr uint32_t kResult0 = 23;
constexpr uint32_t kResult1 = 42;
constexpr uint32_t kResult2 = 51;
// Build the main test function.
BUILD(r,
WASM_TRY_CATCH_T(
kWasmI32,
WASM_TRY_CATCH_T(kWasmI32,
WASM_STMTS(WASM_I32V(kResult1),
WASM_IF(WASM_I32_EQZ(WASM_LOCAL_GET(0)),
WASM_THROW(except2))),
WASM_STMTS(WASM_I32V(kResult2)), except1),
WASM_I32V(kResult0), except2));
if (execution_tier != TestExecutionTier::kInterpreter) {
// Need to call through JS to allow for creation of stack traces.
r.CheckCallViaJS(kResult0, 0);
r.CheckCallViaJS(kResult1, 1);
} else {
CHECK_EQ(kResult0, r.CallInterpreter(0));
CHECK_EQ(kResult1, r.CallInterpreter(1));
}
}
WASM_EXEC_TEST(TryCatchCallDirect) {
TestSignatures sigs;
EXPERIMENTAL_FLAG_SCOPE(eh);
......
......@@ -561,6 +561,7 @@ int64_t ExecuteI64ReinterpretF64(WasmValue a) {
constexpr int32_t kCatchInArity = 1;
constexpr int32_t kCatchAllExceptionIndex = -1;
constexpr int32_t kImplicitRethrowExceptionIndex = -2;
} // namespace
......@@ -840,6 +841,8 @@ class SideTable : public ZoneObject {
}
DCHECK_NOT_NULL(c->else_label);
c->else_label->Bind(i.pc() + 1, kCatchAllExceptionIndex);
c->else_label->Finish(&map_, code->start);
c->else_label = nullptr;
DCHECK_IMPLIES(!unreachable,
stack_height >= c->end_label->target_stack_height);
stack_height = c->end_label->target_stack_height;
......@@ -899,6 +902,14 @@ class SideTable : public ZoneObject {
if (*c->pc == kExprIf) {
// Bind else label for one-armed if.
c->else_label->Bind(i.pc());
} else if (!exception_stack.empty()) {
// No catch_all block, prepare for implicit rethrow.
DCHECK_EQ(*c->pc, kExprTry);
Control* next_try_block =
&control_stack[exception_stack.back()];
c->else_label->Bind(i.pc(), kImplicitRethrowExceptionIndex);
next_try_block->else_label->Ref(
i.pc(), c->else_label->target_stack_height);
}
}
c->end_label->Bind(i.pc() + 1);
......@@ -1366,9 +1377,14 @@ class WasmInterpreterInternals {
auto it = code->side_table->map_.catch_map.find(*pc);
DCHECK_NE(it, code->side_table->map_.catch_map.end());
for (auto& entry : it->second) {
if (entry.exception_index == kCatchAllExceptionIndex) {
if (entry.exception_index < 0) {
ResetStack(StackHeight() - entry.sp_diff);
*pc += entry.pc_diff;
if (entry.exception_index == kImplicitRethrowExceptionIndex) {
// Recursively try to find a handler in the next enclosing try block.
return JumpToHandlerDelta(code, exception_object, pc);
}
DCHECK_EQ(entry.exception_index, kCatchAllExceptionIndex);
return true;
} else if (MatchingExceptionTag(exception_object,
entry.exception_index)) {
......@@ -1382,7 +1398,6 @@ class WasmInterpreterInternals {
return true;
}
}
// TODO(thibaudm): Try rethrowing in the current frame before unwinding.
return false;
}
......
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