Commit 82741108 authored by Thibaud Michaud's avatar Thibaud Michaud Committed by Commit Bot

[wasm][interpreter][eh] Implement catch_all

R=clemensb@chromium.org

Bug: v8:8091
Change-Id: I512db4c4a6dce56c06f6d222f75029eebeaa4f66
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2691046
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72700}
parent e7b2d64e
......@@ -95,6 +95,38 @@ WASM_EXEC_TEST(TryMultiCatchThrow) {
}
}
WASM_EXEC_TEST(TryCatchAllThrow) {
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, kExprTry, static_cast<byte>((kWasmI32).value_type_code()),
WASM_STMTS(WASM_I32V(kResult2),
WASM_IF(WASM_I32_EQZ(WASM_LOCAL_GET(0)), WASM_THROW(except1)),
WASM_IF(WASM_I32_EQ(WASM_LOCAL_GET(0), WASM_I32V(1)),
WASM_THROW(except2))),
kExprCatch, except1, WASM_STMTS(WASM_I32V(kResult0)), kExprElse,
WASM_STMTS(WASM_I32V(kResult1)), kExprEnd);
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);
r.CheckCallViaJS(kResult2, 2);
} else {
CHECK_EQ(kResult0, r.CallInterpreter(0));
CHECK_EQ(kResult1, r.CallInterpreter(1));
CHECK_EQ(kResult2, r.CallInterpreter(2));
}
}
WASM_EXEC_TEST(TryCatchCallDirect) {
TestSignatures sigs;
EXPERIMENTAL_FLAG_SCOPE(eh);
......
......@@ -560,6 +560,7 @@ int64_t ExecuteI64ReinterpretF64(WasmValue a) {
}
constexpr int32_t kCatchInArity = 1;
constexpr int32_t kCatchAllExceptionIndex = -1;
} // namespace
......@@ -810,20 +811,39 @@ class SideTable : public ZoneObject {
break;
}
case kExprElse: {
// TODO(thibaudm): implement catch_all.
// Alias for catch_all if the current block is a try.
Control* c = &control_stack.back();
copy_unreachable();
TRACE("control @%u: Else\n", i.pc_offset());
if (!unreachable) {
c->end_label->Ref(i.pc(), stack_height);
if (*c->pc == kExprIf) {
copy_unreachable();
TRACE("control @%u: Else\n", i.pc_offset());
if (!unreachable) {
c->end_label->Ref(i.pc(), stack_height);
}
DCHECK_NOT_NULL(c->else_label);
c->else_label->Bind(i.pc() + 1);
c->else_label->Finish(&map_, code->start);
stack_height = c->else_label->target_stack_height;
c->else_label = nullptr;
DCHECK_IMPLIES(!unreachable,
stack_height >= c->end_label->target_stack_height);
} else {
DCHECK_EQ(*c->pc, kExprTry);
if (!exception_stack.empty() &&
exception_stack.back() == control_stack.size() - 1) {
// Only pop the exception stack if this is the only catch handler.
exception_stack.pop_back();
}
copy_unreachable();
TRACE("control @%u: CatchAll\n", i.pc_offset());
if (!unreachable) {
c->end_label->Ref(i.pc(), stack_height);
}
DCHECK_NOT_NULL(c->else_label);
c->else_label->Bind(i.pc() + 1, kCatchAllExceptionIndex);
DCHECK_IMPLIES(!unreachable,
stack_height >= c->end_label->target_stack_height);
stack_height = c->end_label->target_stack_height;
}
DCHECK_NOT_NULL(c->else_label);
c->else_label->Bind(i.pc() + 1);
c->else_label->Finish(&map_, code->start);
stack_height = c->else_label->target_stack_height;
c->else_label = nullptr;
DCHECK_IMPLIES(!unreachable,
stack_height >= c->end_label->target_stack_height);
break;
}
case kExprTry: {
......@@ -1346,7 +1366,12 @@ 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 (MatchingExceptionTag(exception_object, entry.exception_index)) {
if (entry.exception_index == kCatchAllExceptionIndex) {
ResetStack(StackHeight() - entry.sp_diff);
*pc += entry.pc_diff;
return true;
} else if (MatchingExceptionTag(exception_object,
entry.exception_index)) {
const WasmException* exception =
&module()->exceptions[entry.exception_index];
const FunctionSig* sig = exception->sig;
......
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