Commit 67805eab authored by Thibaud Michaud's avatar Thibaud Michaud Committed by Commit Bot

[wasm][interpreter] Fix multi-value stack height issue

Unreachable code may consume values from an empty stack as needed, known
as stack polymorphism. After consuming the values, the stack height
should still be 0, which was incorrectly handled by multi-value blocks.

R=ahaas@chromium.org

Bug: chromium:1085507
Change-Id: Ibf5f2d05bec0fbe029cfa66ee2d07540a370934a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2218033Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68070}
parent 69529052
......@@ -655,9 +655,9 @@ class SideTable : public ZoneObject {
// Represents a control flow label.
class CLabel : public ZoneObject {
explicit CLabel(Zone* zone, int32_t target_stack_height, uint32_t arity)
: target_stack_height(target_stack_height),
arity(arity),
refs(zone) {}
: target_stack_height(target_stack_height), arity(arity), refs(zone) {
DCHECK_LE(0, target_stack_height);
}
public:
struct Ref {
......@@ -803,8 +803,14 @@ class SideTable : public ZoneObject {
}
TRACE("control @%u: %s, arity %d->%d\n", i.pc_offset(),
is_loop ? "Loop" : "Block", imm.in_arity(), imm.out_arity());
DCHECK_IMPLIES(!unreachable,
stack_height >= static_cast<int32_t>(imm.in_arity()));
int32_t target_stack_height = stack_height - imm.in_arity();
// The stack may underflow in unreachable code. In this case the
// stack height is clamped at 0.
if (V8_UNLIKELY(target_stack_height < 0)) target_stack_height = 0;
CLabel* label =
CLabel::New(&control_transfer_zone, stack_height - imm.in_arity(),
CLabel::New(&control_transfer_zone, target_stack_height,
is_loop ? imm.in_arity() : imm.out_arity());
control_stack.emplace_back(i.pc(), label, imm.out_arity());
copy_unreachable();
......@@ -819,9 +825,14 @@ class SideTable : public ZoneObject {
}
TRACE("control @%u: If, arity %d->%d\n", i.pc_offset(),
imm.in_arity(), imm.out_arity());
CLabel* end_label =
CLabel::New(&control_transfer_zone, stack_height - imm.in_arity(),
imm.out_arity());
DCHECK_IMPLIES(!unreachable,
stack_height >= static_cast<int32_t>(imm.in_arity()));
int32_t target_stack_height = stack_height - imm.in_arity();
// The stack may underflow in unreachable code. In this case the
// stack height is clamped at 0.
if (V8_UNLIKELY(target_stack_height < 0)) target_stack_height = 0;
CLabel* end_label = CLabel::New(&control_transfer_zone,
target_stack_height, imm.out_arity());
CLabel* else_label =
CLabel::New(&control_transfer_zone, stack_height, 0);
control_stack.emplace_back(i.pc(), end_label, else_label,
......
......@@ -3762,6 +3762,15 @@ TEST(Liftoff_tier_up) {
}
}
TEST(Regression_1085507) {
EXPERIMENTAL_FLAG_SCOPE(mv);
WasmRunner<int32_t> r(ExecutionTier::kInterpreter);
TestSignatures sigs;
uint32_t sig_v_i = r.builder().AddSignature(sigs.v_i());
BUILD(r, WASM_I32V_1(0), kExprIf, kLocalVoid, WASM_UNREACHABLE,
WASM_BLOCK_X(sig_v_i, kExprDrop), kExprElse, kExprEnd, WASM_I32V_1(0));
}
#undef B1
#undef B2
#undef RET
......
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