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