Commit 765e6f03 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[wasm] [cleanup] Remove VALIDATE macro

It has exactly the inverse meaning of CHECK_ERROR. Since CHECK_ERROR is
used in the majority of the cases, and is more readable in most cases,
this CL replaces all uses of VALIDATE by CHECK_ERROR.
It also includes a few minor refactorings of the touched code.

R=titzer@chromium.org

Bug: v8:6600
Change-Id: I3d6b3b8bfd131e14f0d852b07622382b11b488f0
Reviewed-on: https://chromium-review.googlesource.com/643268Reviewed-by: 's avatarBen Titzer <titzer@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47717}
parent 016d53f9
...@@ -31,22 +31,14 @@ struct WasmException; ...@@ -31,22 +31,14 @@ struct WasmException;
#define TRACE(...) #define TRACE(...)
#endif #endif
// Return the evaluation of `condition` if validate==true, DCHECK // Return the evaluation of `condition` if validate==true, DCHECK that it's
// and always return true otherwise. // true and always return true otherwise.
#define VALIDATE(condition) \ #define VALIDATE(condition) \
(validate ? (condition) : [&] { \ (validate ? (condition) : [&] { \
DCHECK(condition); \ DCHECK(condition); \
return true; \ return true; \
}()) }())
// Return the evaluation of `condition` if validate==true, DCHECK that it's
// false and always return false otherwise.
#define CHECK_ERROR(condition) \
(validate ? (condition) : [&] { \
DCHECK(!(condition)); \
return false; \
}())
#define CHECK_PROTOTYPE_OPCODE(flag) \ #define CHECK_PROTOTYPE_OPCODE(flag) \
if (this->module_ != nullptr && this->module_->is_asm_js()) { \ if (this->module_ != nullptr && this->module_->is_asm_js()) { \
this->error("Opcode not supported for asmjs modules"); \ this->error("Opcode not supported for asmjs modules"); \
...@@ -154,11 +146,11 @@ struct BlockTypeOperand { ...@@ -154,11 +146,11 @@ struct BlockTypeOperand {
types = pc + 1; types = pc + 1;
} else { } else {
// Handle multi-value blocks. // Handle multi-value blocks.
if (CHECK_ERROR(!FLAG_experimental_wasm_mv)) { if (!VALIDATE(FLAG_experimental_wasm_mv)) {
decoder->error(pc + 1, "invalid block arity > 1"); decoder->error(pc + 1, "invalid block arity > 1");
return; return;
} }
if (CHECK_ERROR(val != kMultivalBlock)) { if (!VALIDATE(val == kMultivalBlock)) {
decoder->error(pc + 1, "invalid block type"); decoder->error(pc + 1, "invalid block type");
return; return;
} }
...@@ -177,7 +169,7 @@ struct BlockTypeOperand { ...@@ -177,7 +169,7 @@ struct BlockTypeOperand {
uint32_t offset = 1 + 1 + len + i; uint32_t offset = 1 + 1 + len + i;
val = decoder->read_u8<validate>(pc + offset, "block type"); val = decoder->read_u8<validate>(pc + offset, "block type");
decode_local_type(val, &type); decode_local_type(val, &type);
if (CHECK_ERROR(type == kWasmStmt)) { if (!VALIDATE(type != kWasmStmt)) {
decoder->error(pc + offset, "invalid block type"); decoder->error(pc + offset, "invalid block type");
return; return;
} }
...@@ -242,7 +234,7 @@ struct CallIndirectOperand { ...@@ -242,7 +234,7 @@ struct CallIndirectOperand {
unsigned len = 0; unsigned len = 0;
index = decoder->read_u32v<validate>(pc + 1, &len, "signature index"); index = decoder->read_u32v<validate>(pc + 1, &len, "signature index");
table_index = decoder->read_u8<validate>(pc + 1 + len, "table index"); table_index = decoder->read_u8<validate>(pc + 1 + len, "table index");
if (CHECK_ERROR(table_index != 0)) { if (!VALIDATE(table_index == 0)) {
decoder->errorf(pc + 1 + len, "expected table index 0, found %u", decoder->errorf(pc + 1 + len, "expected table index 0, found %u",
table_index); table_index);
} }
...@@ -266,7 +258,7 @@ struct MemoryIndexOperand { ...@@ -266,7 +258,7 @@ struct MemoryIndexOperand {
unsigned length = 1; unsigned length = 1;
inline MemoryIndexOperand(Decoder* decoder, const byte* pc) { inline MemoryIndexOperand(Decoder* decoder, const byte* pc) {
index = decoder->read_u8<validate>(pc + 1, "memory index"); index = decoder->read_u8<validate>(pc + 1, "memory index");
if (CHECK_ERROR(index != 0)) { if (!VALIDATE(index == 0)) {
decoder->errorf(pc + 1, "expected memory index 0, found %u", index); decoder->errorf(pc + 1, "expected memory index 0, found %u", index);
} }
} }
...@@ -335,7 +327,7 @@ struct MemoryAccessOperand { ...@@ -335,7 +327,7 @@ struct MemoryAccessOperand {
unsigned alignment_length; unsigned alignment_length;
alignment = alignment =
decoder->read_u32v<validate>(pc + 1, &alignment_length, "alignment"); decoder->read_u32v<validate>(pc + 1, &alignment_length, "alignment");
if (CHECK_ERROR(alignment > max_alignment)) { if (!VALIDATE(alignment <= max_alignment)) {
decoder->errorf(pc + 1, decoder->errorf(pc + 1,
"invalid alignment; expected maximum alignment is %u, " "invalid alignment; expected maximum alignment is %u, "
"actual alignment is %u", "actual alignment is %u",
...@@ -642,47 +634,44 @@ class WasmDecoder : public Decoder { ...@@ -642,47 +634,44 @@ class WasmDecoder : public Decoder {
} }
inline bool Validate(const byte* pc, LocalIndexOperand<validate>& operand) { inline bool Validate(const byte* pc, LocalIndexOperand<validate>& operand) {
if (VALIDATE(operand.index < total_locals())) { if (!VALIDATE(operand.index < total_locals())) {
if (local_types_) {
operand.type = local_types_->at(operand.index);
} else {
operand.type = kWasmStmt;
}
return true;
}
errorf(pc + 1, "invalid local index: %u", operand.index); errorf(pc + 1, "invalid local index: %u", operand.index);
return false; return false;
} }
operand.type = local_types_ ? local_types_->at(operand.index) : kWasmStmt;
return true;
}
inline bool Validate(const byte* pc, inline bool Validate(const byte* pc,
ExceptionIndexOperand<validate>& operand) { ExceptionIndexOperand<validate>& operand) {
if (module_ != nullptr && operand.index < module_->exceptions.size()) { if (!VALIDATE(module_ != nullptr &&
operand.exception = &module_->exceptions[operand.index]; operand.index < module_->exceptions.size())) {
return true;
}
errorf(pc + 1, "Invalid exception index: %u", operand.index); errorf(pc + 1, "Invalid exception index: %u", operand.index);
return false; return false;
} }
operand.exception = &module_->exceptions[operand.index];
return true;
}
inline bool Validate(const byte* pc, GlobalIndexOperand<validate>& operand) { inline bool Validate(const byte* pc, GlobalIndexOperand<validate>& operand) {
if (VALIDATE(module_ != nullptr && if (!VALIDATE(module_ != nullptr &&
operand.index < module_->globals.size())) { operand.index < module_->globals.size())) {
errorf(pc + 1, "invalid global index: %u", operand.index);
return false;
}
operand.global = &module_->globals[operand.index]; operand.global = &module_->globals[operand.index];
operand.type = operand.global->type; operand.type = operand.global->type;
return true; return true;
} }
errorf(pc + 1, "invalid global index: %u", operand.index);
return false;
}
inline bool Complete(const byte* pc, CallFunctionOperand<validate>& operand) { inline bool Complete(const byte* pc, CallFunctionOperand<validate>& operand) {
if (VALIDATE(module_ != nullptr && if (!VALIDATE(module_ != nullptr &&
operand.index < module_->functions.size())) { operand.index < module_->functions.size())) {
return false;
}
operand.sig = module_->functions[operand.index].sig; operand.sig = module_->functions[operand.index].sig;
return true; return true;
} }
return false;
}
inline bool Validate(const byte* pc, CallFunctionOperand<validate>& operand) { inline bool Validate(const byte* pc, CallFunctionOperand<validate>& operand) {
if (Complete(pc, operand)) { if (Complete(pc, operand)) {
...@@ -693,38 +682,38 @@ class WasmDecoder : public Decoder { ...@@ -693,38 +682,38 @@ class WasmDecoder : public Decoder {
} }
inline bool Complete(const byte* pc, CallIndirectOperand<validate>& operand) { inline bool Complete(const byte* pc, CallIndirectOperand<validate>& operand) {
if (VALIDATE(module_ != nullptr && if (!VALIDATE(module_ != nullptr &&
operand.index < module_->signatures.size())) { operand.index < module_->signatures.size())) {
return false;
}
operand.sig = module_->signatures[operand.index]; operand.sig = module_->signatures[operand.index];
return true; return true;
} }
return false;
}
inline bool Validate(const byte* pc, CallIndirectOperand<validate>& operand) { inline bool Validate(const byte* pc, CallIndirectOperand<validate>& operand) {
if (CHECK_ERROR(module_ == nullptr || module_->function_tables.empty())) { if (!VALIDATE(module_ != nullptr && !module_->function_tables.empty())) {
error("function table has to exist to execute call_indirect"); error("function table has to exist to execute call_indirect");
return false; return false;
} }
if (Complete(pc, operand)) { if (!Complete(pc, operand)) {
return true;
}
errorf(pc + 1, "invalid signature index: #%u", operand.index); errorf(pc + 1, "invalid signature index: #%u", operand.index);
return false; return false;
} }
return true;
}
inline bool Validate(const byte* pc, BreakDepthOperand<validate>& operand, inline bool Validate(const byte* pc, BreakDepthOperand<validate>& operand,
size_t control_depth) { size_t control_depth) {
if (VALIDATE(operand.depth < control_depth)) { if (!VALIDATE(operand.depth < control_depth)) {
return true;
}
errorf(pc + 1, "invalid break depth: %u", operand.depth); errorf(pc + 1, "invalid break depth: %u", operand.depth);
return false; return false;
} }
return true;
}
bool Validate(const byte* pc, BranchTableOperand<validate>& operand, bool Validate(const byte* pc, BranchTableOperand<validate>& operand,
size_t block_depth) { size_t block_depth) {
if (CHECK_ERROR(operand.table_count >= kV8MaxWasmFunctionSize)) { if (!VALIDATE(operand.table_count < kV8MaxWasmFunctionSize)) {
errorf(pc + 1, "invalid table count (> max function size): %u", errorf(pc + 1, "invalid table count (> max function size): %u",
operand.table_count); operand.table_count);
return false; return false;
...@@ -754,7 +743,7 @@ class WasmDecoder : public Decoder { ...@@ -754,7 +743,7 @@ class WasmDecoder : public Decoder {
UNREACHABLE(); UNREACHABLE();
break; break;
} }
if (CHECK_ERROR(operand.lane < 0 || operand.lane >= num_lanes)) { if (!VALIDATE(operand.lane >= 0 && operand.lane < num_lanes)) {
error(pc_ + 2, "invalid lane index"); error(pc_ + 2, "invalid lane index");
return false; return false;
} else { } else {
...@@ -785,7 +774,7 @@ class WasmDecoder : public Decoder { ...@@ -785,7 +774,7 @@ class WasmDecoder : public Decoder {
UNREACHABLE(); UNREACHABLE();
break; break;
} }
if (CHECK_ERROR(operand.shift < 0 || operand.shift >= max_shift)) { if (!VALIDATE(operand.shift >= 0 && operand.shift < max_shift)) {
error(pc_ + 2, "invalid shift amount"); error(pc_ + 2, "invalid shift amount");
return false; return false;
} else { } else {
...@@ -799,12 +788,11 @@ class WasmDecoder : public Decoder { ...@@ -799,12 +788,11 @@ class WasmDecoder : public Decoder {
for (uint32_t i = 0; i < kSimd128Size; ++i) for (uint32_t i = 0; i < kSimd128Size; ++i)
max_lane = std::max(max_lane, operand.shuffle[i]); max_lane = std::max(max_lane, operand.shuffle[i]);
// Shuffle indices must be in [0..31] for a 16 lane shuffle. // Shuffle indices must be in [0..31] for a 16 lane shuffle.
if (CHECK_ERROR(max_lane > 2 * kSimd128Size)) { if (!VALIDATE(max_lane <= 2 * kSimd128Size)) {
error(pc_ + 2, "invalid shuffle mask"); error(pc_ + 2, "invalid shuffle mask");
return false; return false;
} else {
return true;
} }
return true;
} }
static unsigned OpcodeLength(Decoder* decoder, const byte* pc) { static unsigned OpcodeLength(Decoder* decoder, const byte* pc) {
...@@ -1128,10 +1116,12 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -1128,10 +1116,12 @@ class WasmFullDecoder : public WasmDecoder<validate> {
bool last_end_found_; bool last_end_found_;
bool CheckHasMemory() { bool CheckHasMemory() {
if (VALIDATE(this->module_->has_memory)) return true; if (!VALIDATE(this->module_->has_memory)) {
this->error(this->pc_ - 1, "memory instruction with no memory"); this->error(this->pc_ - 1, "memory instruction with no memory");
return false; return false;
} }
return true;
}
// Decodes the body of a function. // Decodes the body of a function.
void DecodeFunctionBody() { void DecodeFunctionBody() {
...@@ -1223,18 +1213,18 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -1223,18 +1213,18 @@ class WasmFullDecoder : public WasmDecoder<validate> {
if (!this->Validate(this->pc_, operand)) break; if (!this->Validate(this->pc_, operand)) break;
if (CHECK_ERROR(control_.empty())) { if (!VALIDATE(!control_.empty())) {
this->error("catch does not match any try"); this->error("catch does not match any try");
break; break;
} }
Control* c = &control_.back(); Control* c = &control_.back();
if (CHECK_ERROR(!c->is_try())) { if (!VALIDATE(c->is_try())) {
this->error("catch does not match any try"); this->error("catch does not match any try");
break; break;
} }
if (CHECK_ERROR(c->is_try_catch())) { if (!VALIDATE(c->is_incomplete_try())) {
OPCODE_ERROR(opcode, "multiple catch blocks not implemented"); OPCODE_ERROR(opcode, "multiple catch blocks not implemented");
break; break;
} }
...@@ -1271,12 +1261,12 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -1271,12 +1261,12 @@ class WasmFullDecoder : public WasmDecoder<validate> {
break; break;
} }
case kExprElse: { case kExprElse: {
if (CHECK_ERROR(control_.empty())) { if (!VALIDATE(!control_.empty())) {
this->error("else does not match any if"); this->error("else does not match any if");
break; break;
} }
Control* c = &control_.back(); Control* c = &control_.back();
if (CHECK_ERROR(!c->is_if())) { if (!VALIDATE(c->is_if())) {
this->error(this->pc_, "else does not match an if"); this->error(this->pc_, "else does not match an if");
break; break;
} }
...@@ -1291,7 +1281,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -1291,7 +1281,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
break; break;
} }
case kExprEnd: { case kExprEnd: {
if (CHECK_ERROR(control_.empty())) { if (!VALIDATE(!control_.empty())) {
this->error("end does not match any if, try, or block"); this->error("end does not match any if, try, or block");
return; return;
} }
...@@ -1305,15 +1295,15 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -1305,15 +1295,15 @@ class WasmFullDecoder : public WasmDecoder<validate> {
} }
if (c->is_onearmed_if()) { if (c->is_onearmed_if()) {
// End the true branch of a one-armed if. // End the true branch of a one-armed if.
if (CHECK_ERROR(!c->unreachable && if (!VALIDATE(c->unreachable ||
stack_.size() != c->stack_depth)) { stack_.size() == c->stack_depth)) {
this->error("end of if expected empty stack"); this->error("end of if expected empty stack");
stack_.resize(c->stack_depth); stack_.resize(c->stack_depth);
} }
if (CHECK_ERROR(c->merge.arity > 0)) { if (!VALIDATE(c->merge.arity == 0)) {
this->error("non-void one-armed if"); this->error("non-void one-armed if");
} }
} else if (CHECK_ERROR(c->is_incomplete_try())) { } else if (!VALIDATE(!c->is_incomplete_try())) {
this->error(this->pc_, "missing catch in try"); this->error(this->pc_, "missing catch in try");
break; break;
} }
...@@ -1322,7 +1312,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -1322,7 +1312,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
if (control_.size() == 1) { if (control_.size() == 1) {
// If at the last (implicit) control, check we are at end. // If at the last (implicit) control, check we are at end.
if (CHECK_ERROR(this->pc_ + 1 != this->end_)) { if (!VALIDATE(this->pc_ + 1 == this->end_)) {
this->error(this->pc_ + 1, "trailing code after function end"); this->error(this->pc_ + 1, "trailing code after function end");
break; break;
} }
...@@ -1350,8 +1340,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -1350,8 +1340,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
} }
case kExprBr: { case kExprBr: {
BreakDepthOperand<validate> operand(this, this->pc_); BreakDepthOperand<validate> operand(this, this->pc_);
if (VALIDATE(this->Validate(this->pc_, operand, control_.size()) && if (this->Validate(this->pc_, operand, control_.size()) &&
TypeCheckBreak(operand.depth))) { TypeCheckBreak(operand.depth)) {
interface_.BreakTo(this, control_at(operand.depth)); interface_.BreakTo(this, control_at(operand.depth));
} }
len = 1 + operand.length; len = 1 + operand.length;
...@@ -1361,9 +1351,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -1361,9 +1351,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
case kExprBrIf: { case kExprBrIf: {
BreakDepthOperand<validate> operand(this, this->pc_); BreakDepthOperand<validate> operand(this, this->pc_);
auto cond = Pop(0, kWasmI32); auto cond = Pop(0, kWasmI32);
if (VALIDATE(this->ok() && if (this->Validate(this->pc_, operand, control_.size()) &&
this->Validate(this->pc_, operand, control_.size()) && TypeCheckBreak(operand.depth)) {
TypeCheckBreak(operand.depth))) {
interface_.BrIf(this, cond, control_at(operand.depth)); interface_.BrIf(this, cond, control_at(operand.depth));
} }
len = 1 + operand.length; len = 1 + operand.length;
...@@ -1379,7 +1368,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -1379,7 +1368,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
const uint32_t i = iterator.cur_index(); const uint32_t i = iterator.cur_index();
const byte* pos = iterator.pc(); const byte* pos = iterator.pc();
uint32_t target = iterator.next(); uint32_t target = iterator.next();
if (CHECK_ERROR(target >= control_.size())) { if (!VALIDATE(target < control_.size())) {
this->error(pos, "improper branch in br_table"); this->error(pos, "improper branch in br_table");
break; break;
} }
...@@ -1389,27 +1378,26 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -1389,27 +1378,26 @@ class WasmFullDecoder : public WasmDecoder<validate> {
MergeValues* current = c->is_loop() ? &loop_dummy : &c->merge; MergeValues* current = c->is_loop() ? &loop_dummy : &c->merge;
if (i == 0) { if (i == 0) {
merge = current; merge = current;
} else if (CHECK_ERROR(merge->arity != current->arity)) { } else if (!VALIDATE(merge->arity == current->arity)) {
this->errorf(pos, this->errorf(pos,
"inconsistent arity in br_table target %d" "inconsistent arity in br_table target %d"
" (previous was %u, this one %u)", " (previous was %u, this one %u)",
i, merge->arity, current->arity); i, merge->arity, current->arity);
} else if (control_at(0)->unreachable) { } else if (control_at(0)->unreachable) {
for (uint32_t j = 0; VALIDATE(this->ok()) && j < merge->arity; for (uint32_t j = 0; j < merge->arity; ++j) {
++j) { if (!VALIDATE((*merge)[j].type == (*current)[j].type)) {
if (CHECK_ERROR((*merge)[j].type != (*current)[j].type)) {
this->errorf(pos, this->errorf(pos,
"type error in br_table target %d operand %d" "type error in br_table target %d operand %d"
" (previous expected %s, this one %s)", " (previous expected %s, this one %s)",
i, j, WasmOpcodes::TypeName((*merge)[j].type), i, j, WasmOpcodes::TypeName((*merge)[j].type),
WasmOpcodes::TypeName((*current)[j].type)); WasmOpcodes::TypeName((*current)[j].type));
break;
} }
} }
} }
bool valid = TypeCheckBreak(target); if (!VALIDATE(TypeCheckBreak(target))) break;
if (CHECK_ERROR(!valid)) break;
} }
if (CHECK_ERROR(this->failed())) break; if (!VALIDATE(this->ok())) break;
if (operand.table_count > 0) { if (operand.table_count > 0) {
interface_.BrTable(this, operand, key); interface_.BrTable(this, operand, key);
...@@ -1418,7 +1406,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -1418,7 +1406,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
BranchTableIterator<validate> iterator(this, operand); BranchTableIterator<validate> iterator(this, operand);
const byte* pos = iterator.pc(); const byte* pos = iterator.pc();
uint32_t target = iterator.next(); uint32_t target = iterator.next();
if (CHECK_ERROR(target >= control_.size())) { if (!VALIDATE(target < control_.size())) {
this->error(pos, "improper branch in br_table"); this->error(pos, "improper branch in br_table");
break; break;
} }
...@@ -1506,7 +1494,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -1506,7 +1494,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
GlobalIndexOperand<validate> operand(this, this->pc_); GlobalIndexOperand<validate> operand(this, this->pc_);
len = 1 + operand.length; len = 1 + operand.length;
if (!this->Validate(this->pc_, operand)) break; if (!this->Validate(this->pc_, operand)) break;
if (CHECK_ERROR(!operand.global->mutability)) { if (!VALIDATE(operand.global->mutability)) {
this->errorf(this->pc_, "immutable global #%u cannot be assigned", this->errorf(this->pc_, "immutable global #%u cannot be assigned",
operand.index); operand.index);
break; break;
...@@ -1589,7 +1577,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -1589,7 +1577,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
MemoryIndexOperand<validate> operand(this, this->pc_); MemoryIndexOperand<validate> operand(this, this->pc_);
len = 1 + operand.length; len = 1 + operand.length;
DCHECK_NOT_NULL(this->module_); DCHECK_NOT_NULL(this->module_);
if (CHECK_ERROR(!this->module_->is_wasm())) { if (!VALIDATE(this->module_->is_wasm())) {
this->error("grow_memory is not supported for asmjs modules"); this->error("grow_memory is not supported for asmjs modules");
break; break;
} }
...@@ -1923,7 +1911,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -1923,7 +1911,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
break; break;
default: { default: {
FunctionSig* sig = WasmOpcodes::Signature(opcode); FunctionSig* sig = WasmOpcodes::Signature(opcode);
if (CHECK_ERROR(sig == nullptr)) { if (!VALIDATE(sig != nullptr)) {
this->error("invalid simd opcode"); this->error("invalid simd opcode");
break; break;
} }
...@@ -2000,8 +1988,8 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2000,8 +1988,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Value Pop(int index, ValueType expected) { Value Pop(int index, ValueType expected) {
auto val = Pop(); auto val = Pop();
if (CHECK_ERROR(val.type != expected && val.type != kWasmVar && if (!VALIDATE(val.type == expected || val.type == kWasmVar ||
expected != kWasmVar)) { expected == kWasmVar)) {
this->errorf(val.pc, "%s[%d] expected type %s, found %s of type %s", this->errorf(val.pc, "%s[%d] expected type %s, found %s of type %s",
SafeOpcodeNameAt(this->pc_), index, SafeOpcodeNameAt(this->pc_), index,
WasmOpcodes::TypeName(expected), SafeOpcodeNameAt(val.pc), WasmOpcodes::TypeName(expected), SafeOpcodeNameAt(val.pc),
...@@ -2015,7 +2003,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2015,7 +2003,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
size_t limit = control_.back().stack_depth; size_t limit = control_.back().stack_depth;
if (stack_.size() <= limit) { if (stack_.size() <= limit) {
// Popping past the current control start in reachable code. // Popping past the current control start in reachable code.
if (CHECK_ERROR(!control_.back().unreachable)) { if (!VALIDATE(control_.back().unreachable)) {
this->errorf(this->pc_, "%s found empty stack", this->errorf(this->pc_, "%s found empty stack",
SafeOpcodeNameAt(this->pc_)); SafeOpcodeNameAt(this->pc_));
} }
...@@ -2043,16 +2031,16 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2043,16 +2031,16 @@ class WasmFullDecoder : public WasmDecoder<validate> {
auto& val = GetMergeValueFromStack(c, i); auto& val = GetMergeValueFromStack(c, i);
auto& old = c->merge[i]; auto& old = c->merge[i];
if (val.type != old.type) { if (val.type != old.type) {
if (val.type == kWasmVar) { // If {val.type} is polymorphic, which results from unreachable, make
// if {val.type} is polymorphic, which results from unreachable, make
// it more specific by using the merge value's expected type. // it more specific by using the merge value's expected type.
val.type = old.type; // If it is not polymorphic, this is a type error.
} else { if (!VALIDATE(val.type == kWasmVar)) {
this->errorf( this->errorf(
this->pc_, "type error in merge[%zu] (expected %s, got %s)", i, this->pc_, "type error in merge[%zu] (expected %s, got %s)", i,
WasmOpcodes::TypeName(old.type), WasmOpcodes::TypeName(val.type)); WasmOpcodes::TypeName(old.type), WasmOpcodes::TypeName(val.type));
return false; return false;
} }
val.type = old.type;
} }
} }
...@@ -2076,7 +2064,6 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2076,7 +2064,6 @@ class WasmFullDecoder : public WasmDecoder<validate> {
} }
bool TypeCheckBreak(unsigned depth) { bool TypeCheckBreak(unsigned depth) {
DCHECK(validate); // Only call this for validation.
Control* c = control_at(depth); Control* c = control_at(depth);
if (c->is_loop()) { if (c->is_loop()) {
// This is the inner loop block, which does not have a value. // This is the inner loop block, which does not have a value.
...@@ -2094,8 +2081,13 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2094,8 +2081,13 @@ class WasmFullDecoder : public WasmDecoder<validate> {
} }
inline bool InsertUnreachablesIfNecessary(size_t expected, size_t actual) { inline bool InsertUnreachablesIfNecessary(size_t expected, size_t actual) {
if (actual < expected) { if (V8_LIKELY(actual >= expected)) {
if (control_.back().unreachable) { return true; // enough actual values are there.
}
if (!VALIDATE(control_.back().unreachable)) {
// There aren't enough values on the stack.
return false;
}
// A slow path. When the actual number of values on the stack is less // A slow path. When the actual number of values on the stack is less
// than the expected number of values and the current control is // than the expected number of values and the current control is
// unreachable, insert unreachable values below the actual values. // unreachable, insert unreachable values below the actual values.
...@@ -2103,12 +2095,6 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2103,12 +2095,6 @@ class WasmFullDecoder : public WasmDecoder<validate> {
auto pos = stack_.begin() + (stack_.size() - actual); auto pos = stack_.begin() + (stack_.size() - actual);
stack_.insert(pos, (expected - actual), Value::Unreachable(this->pc_)); stack_.insert(pos, (expected - actual), Value::Unreachable(this->pc_));
return true; return true;
} else {
// There aren't enough values on the stack.
return false;
}
}
return true; // enough actual values are there.
} }
virtual void onFirstError() { virtual void onFirstError() {
...@@ -2170,7 +2156,6 @@ class EmptyInterface : public InterfaceTemplate<true, EmptyInterface> { ...@@ -2170,7 +2156,6 @@ class EmptyInterface : public InterfaceTemplate<true, EmptyInterface> {
#undef TRACE #undef TRACE
#undef VALIDATE #undef VALIDATE
#undef CHECK_ERROR
#undef CHECK_PROTOTYPE_OPCODE #undef CHECK_PROTOTYPE_OPCODE
#undef OPCODE_ERROR #undef OPCODE_ERROR
......
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