Commit 4f7aff2d authored by Thibaud Michaud's avatar Thibaud Michaud Committed by Commit Bot

[wasm][interpreter][eh] Add delegate

R=clemensb@chromium.org

Bug: v8:8091
Change-Id: Ic01ccc2978642b70c603b1666137ad5f587a152f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2690604Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72739}
parent 312a3fbe
......@@ -2071,6 +2071,7 @@ class WasmDecoder : public Decoder {
case kExprElse:
case kExprTry:
case kExprCatch:
case kExprDelegate:
case kExprNop:
case kExprNopForTestingUnsupportedInLiftoff:
case kExprReturn:
......
......@@ -158,6 +158,66 @@ WASM_EXEC_TEST(TryImplicitRethrow) {
}
}
WASM_EXEC_TEST(TryDelegate) {
TestSignatures sigs;
EXPERIMENTAL_FLAG_SCOPE(eh);
WasmRunner<uint32_t, uint32_t> r(execution_tier);
uint32_t except = r.builder().AddException(sigs.v_v());
constexpr uint32_t kResult0 = 23;
constexpr uint32_t kResult1 = 42;
// Build the main test function.
BUILD(r,
WASM_TRY_CATCH_T(kWasmI32,
WASM_TRY_DELEGATE_T(
kWasmI32,
WASM_STMTS(WASM_I32V(kResult1),
WASM_IF(WASM_I32_EQZ(WASM_LOCAL_GET(0)),
WASM_THROW(except))),
0),
WASM_I32V(kResult0), except));
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(TryDelegateToCaller) {
TestSignatures sigs;
EXPERIMENTAL_FLAG_SCOPE(eh);
WasmRunner<uint32_t, uint32_t> r(execution_tier);
uint32_t except = r.builder().AddException(sigs.v_v());
constexpr uint32_t kResult0 = 23;
constexpr uint32_t kResult1 = 42;
// Build the main test function.
BUILD(r,
WASM_TRY_CATCH_T(kWasmI32,
WASM_TRY_DELEGATE_T(
kWasmI32,
WASM_STMTS(WASM_I32V(kResult1),
WASM_IF(WASM_I32_EQZ(WASM_LOCAL_GET(0)),
WASM_THROW(except))),
1),
WASM_I32V(kResult0), except));
if (execution_tier != TestExecutionTier::kInterpreter) {
// Need to call through JS to allow for creation of stack traces.
constexpr int64_t trap = 0xDEADBEEF;
r.CheckCallViaJS(trap, 0);
r.CheckCallViaJS(kResult1, 1);
} else {
constexpr int stopped = 0;
CHECK_EQ(stopped, r.CallInterpreter(0));
CHECK_EQ(kResult1, r.CallInterpreter(1));
}
}
WASM_EXEC_TEST(TryCatchCallDirect) {
TestSignatures sigs;
EXPERIMENTAL_FLAG_SCOPE(eh);
......
......@@ -561,7 +561,7 @@ int64_t ExecuteI64ReinterpretF64(WasmValue a) {
constexpr int32_t kCatchInArity = 1;
constexpr int32_t kCatchAllExceptionIndex = -1;
constexpr int32_t kImplicitRethrowExceptionIndex = -2;
constexpr int32_t kRethrowOrDelegateExceptionIndex = -2;
} // namespace
......@@ -907,18 +907,49 @@ class SideTable : public ZoneObject {
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->else_label->Bind(i.pc(), kRethrowOrDelegateExceptionIndex);
if (!unreachable) {
next_try_block->else_label->Ref(
i.pc(), c->else_label->target_stack_height);
}
}
}
c->end_label->Bind(i.pc() + 1);
}
c->Finish(&map_, code->start);
DCHECK_IMPLIES(!unreachable,
stack_height >= c->end_label->target_stack_height);
stack_height = c->end_label->target_stack_height + c->exit_arity;
control_stack.pop_back();
break;
}
case kExprDelegate: {
BranchDepthImmediate<Decoder::kNoValidation> imm(&i, i.pc() + 1);
TRACE("control @%u: Delegate[depth=%u]\n", i.pc_offset(), imm.depth);
Control* c = &control_stack.back();
const size_t new_stack_size = control_stack.size() - 1;
const size_t max_depth = new_stack_size - 1;
if (imm.depth < max_depth) {
c->else_label->Bind(i.pc(), kRethrowOrDelegateExceptionIndex);
c->else_label->Finish(&map_, code->start);
Control* target = &control_stack[max_depth - imm.depth];
DCHECK_EQ(*target->pc, kExprTry);
DCHECK_NOT_NULL(target->else_label);
if (!unreachable) {
target->else_label->Ref(i.pc(),
c->end_label->target_stack_height);
}
}
c->else_label = nullptr;
c->end_label->Bind(i.pc() + 1);
c->Finish(&map_, code->start);
DCHECK_IMPLIES(!unreachable,
stack_height >= c->end_label->target_stack_height);
stack_height = c->end_label->target_stack_height + c->exit_arity;
control_stack.pop_back();
exception_stack.pop_back();
break;
}
case kExprBr: {
......@@ -1375,13 +1406,17 @@ class WasmInterpreterInternals {
bool JumpToHandlerDelta(InterpreterCode* code,
Handle<Object> exception_object, pc_t* pc) {
auto it = code->side_table->map_.catch_map.find(*pc);
DCHECK_NE(it, code->side_table->map_.catch_map.end());
if (it == code->side_table->map_.catch_map.end()) {
// No handler in this frame means that we should rethrow to the caller.
return false;
}
for (auto& entry : it->second) {
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.
if (entry.exception_index == kRethrowOrDelegateExceptionIndex) {
// Recursively try to find a handler in the next enclosing try block
// (for the implicit rethrow) or in the delegate target.
return JumpToHandlerDelta(code, exception_object, pc);
}
DCHECK_EQ(entry.exception_index, kCatchAllExceptionIndex);
......@@ -3440,6 +3475,12 @@ class WasmInterpreterInternals {
case kExprUnreachable: {
return DoTrap(kTrapUnreachable, pc);
}
case kExprDelegate: {
BranchDepthImmediate<Decoder::kNoValidation> imm(&decoder,
code->at(pc + 1));
len = 1 + imm.length;
break;
}
case kExprEnd: {
break;
}
......
......@@ -190,6 +190,9 @@
catchstmt, kExprEnd
#define WASM_TRY_DELEGATE(trystmt, depth) \
kExprTry, kVoidCode, trystmt, kExprDelegate, depth
#define WASM_TRY_DELEGATE_T(t, trystmt, depth) \
kExprTry, static_cast<byte>((t).value_type_code()), trystmt, kExprDelegate, \
depth
#define WASM_SELECT(tval, fval, cond) tval, fval, cond, kExprSelect
#define WASM_SELECT_I(tval, fval, cond) \
......
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