[wasm] Rename {ValidateFlag} constants

As a preparation to add a "boolean validation" mode, rename the existing
flags. This removes many unrelated changes from the follow-up change and
makes it easier to review.

R=thibaudm@chromium.org

Bug: v8:10969
Change-Id: I5f71405b525a7caa91be46c035e31d4d960e4e4c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2440036
Reviewed-by: Thibaud Michaud <thibaudm@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70224}
This commit is contained in:
Clemens Backes 2020-09-30 11:37:50 +02:00 committed by Commit Bot
parent 7b24b13981
commit 2a71b32062
11 changed files with 288 additions and 259 deletions

View File

@ -258,7 +258,7 @@ class DebugSideTableBuilder {
class LiftoffCompiler {
public:
// TODO(clemensb): Make this a template parameter.
static constexpr Decoder::ValidateFlag validate = Decoder::kValidate;
static constexpr Decoder::ValidateFlag validate = Decoder::kFullValidation;
using Value = ValueBase;
@ -843,7 +843,8 @@ class LiftoffCompiler {
#ifdef DEBUG
SLOW_DCHECK(__ ValidateCacheState());
if (WasmOpcodes::IsPrefixOpcode(opcode)) {
opcode = decoder->read_prefixed_opcode<Decoder::kValidate>(decoder->pc());
opcode = decoder->read_prefixed_opcode<Decoder::kFullValidation>(
decoder->pc());
}
DEBUG_CODE_COMMENT(WasmOpcodes::OpcodeName(opcode));
#endif
@ -4115,7 +4116,7 @@ WasmCompilationResult ExecuteLiftoffCompilation(
if (debug_sidetable) {
debug_sidetable_builder = std::make_unique<DebugSideTableBuilder>();
}
WasmFullDecoder<Decoder::kValidate, LiftoffCompiler> decoder(
WasmFullDecoder<Decoder::kFullValidation, LiftoffCompiler> decoder(
&zone, env->module, env->enabled_features, detected, func_body,
call_descriptor, env, &zone, instruction_buffer->CreateView(),
debug_sidetable_builder.get(), for_debugging, func_index, breakpoints,
@ -4172,7 +4173,7 @@ std::unique_ptr<DebugSideTable> GenerateLiftoffDebugSideTable(
auto call_descriptor = compiler::GetWasmCallDescriptor(&zone, func_body.sig);
DebugSideTableBuilder debug_sidetable_builder;
WasmFeatures detected;
WasmFullDecoder<Decoder::kValidate, LiftoffCompiler> decoder(
WasmFullDecoder<Decoder::kFullValidation, LiftoffCompiler> decoder(
&zone, env->module, env->enabled_features, &detected, func_body,
call_descriptor, env, &zone,
NewAssemblerBuffer(AssemblerBase::kDefaultBufferSize),

View File

@ -39,7 +39,13 @@ using DecodeResult = VoidResult;
// a buffer of bytes.
class Decoder {
public:
enum ValidateFlag : bool { kValidate = true, kNoValidate = false };
// {ValidateFlag} can be used in a boolean manner ({if (!validate) ...}).
// TODO(clemensb): Introduce a "boolean validation" mode where error messages
// are locations are not tracked.
enum ValidateFlag : int8_t {
kNoValidation = 0, // Don't run validation, assume valid input.
kFullValidation // Run full validation with error message and location.
};
enum AdvancePCFlag : bool { kAdvancePc = true, kNoAdvancePc = false };
@ -160,7 +166,7 @@ class Decoder {
index = *(pc + 1);
*length = 1;
} else {
// If kValidate and size validation fails.
// If size validation fails.
index = 0;
*length = 0;
}
@ -186,21 +192,22 @@ class Decoder {
// Reads a LEB128 variable-length unsigned 32-bit integer and advances {pc_}.
uint32_t consume_u32v(const char* name = nullptr) {
uint32_t length = 0;
return read_leb<uint32_t, kValidate, kAdvancePc, kTrace>(pc_, &length,
name);
return read_leb<uint32_t, kFullValidation, kAdvancePc, kTrace>(pc_, &length,
name);
}
// Reads a LEB128 variable-length signed 32-bit integer and advances {pc_}.
int32_t consume_i32v(const char* name = nullptr) {
uint32_t length = 0;
return read_leb<int32_t, kValidate, kAdvancePc, kTrace>(pc_, &length, name);
return read_leb<int32_t, kFullValidation, kAdvancePc, kTrace>(pc_, &length,
name);
}
// Reads a LEB128 variable-length unsigned 64-bit integer and advances {pc_}.
uint64_t consume_u64v(const char* name = nullptr) {
uint32_t length = 0;
return read_leb<uint64_t, kValidate, kAdvancePc, kTrace>(pc_, &length,
name);
return read_leb<uint64_t, kFullValidation, kAdvancePc, kTrace>(pc_, &length,
name);
}
// Consume {size} bytes and send them to the bit bucket, advancing {pc_}.

View File

@ -1035,7 +1035,8 @@ class WasmDecoder : public Decoder {
: local_types_.begin();
// Decode local declarations, if any.
uint32_t entries = read_u32v<kValidate>(pc, &length, "local decls count");
uint32_t entries =
read_u32v<kFullValidation>(pc, &length, "local decls count");
if (!VALIDATE(ok())) {
error(pc + *total_length, "invalid local decls count");
return false;
@ -1049,8 +1050,8 @@ class WasmDecoder : public Decoder {
error(end(), "expected more local decls but reached end of input");
return false;
}
uint32_t count =
read_u32v<kValidate>(pc + *total_length, &length, "local count");
uint32_t count = read_u32v<kFullValidation>(pc + *total_length, &length,
"local count");
if (!VALIDATE(ok())) {
error(pc + *total_length, "invalid local count");
return false;
@ -1062,7 +1063,7 @@ class WasmDecoder : public Decoder {
}
*total_length += length;
ValueType type = value_type_reader::read_value_type<kValidate>(
ValueType type = value_type_reader::read_value_type<kFullValidation>(
this, pc + *total_length, &length, enabled_);
if (!VALIDATE(type != kWasmBottom)) {
error(pc + *total_length, "invalid local type");
@ -2006,7 +2007,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
if (!WasmOpcodes::IsPrefixOpcode(opcode)) {
return WasmOpcodes::OpcodeName(static_cast<WasmOpcode>(opcode));
}
opcode = this->template read_prefixed_opcode<Decoder::kValidate>(pc);
opcode = this->template read_prefixed_opcode<Decoder::kFullValidation>(pc);
return WasmOpcodes::OpcodeName(opcode);
}
@ -2157,7 +2158,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
WasmOpcode val_opcode = static_cast<WasmOpcode>(*val.pc);
if (WasmOpcodes::IsPrefixOpcode(val_opcode)) {
val_opcode =
decoder_->template read_prefixed_opcode<Decoder::kNoValidate>(
decoder_->template read_prefixed_opcode<Decoder::kNoValidation>(
val.pc);
}
Append(" %c@%d:%s", val.type.short_name(),
@ -2168,21 +2169,22 @@ class WasmFullDecoder : public WasmDecoder<validate> {
if (decoder_->failed()) continue;
switch (val_opcode) {
case kExprI32Const: {
ImmI32Immediate<Decoder::kNoValidate> imm(decoder_, val.pc + 1);
ImmI32Immediate<Decoder::kNoValidation> imm(decoder_, val.pc + 1);
Append("[%d]", imm.value);
break;
}
case kExprLocalGet:
case kExprLocalSet:
case kExprLocalTee: {
LocalIndexImmediate<Decoder::kNoValidate> imm(decoder_, val.pc + 1);
LocalIndexImmediate<Decoder::kNoValidation> imm(decoder_,
val.pc + 1);
Append("[%u]", imm.index);
break;
}
case kExprGlobalGet:
case kExprGlobalSet: {
GlobalIndexImmediate<Decoder::kNoValidate> imm(decoder_,
val.pc + 1);
GlobalIndexImmediate<Decoder::kNoValidation> imm(decoder_,
val.pc + 1);
Append("[%u]", imm.index);
break;
}
@ -4350,7 +4352,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
class EmptyInterface {
public:
static constexpr Decoder::ValidateFlag validate = Decoder::kValidate;
static constexpr Decoder::ValidateFlag validate = Decoder::kFullValidation;
using Value = ValueBase;
using Control = ControlBase<Value>;
using FullDecoder = WasmFullDecoder<validate, EmptyInterface>;

View File

@ -23,8 +23,8 @@ bool DecodeLocalDecls(const WasmFeatures& enabled, BodyLocalDecls* decls,
const byte* start, const byte* end) {
WasmFeatures no_features = WasmFeatures::None();
Zone* zone = decls->type_list.get_allocator().zone();
WasmDecoder<Decoder::kValidate> decoder(zone, nullptr, enabled, &no_features,
nullptr, start, end, 0);
WasmDecoder<Decoder::kFullValidation> decoder(
zone, nullptr, enabled, &no_features, nullptr, start, end, 0);
uint32_t length;
if (!decoder.DecodeLocals(decoder.pc(), &length, 0)) {
decls->encoded_size = 0;
@ -54,7 +54,7 @@ DecodeResult VerifyWasmCode(AccountingAllocator* allocator,
const WasmModule* module, WasmFeatures* detected,
const FunctionBody& body) {
Zone zone(allocator, ZONE_NAME);
WasmFullDecoder<Decoder::kValidate, EmptyInterface> decoder(
WasmFullDecoder<Decoder::kFullValidation, EmptyInterface> decoder(
&zone, module, enabled, detected, body);
decoder.Decode();
return decoder.toResult(nullptr);
@ -65,9 +65,9 @@ unsigned OpcodeLength(const byte* pc, const byte* end) {
Zone* no_zone = nullptr;
WasmModule* no_module = nullptr;
FunctionSig* no_sig = nullptr;
WasmDecoder<Decoder::kNoValidate> decoder(no_zone, no_module, no_features,
&no_features, no_sig, pc, end, 0);
return WasmDecoder<Decoder::kNoValidate>::OpcodeLength(&decoder, pc);
WasmDecoder<Decoder::kNoValidation> decoder(no_zone, no_module, no_features,
&no_features, no_sig, pc, end, 0);
return WasmDecoder<Decoder::kNoValidation>::OpcodeLength(&decoder, pc);
}
std::pair<uint32_t, uint32_t> StackEffect(const WasmModule* module,
@ -75,7 +75,7 @@ std::pair<uint32_t, uint32_t> StackEffect(const WasmModule* module,
const byte* pc, const byte* end) {
WasmFeatures unused_detected_features = WasmFeatures::None();
Zone* no_zone = nullptr;
WasmDecoder<Decoder::kNoValidate> decoder(
WasmDecoder<Decoder::kNoValidation> decoder(
no_zone, module, WasmFeatures::All(), &unused_detected_features, sig, pc,
end);
return decoder.StackEffect(pc);
@ -124,9 +124,9 @@ bool PrintRawWasmCode(AccountingAllocator* allocator, const FunctionBody& body,
std::ostream& os, std::vector<int>* line_numbers) {
Zone zone(allocator, ZONE_NAME);
WasmFeatures unused_detected_features = WasmFeatures::None();
WasmDecoder<Decoder::kNoValidate> decoder(&zone, module, WasmFeatures::All(),
&unused_detected_features, body.sig,
body.start, body.end);
WasmDecoder<Decoder::kNoValidation> decoder(
&zone, module, WasmFeatures::All(), &unused_detected_features, body.sig,
body.start, body.end);
int line_nr = 0;
constexpr int kNoByteCode = -1;
@ -174,7 +174,7 @@ bool PrintRawWasmCode(AccountingAllocator* allocator, const FunctionBody& body,
unsigned control_depth = 0;
for (; i.has_next(); i.next()) {
unsigned length =
WasmDecoder<Decoder::kNoValidate>::OpcodeLength(&decoder, i.pc());
WasmDecoder<Decoder::kNoValidation>::OpcodeLength(&decoder, i.pc());
unsigned offset = 1;
WasmOpcode opcode = i.current();
@ -243,8 +243,8 @@ bool PrintRawWasmCode(AccountingAllocator* allocator, const FunctionBody& body,
case kExprIf:
case kExprBlock:
case kExprTry: {
BlockTypeImmediate<Decoder::kNoValidate> imm(WasmFeatures::All(), &i,
i.pc() + 1);
BlockTypeImmediate<Decoder::kNoValidation> imm(WasmFeatures::All(), &i,
i.pc() + 1);
os << " @" << i.pc_offset();
if (decoder.Complete(imm)) {
for (uint32_t i = 0; i < imm.out_arity(); i++) {
@ -259,23 +259,23 @@ bool PrintRawWasmCode(AccountingAllocator* allocator, const FunctionBody& body,
control_depth--;
break;
case kExprBr: {
BranchDepthImmediate<Decoder::kNoValidate> imm(&i, i.pc() + 1);
BranchDepthImmediate<Decoder::kNoValidation> imm(&i, i.pc() + 1);
os << " depth=" << imm.depth;
break;
}
case kExprBrIf: {
BranchDepthImmediate<Decoder::kNoValidate> imm(&i, i.pc() + 1);
BranchDepthImmediate<Decoder::kNoValidation> imm(&i, i.pc() + 1);
os << " depth=" << imm.depth;
break;
}
case kExprBrTable: {
BranchTableImmediate<Decoder::kNoValidate> imm(&i, i.pc() + 1);
BranchTableImmediate<Decoder::kNoValidation> imm(&i, i.pc() + 1);
os << " entries=" << imm.table_count;
break;
}
case kExprCallIndirect: {
CallIndirectImmediate<Decoder::kNoValidate> imm(WasmFeatures::All(), &i,
i.pc() + 1);
CallIndirectImmediate<Decoder::kNoValidation> imm(WasmFeatures::All(),
&i, i.pc() + 1);
os << " sig #" << imm.sig_index;
if (decoder.Complete(imm)) {
os << ": " << *imm.sig;
@ -283,7 +283,7 @@ bool PrintRawWasmCode(AccountingAllocator* allocator, const FunctionBody& body,
break;
}
case kExprCallFunction: {
CallFunctionImmediate<Decoder::kNoValidate> imm(&i, i.pc() + 1);
CallFunctionImmediate<Decoder::kNoValidation> imm(&i, i.pc() + 1);
os << " function #" << imm.index;
if (decoder.Complete(imm)) {
os << ": " << *imm.sig;
@ -304,9 +304,9 @@ bool PrintRawWasmCode(AccountingAllocator* allocator, const FunctionBody& body,
BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals,
const byte* start, const byte* end) {
WasmFeatures no_features = WasmFeatures::None();
WasmDecoder<Decoder::kValidate> decoder(zone, nullptr, no_features,
&no_features, nullptr, start, end, 0);
return WasmDecoder<Decoder::kValidate>::AnalyzeLoopAssignment(
WasmDecoder<Decoder::kFullValidation> decoder(
zone, nullptr, no_features, &no_features, nullptr, start, end, 0);
return WasmDecoder<Decoder::kFullValidation>::AnalyzeLoopAssignment(
&decoder, start, static_cast<uint32_t>(num_locals), zone);
}

View File

@ -163,7 +163,7 @@ class V8_EXPORT_PRIVATE BytecodeIterator : public NON_EXPORTED_BASE(Decoder) {
WasmOpcode current() {
return static_cast<WasmOpcode>(
read_u8<Decoder::kNoValidate>(pc_, "expected bytecode"));
read_u8<Decoder::kNoValidation>(pc_, "expected bytecode"));
}
void next() {
@ -176,7 +176,7 @@ class V8_EXPORT_PRIVATE BytecodeIterator : public NON_EXPORTED_BASE(Decoder) {
bool has_next() { return pc_ < end_; }
WasmOpcode prefixed_opcode() {
return read_prefixed_opcode<Decoder::kNoValidate>(pc_);
return read_prefixed_opcode<Decoder::kNoValidation>(pc_);
}
};

View File

@ -74,7 +74,7 @@ constexpr uint32_t kNullCatch = static_cast<uint32_t>(-1);
class WasmGraphBuildingInterface {
public:
static constexpr Decoder::ValidateFlag validate = Decoder::kValidate;
static constexpr Decoder::ValidateFlag validate = Decoder::kFullValidation;
using FullDecoder = WasmFullDecoder<validate, WasmGraphBuildingInterface>;
using CheckForNull = compiler::WasmGraphBuilder::CheckForNull;
@ -1200,7 +1200,7 @@ DecodeResult BuildTFGraph(AccountingAllocator* allocator,
WasmFeatures* detected, const FunctionBody& body,
compiler::NodeOriginTable* node_origins) {
Zone zone(allocator, ZONE_NAME);
WasmFullDecoder<Decoder::kValidate, WasmGraphBuildingInterface> decoder(
WasmFullDecoder<Decoder::kFullValidation, WasmGraphBuildingInterface> decoder(
&zone, module, enabled, detected, body, builder);
if (node_origins) {
builder->AddBytecodePositionDecorator(node_origins, &decoder);

View File

@ -1618,7 +1618,8 @@ class ModuleDecoderImpl : public Decoder {
// TODO(manoskouk): This is copy-modified from function-body-decoder-impl.h.
// We should find a way to share this code.
V8_INLINE bool Validate(const byte* pc, HeapTypeImmediate<kValidate>& imm) {
V8_INLINE bool Validate(const byte* pc,
HeapTypeImmediate<kFullValidation>& imm) {
if (V8_UNLIKELY(imm.type.is_bottom())) {
error(pc, "invalid heap type");
return false;
@ -1633,7 +1634,7 @@ class ModuleDecoderImpl : public Decoder {
WasmInitExpr consume_init_expr(WasmModule* module, ValueType expected,
size_t current_global_index) {
constexpr Decoder::ValidateFlag validate = Decoder::kValidate;
constexpr Decoder::ValidateFlag validate = Decoder::kFullValidation;
WasmOpcode opcode = kExprNop;
std::vector<WasmInitExpr> stack;
while (pc() < end() && opcode != kExprEnd) {
@ -1670,25 +1671,25 @@ class ModuleDecoderImpl : public Decoder {
break;
}
case kExprI32Const: {
ImmI32Immediate<Decoder::kValidate> imm(this, pc() + 1);
ImmI32Immediate<Decoder::kFullValidation> imm(this, pc() + 1);
stack.emplace_back(imm.value);
len = 1 + imm.length;
break;
}
case kExprF32Const: {
ImmF32Immediate<Decoder::kValidate> imm(this, pc() + 1);
ImmF32Immediate<Decoder::kFullValidation> imm(this, pc() + 1);
stack.emplace_back(imm.value);
len = 1 + imm.length;
break;
}
case kExprI64Const: {
ImmI64Immediate<Decoder::kValidate> imm(this, pc() + 1);
ImmI64Immediate<Decoder::kFullValidation> imm(this, pc() + 1);
stack.emplace_back(imm.value);
len = 1 + imm.length;
break;
}
case kExprF64Const: {
ImmF64Immediate<Decoder::kValidate> imm(this, pc() + 1);
ImmF64Immediate<Decoder::kFullValidation> imm(this, pc() + 1);
stack.emplace_back(imm.value);
len = 1 + imm.length;
break;
@ -1702,8 +1703,8 @@ class ModuleDecoderImpl : public Decoder {
kExprRefNull);
return {};
}
HeapTypeImmediate<Decoder::kValidate> imm(enabled_features_, this,
pc() + 1);
HeapTypeImmediate<Decoder::kFullValidation> imm(enabled_features_,
this, pc() + 1);
len = 1 + imm.length;
if (!Validate(pc() + 1, imm)) return {};
stack.push_back(
@ -1719,7 +1720,7 @@ class ModuleDecoderImpl : public Decoder {
return {};
}
FunctionIndexImmediate<Decoder::kValidate> imm(this, pc() + 1);
FunctionIndexImmediate<Decoder::kFullValidation> imm(this, pc() + 1);
len = 1 + imm.length;
if (V8_UNLIKELY(module->functions.size() <= imm.index)) {
errorf(pc(), "invalid function index: %u", imm.index);
@ -1836,7 +1837,7 @@ class ModuleDecoderImpl : public Decoder {
ValueType consume_value_type() {
uint32_t type_length;
ValueType result = value_type_reader::read_value_type<kValidate>(
ValueType result = value_type_reader::read_value_type<kFullValidation>(
this, this->pc(), &type_length,
origin_ == kWasmOrigin ? enabled_features_ : WasmFeatures::None());
if (result == kWasmBottom) error(pc_, "invalid value type");
@ -1850,7 +1851,7 @@ class ModuleDecoderImpl : public Decoder {
}
ValueType consume_storage_type() {
uint8_t opcode = read_u8<kValidate>(this->pc());
uint8_t opcode = read_u8<kFullValidation>(this->pc());
switch (opcode) {
case kI8Code:
consume_bytes(1, "i8");
@ -2133,7 +2134,8 @@ class ModuleDecoderImpl : public Decoder {
if (failed()) return index;
switch (opcode) {
case kExprRefNull: {
HeapTypeImmediate<kValidate> imm(WasmFeatures::All(), this, this->pc());
HeapTypeImmediate<kFullValidation> imm(WasmFeatures::All(), this,
this->pc());
consume_bytes(imm.length, "ref.null immediate");
index = WasmElemSegment::kNullIndex;
break;

View File

@ -798,8 +798,8 @@ class SideTable : public ZoneObject {
case kExprBlock:
case kExprLoop: {
bool is_loop = opcode == kExprLoop;
BlockTypeImmediate<Decoder::kNoValidate> imm(WasmFeatures::All(), &i,
i.pc() + 1);
BlockTypeImmediate<Decoder::kNoValidation> imm(WasmFeatures::All(),
&i, i.pc() + 1);
if (imm.type == kWasmBottom) {
imm.sig = module->signature(imm.sig_index);
}
@ -820,8 +820,8 @@ class SideTable : public ZoneObject {
break;
}
case kExprIf: {
BlockTypeImmediate<Decoder::kNoValidate> imm(WasmFeatures::All(), &i,
i.pc() + 1);
BlockTypeImmediate<Decoder::kNoValidation> imm(WasmFeatures::All(),
&i, i.pc() + 1);
if (imm.type == kWasmBottom) {
imm.sig = module->signature(imm.sig_index);
}
@ -860,8 +860,8 @@ class SideTable : public ZoneObject {
break;
}
case kExprTry: {
BlockTypeImmediate<Decoder::kNoValidate> imm(WasmFeatures::All(), &i,
i.pc() + 1);
BlockTypeImmediate<Decoder::kNoValidation> imm(WasmFeatures::All(),
&i, i.pc() + 1);
if (imm.type == kWasmBottom) {
imm.sig = module->signature(imm.sig_index);
}
@ -896,7 +896,8 @@ class SideTable : public ZoneObject {
break;
}
case kExprBrOnExn: {
BranchOnExceptionImmediate<Decoder::kNoValidate> imm(&i, i.pc() + 1);
BranchOnExceptionImmediate<Decoder::kNoValidation> imm(&i,
i.pc() + 1);
uint32_t depth = imm.depth.depth; // Extracted for convenience.
imm.index.exception = &module->exceptions[imm.index.index];
DCHECK_EQ(0, imm.index.exception->sig->return_count());
@ -925,22 +926,22 @@ class SideTable : public ZoneObject {
break;
}
case kExprBr: {
BranchDepthImmediate<Decoder::kNoValidate> imm(&i, i.pc() + 1);
BranchDepthImmediate<Decoder::kNoValidation> imm(&i, i.pc() + 1);
TRACE("control @%u: Br[depth=%u]\n", i.pc_offset(), imm.depth);
Control* c = &control_stack[control_stack.size() - imm.depth - 1];
if (!unreachable) c->end_label->Ref(i.pc(), stack_height);
break;
}
case kExprBrIf: {
BranchDepthImmediate<Decoder::kNoValidate> imm(&i, i.pc() + 1);
BranchDepthImmediate<Decoder::kNoValidation> imm(&i, i.pc() + 1);
TRACE("control @%u: BrIf[depth=%u]\n", i.pc_offset(), imm.depth);
Control* c = &control_stack[control_stack.size() - imm.depth - 1];
if (!unreachable) c->end_label->Ref(i.pc(), stack_height);
break;
}
case kExprBrTable: {
BranchTableImmediate<Decoder::kNoValidate> imm(&i, i.pc() + 1);
BranchTableIterator<Decoder::kNoValidate> iterator(&i, imm);
BranchTableImmediate<Decoder::kNoValidation> imm(&i, i.pc() + 1);
BranchTableIterator<Decoder::kNoValidation> iterator(&i, imm);
TRACE("control @%u: BrTable[count=%u]\n", i.pc_offset(),
imm.table_count);
if (!unreachable) {
@ -1381,12 +1382,12 @@ class WasmInterpreterInternals {
pc_t ReturnPc(Decoder* decoder, InterpreterCode* code, pc_t pc) {
switch (code->start[pc]) {
case kExprCallFunction: {
CallFunctionImmediate<Decoder::kNoValidate> imm(decoder,
code->at(pc + 1));
CallFunctionImmediate<Decoder::kNoValidation> imm(decoder,
code->at(pc + 1));
return pc + 1 + imm.length;
}
case kExprCallIndirect: {
CallIndirectImmediate<Decoder::kNoValidate> imm(
CallIndirectImmediate<Decoder::kNoValidation> imm(
WasmFeatures::All(), decoder, code->at(pc + 1));
return pc + 1 + imm.length;
}
@ -1529,7 +1530,7 @@ class WasmInterpreterInternals {
// increment pc at the caller, because we want to keep pc to the start of
// the operation to keep trap reporting and tracing accurate, otherwise
// those will report at the middle of an opcode.
MemoryAccessImmediate<Decoder::kNoValidate> imm(
MemoryAccessImmediate<Decoder::kNoValidation> imm(
decoder, code->at(pc + prefix_len), sizeof(ctype));
uint32_t index = Pop().to<uint32_t>();
Address addr = BoundsCheckMem<mtype>(imm.offset, index);
@ -1561,7 +1562,7 @@ class WasmInterpreterInternals {
// increment pc at the caller, because we want to keep pc to the start of
// the operation to keep trap reporting and tracing accurate, otherwise
// those will report at the middle of an opcode.
MemoryAccessImmediate<Decoder::kNoValidate> imm(
MemoryAccessImmediate<Decoder::kNoValidation> imm(
decoder, code->at(pc + prefix_len), sizeof(ctype));
ctype val = Pop().to<ctype>();
@ -1588,8 +1589,8 @@ class WasmInterpreterInternals {
bool ExtractAtomicOpParams(Decoder* decoder, InterpreterCode* code,
Address* address, pc_t pc, int* const len,
type* val = nullptr, type* val2 = nullptr) {
MemoryAccessImmediate<Decoder::kNoValidate> imm(decoder, code->at(pc + 2),
sizeof(type));
MemoryAccessImmediate<Decoder::kNoValidation> imm(decoder, code->at(pc + 2),
sizeof(type));
if (val2) *val2 = static_cast<type>(Pop().to<op_type>());
if (val) *val = static_cast<type>(Pop().to<op_type>());
uint32_t index = Pop().to<uint32_t>();
@ -1612,8 +1613,8 @@ class WasmInterpreterInternals {
uint32_t* buffer_offset, type* val,
int64_t* timeout = nullptr) {
// TODO(manoskouk): Introduce test which exposes wrong pc offset below.
MemoryAccessImmediate<Decoder::kValidate> imm(decoder, code->at(pc + *len),
sizeof(type));
MemoryAccessImmediate<Decoder::kFullValidation> imm(
decoder, code->at(pc + *len), sizeof(type));
if (timeout) {
*timeout = Pop().to<int64_t>();
}
@ -1664,8 +1665,8 @@ class WasmInterpreterInternals {
Push(WasmValue(ExecuteI64UConvertSatF64(Pop().to<double>())));
return true;
case kExprMemoryInit: {
MemoryInitImmediate<Decoder::kNoValidate> imm(decoder,
code->at(pc + 2));
MemoryInitImmediate<Decoder::kNoValidation> imm(decoder,
code->at(pc + 2));
// The data segment index must be in bounds since it is required by
// validation.
DCHECK_LT(imm.data_segment_index, module()->num_declared_data_segments);
@ -1689,7 +1690,8 @@ class WasmInterpreterInternals {
return true;
}
case kExprDataDrop: {
DataDropImmediate<Decoder::kNoValidate> imm(decoder, code->at(pc + 2));
DataDropImmediate<Decoder::kNoValidation> imm(decoder,
code->at(pc + 2));
// The data segment index must be in bounds since it is required by
// validation.
DCHECK_LT(imm.index, module()->num_declared_data_segments);
@ -1698,8 +1700,8 @@ class WasmInterpreterInternals {
return true;
}
case kExprMemoryCopy: {
MemoryCopyImmediate<Decoder::kNoValidate> imm(decoder,
code->at(pc + 2));
MemoryCopyImmediate<Decoder::kNoValidation> imm(decoder,
code->at(pc + 2));
*len += imm.length;
auto size = Pop().to<uint32_t>();
auto src = Pop().to<uint32_t>();
@ -1717,8 +1719,8 @@ class WasmInterpreterInternals {
return true;
}
case kExprMemoryFill: {
MemoryIndexImmediate<Decoder::kNoValidate> imm(decoder,
code->at(pc + 2));
MemoryIndexImmediate<Decoder::kNoValidation> imm(decoder,
code->at(pc + 2));
*len += imm.length;
auto size = Pop().to<uint32_t>();
auto value = Pop().to<uint32_t>();
@ -1733,7 +1735,8 @@ class WasmInterpreterInternals {
return true;
}
case kExprTableInit: {
TableInitImmediate<Decoder::kNoValidate> imm(decoder, code->at(pc + 2));
TableInitImmediate<Decoder::kNoValidation> imm(decoder,
code->at(pc + 2));
*len += imm.length;
auto size = Pop().to<uint32_t>();
auto src = Pop().to<uint32_t>();
@ -1746,13 +1749,15 @@ class WasmInterpreterInternals {
return ok;
}
case kExprElemDrop: {
ElemDropImmediate<Decoder::kNoValidate> imm(decoder, code->at(pc + 2));
ElemDropImmediate<Decoder::kNoValidation> imm(decoder,
code->at(pc + 2));
*len += imm.length;
instance_object_->dropped_elem_segments()[imm.index] = 1;
return true;
}
case kExprTableCopy: {
TableCopyImmediate<Decoder::kNoValidate> imm(decoder, code->at(pc + 2));
TableCopyImmediate<Decoder::kNoValidation> imm(decoder,
code->at(pc + 2));
auto size = Pop().to<uint32_t>();
auto src = Pop().to<uint32_t>();
auto dst = Pop().to<uint32_t>();
@ -1765,8 +1770,8 @@ class WasmInterpreterInternals {
return ok;
}
case kExprTableGrow: {
TableIndexImmediate<Decoder::kNoValidate> imm(decoder,
code->at(pc + 2));
TableIndexImmediate<Decoder::kNoValidation> imm(decoder,
code->at(pc + 2));
HandleScope handle_scope(isolate_);
auto table = handle(
WasmTableObject::cast(instance_object_->tables().get(imm.index)),
@ -1779,8 +1784,8 @@ class WasmInterpreterInternals {
return true;
}
case kExprTableSize: {
TableIndexImmediate<Decoder::kNoValidate> imm(decoder,
code->at(pc + 2));
TableIndexImmediate<Decoder::kNoValidation> imm(decoder,
code->at(pc + 2));
HandleScope handle_scope(isolate_);
auto table = handle(
WasmTableObject::cast(instance_object_->tables().get(imm.index)),
@ -1791,8 +1796,8 @@ class WasmInterpreterInternals {
return true;
}
case kExprTableFill: {
TableIndexImmediate<Decoder::kNoValidate> imm(decoder,
code->at(pc + 2));
TableIndexImmediate<Decoder::kNoValidation> imm(decoder,
code->at(pc + 2));
HandleScope handle_scope(isolate_);
auto count = Pop().to<uint32_t>();
auto value = Pop().to_externref();
@ -2099,15 +2104,16 @@ class WasmInterpreterInternals {
SPLAT_CASE(I16x8, int8, int32_t, 8)
SPLAT_CASE(I8x16, int16, int32_t, 16)
#undef SPLAT_CASE
#define EXTRACT_LANE_CASE(format, name) \
case kExpr##format##ExtractLane: { \
SimdLaneImmediate<Decoder::kNoValidate> imm(decoder, code->at(pc + *len)); \
*len += 1; \
WasmValue val = Pop(); \
Simd128 s = val.to_s128(); \
auto ss = s.to_##name(); \
Push(WasmValue(ss.val[LANE(imm.lane, ss)])); \
return true; \
#define EXTRACT_LANE_CASE(format, name) \
case kExpr##format##ExtractLane: { \
SimdLaneImmediate<Decoder::kNoValidation> imm(decoder, \
code->at(pc + *len)); \
*len += 1; \
WasmValue val = Pop(); \
Simd128 s = val.to_s128(); \
auto ss = s.to_##name(); \
Push(WasmValue(ss.val[LANE(imm.lane, ss)])); \
return true; \
}
EXTRACT_LANE_CASE(F64x2, f64x2)
EXTRACT_LANE_CASE(F32x4, f32x4)
@ -2121,23 +2127,24 @@ class WasmInterpreterInternals {
// unsigned extracts, we will cast it int8_t -> uint8_t -> uint32_t. We
// add the DCHECK to ensure that if the array type changes, we know to
// change this function.
#define EXTRACT_LANE_EXTEND_CASE(format, name, sign, extended_type) \
case kExpr##format##ExtractLane##sign: { \
SimdLaneImmediate<Decoder::kNoValidate> imm(decoder, code->at(pc + *len)); \
*len += 1; \
WasmValue val = Pop(); \
Simd128 s = val.to_s128(); \
auto ss = s.to_##name(); \
auto res = ss.val[LANE(imm.lane, ss)]; \
DCHECK(std::is_signed<decltype(res)>::value); \
if (std::is_unsigned<extended_type>::value) { \
using unsigned_type = std::make_unsigned<decltype(res)>::type; \
Push(WasmValue( \
static_cast<extended_type>(static_cast<unsigned_type>(res)))); \
} else { \
Push(WasmValue(static_cast<extended_type>(res))); \
} \
return true; \
#define EXTRACT_LANE_EXTEND_CASE(format, name, sign, extended_type) \
case kExpr##format##ExtractLane##sign: { \
SimdLaneImmediate<Decoder::kNoValidation> imm(decoder, \
code->at(pc + *len)); \
*len += 1; \
WasmValue val = Pop(); \
Simd128 s = val.to_s128(); \
auto ss = s.to_##name(); \
auto res = ss.val[LANE(imm.lane, ss)]; \
DCHECK(std::is_signed<decltype(res)>::value); \
if (std::is_unsigned<extended_type>::value) { \
using unsigned_type = std::make_unsigned<decltype(res)>::type; \
Push(WasmValue( \
static_cast<extended_type>(static_cast<unsigned_type>(res)))); \
} else { \
Push(WasmValue(static_cast<extended_type>(res))); \
} \
return true; \
}
EXTRACT_LANE_EXTEND_CASE(I16x8, i16x8, S, int32_t)
EXTRACT_LANE_EXTEND_CASE(I16x8, i16x8, U, uint32_t)
@ -2378,16 +2385,17 @@ class WasmInterpreterInternals {
CMPOP_CASE(I8x16LeU, i8x16, int16, int16, 16,
static_cast<uint8_t>(a) <= static_cast<uint8_t>(b))
#undef CMPOP_CASE
#define REPLACE_LANE_CASE(format, name, stype, ctype) \
case kExpr##format##ReplaceLane: { \
SimdLaneImmediate<Decoder::kNoValidate> imm(decoder, code->at(pc + *len)); \
*len += 1; \
WasmValue new_val = Pop(); \
WasmValue simd_val = Pop(); \
stype s = simd_val.to_s128().to_##name(); \
s.val[LANE(imm.lane, s)] = new_val.to<ctype>(); \
Push(WasmValue(Simd128(s))); \
return true; \
#define REPLACE_LANE_CASE(format, name, stype, ctype) \
case kExpr##format##ReplaceLane: { \
SimdLaneImmediate<Decoder::kNoValidation> imm(decoder, \
code->at(pc + *len)); \
*len += 1; \
WasmValue new_val = Pop(); \
WasmValue simd_val = Pop(); \
stype s = simd_val.to_s128().to_##name(); \
s.val[LANE(imm.lane, s)] = new_val.to<ctype>(); \
Push(WasmValue(Simd128(s))); \
return true; \
}
REPLACE_LANE_CASE(F64x2, f64x2, float2, double)
REPLACE_LANE_CASE(F32x4, f32x4, float4, float)
@ -2552,8 +2560,8 @@ class WasmInterpreterInternals {
return true;
}
case kExprS128Const: {
Simd128Immediate<Decoder::kNoValidate> imm(decoder,
code->at(pc + *len));
Simd128Immediate<Decoder::kNoValidation> imm(decoder,
code->at(pc + *len));
int16 res;
for (size_t i = 0; i < kSimd128Size; ++i) {
res.val[LANE(i, res)] = imm.value[i];
@ -2575,8 +2583,8 @@ class WasmInterpreterInternals {
return true;
}
case kExprI8x16Shuffle: {
Simd128Immediate<Decoder::kNoValidate> imm(decoder,
code->at(pc + *len));
Simd128Immediate<Decoder::kNoValidation> imm(decoder,
code->at(pc + *len));
*len += 16;
int16 v2 = Pop().to_s128().to_i8x16();
int16 v1 = Pop().to_s128().to_i8x16();
@ -3004,7 +3012,7 @@ class WasmInterpreterInternals {
// 'len'.
if (WasmOpcodes::IsPrefixOpcode(opcode)) {
uint32_t prefixed_opcode_length = 0;
opcode = decoder.read_prefixed_opcode<Decoder::kNoValidate>(
opcode = decoder.read_prefixed_opcode<Decoder::kNoValidation>(
code->at(pc), &prefixed_opcode_length);
len += prefixed_opcode_length;
}
@ -3035,13 +3043,13 @@ class WasmInterpreterInternals {
case kExprBlock:
case kExprLoop:
case kExprTry: {
BlockTypeImmediate<Decoder::kNoValidate> imm(
BlockTypeImmediate<Decoder::kNoValidation> imm(
WasmFeatures::All(), &decoder, code->at(pc + 1));
len = 1 + imm.length;
break;
}
case kExprIf: {
BlockTypeImmediate<Decoder::kNoValidate> imm(
BlockTypeImmediate<Decoder::kNoValidation> imm(
WasmFeatures::All(), &decoder, code->at(pc + 1));
WasmValue cond = Pop();
bool is_true = cond.to<uint32_t>() != 0;
@ -3062,8 +3070,8 @@ class WasmInterpreterInternals {
break;
}
case kExprThrow: {
ExceptionIndexImmediate<Decoder::kNoValidate> imm(&decoder,
code->at(pc + 1));
ExceptionIndexImmediate<Decoder::kNoValidation> imm(&decoder,
code->at(pc + 1));
CommitPc(pc); // Needed for local unwinding.
const WasmException* exception = &module()->exceptions[imm.index];
if (!DoThrowException(exception, imm.index)) return;
@ -3082,7 +3090,7 @@ class WasmInterpreterInternals {
continue; // Do not bump pc.
}
case kExprBrOnExn: {
BranchOnExceptionImmediate<Decoder::kNoValidate> imm(
BranchOnExceptionImmediate<Decoder::kNoValidation> imm(
&decoder, code->at(pc + 1));
HandleScope handle_scope(isolate_); // Avoid leaking handles.
WasmValue ex = Pop();
@ -3101,7 +3109,7 @@ class WasmInterpreterInternals {
break;
}
case kExprSelectWithType: {
SelectTypeImmediate<Decoder::kNoValidate> imm(
SelectTypeImmediate<Decoder::kNoValidation> imm(
WasmFeatures::All(), &decoder, code->at(pc + 1));
len = 1 + imm.length;
V8_FALLTHROUGH;
@ -3115,15 +3123,15 @@ class WasmInterpreterInternals {
break;
}
case kExprBr: {
BranchDepthImmediate<Decoder::kNoValidate> imm(&decoder,
code->at(pc + 1));
BranchDepthImmediate<Decoder::kNoValidation> imm(&decoder,
code->at(pc + 1));
len = DoBreak(code, pc, imm.depth);
TRACE(" br => @%zu\n", pc + len);
break;
}
case kExprBrIf: {
BranchDepthImmediate<Decoder::kNoValidate> imm(&decoder,
code->at(pc + 1));
BranchDepthImmediate<Decoder::kNoValidation> imm(&decoder,
code->at(pc + 1));
WasmValue cond = Pop();
bool is_true = cond.to<uint32_t>() != 0;
if (is_true) {
@ -3136,9 +3144,9 @@ class WasmInterpreterInternals {
break;
}
case kExprBrTable: {
BranchTableImmediate<Decoder::kNoValidate> imm(&decoder,
code->at(pc + 1));
BranchTableIterator<Decoder::kNoValidate> iterator(&decoder, imm);
BranchTableImmediate<Decoder::kNoValidation> imm(&decoder,
code->at(pc + 1));
BranchTableIterator<Decoder::kNoValidation> iterator(&decoder, imm);
uint32_t key = Pop().to<uint32_t>();
uint32_t depth = 0;
if (key >= imm.table_count) key = imm.table_count;
@ -3162,39 +3170,43 @@ class WasmInterpreterInternals {
break;
}
case kExprI32Const: {
ImmI32Immediate<Decoder::kNoValidate> imm(&decoder, code->at(pc + 1));
ImmI32Immediate<Decoder::kNoValidation> imm(&decoder,
code->at(pc + 1));
Push(WasmValue(imm.value));
len = 1 + imm.length;
break;
}
case kExprI64Const: {
ImmI64Immediate<Decoder::kNoValidate> imm(&decoder, code->at(pc + 1));
ImmI64Immediate<Decoder::kNoValidation> imm(&decoder,
code->at(pc + 1));
Push(WasmValue(imm.value));
len = 1 + imm.length;
break;
}
case kExprF32Const: {
ImmF32Immediate<Decoder::kNoValidate> imm(&decoder, code->at(pc + 1));
ImmF32Immediate<Decoder::kNoValidation> imm(&decoder,
code->at(pc + 1));
Push(WasmValue(imm.value));
len = 1 + imm.length;
break;
}
case kExprF64Const: {
ImmF64Immediate<Decoder::kNoValidate> imm(&decoder, code->at(pc + 1));
ImmF64Immediate<Decoder::kNoValidation> imm(&decoder,
code->at(pc + 1));
Push(WasmValue(imm.value));
len = 1 + imm.length;
break;
}
case kExprRefNull: {
HeapTypeImmediate<Decoder::kNoValidate> imm(
HeapTypeImmediate<Decoder::kNoValidation> imm(
WasmFeatures::All(), &decoder, code->at(pc + 1));
len = 1 + imm.length;
Push(WasmValue(isolate_->factory()->null_value()));
break;
}
case kExprRefFunc: {
FunctionIndexImmediate<Decoder::kNoValidate> imm(&decoder,
code->at(pc + 1));
FunctionIndexImmediate<Decoder::kNoValidation> imm(&decoder,
code->at(pc + 1));
HandleScope handle_scope(isolate_); // Avoid leaking handles.
Handle<WasmExternalFunction> function =
@ -3205,16 +3217,16 @@ class WasmInterpreterInternals {
break;
}
case kExprLocalGet: {
LocalIndexImmediate<Decoder::kNoValidate> imm(&decoder,
code->at(pc + 1));
LocalIndexImmediate<Decoder::kNoValidation> imm(&decoder,
code->at(pc + 1));
HandleScope handle_scope(isolate_); // Avoid leaking handles.
Push(GetStackValue(frames_.back().sp + imm.index));
len = 1 + imm.length;
break;
}
case kExprLocalSet: {
LocalIndexImmediate<Decoder::kNoValidate> imm(&decoder,
code->at(pc + 1));
LocalIndexImmediate<Decoder::kNoValidation> imm(&decoder,
code->at(pc + 1));
HandleScope handle_scope(isolate_); // Avoid leaking handles.
WasmValue val = Pop();
SetStackValue(frames_.back().sp + imm.index, val);
@ -3222,8 +3234,8 @@ class WasmInterpreterInternals {
break;
}
case kExprLocalTee: {
LocalIndexImmediate<Decoder::kNoValidate> imm(&decoder,
code->at(pc + 1));
LocalIndexImmediate<Decoder::kNoValidation> imm(&decoder,
code->at(pc + 1));
HandleScope handle_scope(isolate_); // Avoid leaking handles.
WasmValue val = Pop();
SetStackValue(frames_.back().sp + imm.index, val);
@ -3236,8 +3248,8 @@ class WasmInterpreterInternals {
break;
}
case kExprCallFunction: {
CallFunctionImmediate<Decoder::kNoValidate> imm(&decoder,
code->at(pc + 1));
CallFunctionImmediate<Decoder::kNoValidation> imm(&decoder,
code->at(pc + 1));
InterpreterCode* target = codemap_.GetCode(imm.index);
CHECK(!target->function->imported);
// Execute an internal call.
@ -3247,7 +3259,7 @@ class WasmInterpreterInternals {
} break;
case kExprCallIndirect: {
CallIndirectImmediate<Decoder::kNoValidate> imm(
CallIndirectImmediate<Decoder::kNoValidation> imm(
WasmFeatures::All(), &decoder, code->at(pc + 1));
uint32_t entry_index = Pop().to<uint32_t>();
CommitPc(pc); // TODO(wasm): Be more disciplined about committing PC.
@ -3271,8 +3283,8 @@ class WasmInterpreterInternals {
// Make return calls more expensive, so that return call recursions
// don't cause a timeout.
if (max > 0) max = std::max(0, max - 100);
CallFunctionImmediate<Decoder::kNoValidate> imm(&decoder,
code->at(pc + 1));
CallFunctionImmediate<Decoder::kNoValidation> imm(&decoder,
code->at(pc + 1));
InterpreterCode* target = codemap_.GetCode(imm.index);
CHECK(!target->function->imported);
@ -3286,7 +3298,7 @@ class WasmInterpreterInternals {
// Make return calls more expensive, so that return call recursions
// don't cause a timeout.
if (max > 0) max = std::max(0, max - 100);
CallIndirectImmediate<Decoder::kNoValidate> imm(
CallIndirectImmediate<Decoder::kNoValidation> imm(
WasmFeatures::All(), &decoder, code->at(pc + 1));
uint32_t entry_index = Pop().to<uint32_t>();
CommitPc(pc); // TODO(wasm): Be more disciplined about committing PC.
@ -3314,8 +3326,8 @@ class WasmInterpreterInternals {
} break;
case kExprGlobalGet: {
GlobalIndexImmediate<Decoder::kNoValidate> imm(&decoder,
code->at(pc + 1));
GlobalIndexImmediate<Decoder::kNoValidation> imm(&decoder,
code->at(pc + 1));
HandleScope handle_scope(isolate_);
Push(WasmInstanceObject::GetGlobalValue(
instance_object_, module()->globals[imm.index]));
@ -3323,8 +3335,8 @@ class WasmInterpreterInternals {
break;
}
case kExprGlobalSet: {
GlobalIndexImmediate<Decoder::kNoValidate> imm(&decoder,
code->at(pc + 1));
GlobalIndexImmediate<Decoder::kNoValidation> imm(&decoder,
code->at(pc + 1));
auto& global = module()->globals[imm.index];
switch (global.type.kind()) {
#define CASE_TYPE(valuetype, ctype) \
@ -3361,8 +3373,8 @@ class WasmInterpreterInternals {
break;
}
case kExprTableGet: {
TableIndexImmediate<Decoder::kNoValidate> imm(&decoder,
code->at(pc + 1));
TableIndexImmediate<Decoder::kNoValidation> imm(&decoder,
code->at(pc + 1));
HandleScope handle_scope(isolate_);
auto table = handle(
WasmTableObject::cast(instance_object_->tables().get(imm.index)),
@ -3379,8 +3391,8 @@ class WasmInterpreterInternals {
break;
}
case kExprTableSet: {
TableIndexImmediate<Decoder::kNoValidate> imm(&decoder,
code->at(pc + 1));
TableIndexImmediate<Decoder::kNoValidation> imm(&decoder,
code->at(pc + 1));
HandleScope handle_scope(isolate_);
auto table = handle(
WasmTableObject::cast(instance_object_->tables().get(imm.index)),
@ -3482,8 +3494,8 @@ class WasmInterpreterInternals {
ASMJS_STORE_CASE(F64AsmjsStoreMem, double, double);
#undef ASMJS_STORE_CASE
case kExprMemoryGrow: {
MemoryIndexImmediate<Decoder::kNoValidate> imm(&decoder,
code->at(pc + 1));
MemoryIndexImmediate<Decoder::kNoValidation> imm(&decoder,
code->at(pc + 1));
uint32_t delta_pages = Pop().to<uint32_t>();
HandleScope handle_scope(isolate_); // Avoid leaking handles.
Handle<WasmMemoryObject> memory(instance_object_->memory_object(),
@ -3498,8 +3510,8 @@ class WasmInterpreterInternals {
break;
}
case kExprMemorySize: {
MemoryIndexImmediate<Decoder::kNoValidate> imm(&decoder,
code->at(pc + 1));
MemoryIndexImmediate<Decoder::kNoValidation> imm(&decoder,
code->at(pc + 1));
Push(WasmValue(static_cast<uint32_t>(instance_object_->memory_size() /
kWasmPageSize)));
len = 1 + imm.length;

View File

@ -20,54 +20,54 @@ class DecoderTest : public TestWithZone {
Decoder decoder;
};
#define CHECK_UINT32V_INLINE(expected, expected_length, ...) \
do { \
const byte data[] = {__VA_ARGS__}; \
decoder.Reset(data, data + sizeof(data)); \
unsigned length; \
EXPECT_EQ( \
static_cast<uint32_t>(expected), \
decoder.read_u32v<Decoder::kValidate>(decoder.start(), &length)); \
EXPECT_EQ(static_cast<unsigned>(expected_length), length); \
EXPECT_EQ(data, decoder.pc()); \
EXPECT_TRUE(decoder.ok()); \
EXPECT_EQ(static_cast<uint32_t>(expected), decoder.consume_u32v()); \
EXPECT_EQ(data + expected_length, decoder.pc()); \
#define CHECK_UINT32V_INLINE(expected, expected_length, ...) \
do { \
const byte data[] = {__VA_ARGS__}; \
decoder.Reset(data, data + sizeof(data)); \
unsigned length; \
EXPECT_EQ(static_cast<uint32_t>(expected), \
decoder.read_u32v<Decoder::kFullValidation>(decoder.start(), \
&length)); \
EXPECT_EQ(static_cast<unsigned>(expected_length), length); \
EXPECT_EQ(data, decoder.pc()); \
EXPECT_TRUE(decoder.ok()); \
EXPECT_EQ(static_cast<uint32_t>(expected), decoder.consume_u32v()); \
EXPECT_EQ(data + expected_length, decoder.pc()); \
} while (false)
#define CHECK_INT32V_INLINE(expected, expected_length, ...) \
do { \
const byte data[] = {__VA_ARGS__}; \
decoder.Reset(data, data + sizeof(data)); \
unsigned length; \
EXPECT_EQ(expected, decoder.read_i32v<Decoder::kValidate>(decoder.start(), \
&length)); \
EXPECT_EQ(static_cast<unsigned>(expected_length), length); \
EXPECT_EQ(data, decoder.pc()); \
EXPECT_TRUE(decoder.ok()); \
EXPECT_EQ(expected, decoder.consume_i32v()); \
EXPECT_EQ(data + expected_length, decoder.pc()); \
#define CHECK_INT32V_INLINE(expected, expected_length, ...) \
do { \
const byte data[] = {__VA_ARGS__}; \
decoder.Reset(data, data + sizeof(data)); \
unsigned length; \
EXPECT_EQ(expected, decoder.read_i32v<Decoder::kFullValidation>( \
decoder.start(), &length)); \
EXPECT_EQ(static_cast<unsigned>(expected_length), length); \
EXPECT_EQ(data, decoder.pc()); \
EXPECT_TRUE(decoder.ok()); \
EXPECT_EQ(expected, decoder.consume_i32v()); \
EXPECT_EQ(data + expected_length, decoder.pc()); \
} while (false)
#define CHECK_UINT64V_INLINE(expected, expected_length, ...) \
do { \
const byte data[] = {__VA_ARGS__}; \
decoder.Reset(data, data + sizeof(data)); \
unsigned length; \
EXPECT_EQ( \
static_cast<uint64_t>(expected), \
decoder.read_u64v<Decoder::kValidate>(decoder.start(), &length)); \
EXPECT_EQ(static_cast<unsigned>(expected_length), length); \
#define CHECK_UINT64V_INLINE(expected, expected_length, ...) \
do { \
const byte data[] = {__VA_ARGS__}; \
decoder.Reset(data, data + sizeof(data)); \
unsigned length; \
EXPECT_EQ(static_cast<uint64_t>(expected), \
decoder.read_u64v<Decoder::kFullValidation>(decoder.start(), \
&length)); \
EXPECT_EQ(static_cast<unsigned>(expected_length), length); \
} while (false)
#define CHECK_INT64V_INLINE(expected, expected_length, ...) \
do { \
const byte data[] = {__VA_ARGS__}; \
decoder.Reset(data, data + sizeof(data)); \
unsigned length; \
EXPECT_EQ(expected, decoder.read_i64v<Decoder::kValidate>(decoder.start(), \
&length)); \
EXPECT_EQ(static_cast<unsigned>(expected_length), length); \
#define CHECK_INT64V_INLINE(expected, expected_length, ...) \
do { \
const byte data[] = {__VA_ARGS__}; \
decoder.Reset(data, data + sizeof(data)); \
unsigned length; \
EXPECT_EQ(expected, decoder.read_i64v<Decoder::kFullValidation>( \
decoder.start(), &length)); \
EXPECT_EQ(static_cast<unsigned>(expected_length), length); \
} while (false)
TEST_F(DecoderTest, ReadU32v_OneByte) {
@ -379,7 +379,7 @@ TEST_F(DecoderTest, ReadU32v_off_end1) {
static const byte data[] = {U32V_1(11)};
unsigned length = 0;
decoder.Reset(data, data);
decoder.read_u32v<Decoder::kValidate>(decoder.start(), &length);
decoder.read_u32v<Decoder::kFullValidation>(decoder.start(), &length);
EXPECT_EQ(0u, length);
EXPECT_FALSE(decoder.ok());
}
@ -389,7 +389,7 @@ TEST_F(DecoderTest, ReadU32v_off_end2) {
for (size_t i = 0; i < sizeof(data); i++) {
unsigned length = 0;
decoder.Reset(data, data + i);
decoder.read_u32v<Decoder::kValidate>(decoder.start(), &length);
decoder.read_u32v<Decoder::kFullValidation>(decoder.start(), &length);
EXPECT_EQ(i, length);
EXPECT_FALSE(decoder.ok());
}
@ -400,7 +400,7 @@ TEST_F(DecoderTest, ReadU32v_off_end3) {
for (size_t i = 0; i < sizeof(data); i++) {
unsigned length = 0;
decoder.Reset(data, data + i);
decoder.read_u32v<Decoder::kValidate>(decoder.start(), &length);
decoder.read_u32v<Decoder::kFullValidation>(decoder.start(), &length);
EXPECT_EQ(i, length);
EXPECT_FALSE(decoder.ok());
}
@ -411,7 +411,7 @@ TEST_F(DecoderTest, ReadU32v_off_end4) {
for (size_t i = 0; i < sizeof(data); i++) {
unsigned length = 0;
decoder.Reset(data, data + i);
decoder.read_u32v<Decoder::kValidate>(decoder.start(), &length);
decoder.read_u32v<Decoder::kFullValidation>(decoder.start(), &length);
EXPECT_EQ(i, length);
EXPECT_FALSE(decoder.ok());
}
@ -422,7 +422,7 @@ TEST_F(DecoderTest, ReadU32v_off_end5) {
for (size_t i = 0; i < sizeof(data); i++) {
unsigned length = 0;
decoder.Reset(data, data + i);
decoder.read_u32v<Decoder::kValidate>(decoder.start(), &length);
decoder.read_u32v<Decoder::kFullValidation>(decoder.start(), &length);
EXPECT_EQ(i, length);
EXPECT_FALSE(decoder.ok());
}
@ -434,7 +434,7 @@ TEST_F(DecoderTest, ReadU32v_extra_bits) {
data[4] = static_cast<byte>(i << 4);
unsigned length = 0;
decoder.Reset(data, data + sizeof(data));
decoder.read_u32v<Decoder::kValidate>(decoder.start(), &length);
decoder.read_u32v<Decoder::kFullValidation>(decoder.start(), &length);
EXPECT_EQ(5u, length);
EXPECT_FALSE(decoder.ok());
}
@ -445,7 +445,7 @@ TEST_F(DecoderTest, ReadI32v_extra_bits_negative) {
unsigned length = 0;
byte data[] = {0xFF, 0xFF, 0xFF, 0xFF, 0x7F};
decoder.Reset(data, data + sizeof(data));
decoder.read_i32v<Decoder::kValidate>(decoder.start(), &length);
decoder.read_i32v<Decoder::kFullValidation>(decoder.start(), &length);
EXPECT_EQ(5u, length);
EXPECT_TRUE(decoder.ok());
}
@ -455,7 +455,7 @@ TEST_F(DecoderTest, ReadI32v_extra_bits_positive) {
unsigned length = 0;
byte data[] = {0x80, 0x80, 0x80, 0x80, 0x77};
decoder.Reset(data, data + sizeof(data));
decoder.read_i32v<Decoder::kValidate>(decoder.start(), &length);
decoder.read_i32v<Decoder::kFullValidation>(decoder.start(), &length);
EXPECT_EQ(5u, length);
EXPECT_FALSE(decoder.ok());
}
@ -491,7 +491,8 @@ TEST_F(DecoderTest, ReadU32v_Bits) {
for (unsigned limit = 0; limit <= kMaxSize; limit++) {
decoder.Reset(data, data + limit);
unsigned rlen;
uint32_t result = decoder.read_u32v<Decoder::kValidate>(data, &rlen);
uint32_t result =
decoder.read_u32v<Decoder::kFullValidation>(data, &rlen);
if (limit < length) {
EXPECT_FALSE(decoder.ok());
} else {
@ -547,7 +548,8 @@ TEST_F(DecoderTest, ReadU64v_PowerOf2) {
for (unsigned limit = 0; limit <= kMaxSize; limit++) {
decoder.Reset(data, data + limit);
unsigned length;
uint64_t result = decoder.read_u64v<Decoder::kValidate>(data, &length);
uint64_t result =
decoder.read_u64v<Decoder::kFullValidation>(data, &length);
if (limit <= index) {
EXPECT_FALSE(decoder.ok());
} else {
@ -588,7 +590,8 @@ TEST_F(DecoderTest, ReadU64v_Bits) {
for (unsigned limit = 0; limit <= kMaxSize; limit++) {
decoder.Reset(data, data + limit);
unsigned rlen;
uint64_t result = decoder.read_u64v<Decoder::kValidate>(data, &rlen);
uint64_t result =
decoder.read_u64v<Decoder::kFullValidation>(data, &rlen);
if (limit < length) {
EXPECT_FALSE(decoder.ok());
} else {
@ -630,7 +633,8 @@ TEST_F(DecoderTest, ReadI64v_Bits) {
for (unsigned limit = 0; limit <= kMaxSize; limit++) {
decoder.Reset(data, data + limit);
unsigned rlen;
int64_t result = decoder.read_i64v<Decoder::kValidate>(data, &rlen);
int64_t result =
decoder.read_i64v<Decoder::kFullValidation>(data, &rlen);
if (limit < length) {
EXPECT_FALSE(decoder.ok());
} else {
@ -649,7 +653,7 @@ TEST_F(DecoderTest, ReadU64v_extra_bits) {
data[9] = static_cast<byte>(i << 1);
unsigned length = 0;
decoder.Reset(data, data + sizeof(data));
decoder.read_u64v<Decoder::kValidate>(decoder.start(), &length);
decoder.read_u64v<Decoder::kFullValidation>(decoder.start(), &length);
EXPECT_EQ(10u, length);
EXPECT_FALSE(decoder.ok());
}
@ -660,7 +664,7 @@ TEST_F(DecoderTest, ReadI64v_extra_bits_negative) {
unsigned length = 0;
byte data[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F};
decoder.Reset(data, data + sizeof(data));
decoder.read_i64v<Decoder::kValidate>(decoder.start(), &length);
decoder.read_i64v<Decoder::kFullValidation>(decoder.start(), &length);
EXPECT_EQ(10u, length);
EXPECT_TRUE(decoder.ok());
}
@ -670,7 +674,7 @@ TEST_F(DecoderTest, ReadI64v_extra_bits_positive) {
unsigned length = 0;
byte data[] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x77};
decoder.Reset(data, data + sizeof(data));
decoder.read_i64v<Decoder::kValidate>(decoder.start(), &length);
decoder.read_i64v<Decoder::kFullValidation>(decoder.start(), &length);
EXPECT_EQ(10u, length);
EXPECT_FALSE(decoder.ok());
}

View File

@ -4258,15 +4258,15 @@ class BranchTableIteratorTest : public TestWithZone {
BranchTableIteratorTest() : TestWithZone() {}
void CheckBrTableSize(const byte* start, const byte* end) {
Decoder decoder(start, end);
BranchTableImmediate<Decoder::kValidate> operand(&decoder, start + 1);
BranchTableIterator<Decoder::kValidate> iterator(&decoder, operand);
BranchTableImmediate<Decoder::kFullValidation> operand(&decoder, start + 1);
BranchTableIterator<Decoder::kFullValidation> iterator(&decoder, operand);
EXPECT_EQ(end - start - 1u, iterator.length());
EXPECT_OK(decoder);
}
void CheckBrTableError(const byte* start, const byte* end) {
Decoder decoder(start, end);
BranchTableImmediate<Decoder::kValidate> operand(&decoder, start + 1);
BranchTableIterator<Decoder::kValidate> iterator(&decoder, operand);
BranchTableImmediate<Decoder::kFullValidation> operand(&decoder, start + 1);
BranchTableIterator<Decoder::kFullValidation> iterator(&decoder, operand);
iterator.length();
EXPECT_FALSE(decoder.ok());
}
@ -4360,10 +4360,10 @@ class WasmOpcodeLengthTest : public TestWithZone {
void ExpectFailure(Bytes... bytes) {
const byte code[] = {bytes..., 0, 0, 0, 0, 0, 0, 0, 0};
WasmFeatures no_features = WasmFeatures::None();
WasmDecoder<Decoder::kValidate> decoder(this->zone(), nullptr, no_features,
&no_features, nullptr, code,
code + sizeof(code), 0);
WasmDecoder<Decoder::kValidate>::OpcodeLength(&decoder, code);
WasmDecoder<Decoder::kFullValidation> decoder(
this->zone(), nullptr, no_features, &no_features, nullptr, code,
code + sizeof(code), 0);
WasmDecoder<Decoder::kFullValidation>::OpcodeLength(&decoder, code);
EXPECT_EQ(decoder.failed(), true);
}
};

View File

@ -88,19 +88,20 @@ TEST_F(LEBHelperTest, sizeof_i32v) {
}
}
#define DECLARE_ENCODE_DECODE_CHECKER(ctype, name) \
static void CheckEncodeDecode_##name(ctype val) { \
static const int kSize = 16; \
static byte buffer[kSize]; \
byte* ptr = buffer; \
LEBHelper::write_##name(&ptr, val); \
EXPECT_EQ(LEBHelper::sizeof_##name(val), \
static_cast<size_t>(ptr - buffer)); \
Decoder decoder(buffer, buffer + kSize); \
unsigned length = 0; \
ctype result = decoder.read_##name<Decoder::kNoValidate>(buffer, &length); \
EXPECT_EQ(val, result); \
EXPECT_EQ(LEBHelper::sizeof_##name(val), static_cast<size_t>(length)); \
#define DECLARE_ENCODE_DECODE_CHECKER(ctype, name) \
static void CheckEncodeDecode_##name(ctype val) { \
static const int kSize = 16; \
static byte buffer[kSize]; \
byte* ptr = buffer; \
LEBHelper::write_##name(&ptr, val); \
EXPECT_EQ(LEBHelper::sizeof_##name(val), \
static_cast<size_t>(ptr - buffer)); \
Decoder decoder(buffer, buffer + kSize); \
unsigned length = 0; \
ctype result = \
decoder.read_##name<Decoder::kNoValidation>(buffer, &length); \
EXPECT_EQ(val, result); \
EXPECT_EQ(LEBHelper::sizeof_##name(val), static_cast<size_t>(length)); \
}
DECLARE_ENCODE_DECODE_CHECKER(int32_t, i32v)