Commit 389eb1f8 authored by Manos Koukoutos's avatar Manos Koukoutos Committed by Commit Bot

[wasm] Rework CALL_INTERFACE macros in WasmDecoder

Main change: Remove CALL_INTERFACE macro. Use
CALL_INTERFACE_IF_REACHABLE or invoke interface directly instead.
Reasoning: Interfaces assume the Decoder is in a non-error state,
therefore CALL_INTERFACE invoked DCHECK(this->ok()). However,
CALL_INTERFACE (1) was sometimes erroneously called with an error in the
decoder, especially in cases where the error occurred inside immediate
argument parsing, (2) was always called in contexts where the current
control was guaranteed to be reachable. Due to (1) and (2),
CALL_INTERFACE is equivalent to CALL_INTERFACE_IF_REACHABLE (there are
a few exceptions where we can call the interface directly).

Additional change:
- Rename current_code_reachable_ to current_code_reachable_and_ok_
  to make its name reflect its meaning better.

Bug: chromium:1194784
Change-Id: I52055161a802e6981506b2a8dc8bb8233198aa2c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2799351
Commit-Queue: Manos Koukoutos <manoskouk@chromium.org>
Reviewed-by: 's avatarThibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#73771}
parent c76bae7d
...@@ -2183,21 +2183,16 @@ MemoryAccessImmediate<validate>::MemoryAccessImmediate( ...@@ -2183,21 +2183,16 @@ MemoryAccessImmediate<validate>::MemoryAccessImmediate(
: MemoryAccessImmediate(decoder, pc, max_alignment, : MemoryAccessImmediate(decoder, pc, max_alignment,
decoder->module_->is_memory64) {} decoder->module_->is_memory64) {}
#define CALL_INTERFACE(name, ...) \ #define CALL_INTERFACE_IF_OK_AND_REACHABLE(name, ...) \
do { \
DCHECK(this->ok()); \
interface_.name(this, ##__VA_ARGS__); \
} while (false)
#define CALL_INTERFACE_IF_REACHABLE(name, ...) \
do { \ do { \
DCHECK(!control_.empty()); \ DCHECK(!control_.empty()); \
DCHECK_EQ(current_code_reachable_, \ DCHECK_EQ(current_code_reachable_and_ok_, \
this->ok() && control_.back().reachable()); \ this->ok() && control_.back().reachable()); \
if (current_code_reachable_) { \ if (current_code_reachable_and_ok_) { \
interface_.name(this, ##__VA_ARGS__); \ interface_.name(this, ##__VA_ARGS__); \
} \ } \
} while (false) } while (false)
#define CALL_INTERFACE_IF_PARENT_REACHABLE(name, ...) \ #define CALL_INTERFACE_IF_OK_AND_PARENT_REACHABLE(name, ...) \
do { \ do { \
DCHECK(!control_.empty()); \ DCHECK(!control_.empty()); \
if (VALIDATE(this->ok()) && \ if (VALIDATE(this->ok()) && \
...@@ -2250,7 +2245,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2250,7 +2245,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
} }
} }
CALL_INTERFACE(StartFunction); // Cannot use CALL_INTERFACE_* macros because control is empty.
interface().StartFunction(this);
DecodeFunctionBody(); DecodeFunctionBody();
if (this->failed()) return TraceFailed(); if (this->failed()) return TraceFailed();
...@@ -2263,7 +2259,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2263,7 +2259,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
} }
return TraceFailed(); return TraceFailed();
} }
CALL_INTERFACE(FinishFunction); // Cannot use CALL_INTERFACE_* macros because control is empty.
interface().FinishFunction(this);
if (this->failed()) return TraceFailed(); if (this->failed()) return TraceFailed();
TRACE("wasm-decode ok\n\n"); TRACE("wasm-decode ok\n\n");
...@@ -2323,7 +2320,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2323,7 +2320,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Control* current = &control_.back(); Control* current = &control_.back();
if (current->reachable()) { if (current->reachable()) {
current->reachability = kSpecOnlyReachable; current->reachability = kSpecOnlyReachable;
current_code_reachable_ = false; current_code_reachable_and_ok_ = false;
} }
} }
...@@ -2341,7 +2338,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2341,7 +2338,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
// Controls whether code should be generated for the current block (basically // Controls whether code should be generated for the current block (basically
// a cache for {ok() && control_.back().reachable()}). // a cache for {ok() && control_.back().reachable()}).
bool current_code_reachable_ = true; bool current_code_reachable_and_ok_ = true;
static Value UnreachableValue(const uint8_t* pc) { static Value UnreachableValue(const uint8_t* pc) {
return Value{pc, kWasmBottom}; return Value{pc, kWasmBottom};
...@@ -2467,7 +2464,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2467,7 +2464,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
this->DecodeError("Invalid opcode 0x%x", opcode); this->DecodeError("Invalid opcode 0x%x", opcode);
return 0; return 0;
} }
CALL_INTERFACE_IF_REACHABLE(NopForTestingUnsupportedInLiftoff); CALL_INTERFACE_IF_OK_AND_REACHABLE(NopForTestingUnsupportedInLiftoff);
return 1; return 1;
} }
...@@ -2483,7 +2480,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2483,7 +2480,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
ArgVector args = PeekArgs(imm.sig); ArgVector args = PeekArgs(imm.sig);
Control* block = PushControl(kControlBlock, 0, args.length()); Control* block = PushControl(kControlBlock, 0, args.length());
SetBlockType(block, imm, args.begin()); SetBlockType(block, imm, args.begin());
CALL_INTERFACE_IF_REACHABLE(Block, block); CALL_INTERFACE_IF_OK_AND_REACHABLE(Block, block);
DropArgs(imm.sig); DropArgs(imm.sig);
PushMergeValues(block, &block->start_merge); PushMergeValues(block, &block->start_merge);
return 1 + imm.length; return 1 + imm.length;
...@@ -2498,7 +2495,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2498,7 +2495,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
this->error("rethrow not targeting catch or catch-all"); this->error("rethrow not targeting catch or catch-all");
return 0; return 0;
} }
CALL_INTERFACE_IF_REACHABLE(Rethrow, c); CALL_INTERFACE_IF_OK_AND_REACHABLE(Rethrow, c);
EndControl(); EndControl();
return 1 + imm.length; return 1 + imm.length;
} }
...@@ -2508,7 +2505,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2508,7 +2505,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
ExceptionIndexImmediate<validate> imm(this, this->pc_ + 1); ExceptionIndexImmediate<validate> imm(this, this->pc_ + 1);
if (!this->Validate(this->pc_ + 1, imm)) return 0; if (!this->Validate(this->pc_ + 1, imm)) return 0;
ArgVector args = PeekArgs(imm.exception->ToFunctionSig()); ArgVector args = PeekArgs(imm.exception->ToFunctionSig());
CALL_INTERFACE_IF_REACHABLE(Throw, imm, VectorOf(args)); CALL_INTERFACE_IF_OK_AND_REACHABLE(Throw, imm, VectorOf(args));
DropArgs(imm.exception->ToFunctionSig()); DropArgs(imm.exception->ToFunctionSig());
EndControl(); EndControl();
return 1 + imm.length; return 1 + imm.length;
...@@ -2522,7 +2519,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2522,7 +2519,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
ArgVector args = PeekArgs(imm.sig); ArgVector args = PeekArgs(imm.sig);
Control* try_block = PushControl(kControlTry, 0, args.length()); Control* try_block = PushControl(kControlTry, 0, args.length());
SetBlockType(try_block, imm, args.begin()); SetBlockType(try_block, imm, args.begin());
CALL_INTERFACE_IF_REACHABLE(Try, try_block); CALL_INTERFACE_IF_OK_AND_REACHABLE(Try, try_block);
DropArgs(imm.sig); DropArgs(imm.sig);
PushMergeValues(try_block, &try_block->start_merge); PushMergeValues(try_block, &try_block->start_merge);
return 1 + imm.length; return 1 + imm.length;
...@@ -2559,8 +2556,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2559,8 +2556,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Push(CreateValue(sig->GetParam(i))); Push(CreateValue(sig->GetParam(i)));
} }
Vector<Value> values(stack_ + c->stack_depth, sig->parameter_count()); Vector<Value> values(stack_ + c->stack_depth, sig->parameter_count());
CALL_INTERFACE_IF_PARENT_REACHABLE(CatchException, imm, c, values); CALL_INTERFACE_IF_OK_AND_PARENT_REACHABLE(CatchException, imm, c, values);
current_code_reachable_ = this->ok() && c->reachable(); current_code_reachable_and_ok_ = this->ok() && c->reachable();
return 1 + imm.length; return 1 + imm.length;
} }
...@@ -2588,8 +2585,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2588,8 +2585,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
return 0; return 0;
} }
FallThruTo(c); FallThruTo(c);
CALL_INTERFACE_IF_PARENT_REACHABLE(Delegate, imm.depth + 1, c); CALL_INTERFACE_IF_OK_AND_PARENT_REACHABLE(Delegate, imm.depth + 1, c);
current_code_reachable_ = this->ok() && control_.back().reachable(); current_code_reachable_and_ok_ = this->ok() && control_.back().reachable();
EndControl(); EndControl();
PopControl(c); PopControl(c);
return 1 + imm.length; return 1 + imm.length;
...@@ -2614,9 +2611,9 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2614,9 +2611,9 @@ class WasmFullDecoder : public WasmDecoder<validate> {
FallThruTo(c); FallThruTo(c);
c->kind = kControlTryCatchAll; c->kind = kControlTryCatchAll;
c->reachability = control_at(1)->innerReachability(); c->reachability = control_at(1)->innerReachability();
CALL_INTERFACE_IF_PARENT_REACHABLE(CatchAll, c); CALL_INTERFACE_IF_OK_AND_PARENT_REACHABLE(CatchAll, c);
stack_end_ = stack_ + c->stack_depth; stack_end_ = stack_ + c->stack_depth;
current_code_reachable_ = this->ok() && c->reachable(); current_code_reachable_and_ok_ = this->ok() && c->reachable();
return 1; return 1;
} }
...@@ -2636,9 +2633,9 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2636,9 +2633,9 @@ class WasmFullDecoder : public WasmDecoder<validate> {
FallThruTo(c); FallThruTo(c);
c->kind = kControlTryUnwind; c->kind = kControlTryUnwind;
c->reachability = control_at(1)->innerReachability(); c->reachability = control_at(1)->innerReachability();
CALL_INTERFACE_IF_PARENT_REACHABLE(CatchAll, c); CALL_INTERFACE_IF_OK_AND_PARENT_REACHABLE(CatchAll, c);
stack_end_ = stack_ + c->stack_depth; stack_end_ = stack_ + c->stack_depth;
current_code_reachable_ = this->ok() && c->reachable(); current_code_reachable_and_ok_ = this->ok() && c->reachable();
return 1; return 1;
} }
...@@ -2660,12 +2657,12 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2660,12 +2657,12 @@ class WasmFullDecoder : public WasmDecoder<validate> {
break; break;
case kOptRef: { case kOptRef: {
if (V8_LIKELY(check_result == kReachableBranch)) { if (V8_LIKELY(check_result == kReachableBranch)) {
CALL_INTERFACE_IF_REACHABLE(BrOnNull, ref_object, imm.depth); CALL_INTERFACE_IF_OK_AND_REACHABLE(BrOnNull, ref_object, imm.depth);
Value result = CreateValue( Value result = CreateValue(
ValueType::Ref(ref_object.type.heap_type(), kNonNullable)); ValueType::Ref(ref_object.type.heap_type(), kNonNullable));
// The result of br_on_null has the same value as the argument (but a // The result of br_on_null has the same value as the argument (but a
// non-nullable type). // non-nullable type).
CALL_INTERFACE(Forward, ref_object, &result); CALL_INTERFACE_IF_OK_AND_REACHABLE(Forward, ref_object, &result);
c->br_merge()->reached = true; c->br_merge()->reached = true;
Drop(ref_object); Drop(ref_object);
Push(result); Push(result);
...@@ -2705,8 +2702,9 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2705,8 +2702,9 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Control* let_block = PushControl(kControlLet, new_locals_count, Control* let_block = PushControl(kControlLet, new_locals_count,
let_local_values.length() + args.length()); let_local_values.length() + args.length());
SetBlockType(let_block, imm, args.begin()); SetBlockType(let_block, imm, args.begin());
CALL_INTERFACE_IF_REACHABLE(Block, let_block); CALL_INTERFACE_IF_OK_AND_REACHABLE(Block, let_block);
CALL_INTERFACE_IF_REACHABLE(AllocateLocals, VectorOf(let_local_values)); CALL_INTERFACE_IF_OK_AND_REACHABLE(AllocateLocals,
VectorOf(let_local_values));
Drop(new_locals_count); // Drop {let_local_values}. Drop(new_locals_count); // Drop {let_local_values}.
DropArgs(imm.sig); // Drop {args}. DropArgs(imm.sig); // Drop {args}.
PushMergeValues(let_block, &let_block->start_merge); PushMergeValues(let_block, &let_block->start_merge);
...@@ -2720,7 +2718,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2720,7 +2718,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
ArgVector args = PeekArgs(imm.sig); ArgVector args = PeekArgs(imm.sig);
Control* block = PushControl(kControlLoop, 0, args.length()); Control* block = PushControl(kControlLoop, 0, args.length());
SetBlockType(&control_.back(), imm, args.begin()); SetBlockType(&control_.back(), imm, args.begin());
CALL_INTERFACE_IF_REACHABLE(Loop, block); CALL_INTERFACE_IF_OK_AND_REACHABLE(Loop, block);
DropArgs(imm.sig); DropArgs(imm.sig);
PushMergeValues(block, &block->start_merge); PushMergeValues(block, &block->start_merge);
return 1 + imm.length; return 1 + imm.length;
...@@ -2735,7 +2733,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2735,7 +2733,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
if (!VALIDATE(this->ok())) return 0; if (!VALIDATE(this->ok())) return 0;
Control* if_block = PushControl(kControlIf, 0, 1 + args.length()); Control* if_block = PushControl(kControlIf, 0, 1 + args.length());
SetBlockType(if_block, imm, args.begin()); SetBlockType(if_block, imm, args.begin());
CALL_INTERFACE_IF_REACHABLE(If, cond, if_block); CALL_INTERFACE_IF_OK_AND_REACHABLE(If, cond, if_block);
Drop(cond); Drop(cond);
DropArgs(imm.sig); // Drop {args}. DropArgs(imm.sig); // Drop {args}.
PushMergeValues(if_block, &if_block->start_merge); PushMergeValues(if_block, &if_block->start_merge);
...@@ -2755,11 +2753,11 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2755,11 +2753,11 @@ class WasmFullDecoder : public WasmDecoder<validate> {
} }
if (!TypeCheckFallThru()) return 0; if (!TypeCheckFallThru()) return 0;
c->kind = kControlIfElse; c->kind = kControlIfElse;
CALL_INTERFACE_IF_PARENT_REACHABLE(Else, c); CALL_INTERFACE_IF_OK_AND_PARENT_REACHABLE(Else, c);
if (c->reachable()) c->end_merge.reached = true; if (c->reachable()) c->end_merge.reached = true;
PushMergeValues(c, &c->start_merge); PushMergeValues(c, &c->start_merge);
c->reachability = control_at(1)->innerReachability(); c->reachability = control_at(1)->innerReachability();
current_code_reachable_ = this->ok() && c->reachable(); current_code_reachable_and_ok_ = this->ok() && c->reachable();
return 1; return 1;
} }
...@@ -2782,19 +2780,20 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2782,19 +2780,20 @@ class WasmFullDecoder : public WasmDecoder<validate> {
// Emulate catch-all + re-throw. // Emulate catch-all + re-throw.
FallThruTo(c); FallThruTo(c);
c->reachability = control_at(1)->innerReachability(); c->reachability = control_at(1)->innerReachability();
CALL_INTERFACE_IF_PARENT_REACHABLE(CatchAll, c); CALL_INTERFACE_IF_OK_AND_PARENT_REACHABLE(CatchAll, c);
current_code_reachable_ = this->ok() && control_.back().reachable(); current_code_reachable_and_ok_ =
CALL_INTERFACE_IF_REACHABLE(Rethrow, c); this->ok() && control_.back().reachable();
CALL_INTERFACE_IF_OK_AND_REACHABLE(Rethrow, c);
EndControl(); EndControl();
} }
if (c->is_try_unwind()) { if (c->is_try_unwind()) {
// Unwind implicitly rethrows at the end. // Unwind implicitly rethrows at the end.
CALL_INTERFACE_IF_REACHABLE(Rethrow, c); CALL_INTERFACE_IF_OK_AND_REACHABLE(Rethrow, c);
EndControl(); EndControl();
} }
if (c->is_let()) { if (c->is_let()) {
CALL_INTERFACE_IF_REACHABLE(DeallocateLocals, c->locals_count); CALL_INTERFACE_IF_OK_AND_REACHABLE(DeallocateLocals, c->locals_count);
this->local_types_.erase(this->local_types_.begin(), this->local_types_.erase(this->local_types_.begin(),
this->local_types_.begin() + c->locals_count); this->local_types_.begin() + c->locals_count);
this->num_locals_ -= c->locals_count; this->num_locals_ -= c->locals_count;
...@@ -2829,7 +2828,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2829,7 +2828,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
return 0; return 0;
} }
Value result = CreateValue(type); Value result = CreateValue(type);
CALL_INTERFACE_IF_REACHABLE(Select, cond, fval, tval, &result); CALL_INTERFACE_IF_OK_AND_REACHABLE(Select, cond, fval, tval, &result);
Drop(3); Drop(3);
Push(result); Push(result);
return 1; return 1;
...@@ -2844,7 +2843,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2844,7 +2843,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Value fval = Peek(1, 1, imm.type); Value fval = Peek(1, 1, imm.type);
Value tval = Peek(2, 0, imm.type); Value tval = Peek(2, 0, imm.type);
Value result = CreateValue(imm.type); Value result = CreateValue(imm.type);
CALL_INTERFACE_IF_REACHABLE(Select, cond, fval, tval, &result); CALL_INTERFACE_IF_OK_AND_REACHABLE(Select, cond, fval, tval, &result);
Drop(3); Drop(3);
Push(result); Push(result);
return 1 + imm.length; return 1 + imm.length;
...@@ -2856,7 +2855,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2856,7 +2855,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Control* c = control_at(imm.depth); Control* c = control_at(imm.depth);
TypeCheckBranchResult check_result = TypeCheckBranch(c, false, 0); TypeCheckBranchResult check_result = TypeCheckBranch(c, false, 0);
if (V8_LIKELY(check_result == kReachableBranch)) { if (V8_LIKELY(check_result == kReachableBranch)) {
CALL_INTERFACE_IF_REACHABLE(BrOrRet, imm.depth, 0); CALL_INTERFACE_IF_OK_AND_REACHABLE(BrOrRet, imm.depth, 0);
c->br_merge()->reached = true; c->br_merge()->reached = true;
} }
EndControl(); EndControl();
...@@ -2870,7 +2869,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2870,7 +2869,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Control* c = control_at(imm.depth); Control* c = control_at(imm.depth);
TypeCheckBranchResult check_result = TypeCheckBranch(c, true, 1); TypeCheckBranchResult check_result = TypeCheckBranch(c, true, 1);
if (V8_LIKELY(check_result == kReachableBranch)) { if (V8_LIKELY(check_result == kReachableBranch)) {
CALL_INTERFACE_IF_REACHABLE(BrIf, cond, imm.depth); CALL_INTERFACE_IF_OK_AND_REACHABLE(BrIf, cond, imm.depth);
c->br_merge()->reached = true; c->br_merge()->reached = true;
} }
Drop(cond); Drop(cond);
...@@ -2916,8 +2915,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2916,8 +2915,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
DCHECK(this->ok()); DCHECK(this->ok());
if (current_code_reachable_) { if (current_code_reachable_and_ok_) {
CALL_INTERFACE(BrTable, imm, key); CALL_INTERFACE_IF_OK_AND_REACHABLE(BrTable, imm, key);
for (int i = 0, e = control_depth(); i < e; ++i) { for (int i = 0, e = control_depth(); i < e; ++i) {
if (!br_targets[i]) continue; if (!br_targets[i]) continue;
...@@ -2930,7 +2929,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2930,7 +2929,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
} }
DECODE(Return) { DECODE(Return) {
if (V8_LIKELY(current_code_reachable_)) { if (V8_LIKELY(current_code_reachable_and_ok_)) {
if (!VALIDATE(TypeCheckReturn())) return 0; if (!VALIDATE(TypeCheckReturn())) return 0;
DoReturn(); DoReturn();
} else { } else {
...@@ -2949,7 +2948,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2949,7 +2948,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
} }
DECODE(Unreachable) { DECODE(Unreachable) {
CALL_INTERFACE_IF_REACHABLE(Trap, TrapReason::kTrapUnreachable); CALL_INTERFACE_IF_OK_AND_REACHABLE(Trap, TrapReason::kTrapUnreachable);
EndControl(); EndControl();
return 1; return 1;
} }
...@@ -2957,7 +2956,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2957,7 +2956,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
DECODE(I32Const) { DECODE(I32Const) {
ImmI32Immediate<validate> imm(this, this->pc_ + 1); ImmI32Immediate<validate> imm(this, this->pc_ + 1);
Value value = CreateValue(kWasmI32); Value value = CreateValue(kWasmI32);
CALL_INTERFACE_IF_REACHABLE(I32Const, &value, imm.value); CALL_INTERFACE_IF_OK_AND_REACHABLE(I32Const, &value, imm.value);
Push(value); Push(value);
return 1 + imm.length; return 1 + imm.length;
} }
...@@ -2965,7 +2964,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2965,7 +2964,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
DECODE(I64Const) { DECODE(I64Const) {
ImmI64Immediate<validate> imm(this, this->pc_ + 1); ImmI64Immediate<validate> imm(this, this->pc_ + 1);
Value value = CreateValue(kWasmI64); Value value = CreateValue(kWasmI64);
CALL_INTERFACE_IF_REACHABLE(I64Const, &value, imm.value); CALL_INTERFACE_IF_OK_AND_REACHABLE(I64Const, &value, imm.value);
Push(value); Push(value);
return 1 + imm.length; return 1 + imm.length;
} }
...@@ -2973,7 +2972,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2973,7 +2972,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
DECODE(F32Const) { DECODE(F32Const) {
ImmF32Immediate<validate> imm(this, this->pc_ + 1); ImmF32Immediate<validate> imm(this, this->pc_ + 1);
Value value = CreateValue(kWasmF32); Value value = CreateValue(kWasmF32);
CALL_INTERFACE_IF_REACHABLE(F32Const, &value, imm.value); CALL_INTERFACE_IF_OK_AND_REACHABLE(F32Const, &value, imm.value);
Push(value); Push(value);
return 1 + imm.length; return 1 + imm.length;
} }
...@@ -2981,7 +2980,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2981,7 +2980,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
DECODE(F64Const) { DECODE(F64Const) {
ImmF64Immediate<validate> imm(this, this->pc_ + 1); ImmF64Immediate<validate> imm(this, this->pc_ + 1);
Value value = CreateValue(kWasmF64); Value value = CreateValue(kWasmF64);
CALL_INTERFACE_IF_REACHABLE(F64Const, &value, imm.value); CALL_INTERFACE_IF_OK_AND_REACHABLE(F64Const, &value, imm.value);
Push(value); Push(value);
return 1 + imm.length; return 1 + imm.length;
} }
...@@ -2993,7 +2992,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2993,7 +2992,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
if (!VALIDATE(this->ok())) return 0; if (!VALIDATE(this->ok())) return 0;
ValueType type = ValueType::Ref(imm.type, kNullable); ValueType type = ValueType::Ref(imm.type, kNullable);
Value value = CreateValue(type); Value value = CreateValue(type);
CALL_INTERFACE_IF_REACHABLE(RefNull, type, &value); CALL_INTERFACE_IF_OK_AND_REACHABLE(RefNull, type, &value);
Push(value); Push(value);
return 1 + imm.length; return 1 + imm.length;
} }
...@@ -3004,7 +3003,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3004,7 +3003,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Value result = CreateValue(kWasmI32); Value result = CreateValue(kWasmI32);
switch (value.type.kind()) { switch (value.type.kind()) {
case kOptRef: case kOptRef:
CALL_INTERFACE_IF_REACHABLE(UnOp, kExprRefIsNull, value, &result); CALL_INTERFACE_IF_OK_AND_REACHABLE(UnOp, kExprRefIsNull, value,
&result);
Drop(value); Drop(value);
Push(result); Push(result);
return 1; return 1;
...@@ -3012,9 +3012,9 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3012,9 +3012,9 @@ class WasmFullDecoder : public WasmDecoder<validate> {
// We are in unreachable code, the return value does not matter. // We are in unreachable code, the return value does not matter.
case kRef: case kRef:
// For non-nullable references, the result is always false. // For non-nullable references, the result is always false.
CALL_INTERFACE_IF_REACHABLE(Drop); CALL_INTERFACE_IF_OK_AND_REACHABLE(Drop);
Drop(value); Drop(value);
CALL_INTERFACE_IF_REACHABLE(I32Const, &result, 0); CALL_INTERFACE_IF_OK_AND_REACHABLE(I32Const, &result, 0);
Push(result); Push(result);
return 1; return 1;
default: default:
...@@ -3034,7 +3034,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3034,7 +3034,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
? this->module_->functions[imm.index].sig_index ? this->module_->functions[imm.index].sig_index
: HeapType::kFunc); : HeapType::kFunc);
Value value = CreateValue(ValueType::Ref(heap_type, kNonNullable)); Value value = CreateValue(ValueType::Ref(heap_type, kNonNullable));
CALL_INTERFACE_IF_REACHABLE(RefFunc, imm.index, &value); CALL_INTERFACE_IF_OK_AND_REACHABLE(RefFunc, imm.index, &value);
Push(value); Push(value);
return 1 + imm.length; return 1 + imm.length;
} }
...@@ -3051,7 +3051,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3051,7 +3051,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
case kOptRef: { case kOptRef: {
Value result = Value result =
CreateValue(ValueType::Ref(value.type.heap_type(), kNonNullable)); CreateValue(ValueType::Ref(value.type.heap_type(), kNonNullable));
CALL_INTERFACE_IF_REACHABLE(RefAsNonNull, value, &result); CALL_INTERFACE_IF_OK_AND_REACHABLE(RefAsNonNull, value, &result);
Drop(value); Drop(value);
Push(result); Push(result);
return 1; return 1;
...@@ -3068,7 +3068,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3068,7 +3068,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
LocalIndexImmediate<validate> imm(this, this->pc_ + 1); LocalIndexImmediate<validate> imm(this, this->pc_ + 1);
if (!this->Validate(this->pc_ + 1, imm)) return 0; if (!this->Validate(this->pc_ + 1, imm)) return 0;
Value value = CreateValue(this->local_type(imm.index)); Value value = CreateValue(this->local_type(imm.index));
CALL_INTERFACE_IF_REACHABLE(LocalGet, &value, imm); CALL_INTERFACE_IF_OK_AND_REACHABLE(LocalGet, &value, imm);
Push(value); Push(value);
return 1 + imm.length; return 1 + imm.length;
} }
...@@ -3077,7 +3077,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3077,7 +3077,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
LocalIndexImmediate<validate> imm(this, this->pc_ + 1); LocalIndexImmediate<validate> imm(this, this->pc_ + 1);
if (!this->Validate(this->pc_ + 1, imm)) return 0; if (!this->Validate(this->pc_ + 1, imm)) return 0;
Value value = Peek(0, 0, this->local_type(imm.index)); Value value = Peek(0, 0, this->local_type(imm.index));
CALL_INTERFACE_IF_REACHABLE(LocalSet, value, imm); CALL_INTERFACE_IF_OK_AND_REACHABLE(LocalSet, value, imm);
Drop(value); Drop(value);
return 1 + imm.length; return 1 + imm.length;
} }
...@@ -3088,7 +3088,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3088,7 +3088,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
ValueType local_type = this->local_type(imm.index); ValueType local_type = this->local_type(imm.index);
Value value = Peek(0, 0, local_type); Value value = Peek(0, 0, local_type);
Value result = CreateValue(local_type); Value result = CreateValue(local_type);
CALL_INTERFACE_IF_REACHABLE(LocalTee, value, &result, imm); CALL_INTERFACE_IF_OK_AND_REACHABLE(LocalTee, value, &result, imm);
Drop(value); Drop(value);
Push(result); Push(result);
return 1 + imm.length; return 1 + imm.length;
...@@ -3096,7 +3096,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3096,7 +3096,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
DECODE(Drop) { DECODE(Drop) {
Peek(0, 0); Peek(0, 0);
CALL_INTERFACE_IF_REACHABLE(Drop); CALL_INTERFACE_IF_OK_AND_REACHABLE(Drop);
Drop(1); Drop(1);
return 1; return 1;
} }
...@@ -3105,7 +3105,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3105,7 +3105,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
GlobalIndexImmediate<validate> imm(this, this->pc_ + 1); GlobalIndexImmediate<validate> imm(this, this->pc_ + 1);
if (!this->Validate(this->pc_ + 1, imm)) return 0; if (!this->Validate(this->pc_ + 1, imm)) return 0;
Value result = CreateValue(imm.type); Value result = CreateValue(imm.type);
CALL_INTERFACE_IF_REACHABLE(GlobalGet, &result, imm); CALL_INTERFACE_IF_OK_AND_REACHABLE(GlobalGet, &result, imm);
Push(result); Push(result);
return 1 + imm.length; return 1 + imm.length;
} }
...@@ -3118,7 +3118,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3118,7 +3118,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
return 0; return 0;
} }
Value value = Peek(0, 0, imm.type); Value value = Peek(0, 0, imm.type);
CALL_INTERFACE_IF_REACHABLE(GlobalSet, value, imm); CALL_INTERFACE_IF_OK_AND_REACHABLE(GlobalSet, value, imm);
Drop(value); Drop(value);
return 1 + imm.length; return 1 + imm.length;
} }
...@@ -3129,7 +3129,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3129,7 +3129,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
if (!this->Validate(this->pc_ + 1, imm)) return 0; if (!this->Validate(this->pc_ + 1, imm)) return 0;
Value index = Peek(0, 0, kWasmI32); Value index = Peek(0, 0, kWasmI32);
Value result = CreateValue(this->module_->tables[imm.index].type); Value result = CreateValue(this->module_->tables[imm.index].type);
CALL_INTERFACE_IF_REACHABLE(TableGet, index, &result, imm); CALL_INTERFACE_IF_OK_AND_REACHABLE(TableGet, index, &result, imm);
Drop(index); Drop(index);
Push(result); Push(result);
return 1 + imm.length; return 1 + imm.length;
...@@ -3141,7 +3141,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3141,7 +3141,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
if (!this->Validate(this->pc_ + 1, imm)) return 0; if (!this->Validate(this->pc_ + 1, imm)) return 0;
Value value = Peek(0, 1, this->module_->tables[imm.index].type); Value value = Peek(0, 1, this->module_->tables[imm.index].type);
Value index = Peek(1, 0, kWasmI32); Value index = Peek(1, 0, kWasmI32);
CALL_INTERFACE_IF_REACHABLE(TableSet, index, value, imm); CALL_INTERFACE_IF_OK_AND_REACHABLE(TableSet, index, value, imm);
Drop(2); Drop(2);
return 1 + imm.length; return 1 + imm.length;
} }
...@@ -3188,7 +3188,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3188,7 +3188,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
ValueType mem_type = this->module_->is_memory64 ? kWasmI64 : kWasmI32; ValueType mem_type = this->module_->is_memory64 ? kWasmI64 : kWasmI32;
Value value = Peek(0, 0, mem_type); Value value = Peek(0, 0, mem_type);
Value result = CreateValue(mem_type); Value result = CreateValue(mem_type);
CALL_INTERFACE_IF_REACHABLE(MemoryGrow, value, &result); CALL_INTERFACE_IF_OK_AND_REACHABLE(MemoryGrow, value, &result);
Drop(value); Drop(value);
Push(result); Push(result);
return 1 + imm.length; return 1 + imm.length;
...@@ -3199,7 +3199,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3199,7 +3199,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
MemoryIndexImmediate<validate> imm(this, this->pc_ + 1); MemoryIndexImmediate<validate> imm(this, this->pc_ + 1);
ValueType result_type = this->module_->is_memory64 ? kWasmI64 : kWasmI32; ValueType result_type = this->module_->is_memory64 ? kWasmI64 : kWasmI32;
Value result = CreateValue(result_type); Value result = CreateValue(result_type);
CALL_INTERFACE_IF_REACHABLE(CurrentMemoryPages, &result); CALL_INTERFACE_IF_OK_AND_REACHABLE(CurrentMemoryPages, &result);
Push(result); Push(result);
return 1 + imm.length; return 1 + imm.length;
} }
...@@ -3209,7 +3209,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3209,7 +3209,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
if (!this->Validate(this->pc_ + 1, imm)) return 0; if (!this->Validate(this->pc_ + 1, imm)) return 0;
ArgVector args = PeekArgs(imm.sig); ArgVector args = PeekArgs(imm.sig);
ReturnVector returns = CreateReturnValues(imm.sig); ReturnVector returns = CreateReturnValues(imm.sig);
CALL_INTERFACE_IF_REACHABLE(CallDirect, imm, args.begin(), returns.begin()); CALL_INTERFACE_IF_OK_AND_REACHABLE(CallDirect, imm, args.begin(),
returns.begin());
DropArgs(imm.sig); DropArgs(imm.sig);
PushReturns(returns); PushReturns(returns);
return 1 + imm.length; return 1 + imm.length;
...@@ -3221,8 +3222,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3221,8 +3222,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Value index = Peek(0, 0, kWasmI32); Value index = Peek(0, 0, kWasmI32);
ArgVector args = PeekArgs(imm.sig, 1); ArgVector args = PeekArgs(imm.sig, 1);
ReturnVector returns = CreateReturnValues(imm.sig); ReturnVector returns = CreateReturnValues(imm.sig);
CALL_INTERFACE_IF_REACHABLE(CallIndirect, index, imm, args.begin(), CALL_INTERFACE_IF_OK_AND_REACHABLE(CallIndirect, index, imm, args.begin(),
returns.begin()); returns.begin());
Drop(index); Drop(index);
DropArgs(imm.sig); DropArgs(imm.sig);
PushReturns(returns); PushReturns(returns);
...@@ -3239,7 +3240,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3239,7 +3240,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
return 0; return 0;
} }
ArgVector args = PeekArgs(imm.sig); ArgVector args = PeekArgs(imm.sig);
CALL_INTERFACE_IF_REACHABLE(ReturnCall, imm, args.begin()); CALL_INTERFACE_IF_OK_AND_REACHABLE(ReturnCall, imm, args.begin());
DropArgs(imm.sig); DropArgs(imm.sig);
EndControl(); EndControl();
return 1 + imm.length; return 1 + imm.length;
...@@ -3257,7 +3258,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3257,7 +3258,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
} }
Value index = Peek(0, 0, kWasmI32); Value index = Peek(0, 0, kWasmI32);
ArgVector args = PeekArgs(imm.sig, 1); ArgVector args = PeekArgs(imm.sig, 1);
CALL_INTERFACE_IF_REACHABLE(ReturnCallIndirect, index, imm, args.begin()); CALL_INTERFACE_IF_OK_AND_REACHABLE(ReturnCallIndirect, index, imm,
args.begin());
Drop(index); Drop(index);
DropArgs(imm.sig); DropArgs(imm.sig);
EndControl(); EndControl();
...@@ -3280,8 +3282,9 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3280,8 +3282,9 @@ class WasmFullDecoder : public WasmDecoder<validate> {
const FunctionSig* sig = this->module_->signature(func_type.ref_index()); const FunctionSig* sig = this->module_->signature(func_type.ref_index());
ArgVector args = PeekArgs(sig, 1); ArgVector args = PeekArgs(sig, 1);
ReturnVector returns = CreateReturnValues(sig); ReturnVector returns = CreateReturnValues(sig);
CALL_INTERFACE_IF_REACHABLE(CallRef, func_ref, sig, func_type.ref_index(), CALL_INTERFACE_IF_OK_AND_REACHABLE(CallRef, func_ref, sig,
args.begin(), returns.begin()); func_type.ref_index(), args.begin(),
returns.begin());
Drop(func_ref); Drop(func_ref);
DropArgs(sig); DropArgs(sig);
PushReturns(returns); PushReturns(returns);
...@@ -3304,8 +3307,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3304,8 +3307,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
} }
const FunctionSig* sig = this->module_->signature(func_type.ref_index()); const FunctionSig* sig = this->module_->signature(func_type.ref_index());
ArgVector args = PeekArgs(sig, 1); ArgVector args = PeekArgs(sig, 1);
CALL_INTERFACE_IF_REACHABLE(ReturnCallRef, func_ref, sig, CALL_INTERFACE_IF_OK_AND_REACHABLE(ReturnCallRef, func_ref, sig,
func_type.ref_index(), args.begin()); func_type.ref_index(), args.begin());
Drop(func_ref); Drop(func_ref);
DropArgs(sig); DropArgs(sig);
EndControl(); EndControl();
...@@ -3484,7 +3487,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3484,7 +3487,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
[&](uint32_t i) { [&](uint32_t i) {
return Value{this->pc_, this->sig_->GetReturn(i)}; return Value{this->pc_, this->sig_->GetReturn(i)};
}); });
CALL_INTERFACE(StartFunctionBody, c); CALL_INTERFACE_IF_OK_AND_REACHABLE(StartFunctionBody, c);
} }
// Decode the function body. // Decode the function body.
...@@ -3496,7 +3499,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3496,7 +3499,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
EnsureStackSpace(1); EnsureStackSpace(1);
uint8_t first_byte = *this->pc_; uint8_t first_byte = *this->pc_;
WasmOpcode opcode = static_cast<WasmOpcode>(first_byte); WasmOpcode opcode = static_cast<WasmOpcode>(first_byte);
CALL_INTERFACE_IF_REACHABLE(NextInstruction, opcode); CALL_INTERFACE_IF_OK_AND_REACHABLE(NextInstruction, opcode);
int len; int len;
// Allowing two of the most common decoding functions to get inlined // Allowing two of the most common decoding functions to get inlined
// appears to be the sweet spot. // appears to be the sweet spot.
...@@ -3523,9 +3526,9 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3523,9 +3526,9 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Control* current = &control_.back(); Control* current = &control_.back();
DCHECK_LE(stack_ + current->stack_depth, stack_end_); DCHECK_LE(stack_ + current->stack_depth, stack_end_);
stack_end_ = stack_ + current->stack_depth; stack_end_ = stack_ + current->stack_depth;
CALL_INTERFACE_IF_REACHABLE(EndControl, current); CALL_INTERFACE_IF_OK_AND_REACHABLE(EndControl, current);
current->reachability = kUnreachable; current->reachability = kUnreachable;
current_code_reachable_ = false; current_code_reachable_and_ok_ = false;
} }
template <typename func> template <typename func>
...@@ -3635,7 +3638,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3635,7 +3638,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
stack_depth = std::max(stack_depth, control_.back().stack_depth); stack_depth = std::max(stack_depth, control_.back().stack_depth);
control_.emplace_back(kind, locals_count, stack_depth, this->pc_, control_.emplace_back(kind, locals_count, stack_depth, this->pc_,
reachability); reachability);
current_code_reachable_ = this->ok() && reachability == kReachable; current_code_reachable_and_ok_ = this->ok() && reachability == kReachable;
return &control_.back(); return &control_.back();
} }
...@@ -3644,7 +3647,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3644,7 +3647,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
DCHECK_LT(1, control_.size()); DCHECK_LT(1, control_.size());
DCHECK_EQ(c, &control_.back()); DCHECK_EQ(c, &control_.back());
CALL_INTERFACE_IF_PARENT_REACHABLE(PopControl, c); CALL_INTERFACE_IF_OK_AND_PARENT_REACHABLE(PopControl, c);
// A loop just leaves the values on the stack. // A loop just leaves the values on the stack.
if (!c->is_loop()) PushMergeValues(c, &c->end_merge); if (!c->is_loop()) PushMergeValues(c, &c->end_merge);
...@@ -3655,7 +3658,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3655,7 +3658,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
// If the parent block was reachable before, but the popped control does not // If the parent block was reachable before, but the popped control does not
// return to here, this block becomes "spec only reachable". // return to here, this block becomes "spec only reachable".
if (!parent_reached) SetSucceedingCodeDynamicallyUnreachable(); if (!parent_reached) SetSucceedingCodeDynamicallyUnreachable();
current_code_reachable_ = control_.back().reachable(); current_code_reachable_and_ok_ = control_.back().reachable();
} }
int DecodeLoadMem(LoadType type, int prefix_len = 1) { int DecodeLoadMem(LoadType type, int prefix_len = 1) {
...@@ -3665,7 +3668,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3665,7 +3668,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
ValueType index_type = this->module_->is_memory64 ? kWasmI64 : kWasmI32; ValueType index_type = this->module_->is_memory64 ? kWasmI64 : kWasmI32;
Value index = Peek(0, 0, index_type); Value index = Peek(0, 0, index_type);
Value result = CreateValue(type.value_type()); Value result = CreateValue(type.value_type());
CALL_INTERFACE_IF_REACHABLE(LoadMem, type, imm, index, &result); CALL_INTERFACE_IF_OK_AND_REACHABLE(LoadMem, type, imm, index, &result);
Drop(index); Drop(index);
Push(result); Push(result);
return prefix_len + imm.length; return prefix_len + imm.length;
...@@ -3682,8 +3685,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3682,8 +3685,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
ValueType index_type = this->module_->is_memory64 ? kWasmI64 : kWasmI32; ValueType index_type = this->module_->is_memory64 ? kWasmI64 : kWasmI32;
Value index = Peek(0, 0, index_type); Value index = Peek(0, 0, index_type);
Value result = CreateValue(kWasmS128); Value result = CreateValue(kWasmS128);
CALL_INTERFACE_IF_REACHABLE(LoadTransform, type, transform, imm, index, CALL_INTERFACE_IF_OK_AND_REACHABLE(LoadTransform, type, transform, imm,
&result); index, &result);
Drop(index); Drop(index);
Push(result); Push(result);
return opcode_length + imm.length; return opcode_length + imm.length;
...@@ -3700,8 +3703,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3700,8 +3703,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Value index = Peek(1, 0, kWasmI32); Value index = Peek(1, 0, kWasmI32);
Value result = CreateValue(kWasmS128); Value result = CreateValue(kWasmS128);
CALL_INTERFACE_IF_REACHABLE(LoadLane, type, v128, index, mem_imm, CALL_INTERFACE_IF_OK_AND_REACHABLE(LoadLane, type, v128, index, mem_imm,
lane_imm.lane, &result); lane_imm.lane, &result);
Drop(2); Drop(2);
Push(result); Push(result);
return opcode_length + mem_imm.length + lane_imm.length; return opcode_length + mem_imm.length + lane_imm.length;
...@@ -3718,8 +3721,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3718,8 +3721,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Value v128 = Peek(0, 1, kWasmS128); Value v128 = Peek(0, 1, kWasmS128);
Value index = Peek(1, 0, kWasmI32); Value index = Peek(1, 0, kWasmI32);
CALL_INTERFACE_IF_REACHABLE(StoreLane, type, mem_imm, index, v128, CALL_INTERFACE_IF_OK_AND_REACHABLE(StoreLane, type, mem_imm, index, v128,
lane_imm.lane); lane_imm.lane);
Drop(2); Drop(2);
return opcode_length + mem_imm.length + lane_imm.length; return opcode_length + mem_imm.length + lane_imm.length;
} }
...@@ -3731,7 +3734,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3731,7 +3734,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Value value = Peek(0, 1, store.value_type()); Value value = Peek(0, 1, store.value_type());
ValueType index_type = this->module_->is_memory64 ? kWasmI64 : kWasmI32; ValueType index_type = this->module_->is_memory64 ? kWasmI64 : kWasmI32;
Value index = Peek(1, 0, index_type); Value index = Peek(1, 0, index_type);
CALL_INTERFACE_IF_REACHABLE(StoreMem, store, imm, index, value); CALL_INTERFACE_IF_OK_AND_REACHABLE(StoreMem, store, imm, index, value);
Drop(2); Drop(2);
return prefix_len + imm.length; return prefix_len + imm.length;
} }
...@@ -3825,7 +3828,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3825,7 +3828,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
uint32_t SimdConstOp(uint32_t opcode_length) { uint32_t SimdConstOp(uint32_t opcode_length) {
Simd128Immediate<validate> imm(this, this->pc_ + opcode_length); Simd128Immediate<validate> imm(this, this->pc_ + opcode_length);
Value result = CreateValue(kWasmS128); Value result = CreateValue(kWasmS128);
CALL_INTERFACE_IF_REACHABLE(S128Const, imm, &result); CALL_INTERFACE_IF_OK_AND_REACHABLE(S128Const, imm, &result);
Push(result); Push(result);
return opcode_length + kSimd128Size; return opcode_length + kSimd128Size;
} }
...@@ -3836,8 +3839,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3836,8 +3839,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
if (this->Validate(this->pc_ + opcode_length, opcode, imm)) { if (this->Validate(this->pc_ + opcode_length, opcode, imm)) {
Value inputs[] = {Peek(0, 0, kWasmS128)}; Value inputs[] = {Peek(0, 0, kWasmS128)};
Value result = CreateValue(type); Value result = CreateValue(type);
CALL_INTERFACE_IF_REACHABLE(SimdLaneOp, opcode, imm, ArrayVector(inputs), CALL_INTERFACE_IF_OK_AND_REACHABLE(SimdLaneOp, opcode, imm,
&result); ArrayVector(inputs), &result);
Drop(1); Drop(1);
Push(result); Push(result);
} }
...@@ -3850,8 +3853,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3850,8 +3853,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
if (this->Validate(this->pc_ + opcode_length, opcode, imm)) { if (this->Validate(this->pc_ + opcode_length, opcode, imm)) {
Value inputs[2] = {Peek(1, 0, kWasmS128), Peek(0, 1, type)}; Value inputs[2] = {Peek(1, 0, kWasmS128), Peek(0, 1, type)};
Value result = CreateValue(kWasmS128); Value result = CreateValue(kWasmS128);
CALL_INTERFACE_IF_REACHABLE(SimdLaneOp, opcode, imm, ArrayVector(inputs), CALL_INTERFACE_IF_OK_AND_REACHABLE(SimdLaneOp, opcode, imm,
&result); ArrayVector(inputs), &result);
Drop(2); Drop(2);
Push(result); Push(result);
} }
...@@ -3864,8 +3867,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3864,8 +3867,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Value input1 = Peek(0, 1, kWasmS128); Value input1 = Peek(0, 1, kWasmS128);
Value input0 = Peek(1, 0, kWasmS128); Value input0 = Peek(1, 0, kWasmS128);
Value result = CreateValue(kWasmS128); Value result = CreateValue(kWasmS128);
CALL_INTERFACE_IF_REACHABLE(Simd8x16ShuffleOp, imm, input0, input1, CALL_INTERFACE_IF_OK_AND_REACHABLE(Simd8x16ShuffleOp, imm, input0, input1,
&result); &result);
Drop(2); Drop(2);
Push(result); Push(result);
} }
...@@ -3984,12 +3987,13 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -3984,12 +3987,13 @@ class WasmFullDecoder : public WasmDecoder<validate> {
} }
ArgVector args = PeekArgs(sig); ArgVector args = PeekArgs(sig);
if (sig->return_count() == 0) { if (sig->return_count() == 0) {
CALL_INTERFACE_IF_REACHABLE(SimdOp, opcode, VectorOf(args), nullptr); CALL_INTERFACE_IF_OK_AND_REACHABLE(SimdOp, opcode, VectorOf(args),
nullptr);
DropArgs(sig); DropArgs(sig);
} else { } else {
ReturnVector results = CreateReturnValues(sig); ReturnVector results = CreateReturnValues(sig);
CALL_INTERFACE_IF_REACHABLE(SimdOp, opcode, VectorOf(args), CALL_INTERFACE_IF_OK_AND_REACHABLE(SimdOp, opcode, VectorOf(args),
results.begin()); results.begin());
DropArgs(sig); DropArgs(sig);
PushReturns(results); PushReturns(results);
} }
...@@ -4027,8 +4031,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4027,8 +4031,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
} }
ArgVector args = PeekArgs(imm.struct_type, 1); ArgVector args = PeekArgs(imm.struct_type, 1);
Value value = CreateValue(ValueType::Ref(imm.index, kNonNullable)); Value value = CreateValue(ValueType::Ref(imm.index, kNonNullable));
CALL_INTERFACE_IF_REACHABLE(StructNewWithRtt, imm, rtt, args.begin(), CALL_INTERFACE_IF_OK_AND_REACHABLE(StructNewWithRtt, imm, rtt,
&value); args.begin(), &value);
Drop(rtt); Drop(rtt);
DropArgs(imm.struct_type); DropArgs(imm.struct_type);
Push(value); Push(value);
...@@ -4063,7 +4067,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4063,7 +4067,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
return 0; return 0;
} }
Value value = CreateValue(ValueType::Ref(imm.index, kNonNullable)); Value value = CreateValue(ValueType::Ref(imm.index, kNonNullable));
CALL_INTERFACE_IF_REACHABLE(StructNewDefault, imm, rtt, &value); CALL_INTERFACE_IF_OK_AND_REACHABLE(StructNewDefault, imm, rtt, &value);
Drop(rtt); Drop(rtt);
Push(value); Push(value);
return opcode_length + imm.length; return opcode_length + imm.length;
...@@ -4083,7 +4087,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4083,7 +4087,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Value struct_obj = Value struct_obj =
Peek(0, 0, ValueType::Ref(field.struct_index.index, kNullable)); Peek(0, 0, ValueType::Ref(field.struct_index.index, kNullable));
Value value = CreateValue(field_type); Value value = CreateValue(field_type);
CALL_INTERFACE_IF_REACHABLE(StructGet, struct_obj, field, true, &value); CALL_INTERFACE_IF_OK_AND_REACHABLE(StructGet, struct_obj, field, true,
&value);
Drop(struct_obj); Drop(struct_obj);
Push(value); Push(value);
return opcode_length + field.length; return opcode_length + field.length;
...@@ -4105,8 +4110,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4105,8 +4110,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Value struct_obj = Value struct_obj =
Peek(0, 0, ValueType::Ref(field.struct_index.index, kNullable)); Peek(0, 0, ValueType::Ref(field.struct_index.index, kNullable));
Value value = CreateValue(field_type.Unpacked()); Value value = CreateValue(field_type.Unpacked());
CALL_INTERFACE_IF_REACHABLE(StructGet, struct_obj, field, CALL_INTERFACE_IF_OK_AND_REACHABLE(StructGet, struct_obj, field,
opcode == kExprStructGetS, &value); opcode == kExprStructGetS, &value);
Drop(struct_obj); Drop(struct_obj);
Push(value); Push(value);
return opcode_length + field.length; return opcode_length + field.length;
...@@ -4124,7 +4129,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4124,7 +4129,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Peek(0, 1, struct_type->field(field.index).Unpacked()); Peek(0, 1, struct_type->field(field.index).Unpacked());
Value struct_obj = Value struct_obj =
Peek(1, 0, ValueType::Ref(field.struct_index.index, kNullable)); Peek(1, 0, ValueType::Ref(field.struct_index.index, kNullable));
CALL_INTERFACE_IF_REACHABLE(StructSet, struct_obj, field, field_value); CALL_INTERFACE_IF_OK_AND_REACHABLE(StructSet, struct_obj, field,
field_value);
Drop(2); Drop(2);
return opcode_length + field.length; return opcode_length + field.length;
} }
...@@ -4148,8 +4154,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4148,8 +4154,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Value initial_value = Value initial_value =
Peek(2, 0, imm.array_type->element_type().Unpacked()); Peek(2, 0, imm.array_type->element_type().Unpacked());
Value value = CreateValue(ValueType::Ref(imm.index, kNonNullable)); Value value = CreateValue(ValueType::Ref(imm.index, kNonNullable));
CALL_INTERFACE_IF_REACHABLE(ArrayNewWithRtt, imm, length, initial_value, CALL_INTERFACE_IF_OK_AND_REACHABLE(ArrayNewWithRtt, imm, length,
rtt, &value); initial_value, rtt, &value);
Drop(3); // rtt, length, initial_value. Drop(3); // rtt, length, initial_value.
Push(value); Push(value);
return opcode_length + imm.length; return opcode_length + imm.length;
...@@ -4179,7 +4185,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4179,7 +4185,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
} }
Value length = Peek(1, 0, kWasmI32); Value length = Peek(1, 0, kWasmI32);
Value value = CreateValue(ValueType::Ref(imm.index, kNonNullable)); Value value = CreateValue(ValueType::Ref(imm.index, kNonNullable));
CALL_INTERFACE_IF_REACHABLE(ArrayNewDefault, imm, length, rtt, &value); CALL_INTERFACE_IF_OK_AND_REACHABLE(ArrayNewDefault, imm, length, rtt,
&value);
Drop(2); // rtt, length Drop(2); // rtt, length
Push(value); Push(value);
return opcode_length + imm.length; return opcode_length + imm.length;
...@@ -4199,8 +4206,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4199,8 +4206,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Value index = Peek(0, 1, kWasmI32); Value index = Peek(0, 1, kWasmI32);
Value array_obj = Peek(1, 0, ValueType::Ref(imm.index, kNullable)); Value array_obj = Peek(1, 0, ValueType::Ref(imm.index, kNullable));
Value value = CreateValue(imm.array_type->element_type().Unpacked()); Value value = CreateValue(imm.array_type->element_type().Unpacked());
CALL_INTERFACE_IF_REACHABLE(ArrayGet, array_obj, imm, index, CALL_INTERFACE_IF_OK_AND_REACHABLE(ArrayGet, array_obj, imm, index,
opcode == kExprArrayGetS, &value); opcode == kExprArrayGetS, &value);
Drop(2); // index, array_obj Drop(2); // index, array_obj
Push(value); Push(value);
return opcode_length + imm.length; return opcode_length + imm.length;
...@@ -4218,8 +4225,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4218,8 +4225,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Value index = Peek(0, 1, kWasmI32); Value index = Peek(0, 1, kWasmI32);
Value array_obj = Peek(1, 0, ValueType::Ref(imm.index, kNullable)); Value array_obj = Peek(1, 0, ValueType::Ref(imm.index, kNullable));
Value value = CreateValue(imm.array_type->element_type()); Value value = CreateValue(imm.array_type->element_type());
CALL_INTERFACE_IF_REACHABLE(ArrayGet, array_obj, imm, index, true, CALL_INTERFACE_IF_OK_AND_REACHABLE(ArrayGet, array_obj, imm, index,
&value); true, &value);
Drop(2); // index, array_obj Drop(2); // index, array_obj
Push(value); Push(value);
return opcode_length + imm.length; return opcode_length + imm.length;
...@@ -4235,7 +4242,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4235,7 +4242,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Value value = Peek(0, 2, imm.array_type->element_type().Unpacked()); Value value = Peek(0, 2, imm.array_type->element_type().Unpacked());
Value index = Peek(1, 1, kWasmI32); Value index = Peek(1, 1, kWasmI32);
Value array_obj = Peek(2, 0, ValueType::Ref(imm.index, kNullable)); Value array_obj = Peek(2, 0, ValueType::Ref(imm.index, kNullable));
CALL_INTERFACE_IF_REACHABLE(ArraySet, array_obj, imm, index, value); CALL_INTERFACE_IF_OK_AND_REACHABLE(ArraySet, array_obj, imm, index,
value);
Drop(3); Drop(3);
return opcode_length + imm.length; return opcode_length + imm.length;
} }
...@@ -4244,7 +4252,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4244,7 +4252,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
if (!this->Validate(this->pc_ + opcode_length, imm)) return 0; if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
Value array_obj = Peek(0, 0, ValueType::Ref(imm.index, kNullable)); Value array_obj = Peek(0, 0, ValueType::Ref(imm.index, kNullable));
Value value = CreateValue(kWasmI32); Value value = CreateValue(kWasmI32);
CALL_INTERFACE_IF_REACHABLE(ArrayLen, array_obj, &value); CALL_INTERFACE_IF_OK_AND_REACHABLE(ArrayLen, array_obj, &value);
Drop(array_obj); Drop(array_obj);
Push(value); Push(value);
return opcode_length + imm.length; return opcode_length + imm.length;
...@@ -4252,7 +4260,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4252,7 +4260,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
case kExprI31New: { case kExprI31New: {
Value input = Peek(0, 0, kWasmI32); Value input = Peek(0, 0, kWasmI32);
Value value = CreateValue(kWasmI31Ref); Value value = CreateValue(kWasmI31Ref);
CALL_INTERFACE_IF_REACHABLE(I31New, input, &value); CALL_INTERFACE_IF_OK_AND_REACHABLE(I31New, input, &value);
Drop(input); Drop(input);
Push(value); Push(value);
return opcode_length; return opcode_length;
...@@ -4260,7 +4268,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4260,7 +4268,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
case kExprI31GetS: { case kExprI31GetS: {
Value i31 = Peek(0, 0, kWasmI31Ref); Value i31 = Peek(0, 0, kWasmI31Ref);
Value value = CreateValue(kWasmI32); Value value = CreateValue(kWasmI32);
CALL_INTERFACE_IF_REACHABLE(I31GetS, i31, &value); CALL_INTERFACE_IF_OK_AND_REACHABLE(I31GetS, i31, &value);
Drop(i31); Drop(i31);
Push(value); Push(value);
return opcode_length; return opcode_length;
...@@ -4268,7 +4276,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4268,7 +4276,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
case kExprI31GetU: { case kExprI31GetU: {
Value i31 = Peek(0, 0, kWasmI31Ref); Value i31 = Peek(0, 0, kWasmI31Ref);
Value value = CreateValue(kWasmI32); Value value = CreateValue(kWasmI32);
CALL_INTERFACE_IF_REACHABLE(I31GetU, i31, &value); CALL_INTERFACE_IF_OK_AND_REACHABLE(I31GetU, i31, &value);
Drop(i31); Drop(i31);
Push(value); Push(value);
return opcode_length; return opcode_length;
...@@ -4277,7 +4285,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4277,7 +4285,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
TypeIndexImmediate<validate> imm(this, this->pc_ + opcode_length); TypeIndexImmediate<validate> imm(this, this->pc_ + opcode_length);
if (!this->Validate(this->pc_ + opcode_length, imm)) return 0; if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
Value value = CreateValue(ValueType::Rtt(imm.index, 0)); Value value = CreateValue(ValueType::Rtt(imm.index, 0));
CALL_INTERFACE_IF_REACHABLE(RttCanon, imm.index, &value); CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &value);
Push(value); Push(value);
return opcode_length + imm.length; return opcode_length + imm.length;
} }
...@@ -4286,7 +4294,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4286,7 +4294,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
if (!this->Validate(this->pc_ + opcode_length, imm)) return 0; if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
Value parent = Peek(0, 0); Value parent = Peek(0, 0);
if (parent.type.is_bottom()) { if (parent.type.is_bottom()) {
DCHECK(!current_code_reachable_); DCHECK(!current_code_reachable_and_ok_);
// Just leave the unreachable/bottom value on the stack. // Just leave the unreachable/bottom value on the stack.
} else { } else {
if (!VALIDATE(parent.type.is_rtt() && if (!VALIDATE(parent.type.is_rtt() &&
...@@ -4302,7 +4310,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4302,7 +4310,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
imm.index, parent.type.depth() + 1)) imm.index, parent.type.depth() + 1))
: CreateValue(ValueType::Rtt(imm.index)); : CreateValue(ValueType::Rtt(imm.index));
CALL_INTERFACE_IF_REACHABLE(RttSub, imm.index, parent, &value); CALL_INTERFACE_IF_OK_AND_REACHABLE(RttSub, imm.index, parent, &value);
Drop(parent); Drop(parent);
Push(value); Push(value);
} }
...@@ -4329,10 +4337,10 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4329,10 +4337,10 @@ class WasmFullDecoder : public WasmDecoder<validate> {
// This logic ensures that code generation can assume that functions // This logic ensures that code generation can assume that functions
// can only be cast to function types, and data objects to data types. // can only be cast to function types, and data objects to data types.
if (V8_LIKELY(ObjectRelatedWithRtt(obj, rtt))) { if (V8_LIKELY(ObjectRelatedWithRtt(obj, rtt))) {
CALL_INTERFACE_IF_REACHABLE(RefTest, obj, rtt, &value); CALL_INTERFACE_IF_OK_AND_REACHABLE(RefTest, obj, rtt, &value);
} else { } else {
// Unrelated types. Will always fail. // Unrelated types. Will always fail.
CALL_INTERFACE_IF_REACHABLE(I32Const, &value, 0); CALL_INTERFACE_IF_OK_AND_REACHABLE(I32Const, &value, 0);
} }
} }
Drop(2); Drop(2);
...@@ -4360,17 +4368,18 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4360,17 +4368,18 @@ class WasmFullDecoder : public WasmDecoder<validate> {
// This logic ensures that code generation can assume that functions // This logic ensures that code generation can assume that functions
// can only be cast to function types, and data objects to data types. // can only be cast to function types, and data objects to data types.
if (V8_LIKELY(ObjectRelatedWithRtt(obj, rtt))) { if (V8_LIKELY(ObjectRelatedWithRtt(obj, rtt))) {
CALL_INTERFACE_IF_REACHABLE(RefCast, obj, rtt, &value); CALL_INTERFACE_IF_OK_AND_REACHABLE(RefCast, obj, rtt, &value);
} else { } else {
// Unrelated types. The only way this will not trap is if the object // Unrelated types. The only way this will not trap is if the object
// is null. // is null.
if (obj.type.is_nullable()) { if (obj.type.is_nullable()) {
// Drop rtt from the stack, then assert that obj is null. // Drop rtt from the stack, then assert that obj is null.
CALL_INTERFACE_IF_REACHABLE(Drop); CALL_INTERFACE_IF_OK_AND_REACHABLE(Drop);
CALL_INTERFACE_IF_REACHABLE(AssertNull, obj, &value); CALL_INTERFACE_IF_OK_AND_REACHABLE(AssertNull, obj, &value);
} else { } else {
// TODO(manoskouk): Change the trap label. // TODO(manoskouk): Change the trap label.
CALL_INTERFACE_IF_REACHABLE(Trap, TrapReason::kTrapIllegalCast); CALL_INTERFACE_IF_OK_AND_REACHABLE(Trap,
TrapReason::kTrapIllegalCast);
EndControl(); EndControl();
} }
} }
...@@ -4426,8 +4435,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4426,8 +4435,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
// be pointer-identical to the object on the stack, so we can't // be pointer-identical to the object on the stack, so we can't
// reuse {result_on_branch} which was passed-by-value to {Push}. // reuse {result_on_branch} which was passed-by-value to {Push}.
Value* value_on_branch = stack_value(1); Value* value_on_branch = stack_value(1);
CALL_INTERFACE(BrOnCast, obj, rtt, value_on_branch, CALL_INTERFACE_IF_OK_AND_REACHABLE(
branch_depth.depth); BrOnCast, obj, rtt, value_on_branch, branch_depth.depth);
c->br_merge()->reached = true; c->br_merge()->reached = true;
} }
// Otherwise the types are unrelated. Do not branch. // Otherwise the types are unrelated. Do not branch.
...@@ -4438,14 +4447,14 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4438,14 +4447,14 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Push(obj); // Restore stack state on fallthrough. Push(obj); // Restore stack state on fallthrough.
return opcode_length + branch_depth.length; return opcode_length + branch_depth.length;
} }
#define ABSTRACT_TYPE_CHECK(heap_type) \ #define ABSTRACT_TYPE_CHECK(heap_type) \
case kExprRefIs##heap_type: { \ case kExprRefIs##heap_type: { \
Value arg = Peek(0, 0, kWasmAnyRef); \ Value arg = Peek(0, 0, kWasmAnyRef); \
Value result = CreateValue(kWasmI32); \ Value result = CreateValue(kWasmI32); \
CALL_INTERFACE_IF_REACHABLE(RefIs##heap_type, arg, &result); \ CALL_INTERFACE_IF_OK_AND_REACHABLE(RefIs##heap_type, arg, &result); \
Drop(arg); \ Drop(arg); \
Push(result); \ Push(result); \
return opcode_length; \ return opcode_length; \
} }
ABSTRACT_TYPE_CHECK(Data) ABSTRACT_TYPE_CHECK(Data)
...@@ -4459,7 +4468,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4459,7 +4468,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
if (!arg.type.is_bottom()) { \ if (!arg.type.is_bottom()) { \
Value result = \ Value result = \
CreateValue(ValueType::Ref(HeapType::k##heap_type, kNonNullable)); \ CreateValue(ValueType::Ref(HeapType::k##heap_type, kNonNullable)); \
CALL_INTERFACE_IF_REACHABLE(RefAs##heap_type, arg, &result); \ CALL_INTERFACE_IF_OK_AND_REACHABLE(RefAs##heap_type, arg, &result); \
Drop(arg); \ Drop(arg); \
Push(result); \ Push(result); \
} \ } \
...@@ -4508,11 +4517,14 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4508,11 +4517,14 @@ class WasmFullDecoder : public WasmDecoder<validate> {
// {result_on_branch} which was passed-by-value to {Push}. // {result_on_branch} which was passed-by-value to {Push}.
Value* value_on_branch = stack_value(1); Value* value_on_branch = stack_value(1);
if (opcode == kExprBrOnFunc) { if (opcode == kExprBrOnFunc) {
CALL_INTERFACE(BrOnFunc, obj, value_on_branch, branch_depth.depth); CALL_INTERFACE_IF_OK_AND_REACHABLE(BrOnFunc, obj, value_on_branch,
branch_depth.depth);
} else if (opcode == kExprBrOnData) { } else if (opcode == kExprBrOnData) {
CALL_INTERFACE(BrOnData, obj, value_on_branch, branch_depth.depth); CALL_INTERFACE_IF_OK_AND_REACHABLE(BrOnData, obj, value_on_branch,
branch_depth.depth);
} else { } else {
CALL_INTERFACE(BrOnI31, obj, value_on_branch, branch_depth.depth); CALL_INTERFACE_IF_OK_AND_REACHABLE(BrOnI31, obj, value_on_branch,
branch_depth.depth);
} }
c->br_merge()->reached = true; c->br_merge()->reached = true;
} else if (check_result == kInvalidStack) { } else if (check_result == kInvalidStack) {
...@@ -4561,7 +4573,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4561,7 +4573,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
"invalid atomic operand"); "invalid atomic operand");
return 0; return 0;
} }
CALL_INTERFACE_IF_REACHABLE(AtomicFence); CALL_INTERFACE_IF_OK_AND_REACHABLE(AtomicFence);
return 1 + opcode_length; return 1 + opcode_length;
} }
default: default:
...@@ -4577,13 +4589,13 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4577,13 +4589,13 @@ class WasmFullDecoder : public WasmDecoder<validate> {
CHECK(!this->module_->is_memory64); CHECK(!this->module_->is_memory64);
ArgVector args = PeekArgs(sig); ArgVector args = PeekArgs(sig);
if (ret_type == kWasmVoid) { if (ret_type == kWasmVoid) {
CALL_INTERFACE_IF_REACHABLE(AtomicOp, opcode, VectorOf(args), imm, CALL_INTERFACE_IF_OK_AND_REACHABLE(AtomicOp, opcode, VectorOf(args), imm,
nullptr); nullptr);
DropArgs(sig); DropArgs(sig);
} else { } else {
Value result = CreateValue(GetReturnType(sig)); Value result = CreateValue(GetReturnType(sig));
CALL_INTERFACE_IF_REACHABLE(AtomicOp, opcode, VectorOf(args), imm, CALL_INTERFACE_IF_OK_AND_REACHABLE(AtomicOp, opcode, VectorOf(args), imm,
&result); &result);
DropArgs(sig); DropArgs(sig);
Push(result); Push(result);
} }
...@@ -4614,14 +4626,14 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4614,14 +4626,14 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Value size = Peek(0, 2, sig->GetParam(2)); Value size = Peek(0, 2, sig->GetParam(2));
Value src = Peek(1, 1, sig->GetParam(1)); Value src = Peek(1, 1, sig->GetParam(1));
Value dst = Peek(2, 0, sig->GetParam(0)); Value dst = Peek(2, 0, sig->GetParam(0));
CALL_INTERFACE_IF_REACHABLE(MemoryInit, imm, dst, src, size); CALL_INTERFACE_IF_OK_AND_REACHABLE(MemoryInit, imm, dst, src, size);
Drop(3); Drop(3);
return opcode_length + imm.length; return opcode_length + imm.length;
} }
case kExprDataDrop: { case kExprDataDrop: {
DataDropImmediate<validate> imm(this, this->pc_ + opcode_length); DataDropImmediate<validate> imm(this, this->pc_ + opcode_length);
if (!this->Validate(this->pc_ + opcode_length, imm)) return 0; if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
CALL_INTERFACE_IF_REACHABLE(DataDrop, imm); CALL_INTERFACE_IF_OK_AND_REACHABLE(DataDrop, imm);
return opcode_length + imm.length; return opcode_length + imm.length;
} }
case kExprMemoryCopy: { case kExprMemoryCopy: {
...@@ -4630,7 +4642,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4630,7 +4642,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Value size = Peek(0, 2, sig->GetParam(2)); Value size = Peek(0, 2, sig->GetParam(2));
Value src = Peek(1, 1, sig->GetParam(1)); Value src = Peek(1, 1, sig->GetParam(1));
Value dst = Peek(2, 0, sig->GetParam(0)); Value dst = Peek(2, 0, sig->GetParam(0));
CALL_INTERFACE_IF_REACHABLE(MemoryCopy, imm, dst, src, size); CALL_INTERFACE_IF_OK_AND_REACHABLE(MemoryCopy, imm, dst, src, size);
Drop(3); Drop(3);
return opcode_length + imm.length; return opcode_length + imm.length;
} }
...@@ -4640,7 +4652,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4640,7 +4652,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Value size = Peek(0, 2, sig->GetParam(2)); Value size = Peek(0, 2, sig->GetParam(2));
Value value = Peek(1, 1, sig->GetParam(1)); Value value = Peek(1, 1, sig->GetParam(1));
Value dst = Peek(2, 0, sig->GetParam(0)); Value dst = Peek(2, 0, sig->GetParam(0));
CALL_INTERFACE_IF_REACHABLE(MemoryFill, imm, dst, value, size); CALL_INTERFACE_IF_OK_AND_REACHABLE(MemoryFill, imm, dst, value, size);
Drop(3); Drop(3);
return opcode_length + imm.length; return opcode_length + imm.length;
} }
...@@ -4648,21 +4660,21 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4648,21 +4660,21 @@ class WasmFullDecoder : public WasmDecoder<validate> {
TableInitImmediate<validate> imm(this, this->pc_ + opcode_length); TableInitImmediate<validate> imm(this, this->pc_ + opcode_length);
if (!this->Validate(this->pc_ + opcode_length, imm)) return 0; if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
ArgVector args = PeekArgs(sig); ArgVector args = PeekArgs(sig);
CALL_INTERFACE_IF_REACHABLE(TableInit, imm, VectorOf(args)); CALL_INTERFACE_IF_OK_AND_REACHABLE(TableInit, imm, VectorOf(args));
DropArgs(sig); DropArgs(sig);
return opcode_length + imm.length; return opcode_length + imm.length;
} }
case kExprElemDrop: { case kExprElemDrop: {
ElemDropImmediate<validate> imm(this, this->pc_ + opcode_length); ElemDropImmediate<validate> imm(this, this->pc_ + opcode_length);
if (!this->Validate(this->pc_ + opcode_length, imm)) return 0; if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
CALL_INTERFACE_IF_REACHABLE(ElemDrop, imm); CALL_INTERFACE_IF_OK_AND_REACHABLE(ElemDrop, imm);
return opcode_length + imm.length; return opcode_length + imm.length;
} }
case kExprTableCopy: { case kExprTableCopy: {
TableCopyImmediate<validate> imm(this, this->pc_ + opcode_length); TableCopyImmediate<validate> imm(this, this->pc_ + opcode_length);
if (!this->Validate(this->pc_ + opcode_length, imm)) return 0; if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
ArgVector args = PeekArgs(sig); ArgVector args = PeekArgs(sig);
CALL_INTERFACE_IF_REACHABLE(TableCopy, imm, VectorOf(args)); CALL_INTERFACE_IF_OK_AND_REACHABLE(TableCopy, imm, VectorOf(args));
DropArgs(sig); DropArgs(sig);
return opcode_length + imm.length; return opcode_length + imm.length;
} }
...@@ -4672,7 +4684,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4672,7 +4684,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Value delta = Peek(0, 1, sig->GetParam(1)); Value delta = Peek(0, 1, sig->GetParam(1));
Value value = Peek(1, 0, this->module_->tables[imm.index].type); Value value = Peek(1, 0, this->module_->tables[imm.index].type);
Value result = CreateValue(kWasmI32); Value result = CreateValue(kWasmI32);
CALL_INTERFACE_IF_REACHABLE(TableGrow, imm, value, delta, &result); CALL_INTERFACE_IF_OK_AND_REACHABLE(TableGrow, imm, value, delta,
&result);
Drop(2); Drop(2);
Push(result); Push(result);
return opcode_length + imm.length; return opcode_length + imm.length;
...@@ -4681,7 +4694,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4681,7 +4694,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
TableIndexImmediate<validate> imm(this, this->pc_ + opcode_length); TableIndexImmediate<validate> imm(this, this->pc_ + opcode_length);
if (!this->Validate(this->pc_ + opcode_length, imm)) return 0; if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
Value result = CreateValue(kWasmI32); Value result = CreateValue(kWasmI32);
CALL_INTERFACE_IF_REACHABLE(TableSize, imm, &result); CALL_INTERFACE_IF_OK_AND_REACHABLE(TableSize, imm, &result);
Push(result); Push(result);
return opcode_length + imm.length; return opcode_length + imm.length;
} }
...@@ -4691,7 +4704,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4691,7 +4704,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Value count = Peek(0, 2, sig->GetParam(2)); Value count = Peek(0, 2, sig->GetParam(2));
Value value = Peek(1, 1, this->module_->tables[imm.index].type); Value value = Peek(1, 1, this->module_->tables[imm.index].type);
Value start = Peek(2, 0, sig->GetParam(0)); Value start = Peek(2, 0, sig->GetParam(0));
CALL_INTERFACE_IF_REACHABLE(TableFill, imm, start, value, count); CALL_INTERFACE_IF_OK_AND_REACHABLE(TableFill, imm, start, value, count);
Drop(3); Drop(3);
return opcode_length + imm.length; return opcode_length + imm.length;
} }
...@@ -4703,7 +4716,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4703,7 +4716,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
void DoReturn() { void DoReturn() {
DCHECK_GE(stack_size(), this->sig_->return_count()); DCHECK_GE(stack_size(), this->sig_->return_count());
CALL_INTERFACE_IF_REACHABLE(DoReturn, 0); CALL_INTERFACE_IF_OK_AND_REACHABLE(DoReturn, 0);
} }
V8_INLINE void EnsureStackSpace(int slots_needed) { V8_INLINE void EnsureStackSpace(int slots_needed) {
...@@ -4875,9 +4888,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -4875,9 +4888,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
DCHECK_EQ(c, &control_.back()); DCHECK_EQ(c, &control_.back());
DCHECK_NE(c->kind, kControlLoop); DCHECK_NE(c->kind, kControlLoop);
if (!TypeCheckFallThru()) return; if (!TypeCheckFallThru()) return;
if (!c->reachable()) return; CALL_INTERFACE_IF_OK_AND_REACHABLE(FallThruTo, c);
CALL_INTERFACE(FallThruTo, c); if (c->reachable()) c->end_merge.reached = true;
c->end_merge.reached = true;
} }
bool TypeCheckMergeValues(Control* c, uint32_t drop_values, bool TypeCheckMergeValues(Control* c, uint32_t drop_values,
...@@ -5028,10 +5040,10 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -5028,10 +5040,10 @@ class WasmFullDecoder : public WasmDecoder<validate> {
void onFirstError() override { void onFirstError() override {
this->end_ = this->pc_; // Terminate decoding loop. this->end_ = this->pc_; // Terminate decoding loop.
this->current_code_reachable_ = false; this->current_code_reachable_and_ok_ = false;
TRACE(" !%s\n", this->error_.message().c_str()); TRACE(" !%s\n", this->error_.message().c_str());
// Cannot use CALL_INTERFACE here because it checks if this->ok(). // Cannot use CALL_INTERFACE_* macros because we emitted an error.
interface_.OnFirstError(this); interface().OnFirstError(this);
} }
int BuildSimplePrototypeOperator(WasmOpcode opcode) { int BuildSimplePrototypeOperator(WasmOpcode opcode) {
...@@ -5058,11 +5070,11 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -5058,11 +5070,11 @@ class WasmFullDecoder : public WasmDecoder<validate> {
ValueType arg_type) { ValueType arg_type) {
Value val = Peek(0, 0, arg_type); Value val = Peek(0, 0, arg_type);
if (return_type == kWasmVoid) { if (return_type == kWasmVoid) {
CALL_INTERFACE_IF_REACHABLE(UnOp, opcode, val, nullptr); CALL_INTERFACE_IF_OK_AND_REACHABLE(UnOp, opcode, val, nullptr);
Drop(val); Drop(val);
} else { } else {
Value ret = CreateValue(return_type); Value ret = CreateValue(return_type);
CALL_INTERFACE_IF_REACHABLE(UnOp, opcode, val, &ret); CALL_INTERFACE_IF_OK_AND_REACHABLE(UnOp, opcode, val, &ret);
Drop(val); Drop(val);
Push(ret); Push(ret);
} }
...@@ -5074,11 +5086,11 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -5074,11 +5086,11 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Value rval = Peek(0, 1, rhs_type); Value rval = Peek(0, 1, rhs_type);
Value lval = Peek(1, 0, lhs_type); Value lval = Peek(1, 0, lhs_type);
if (return_type == kWasmVoid) { if (return_type == kWasmVoid) {
CALL_INTERFACE_IF_REACHABLE(BinOp, opcode, lval, rval, nullptr); CALL_INTERFACE_IF_OK_AND_REACHABLE(BinOp, opcode, lval, rval, nullptr);
Drop(2); Drop(2);
} else { } else {
Value ret = CreateValue(return_type); Value ret = CreateValue(return_type);
CALL_INTERFACE_IF_REACHABLE(BinOp, opcode, lval, rval, &ret); CALL_INTERFACE_IF_OK_AND_REACHABLE(BinOp, opcode, lval, rval, &ret);
Drop(2); Drop(2);
Push(ret); Push(ret);
} }
...@@ -5093,10 +5105,6 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -5093,10 +5105,6 @@ class WasmFullDecoder : public WasmDecoder<validate> {
#undef DEFINE_SIMPLE_SIG_OPERATOR #undef DEFINE_SIMPLE_SIG_OPERATOR
}; };
#undef CALL_INTERFACE
#undef CALL_INTERFACE_IF_REACHABLE
#undef CALL_INTERFACE_IF_PARENT_REACHABLE
class EmptyInterface { class EmptyInterface {
public: public:
static constexpr Decoder::ValidateFlag validate = Decoder::kFullValidation; static constexpr Decoder::ValidateFlag validate = Decoder::kFullValidation;
...@@ -5110,6 +5118,8 @@ class EmptyInterface { ...@@ -5110,6 +5118,8 @@ class EmptyInterface {
#undef DEFINE_EMPTY_CALLBACK #undef DEFINE_EMPTY_CALLBACK
}; };
#undef CALL_INTERFACE_IF_OK_AND_REACHABLE
#undef CALL_INTERFACE_IF_OK_AND_PARENT_REACHABLE
#undef TRACE #undef TRACE
#undef TRACE_INST_FORMAT #undef TRACE_INST_FORMAT
#undef VALIDATE #undef VALIDATE
......
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