[wasm][cleanup] Use enums for template parameter values instead of bool
Calls like read_leb<int32_t, true, true, true>(...) can be hard to read and understand. This CL replaces the three boolean template parameters with enums so that the call is read_leb<int32_t, kChecked, kAdvancePC, kTrace>(...) now. R=clemensh@chromium.org Bug: v8:6921 Change-Id: Id876a727d5e17df721444e7e5a117ad5395071aa Reviewed-on: https://chromium-review.googlesource.com/718204 Commit-Queue: Andreas Haas <ahaas@chromium.org> Reviewed-by: Clemens Hammacher <clemensh@chromium.org> Reviewed-by: Ben Titzer <titzer@chromium.org> Cr-Commit-Position: refs/heads/master@{#48607}
This commit is contained in:
parent
d0e3fb4f2e
commit
efa038361d
@ -43,6 +43,12 @@ using DecodeResult = Result<std::nullptr_t>;
|
||||
// a buffer of bytes.
|
||||
class Decoder {
|
||||
public:
|
||||
enum ValidateFlag : bool { kValidate = true, kNoValidate = false };
|
||||
|
||||
enum AdvancePCFlag : bool { kAdvancePc = true, kNoAdvancePc = false };
|
||||
|
||||
enum TraceFlag : bool { kTrace = true, kNoTrace = false };
|
||||
|
||||
Decoder(const byte* start, const byte* end, uint32_t buffer_offset = 0)
|
||||
: start_(start), pc_(start), end_(end), buffer_offset_(buffer_offset) {}
|
||||
Decoder(const byte* start, const byte* pc, const byte* end,
|
||||
@ -51,7 +57,7 @@ class Decoder {
|
||||
|
||||
virtual ~Decoder() {}
|
||||
|
||||
inline bool check(const byte* pc, uint32_t length, const char* msg) {
|
||||
inline bool validate_size(const byte* pc, uint32_t length, const char* msg) {
|
||||
DCHECK_LE(start_, pc);
|
||||
if (V8_UNLIKELY(pc + length > end_)) {
|
||||
error(pc, msg);
|
||||
@ -61,58 +67,62 @@ class Decoder {
|
||||
}
|
||||
|
||||
// Reads an 8-bit unsigned integer.
|
||||
template <bool checked>
|
||||
template <ValidateFlag validate>
|
||||
inline uint8_t read_u8(const byte* pc, const char* msg = "expected 1 byte") {
|
||||
return read_little_endian<uint8_t, checked>(pc, msg);
|
||||
return read_little_endian<uint8_t, validate>(pc, msg);
|
||||
}
|
||||
|
||||
// Reads a 16-bit unsigned integer (little endian).
|
||||
template <bool checked>
|
||||
template <ValidateFlag validate>
|
||||
inline uint16_t read_u16(const byte* pc,
|
||||
const char* msg = "expected 2 bytes") {
|
||||
return read_little_endian<uint16_t, checked>(pc, msg);
|
||||
return read_little_endian<uint16_t, validate>(pc, msg);
|
||||
}
|
||||
|
||||
// Reads a 32-bit unsigned integer (little endian).
|
||||
template <bool checked>
|
||||
template <ValidateFlag validate>
|
||||
inline uint32_t read_u32(const byte* pc,
|
||||
const char* msg = "expected 4 bytes") {
|
||||
return read_little_endian<uint32_t, checked>(pc, msg);
|
||||
return read_little_endian<uint32_t, validate>(pc, msg);
|
||||
}
|
||||
|
||||
// Reads a 64-bit unsigned integer (little endian).
|
||||
template <bool checked>
|
||||
template <ValidateFlag validate>
|
||||
inline uint64_t read_u64(const byte* pc,
|
||||
const char* msg = "expected 8 bytes") {
|
||||
return read_little_endian<uint64_t, checked>(pc, msg);
|
||||
return read_little_endian<uint64_t, validate>(pc, msg);
|
||||
}
|
||||
|
||||
// Reads a variable-length unsigned integer (little endian).
|
||||
template <bool checked>
|
||||
template <ValidateFlag validate>
|
||||
uint32_t read_u32v(const byte* pc, uint32_t* length,
|
||||
const char* name = "LEB32") {
|
||||
return read_leb<uint32_t, checked, false, false>(pc, length, name);
|
||||
return read_leb<uint32_t, validate, kNoAdvancePc, kNoTrace>(pc, length,
|
||||
name);
|
||||
}
|
||||
|
||||
// Reads a variable-length signed integer (little endian).
|
||||
template <bool checked>
|
||||
template <ValidateFlag validate>
|
||||
int32_t read_i32v(const byte* pc, uint32_t* length,
|
||||
const char* name = "signed LEB32") {
|
||||
return read_leb<int32_t, checked, false, false>(pc, length, name);
|
||||
return read_leb<int32_t, validate, kNoAdvancePc, kNoTrace>(pc, length,
|
||||
name);
|
||||
}
|
||||
|
||||
// Reads a variable-length unsigned integer (little endian).
|
||||
template <bool checked>
|
||||
template <ValidateFlag validate>
|
||||
uint64_t read_u64v(const byte* pc, uint32_t* length,
|
||||
const char* name = "LEB64") {
|
||||
return read_leb<uint64_t, checked, false, false>(pc, length, name);
|
||||
return read_leb<uint64_t, validate, kNoAdvancePc, kNoTrace>(pc, length,
|
||||
name);
|
||||
}
|
||||
|
||||
// Reads a variable-length signed integer (little endian).
|
||||
template <bool checked>
|
||||
template <ValidateFlag validate>
|
||||
int64_t read_i64v(const byte* pc, uint32_t* length,
|
||||
const char* name = "signed LEB64") {
|
||||
return read_leb<int64_t, checked, false, false>(pc, length, name);
|
||||
return read_leb<int64_t, validate, kNoAdvancePc, kNoTrace>(pc, length,
|
||||
name);
|
||||
}
|
||||
|
||||
// Reads a 8-bit unsigned integer (byte) and advances {pc_}.
|
||||
@ -133,13 +143,14 @@ 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, true, true, true>(pc_, &length, name);
|
||||
return read_leb<uint32_t, kValidate, 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, true, true, true>(pc_, &length, name);
|
||||
return read_leb<int32_t, kValidate, kAdvancePc, kTrace>(pc_, &length, name);
|
||||
}
|
||||
|
||||
// Consume {size} bytes and send them to the bit bucket, advancing {pc_}.
|
||||
@ -261,11 +272,11 @@ class Decoder {
|
||||
std::string error_msg_;
|
||||
|
||||
private:
|
||||
template <typename IntType, bool checked>
|
||||
template <typename IntType, bool validate>
|
||||
inline IntType read_little_endian(const byte* pc, const char* msg) {
|
||||
if (!checked) {
|
||||
DCHECK(check(pc, sizeof(IntType), msg));
|
||||
} else if (!check(pc, sizeof(IntType), msg)) {
|
||||
if (!validate) {
|
||||
DCHECK(validate_size(pc, sizeof(IntType), msg));
|
||||
} else if (!validate_size(pc, sizeof(IntType), msg)) {
|
||||
return IntType{0};
|
||||
}
|
||||
return ReadLittleEndianValue<IntType>(pc);
|
||||
@ -286,17 +297,18 @@ class Decoder {
|
||||
return val;
|
||||
}
|
||||
|
||||
template <typename IntType, bool checked, bool advance_pc, bool trace>
|
||||
template <typename IntType, ValidateFlag validate, AdvancePCFlag advance_pc,
|
||||
TraceFlag trace>
|
||||
inline IntType read_leb(const byte* pc, uint32_t* length,
|
||||
const char* name = "varint") {
|
||||
DCHECK_IMPLIES(advance_pc, pc == pc_);
|
||||
TRACE_IF(trace, " +%u %-20s: ", pc_offset(), name);
|
||||
return read_leb_tail<IntType, checked, advance_pc, trace, 0>(pc, length,
|
||||
return read_leb_tail<IntType, validate, advance_pc, trace, 0>(pc, length,
|
||||
name, 0);
|
||||
}
|
||||
|
||||
template <typename IntType, bool checked, bool advance_pc, bool trace,
|
||||
int byte_index>
|
||||
template <typename IntType, ValidateFlag validate, AdvancePCFlag advance_pc,
|
||||
TraceFlag trace, int byte_index>
|
||||
IntType read_leb_tail(const byte* pc, uint32_t* length, const char* name,
|
||||
IntType result) {
|
||||
constexpr bool is_signed = std::is_signed<IntType>::value;
|
||||
@ -304,7 +316,7 @@ class Decoder {
|
||||
static_assert(byte_index < kMaxLength, "invalid template instantiation");
|
||||
constexpr int shift = byte_index * 7;
|
||||
constexpr bool is_last_byte = byte_index == kMaxLength - 1;
|
||||
const bool at_end = checked && pc >= end_;
|
||||
const bool at_end = validate && pc >= end_;
|
||||
byte b = 0;
|
||||
if (!at_end) {
|
||||
DCHECK_LT(pc, end_);
|
||||
@ -317,12 +329,12 @@ class Decoder {
|
||||
// Compilers are not smart enough to figure out statically that the
|
||||
// following call is unreachable if is_last_byte is false.
|
||||
constexpr int next_byte_index = byte_index + (is_last_byte ? 0 : 1);
|
||||
return read_leb_tail<IntType, checked, advance_pc, trace,
|
||||
return read_leb_tail<IntType, validate, advance_pc, trace,
|
||||
next_byte_index>(pc + 1, length, name, result);
|
||||
}
|
||||
if (advance_pc) pc_ = pc + (at_end ? 0 : 1);
|
||||
*length = byte_index + (at_end ? 0 : 1);
|
||||
if (checked && (at_end || (b & 0x80))) {
|
||||
if (validate && (at_end || (b & 0x80))) {
|
||||
TRACE_IF(trace, at_end ? "<end> " : "<length overflow> ");
|
||||
errorf(pc, "expected %s", name);
|
||||
result = 0;
|
||||
@ -341,7 +353,7 @@ class Decoder {
|
||||
bool valid_extra_bits =
|
||||
checked_bits == 0 ||
|
||||
(is_signed && checked_bits == kSignExtendedExtraBits);
|
||||
if (!checked) {
|
||||
if (!validate) {
|
||||
DCHECK(valid_extra_bits);
|
||||
} else if (!valid_extra_bits) {
|
||||
error(pc, "extra bits in varint");
|
||||
|
@ -87,7 +87,7 @@ Vector<T> vec2vec(std::vector<T>& vec) {
|
||||
}
|
||||
|
||||
// Helpers for decoding different kinds of operands which follow bytecodes.
|
||||
template <bool validate>
|
||||
template <Decoder::ValidateFlag validate>
|
||||
struct LocalIndexOperand {
|
||||
uint32_t index;
|
||||
ValueType type = kWasmStmt;
|
||||
@ -98,7 +98,7 @@ struct LocalIndexOperand {
|
||||
}
|
||||
};
|
||||
|
||||
template <bool validate>
|
||||
template <Decoder::ValidateFlag validate>
|
||||
struct ExceptionIndexOperand {
|
||||
uint32_t index;
|
||||
const WasmException* exception = nullptr;
|
||||
@ -109,7 +109,7 @@ struct ExceptionIndexOperand {
|
||||
}
|
||||
};
|
||||
|
||||
template <bool validate>
|
||||
template <Decoder::ValidateFlag validate>
|
||||
struct ImmI32Operand {
|
||||
int32_t value;
|
||||
unsigned length;
|
||||
@ -118,7 +118,7 @@ struct ImmI32Operand {
|
||||
}
|
||||
};
|
||||
|
||||
template <bool validate>
|
||||
template <Decoder::ValidateFlag validate>
|
||||
struct ImmI64Operand {
|
||||
int64_t value;
|
||||
unsigned length;
|
||||
@ -127,7 +127,7 @@ struct ImmI64Operand {
|
||||
}
|
||||
};
|
||||
|
||||
template <bool validate>
|
||||
template <Decoder::ValidateFlag validate>
|
||||
struct ImmF32Operand {
|
||||
float value;
|
||||
unsigned length = 4;
|
||||
@ -138,7 +138,7 @@ struct ImmF32Operand {
|
||||
}
|
||||
};
|
||||
|
||||
template <bool validate>
|
||||
template <Decoder::ValidateFlag validate>
|
||||
struct ImmF64Operand {
|
||||
double value;
|
||||
unsigned length = 8;
|
||||
@ -149,7 +149,7 @@ struct ImmF64Operand {
|
||||
}
|
||||
};
|
||||
|
||||
template <bool validate>
|
||||
template <Decoder::ValidateFlag validate>
|
||||
struct GlobalIndexOperand {
|
||||
uint32_t index;
|
||||
ValueType type = kWasmStmt;
|
||||
@ -161,7 +161,7 @@ struct GlobalIndexOperand {
|
||||
}
|
||||
};
|
||||
|
||||
template <bool validate>
|
||||
template <Decoder::ValidateFlag validate>
|
||||
struct BlockTypeOperand {
|
||||
unsigned length = 1;
|
||||
ValueType type = kWasmStmt;
|
||||
@ -235,7 +235,7 @@ struct BlockTypeOperand {
|
||||
}
|
||||
};
|
||||
|
||||
template <bool validate>
|
||||
template <Decoder::ValidateFlag validate>
|
||||
struct BreakDepthOperand {
|
||||
uint32_t depth;
|
||||
unsigned length;
|
||||
@ -244,7 +244,7 @@ struct BreakDepthOperand {
|
||||
}
|
||||
};
|
||||
|
||||
template <bool validate>
|
||||
template <Decoder::ValidateFlag validate>
|
||||
struct CallIndirectOperand {
|
||||
uint32_t table_index;
|
||||
uint32_t index;
|
||||
@ -262,7 +262,7 @@ struct CallIndirectOperand {
|
||||
}
|
||||
};
|
||||
|
||||
template <bool validate>
|
||||
template <Decoder::ValidateFlag validate>
|
||||
struct CallFunctionOperand {
|
||||
uint32_t index;
|
||||
FunctionSig* sig = nullptr;
|
||||
@ -272,7 +272,7 @@ struct CallFunctionOperand {
|
||||
}
|
||||
};
|
||||
|
||||
template <bool validate>
|
||||
template <Decoder::ValidateFlag validate>
|
||||
struct MemoryIndexOperand {
|
||||
uint32_t index;
|
||||
unsigned length = 1;
|
||||
@ -284,7 +284,7 @@ struct MemoryIndexOperand {
|
||||
}
|
||||
};
|
||||
|
||||
template <bool validate>
|
||||
template <Decoder::ValidateFlag validate>
|
||||
struct BranchTableOperand {
|
||||
uint32_t table_count;
|
||||
const byte* start;
|
||||
@ -299,7 +299,7 @@ struct BranchTableOperand {
|
||||
};
|
||||
|
||||
// A helper to iterate over a branch table.
|
||||
template <bool validate>
|
||||
template <Decoder::ValidateFlag validate>
|
||||
class BranchTableIterator {
|
||||
public:
|
||||
unsigned cur_index() { return index_; }
|
||||
@ -337,7 +337,7 @@ class BranchTableIterator {
|
||||
uint32_t table_count_; // the count of entries, not including default.
|
||||
};
|
||||
|
||||
template <bool validate>
|
||||
template <Decoder::ValidateFlag validate>
|
||||
struct MemoryAccessOperand {
|
||||
uint32_t alignment;
|
||||
uint32_t offset;
|
||||
@ -361,7 +361,7 @@ struct MemoryAccessOperand {
|
||||
};
|
||||
|
||||
// Operand for SIMD lane operations.
|
||||
template <bool validate>
|
||||
template <Decoder::ValidateFlag validate>
|
||||
struct SimdLaneOperand {
|
||||
uint8_t lane;
|
||||
unsigned length = 1;
|
||||
@ -372,7 +372,7 @@ struct SimdLaneOperand {
|
||||
};
|
||||
|
||||
// Operand for SIMD shift operations.
|
||||
template <bool validate>
|
||||
template <Decoder::ValidateFlag validate>
|
||||
struct SimdShiftOperand {
|
||||
uint8_t shift;
|
||||
unsigned length = 1;
|
||||
@ -383,7 +383,7 @@ struct SimdShiftOperand {
|
||||
};
|
||||
|
||||
// Operand for SIMD S8x16 shuffle operations.
|
||||
template <bool validate>
|
||||
template <Decoder::ValidateFlag validate>
|
||||
struct Simd8x16ShuffleOperand {
|
||||
uint8_t shuffle[kSimd128Size];
|
||||
|
||||
@ -606,7 +606,7 @@ struct ControlWithNamedConstructors : public ControlBase<Value> {
|
||||
|
||||
// Generic Wasm bytecode decoder with utilities for decoding operands,
|
||||
// lengths, etc.
|
||||
template <bool validate>
|
||||
template <Decoder::ValidateFlag validate>
|
||||
class WasmDecoder : public Decoder {
|
||||
public:
|
||||
WasmDecoder(const WasmModule* module, FunctionSig* sig, const byte* start,
|
||||
@ -703,7 +703,7 @@ class WasmDecoder : public Decoder {
|
||||
break;
|
||||
case kExprSetLocal: // fallthru
|
||||
case kExprTeeLocal: {
|
||||
LocalIndexOperand<validate> operand(decoder, pc);
|
||||
LocalIndexOperand<Decoder::kValidate> operand(decoder, pc);
|
||||
if (assigned->length() > 0 &&
|
||||
operand.index < static_cast<uint32_t>(assigned->length())) {
|
||||
// Unverified code might have an out-of-bounds index.
|
||||
@ -733,7 +733,8 @@ class WasmDecoder : public Decoder {
|
||||
return decoder->ok() ? assigned : nullptr;
|
||||
}
|
||||
|
||||
inline bool Validate(const byte* pc, LocalIndexOperand<validate>& operand) {
|
||||
inline bool Validate(const byte* pc,
|
||||
LocalIndexOperand<Decoder::kValidate>& operand) {
|
||||
if (!VALIDATE(operand.index < total_locals())) {
|
||||
errorf(pc + 1, "invalid local index: %u", operand.index);
|
||||
return false;
|
||||
@ -943,7 +944,7 @@ class WasmDecoder : public Decoder {
|
||||
case kExprSetLocal:
|
||||
case kExprTeeLocal:
|
||||
case kExprGetLocal: {
|
||||
LocalIndexOperand<validate> operand(decoder, pc);
|
||||
LocalIndexOperand<Decoder::kValidate> operand(decoder, pc);
|
||||
return 1 + operand.length;
|
||||
}
|
||||
case kExprBrTable: {
|
||||
@ -1103,7 +1104,7 @@ class WasmDecoder : public Decoder {
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
template <bool validate, typename Interface>
|
||||
template <Decoder::ValidateFlag validate, typename Interface>
|
||||
class WasmFullDecoder : public WasmDecoder<validate> {
|
||||
using Value = typename Interface::Value;
|
||||
using Control = typename Interface::Control;
|
||||
@ -1321,7 +1322,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
|
||||
}
|
||||
case kExprThrow: {
|
||||
CHECK_PROTOTYPE_OPCODE(eh);
|
||||
ExceptionIndexOperand<true> operand(this, this->pc_);
|
||||
ExceptionIndexOperand<Decoder::kValidate> operand(this, this->pc_);
|
||||
len = 1 + operand.length;
|
||||
if (!this->Validate(this->pc_, operand)) break;
|
||||
std::vector<Value> args;
|
||||
@ -1344,7 +1345,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
|
||||
case kExprCatch: {
|
||||
// TODO(kschimpf): Fix to use type signature of exception.
|
||||
CHECK_PROTOTYPE_OPCODE(eh);
|
||||
ExceptionIndexOperand<true> operand(this, this->pc_);
|
||||
ExceptionIndexOperand<Decoder::kValidate> operand(this, this->pc_);
|
||||
len = 1 + operand.length;
|
||||
|
||||
if (!this->Validate(this->pc_, operand)) break;
|
||||
@ -1576,7 +1577,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
|
||||
break;
|
||||
}
|
||||
case kExprGetLocal: {
|
||||
LocalIndexOperand<validate> operand(this, this->pc_);
|
||||
LocalIndexOperand<Decoder::kValidate> operand(this, this->pc_);
|
||||
if (!this->Validate(this->pc_, operand)) break;
|
||||
auto* value = Push(operand.type);
|
||||
CALL_INTERFACE_IF_REACHABLE(GetLocal, value, operand);
|
||||
@ -1584,7 +1585,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
|
||||
break;
|
||||
}
|
||||
case kExprSetLocal: {
|
||||
LocalIndexOperand<validate> operand(this, this->pc_);
|
||||
LocalIndexOperand<Decoder::kValidate> operand(this, this->pc_);
|
||||
if (!this->Validate(this->pc_, operand)) break;
|
||||
auto value = Pop(0, local_type_vec_[operand.index]);
|
||||
CALL_INTERFACE_IF_REACHABLE(SetLocal, value, operand);
|
||||
@ -1592,7 +1593,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
|
||||
break;
|
||||
}
|
||||
case kExprTeeLocal: {
|
||||
LocalIndexOperand<validate> operand(this, this->pc_);
|
||||
LocalIndexOperand<Decoder::kValidate> operand(this, this->pc_);
|
||||
if (!this->Validate(this->pc_, operand)) break;
|
||||
auto value = Pop(0, local_type_vec_[operand.index]);
|
||||
auto* result = Push(value.type);
|
||||
@ -1822,7 +1823,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
|
||||
case kExprGetLocal:
|
||||
case kExprSetLocal:
|
||||
case kExprTeeLocal: {
|
||||
LocalIndexOperand<validate> operand(this, val.pc);
|
||||
LocalIndexOperand<Decoder::kValidate> operand(this, val.pc);
|
||||
PrintF("[%u]", operand.index);
|
||||
break;
|
||||
}
|
||||
@ -2330,7 +2331,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
|
||||
|
||||
class EmptyInterface {
|
||||
public:
|
||||
constexpr static bool validate = true;
|
||||
static constexpr wasm::Decoder::ValidateFlag validate =
|
||||
wasm::Decoder::kValidate;
|
||||
using Value = ValueBase;
|
||||
using Control = ControlBase<Value>;
|
||||
using Decoder = WasmFullDecoder<validate, EmptyInterface>;
|
||||
|
@ -71,7 +71,9 @@ constexpr uint32_t kNullCatch = static_cast<uint32_t>(-1);
|
||||
|
||||
class WasmGraphBuildingInterface {
|
||||
public:
|
||||
using Decoder = WasmFullDecoder<true, WasmGraphBuildingInterface>;
|
||||
static constexpr wasm::Decoder::ValidateFlag validate =
|
||||
wasm::Decoder::kValidate;
|
||||
using Decoder = WasmFullDecoder<validate, WasmGraphBuildingInterface>;
|
||||
|
||||
struct Value : public ValueWithNamedConstructors<Value> {
|
||||
TFNode* node;
|
||||
@ -259,31 +261,31 @@ class WasmGraphBuildingInterface {
|
||||
}
|
||||
|
||||
void GetLocal(Decoder* decoder, Value* result,
|
||||
const LocalIndexOperand<true>& operand) {
|
||||
const LocalIndexOperand<validate>& operand) {
|
||||
if (!ssa_env_->locals) return; // unreachable
|
||||
result->node = ssa_env_->locals[operand.index];
|
||||
}
|
||||
|
||||
void SetLocal(Decoder* decoder, const Value& value,
|
||||
const LocalIndexOperand<true>& operand) {
|
||||
const LocalIndexOperand<validate>& operand) {
|
||||
if (!ssa_env_->locals) return; // unreachable
|
||||
ssa_env_->locals[operand.index] = value.node;
|
||||
}
|
||||
|
||||
void TeeLocal(Decoder* decoder, const Value& value, Value* result,
|
||||
const LocalIndexOperand<true>& operand) {
|
||||
const LocalIndexOperand<validate>& operand) {
|
||||
result->node = value.node;
|
||||
if (!ssa_env_->locals) return; // unreachable
|
||||
ssa_env_->locals[operand.index] = value.node;
|
||||
}
|
||||
|
||||
void GetGlobal(Decoder* decoder, Value* result,
|
||||
const GlobalIndexOperand<true>& operand) {
|
||||
const GlobalIndexOperand<validate>& operand) {
|
||||
result->node = BUILD(GetGlobal, operand.index);
|
||||
}
|
||||
|
||||
void SetGlobal(Decoder* decoder, const Value& value,
|
||||
const GlobalIndexOperand<true>& operand) {
|
||||
const GlobalIndexOperand<validate>& operand) {
|
||||
BUILD(SetGlobal, operand.index, value.node);
|
||||
}
|
||||
|
||||
@ -320,11 +322,11 @@ class WasmGraphBuildingInterface {
|
||||
ssa_env_ = fenv;
|
||||
}
|
||||
|
||||
void BrTable(Decoder* decoder, const BranchTableOperand<true>& operand,
|
||||
void BrTable(Decoder* decoder, const BranchTableOperand<validate>& operand,
|
||||
const Value& key) {
|
||||
if (operand.table_count == 0) {
|
||||
// Only a default target. Do the equivalent of br.
|
||||
uint32_t target = BranchTableIterator<true>(decoder, operand).next();
|
||||
uint32_t target = BranchTableIterator<validate>(decoder, operand).next();
|
||||
BreakTo(decoder, decoder->control_at(target));
|
||||
return;
|
||||
}
|
||||
@ -335,7 +337,7 @@ class WasmGraphBuildingInterface {
|
||||
|
||||
SsaEnv* copy = Steal(decoder->zone(), break_env);
|
||||
ssa_env_ = copy;
|
||||
BranchTableIterator<true> iterator(decoder, operand);
|
||||
BranchTableIterator<validate> iterator(decoder, operand);
|
||||
while (iterator.has_next()) {
|
||||
uint32_t i = iterator.cur_index();
|
||||
uint32_t target = iterator.next();
|
||||
@ -353,15 +355,15 @@ class WasmGraphBuildingInterface {
|
||||
}
|
||||
|
||||
void LoadMem(Decoder* decoder, ValueType type, MachineType mem_type,
|
||||
const MemoryAccessOperand<true>& operand, const Value& index,
|
||||
const MemoryAccessOperand<validate>& operand, const Value& index,
|
||||
Value* result) {
|
||||
result->node = BUILD(LoadMem, type, mem_type, index.node, operand.offset,
|
||||
operand.alignment, decoder->position());
|
||||
}
|
||||
|
||||
void StoreMem(Decoder* decoder, ValueType type, MachineType mem_type,
|
||||
const MemoryAccessOperand<true>& operand, const Value& index,
|
||||
const Value& value) {
|
||||
const MemoryAccessOperand<validate>& operand,
|
||||
const Value& index, const Value& value) {
|
||||
BUILD(StoreMem, mem_type, index.node, operand.offset, operand.alignment,
|
||||
value.node, decoder->position(), type);
|
||||
}
|
||||
@ -376,13 +378,14 @@ class WasmGraphBuildingInterface {
|
||||
LoadContextIntoSsa(ssa_env_);
|
||||
}
|
||||
|
||||
void CallDirect(Decoder* decoder, const CallFunctionOperand<true>& operand,
|
||||
void CallDirect(Decoder* decoder,
|
||||
const CallFunctionOperand<validate>& operand,
|
||||
const Value args[], Value returns[]) {
|
||||
DoCall(decoder, nullptr, operand, args, returns, false);
|
||||
}
|
||||
|
||||
void CallIndirect(Decoder* decoder, const Value& index,
|
||||
const CallIndirectOperand<true>& operand,
|
||||
const CallIndirectOperand<validate>& operand,
|
||||
const Value args[], Value returns[]) {
|
||||
DoCall(decoder, index.node, operand, args, returns, true);
|
||||
}
|
||||
@ -395,21 +398,21 @@ class WasmGraphBuildingInterface {
|
||||
}
|
||||
|
||||
void SimdLaneOp(Decoder* decoder, WasmOpcode opcode,
|
||||
const SimdLaneOperand<true> operand, Vector<Value> inputs,
|
||||
const SimdLaneOperand<validate> operand, Vector<Value> inputs,
|
||||
Value* result) {
|
||||
TFNode** nodes = GetNodes(inputs);
|
||||
result->node = BUILD(SimdLaneOp, opcode, operand.lane, nodes);
|
||||
}
|
||||
|
||||
void SimdShiftOp(Decoder* decoder, WasmOpcode opcode,
|
||||
const SimdShiftOperand<true> operand, const Value& input,
|
||||
const SimdShiftOperand<validate> operand, const Value& input,
|
||||
Value* result) {
|
||||
TFNode* inputs[] = {input.node};
|
||||
result->node = BUILD(SimdShiftOp, opcode, operand.shift, inputs);
|
||||
}
|
||||
|
||||
void Simd8x16ShuffleOp(Decoder* decoder,
|
||||
const Simd8x16ShuffleOperand<true>& operand,
|
||||
const Simd8x16ShuffleOperand<validate>& operand,
|
||||
const Value& input0, const Value& input1,
|
||||
Value* result) {
|
||||
TFNode* input_nodes[] = {input0.node, input1.node};
|
||||
@ -417,13 +420,13 @@ class WasmGraphBuildingInterface {
|
||||
}
|
||||
|
||||
TFNode* GetExceptionTag(Decoder* decoder,
|
||||
const ExceptionIndexOperand<true>& operand) {
|
||||
const ExceptionIndexOperand<validate>& operand) {
|
||||
// TODO(kschimpf): Need to get runtime exception tag values. This
|
||||
// code only handles non-imported/exported exceptions.
|
||||
return BUILD(Int32Constant, operand.index);
|
||||
}
|
||||
|
||||
void Throw(Decoder* decoder, const ExceptionIndexOperand<true>& operand,
|
||||
void Throw(Decoder* decoder, const ExceptionIndexOperand<validate>& operand,
|
||||
Control* block, const Vector<Value>& value_args) {
|
||||
int count = value_args.length();
|
||||
ZoneVector<TFNode*> args(count, decoder->zone());
|
||||
@ -436,7 +439,7 @@ class WasmGraphBuildingInterface {
|
||||
}
|
||||
|
||||
void CatchException(Decoder* decoder,
|
||||
const ExceptionIndexOperand<true>& operand,
|
||||
const ExceptionIndexOperand<validate>& operand,
|
||||
Control* block, Vector<Value> values) {
|
||||
DCHECK(block->is_try_catch());
|
||||
current_catch_ = block->previous_catch;
|
||||
@ -496,7 +499,7 @@ class WasmGraphBuildingInterface {
|
||||
}
|
||||
|
||||
void AtomicOp(Decoder* decoder, WasmOpcode opcode, Vector<Value> args,
|
||||
const MemoryAccessOperand<true>& operand, Value* result) {
|
||||
const MemoryAccessOperand<validate>& operand, Value* result) {
|
||||
TFNode** inputs = GetNodes(args);
|
||||
TFNode* node = BUILD(AtomicOp, opcode, inputs, operand.alignment,
|
||||
operand.offset, decoder->position());
|
||||
@ -743,7 +746,7 @@ class WasmGraphBuildingInterface {
|
||||
env->effect = builder_->EffectPhi(1, &env->effect, env->control);
|
||||
builder_->Terminate(env->effect, env->control);
|
||||
// The '+ 2' here is to be able to set mem_size and mem_start as assigned.
|
||||
BitVector* assigned = WasmDecoder<true>::AnalyzeLoopAssignment(
|
||||
BitVector* assigned = WasmDecoder<validate>::AnalyzeLoopAssignment(
|
||||
decoder, decoder->pc(), decoder->total_locals() + 2, decoder->zone());
|
||||
if (decoder->failed()) return env;
|
||||
if (assigned != nullptr) {
|
||||
@ -846,7 +849,7 @@ class WasmGraphBuildingInterface {
|
||||
}
|
||||
|
||||
template <typename Operand>
|
||||
void DoCall(WasmFullDecoder<true, WasmGraphBuildingInterface>* decoder,
|
||||
void DoCall(WasmFullDecoder<validate, WasmGraphBuildingInterface>* decoder,
|
||||
TFNode* index_node, const Operand& operand, const Value args[],
|
||||
Value returns[], bool is_indirect) {
|
||||
if (!build(decoder)) return;
|
||||
@ -879,7 +882,8 @@ class WasmGraphBuildingInterface {
|
||||
bool DecodeLocalDecls(BodyLocalDecls* decls, const byte* start,
|
||||
const byte* end) {
|
||||
Decoder decoder(start, end);
|
||||
if (WasmDecoder<true>::DecodeLocals(&decoder, nullptr, &decls->type_list)) {
|
||||
if (WasmDecoder<Decoder::kValidate>::DecodeLocals(&decoder, nullptr,
|
||||
&decls->type_list)) {
|
||||
DCHECK(decoder.ok());
|
||||
decls->encoded_size = decoder.pc_offset();
|
||||
return true;
|
||||
@ -902,7 +906,8 @@ DecodeResult VerifyWasmCode(AccountingAllocator* allocator,
|
||||
const wasm::WasmModule* module,
|
||||
FunctionBody& body) {
|
||||
Zone zone(allocator, ZONE_NAME);
|
||||
WasmFullDecoder<true, EmptyInterface> decoder(&zone, module, body);
|
||||
WasmFullDecoder<Decoder::kValidate, EmptyInterface> decoder(&zone, module,
|
||||
body);
|
||||
decoder.Decode();
|
||||
return decoder.toResult(nullptr);
|
||||
}
|
||||
@ -921,7 +926,7 @@ DecodeResult VerifyWasmCodeWithStats(AccountingAllocator* allocator,
|
||||
DecodeResult BuildTFGraph(AccountingAllocator* allocator, TFBuilder* builder,
|
||||
FunctionBody& body) {
|
||||
Zone zone(allocator, ZONE_NAME);
|
||||
WasmFullDecoder<true, WasmGraphBuildingInterface> decoder(
|
||||
WasmFullDecoder<Decoder::kValidate, WasmGraphBuildingInterface> decoder(
|
||||
&zone, builder->module(), body, builder);
|
||||
decoder.Decode();
|
||||
return decoder.toResult(nullptr);
|
||||
@ -929,13 +934,13 @@ DecodeResult BuildTFGraph(AccountingAllocator* allocator, TFBuilder* builder,
|
||||
|
||||
unsigned OpcodeLength(const byte* pc, const byte* end) {
|
||||
Decoder decoder(pc, end);
|
||||
return WasmDecoder<false>::OpcodeLength(&decoder, pc);
|
||||
return WasmDecoder<Decoder::kNoValidate>::OpcodeLength(&decoder, pc);
|
||||
}
|
||||
|
||||
std::pair<uint32_t, uint32_t> StackEffect(const WasmModule* module,
|
||||
FunctionSig* sig, const byte* pc,
|
||||
const byte* end) {
|
||||
WasmDecoder<false> decoder(module, sig, pc, end);
|
||||
WasmDecoder<Decoder::kNoValidate> decoder(module, sig, pc, end);
|
||||
return decoder.StackEffect(pc);
|
||||
}
|
||||
|
||||
@ -963,7 +968,8 @@ bool PrintRawWasmCode(AccountingAllocator* allocator, const FunctionBody& body,
|
||||
const wasm::WasmModule* module) {
|
||||
OFStream os(stdout);
|
||||
Zone zone(allocator, ZONE_NAME);
|
||||
WasmDecoder<false> decoder(module, body.sig, body.start, body.end);
|
||||
WasmDecoder<Decoder::kNoValidate> decoder(module, body.sig, body.start,
|
||||
body.end);
|
||||
int line_nr = 0;
|
||||
|
||||
// Print the function signature.
|
||||
@ -1004,7 +1010,8 @@ bool PrintRawWasmCode(AccountingAllocator* allocator, const FunctionBody& body,
|
||||
++line_nr;
|
||||
unsigned control_depth = 0;
|
||||
for (; i.has_next(); i.next()) {
|
||||
unsigned length = WasmDecoder<false>::OpcodeLength(&decoder, i.pc());
|
||||
unsigned length =
|
||||
WasmDecoder<Decoder::kNoValidate>::OpcodeLength(&decoder, i.pc());
|
||||
|
||||
WasmOpcode opcode = i.current();
|
||||
if (opcode == kExprElse) control_depth--;
|
||||
@ -1031,7 +1038,7 @@ bool PrintRawWasmCode(AccountingAllocator* allocator, const FunctionBody& body,
|
||||
case kExprIf:
|
||||
case kExprBlock:
|
||||
case kExprTry: {
|
||||
BlockTypeOperand<false> operand(&i, i.pc());
|
||||
BlockTypeOperand<Decoder::kNoValidate> operand(&i, i.pc());
|
||||
os << " // @" << i.pc_offset();
|
||||
for (unsigned i = 0; i < operand.out_arity(); i++) {
|
||||
os << " " << WasmOpcodes::TypeName(operand.out_type(i));
|
||||
@ -1044,22 +1051,22 @@ bool PrintRawWasmCode(AccountingAllocator* allocator, const FunctionBody& body,
|
||||
control_depth--;
|
||||
break;
|
||||
case kExprBr: {
|
||||
BreakDepthOperand<false> operand(&i, i.pc());
|
||||
BreakDepthOperand<Decoder::kNoValidate> operand(&i, i.pc());
|
||||
os << " // depth=" << operand.depth;
|
||||
break;
|
||||
}
|
||||
case kExprBrIf: {
|
||||
BreakDepthOperand<false> operand(&i, i.pc());
|
||||
BreakDepthOperand<Decoder::kNoValidate> operand(&i, i.pc());
|
||||
os << " // depth=" << operand.depth;
|
||||
break;
|
||||
}
|
||||
case kExprBrTable: {
|
||||
BranchTableOperand<false> operand(&i, i.pc());
|
||||
BranchTableOperand<Decoder::kNoValidate> operand(&i, i.pc());
|
||||
os << " // entries=" << operand.table_count;
|
||||
break;
|
||||
}
|
||||
case kExprCallIndirect: {
|
||||
CallIndirectOperand<false> operand(&i, i.pc());
|
||||
CallIndirectOperand<Decoder::kNoValidate> operand(&i, i.pc());
|
||||
os << " // sig #" << operand.index;
|
||||
if (decoder.Complete(i.pc(), operand)) {
|
||||
os << ": " << *operand.sig;
|
||||
@ -1067,7 +1074,7 @@ bool PrintRawWasmCode(AccountingAllocator* allocator, const FunctionBody& body,
|
||||
break;
|
||||
}
|
||||
case kExprCallFunction: {
|
||||
CallFunctionOperand<false> operand(&i, i.pc());
|
||||
CallFunctionOperand<Decoder::kNoValidate> operand(&i, i.pc());
|
||||
os << " // function #" << operand.index;
|
||||
if (decoder.Complete(i.pc(), operand)) {
|
||||
os << ": " << *operand.sig;
|
||||
@ -1087,7 +1094,7 @@ bool PrintRawWasmCode(AccountingAllocator* allocator, const FunctionBody& body,
|
||||
BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals,
|
||||
const byte* start, const byte* end) {
|
||||
Decoder decoder(start, end);
|
||||
return WasmDecoder<true>::AnalyzeLoopAssignment(
|
||||
return WasmDecoder<Decoder::kValidate>::AnalyzeLoopAssignment(
|
||||
&decoder, start, static_cast<uint32_t>(num_locals), zone);
|
||||
}
|
||||
|
||||
|
@ -178,7 +178,8 @@ class V8_EXPORT_PRIVATE BytecodeIterator : public NON_EXPORTED_BASE(Decoder) {
|
||||
}
|
||||
|
||||
WasmOpcode current() {
|
||||
return static_cast<WasmOpcode>(read_u8<false>(pc_, "expected bytecode"));
|
||||
return static_cast<WasmOpcode>(
|
||||
read_u8<Decoder::kNoValidate>(pc_, "expected bytecode"));
|
||||
}
|
||||
|
||||
void next() {
|
||||
@ -191,8 +192,8 @@ class V8_EXPORT_PRIVATE BytecodeIterator : public NON_EXPORTED_BASE(Decoder) {
|
||||
bool has_next() { return pc_ < end_; }
|
||||
|
||||
WasmOpcode prefixed_opcode() {
|
||||
byte prefix = read_u8<false>(pc_, "expected prefix");
|
||||
byte index = read_u8<false>(pc_ + 1, "expected index");
|
||||
byte prefix = read_u8<Decoder::kNoValidate>(pc_, "expected prefix");
|
||||
byte index = read_u8<Decoder::kNoValidate>(pc_ + 1, "expected index");
|
||||
return static_cast<WasmOpcode>(prefix << 8 | index);
|
||||
}
|
||||
};
|
||||
|
@ -1177,7 +1177,7 @@ class ModuleDecoderImpl : public Decoder {
|
||||
unsigned len = 0;
|
||||
switch (opcode) {
|
||||
case kExprGetGlobal: {
|
||||
GlobalIndexOperand<true> operand(this, pc() - 1);
|
||||
GlobalIndexOperand<Decoder::kValidate> operand(this, pc() - 1);
|
||||
if (module->globals.size() <= operand.index) {
|
||||
error("global index is out of bounds");
|
||||
expr.kind = WasmInitExpr::kNone;
|
||||
@ -1199,28 +1199,28 @@ class ModuleDecoderImpl : public Decoder {
|
||||
break;
|
||||
}
|
||||
case kExprI32Const: {
|
||||
ImmI32Operand<true> operand(this, pc() - 1);
|
||||
ImmI32Operand<Decoder::kValidate> operand(this, pc() - 1);
|
||||
expr.kind = WasmInitExpr::kI32Const;
|
||||
expr.val.i32_const = operand.value;
|
||||
len = operand.length;
|
||||
break;
|
||||
}
|
||||
case kExprF32Const: {
|
||||
ImmF32Operand<true> operand(this, pc() - 1);
|
||||
ImmF32Operand<Decoder::kValidate> operand(this, pc() - 1);
|
||||
expr.kind = WasmInitExpr::kF32Const;
|
||||
expr.val.f32_const = operand.value;
|
||||
len = operand.length;
|
||||
break;
|
||||
}
|
||||
case kExprI64Const: {
|
||||
ImmI64Operand<true> operand(this, pc() - 1);
|
||||
ImmI64Operand<Decoder::kValidate> operand(this, pc() - 1);
|
||||
expr.kind = WasmInitExpr::kI64Const;
|
||||
expr.val.i64_const = operand.value;
|
||||
len = operand.length;
|
||||
break;
|
||||
}
|
||||
case kExprF64Const: {
|
||||
ImmF64Operand<true> operand(this, pc() - 1);
|
||||
ImmF64Operand<Decoder::kValidate> operand(this, pc() - 1);
|
||||
expr.kind = WasmInitExpr::kF64Const;
|
||||
expr.val.f64_const = operand.value;
|
||||
len = operand.length;
|
||||
|
@ -811,7 +811,7 @@ class SideTable : public ZoneObject {
|
||||
case kExprBlock:
|
||||
case kExprLoop: {
|
||||
bool is_loop = opcode == kExprLoop;
|
||||
BlockTypeOperand<false> operand(&i, i.pc());
|
||||
BlockTypeOperand<Decoder::kNoValidate> operand(&i, i.pc());
|
||||
if (operand.type == kWasmVar) {
|
||||
operand.sig = module->signatures[operand.sig_index];
|
||||
}
|
||||
@ -827,7 +827,7 @@ class SideTable : public ZoneObject {
|
||||
break;
|
||||
}
|
||||
case kExprIf: {
|
||||
BlockTypeOperand<false> operand(&i, i.pc());
|
||||
BlockTypeOperand<Decoder::kNoValidate> operand(&i, i.pc());
|
||||
if (operand.type == kWasmVar) {
|
||||
operand.sig = module->signatures[operand.sig_index];
|
||||
}
|
||||
@ -875,22 +875,22 @@ class SideTable : public ZoneObject {
|
||||
break;
|
||||
}
|
||||
case kExprBr: {
|
||||
BreakDepthOperand<false> operand(&i, i.pc());
|
||||
BreakDepthOperand<Decoder::kNoValidate> operand(&i, i.pc());
|
||||
TRACE("control @%u: Br[depth=%u]\n", i.pc_offset(), operand.depth);
|
||||
Control* c = &control_stack[control_stack.size() - operand.depth - 1];
|
||||
if (!unreachable) c->end_label->Ref(i.pc(), stack_height);
|
||||
break;
|
||||
}
|
||||
case kExprBrIf: {
|
||||
BreakDepthOperand<false> operand(&i, i.pc());
|
||||
BreakDepthOperand<Decoder::kNoValidate> operand(&i, i.pc());
|
||||
TRACE("control @%u: BrIf[depth=%u]\n", i.pc_offset(), operand.depth);
|
||||
Control* c = &control_stack[control_stack.size() - operand.depth - 1];
|
||||
if (!unreachable) c->end_label->Ref(i.pc(), stack_height);
|
||||
break;
|
||||
}
|
||||
case kExprBrTable: {
|
||||
BranchTableOperand<false> operand(&i, i.pc());
|
||||
BranchTableIterator<false> iterator(&i, operand);
|
||||
BranchTableOperand<Decoder::kNoValidate> operand(&i, i.pc());
|
||||
BranchTableIterator<Decoder::kNoValidate> iterator(&i, operand);
|
||||
TRACE("control @%u: BrTable[count=%u]\n", i.pc_offset(),
|
||||
operand.table_count);
|
||||
if (!unreachable) {
|
||||
@ -1366,11 +1366,13 @@ class ThreadImpl {
|
||||
pc_t ReturnPc(Decoder* decoder, InterpreterCode* code, pc_t pc) {
|
||||
switch (code->orig_start[pc]) {
|
||||
case kExprCallFunction: {
|
||||
CallFunctionOperand<false> operand(decoder, code->at(pc));
|
||||
CallFunctionOperand<Decoder::kNoValidate> operand(decoder,
|
||||
code->at(pc));
|
||||
return pc + 1 + operand.length;
|
||||
}
|
||||
case kExprCallIndirect: {
|
||||
CallIndirectOperand<false> operand(decoder, code->at(pc));
|
||||
CallIndirectOperand<Decoder::kNoValidate> operand(decoder,
|
||||
code->at(pc));
|
||||
return pc + 1 + operand.length;
|
||||
}
|
||||
default:
|
||||
@ -1439,7 +1441,8 @@ class ThreadImpl {
|
||||
template <typename ctype, typename mtype>
|
||||
bool ExecuteLoad(Decoder* decoder, InterpreterCode* code, pc_t pc, int& len,
|
||||
MachineRepresentation rep) {
|
||||
MemoryAccessOperand<false> operand(decoder, code->at(pc), sizeof(ctype));
|
||||
MemoryAccessOperand<Decoder::kNoValidate> operand(decoder, code->at(pc),
|
||||
sizeof(ctype));
|
||||
uint32_t index = Pop().to<uint32_t>();
|
||||
if (!BoundsCheck<mtype>(wasm_context_->mem_size, operand.offset, index)) {
|
||||
DoTrap(kTrapMemOutOfBounds, pc);
|
||||
@ -1464,7 +1467,8 @@ class ThreadImpl {
|
||||
template <typename ctype, typename mtype>
|
||||
bool ExecuteStore(Decoder* decoder, InterpreterCode* code, pc_t pc, int& len,
|
||||
MachineRepresentation rep) {
|
||||
MemoryAccessOperand<false> operand(decoder, code->at(pc), sizeof(ctype));
|
||||
MemoryAccessOperand<Decoder::kNoValidate> operand(decoder, code->at(pc),
|
||||
sizeof(ctype));
|
||||
WasmValue val = Pop();
|
||||
|
||||
uint32_t index = Pop().to<uint32_t>();
|
||||
@ -1584,17 +1588,20 @@ class ThreadImpl {
|
||||
case kExprNop:
|
||||
break;
|
||||
case kExprBlock: {
|
||||
BlockTypeOperand<false> operand(&decoder, code->at(pc));
|
||||
BlockTypeOperand<Decoder::kNoValidate> operand(&decoder,
|
||||
code->at(pc));
|
||||
len = 1 + operand.length;
|
||||
break;
|
||||
}
|
||||
case kExprLoop: {
|
||||
BlockTypeOperand<false> operand(&decoder, code->at(pc));
|
||||
BlockTypeOperand<Decoder::kNoValidate> operand(&decoder,
|
||||
code->at(pc));
|
||||
len = 1 + operand.length;
|
||||
break;
|
||||
}
|
||||
case kExprIf: {
|
||||
BlockTypeOperand<false> operand(&decoder, code->at(pc));
|
||||
BlockTypeOperand<Decoder::kNoValidate> operand(&decoder,
|
||||
code->at(pc));
|
||||
WasmValue cond = Pop();
|
||||
bool is_true = cond.to<uint32_t>() != 0;
|
||||
if (is_true) {
|
||||
@ -1620,13 +1627,15 @@ class ThreadImpl {
|
||||
break;
|
||||
}
|
||||
case kExprBr: {
|
||||
BreakDepthOperand<false> operand(&decoder, code->at(pc));
|
||||
BreakDepthOperand<Decoder::kNoValidate> operand(&decoder,
|
||||
code->at(pc));
|
||||
len = DoBreak(code, pc, operand.depth);
|
||||
TRACE(" br => @%zu\n", pc + len);
|
||||
break;
|
||||
}
|
||||
case kExprBrIf: {
|
||||
BreakDepthOperand<false> operand(&decoder, code->at(pc));
|
||||
BreakDepthOperand<Decoder::kNoValidate> operand(&decoder,
|
||||
code->at(pc));
|
||||
WasmValue cond = Pop();
|
||||
bool is_true = cond.to<uint32_t>() != 0;
|
||||
if (is_true) {
|
||||
@ -1639,8 +1648,9 @@ class ThreadImpl {
|
||||
break;
|
||||
}
|
||||
case kExprBrTable: {
|
||||
BranchTableOperand<false> operand(&decoder, code->at(pc));
|
||||
BranchTableIterator<false> iterator(&decoder, operand);
|
||||
BranchTableOperand<Decoder::kNoValidate> operand(&decoder,
|
||||
code->at(pc));
|
||||
BranchTableIterator<Decoder::kNoValidate> iterator(&decoder, operand);
|
||||
uint32_t key = Pop().to<uint32_t>();
|
||||
uint32_t depth = 0;
|
||||
if (key >= operand.table_count) key = operand.table_count;
|
||||
@ -1665,44 +1675,47 @@ class ThreadImpl {
|
||||
break;
|
||||
}
|
||||
case kExprI32Const: {
|
||||
ImmI32Operand<false> operand(&decoder, code->at(pc));
|
||||
ImmI32Operand<Decoder::kNoValidate> operand(&decoder, code->at(pc));
|
||||
Push(WasmValue(operand.value));
|
||||
len = 1 + operand.length;
|
||||
break;
|
||||
}
|
||||
case kExprI64Const: {
|
||||
ImmI64Operand<false> operand(&decoder, code->at(pc));
|
||||
ImmI64Operand<Decoder::kNoValidate> operand(&decoder, code->at(pc));
|
||||
Push(WasmValue(operand.value));
|
||||
len = 1 + operand.length;
|
||||
break;
|
||||
}
|
||||
case kExprF32Const: {
|
||||
ImmF32Operand<false> operand(&decoder, code->at(pc));
|
||||
ImmF32Operand<Decoder::kNoValidate> operand(&decoder, code->at(pc));
|
||||
Push(WasmValue(operand.value));
|
||||
len = 1 + operand.length;
|
||||
break;
|
||||
}
|
||||
case kExprF64Const: {
|
||||
ImmF64Operand<false> operand(&decoder, code->at(pc));
|
||||
ImmF64Operand<Decoder::kNoValidate> operand(&decoder, code->at(pc));
|
||||
Push(WasmValue(operand.value));
|
||||
len = 1 + operand.length;
|
||||
break;
|
||||
}
|
||||
case kExprGetLocal: {
|
||||
LocalIndexOperand<false> operand(&decoder, code->at(pc));
|
||||
LocalIndexOperand<Decoder::kNoValidate> operand(&decoder,
|
||||
code->at(pc));
|
||||
Push(GetStackValue(frames_.back().sp + operand.index));
|
||||
len = 1 + operand.length;
|
||||
break;
|
||||
}
|
||||
case kExprSetLocal: {
|
||||
LocalIndexOperand<false> operand(&decoder, code->at(pc));
|
||||
LocalIndexOperand<Decoder::kNoValidate> operand(&decoder,
|
||||
code->at(pc));
|
||||
WasmValue val = Pop();
|
||||
SetStackValue(frames_.back().sp + operand.index, val);
|
||||
len = 1 + operand.length;
|
||||
break;
|
||||
}
|
||||
case kExprTeeLocal: {
|
||||
LocalIndexOperand<false> operand(&decoder, code->at(pc));
|
||||
LocalIndexOperand<Decoder::kNoValidate> operand(&decoder,
|
||||
code->at(pc));
|
||||
WasmValue val = Pop();
|
||||
SetStackValue(frames_.back().sp + operand.index, val);
|
||||
Push(val);
|
||||
@ -1714,7 +1727,8 @@ class ThreadImpl {
|
||||
break;
|
||||
}
|
||||
case kExprCallFunction: {
|
||||
CallFunctionOperand<false> operand(&decoder, code->at(pc));
|
||||
CallFunctionOperand<Decoder::kNoValidate> operand(&decoder,
|
||||
code->at(pc));
|
||||
InterpreterCode* target = codemap()->GetCode(operand.index);
|
||||
if (target->function->imported) {
|
||||
CommitPc(pc);
|
||||
@ -1746,7 +1760,8 @@ class ThreadImpl {
|
||||
continue; // don't bump pc
|
||||
} break;
|
||||
case kExprCallIndirect: {
|
||||
CallIndirectOperand<false> operand(&decoder, code->at(pc));
|
||||
CallIndirectOperand<Decoder::kNoValidate> operand(&decoder,
|
||||
code->at(pc));
|
||||
uint32_t entry_index = Pop().to<uint32_t>();
|
||||
// Assume only one table for now.
|
||||
DCHECK_LE(module()->function_tables.size(), 1u);
|
||||
@ -1773,7 +1788,8 @@ class ThreadImpl {
|
||||
}
|
||||
} break;
|
||||
case kExprGetGlobal: {
|
||||
GlobalIndexOperand<false> operand(&decoder, code->at(pc));
|
||||
GlobalIndexOperand<Decoder::kNoValidate> operand(&decoder,
|
||||
code->at(pc));
|
||||
const WasmGlobal* global = &module()->globals[operand.index];
|
||||
byte* ptr = wasm_context_->globals_start + global->offset;
|
||||
WasmValue val;
|
||||
@ -1792,7 +1808,8 @@ class ThreadImpl {
|
||||
break;
|
||||
}
|
||||
case kExprSetGlobal: {
|
||||
GlobalIndexOperand<false> operand(&decoder, code->at(pc));
|
||||
GlobalIndexOperand<Decoder::kNoValidate> operand(&decoder,
|
||||
code->at(pc));
|
||||
const WasmGlobal* global = &module()->globals[operand.index];
|
||||
byte* ptr = wasm_context_->globals_start + global->offset;
|
||||
WasmValue val = Pop();
|
||||
@ -1898,7 +1915,8 @@ class ThreadImpl {
|
||||
ASMJS_STORE_CASE(F64AsmjsStoreMem, double, double);
|
||||
#undef ASMJS_STORE_CASE
|
||||
case kExprGrowMemory: {
|
||||
MemoryIndexOperand<false> operand(&decoder, code->at(pc));
|
||||
MemoryIndexOperand<Decoder::kNoValidate> operand(&decoder,
|
||||
code->at(pc));
|
||||
uint32_t delta_pages = Pop().to<uint32_t>();
|
||||
Handle<WasmInstanceObject> instance =
|
||||
codemap()->maybe_instance().ToHandleChecked();
|
||||
@ -1911,7 +1929,8 @@ class ThreadImpl {
|
||||
break;
|
||||
}
|
||||
case kExprMemorySize: {
|
||||
MemoryIndexOperand<false> operand(&decoder, code->at(pc));
|
||||
MemoryIndexOperand<Decoder::kNoValidate> operand(&decoder,
|
||||
code->at(pc));
|
||||
Push(WasmValue(static_cast<uint32_t>(wasm_context_->mem_size /
|
||||
WasmModule::kPageSize)));
|
||||
len = 1 + operand.length;
|
||||
|
@ -101,7 +101,7 @@ void PrintWasmText(const WasmModule* module, const ModuleWireBytes& wire_bytes,
|
||||
case kExprIf:
|
||||
case kExprBlock:
|
||||
case kExprTry: {
|
||||
BlockTypeOperand<false> operand(&i, i.pc());
|
||||
BlockTypeOperand<Decoder::kNoValidate> operand(&i, i.pc());
|
||||
os << WasmOpcodes::OpcodeName(opcode);
|
||||
if (operand.type == kWasmVar) {
|
||||
os << " (type " << operand.sig_index << ")";
|
||||
@ -113,7 +113,7 @@ void PrintWasmText(const WasmModule* module, const ModuleWireBytes& wire_bytes,
|
||||
}
|
||||
case kExprBr:
|
||||
case kExprBrIf: {
|
||||
BreakDepthOperand<false> operand(&i, i.pc());
|
||||
BreakDepthOperand<Decoder::kNoValidate> operand(&i, i.pc());
|
||||
os << WasmOpcodes::OpcodeName(opcode) << ' ' << operand.depth;
|
||||
break;
|
||||
}
|
||||
@ -125,45 +125,45 @@ void PrintWasmText(const WasmModule* module, const ModuleWireBytes& wire_bytes,
|
||||
os << "end";
|
||||
break;
|
||||
case kExprBrTable: {
|
||||
BranchTableOperand<false> operand(&i, i.pc());
|
||||
BranchTableIterator<false> iterator(&i, operand);
|
||||
BranchTableOperand<Decoder::kNoValidate> operand(&i, i.pc());
|
||||
BranchTableIterator<Decoder::kNoValidate> iterator(&i, operand);
|
||||
os << "br_table";
|
||||
while (iterator.has_next()) os << ' ' << iterator.next();
|
||||
break;
|
||||
}
|
||||
case kExprCallIndirect: {
|
||||
CallIndirectOperand<false> operand(&i, i.pc());
|
||||
CallIndirectOperand<Decoder::kNoValidate> operand(&i, i.pc());
|
||||
DCHECK_EQ(0, operand.table_index);
|
||||
os << "call_indirect " << operand.index;
|
||||
break;
|
||||
}
|
||||
case kExprCallFunction: {
|
||||
CallFunctionOperand<false> operand(&i, i.pc());
|
||||
CallFunctionOperand<Decoder::kNoValidate> operand(&i, i.pc());
|
||||
os << "call " << operand.index;
|
||||
break;
|
||||
}
|
||||
case kExprGetLocal:
|
||||
case kExprSetLocal:
|
||||
case kExprTeeLocal: {
|
||||
LocalIndexOperand<false> operand(&i, i.pc());
|
||||
LocalIndexOperand<Decoder::kNoValidate> operand(&i, i.pc());
|
||||
os << WasmOpcodes::OpcodeName(opcode) << ' ' << operand.index;
|
||||
break;
|
||||
}
|
||||
case kExprThrow:
|
||||
case kExprCatch: {
|
||||
ExceptionIndexOperand<false> operand(&i, i.pc());
|
||||
ExceptionIndexOperand<Decoder::kNoValidate> operand(&i, i.pc());
|
||||
os << WasmOpcodes::OpcodeName(opcode) << ' ' << operand.index;
|
||||
break;
|
||||
}
|
||||
case kExprGetGlobal:
|
||||
case kExprSetGlobal: {
|
||||
GlobalIndexOperand<false> operand(&i, i.pc());
|
||||
GlobalIndexOperand<Decoder::kNoValidate> operand(&i, i.pc());
|
||||
os << WasmOpcodes::OpcodeName(opcode) << ' ' << operand.index;
|
||||
break;
|
||||
}
|
||||
#define CASE_CONST(type, str, cast_type) \
|
||||
case kExpr##type##Const: { \
|
||||
Imm##type##Operand<false> operand(&i, i.pc()); \
|
||||
Imm##type##Operand<Decoder::kNoValidate> operand(&i, i.pc()); \
|
||||
os << #str ".const " << static_cast<cast_type>(operand.value); \
|
||||
break; \
|
||||
}
|
||||
@ -176,7 +176,8 @@ void PrintWasmText(const WasmModule* module, const ModuleWireBytes& wire_bytes,
|
||||
#define CASE_OPCODE(opcode, _, __) case kExpr##opcode:
|
||||
FOREACH_LOAD_MEM_OPCODE(CASE_OPCODE)
|
||||
FOREACH_STORE_MEM_OPCODE(CASE_OPCODE) {
|
||||
MemoryAccessOperand<false> operand(&i, i.pc(), kMaxUInt32);
|
||||
MemoryAccessOperand<Decoder::kNoValidate> operand(&i, i.pc(),
|
||||
kMaxUInt32);
|
||||
os << WasmOpcodes::OpcodeName(opcode) << " offset=" << operand.offset
|
||||
<< " align=" << (1ULL << operand.alignment);
|
||||
break;
|
||||
@ -196,7 +197,8 @@ void PrintWasmText(const WasmModule* module, const ModuleWireBytes& wire_bytes,
|
||||
WasmOpcode atomic_opcode = i.prefixed_opcode();
|
||||
switch (atomic_opcode) {
|
||||
FOREACH_ATOMIC_OPCODE(CASE_OPCODE) {
|
||||
MemoryAccessOperand<false> operand(&i, i.pc(), kMaxUInt32);
|
||||
MemoryAccessOperand<Decoder::kNoValidate> operand(&i, i.pc(),
|
||||
kMaxUInt32);
|
||||
os << WasmOpcodes::OpcodeName(atomic_opcode)
|
||||
<< " offset=" << operand.offset
|
||||
<< " align=" << (1ULL << operand.alignment);
|
||||
|
@ -24,8 +24,9 @@ class DecoderTest : public TestWithZone {
|
||||
const byte data[] = {__VA_ARGS__}; \
|
||||
decoder.Reset(data, data + sizeof(data)); \
|
||||
unsigned length; \
|
||||
EXPECT_EQ(static_cast<uint32_t>(expected), \
|
||||
decoder.read_u32v<true>(decoder.start(), &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()); \
|
||||
@ -38,7 +39,8 @@ class DecoderTest : public TestWithZone {
|
||||
const byte data[] = {__VA_ARGS__}; \
|
||||
decoder.Reset(data, data + sizeof(data)); \
|
||||
unsigned length; \
|
||||
EXPECT_EQ(expected, decoder.read_i32v<true>(decoder.start(), &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()); \
|
||||
@ -51,8 +53,9 @@ class DecoderTest : public TestWithZone {
|
||||
const byte data[] = {__VA_ARGS__}; \
|
||||
decoder.Reset(data, data + sizeof(data)); \
|
||||
unsigned length; \
|
||||
EXPECT_EQ(static_cast<uint64_t>(expected), \
|
||||
decoder.read_u64v<false>(decoder.start(), &length)); \
|
||||
EXPECT_EQ( \
|
||||
static_cast<uint64_t>(expected), \
|
||||
decoder.read_u64v<Decoder::kValidate>(decoder.start(), &length)); \
|
||||
EXPECT_EQ(static_cast<unsigned>(expected_length), length); \
|
||||
} while (false)
|
||||
|
||||
@ -61,7 +64,8 @@ class DecoderTest : public TestWithZone {
|
||||
const byte data[] = {__VA_ARGS__}; \
|
||||
decoder.Reset(data, data + sizeof(data)); \
|
||||
unsigned length; \
|
||||
EXPECT_EQ(expected, decoder.read_i64v<false>(decoder.start(), &length)); \
|
||||
EXPECT_EQ(expected, decoder.read_i64v<Decoder::kValidate>(decoder.start(), \
|
||||
&length)); \
|
||||
EXPECT_EQ(static_cast<unsigned>(expected_length), length); \
|
||||
} while (false)
|
||||
|
||||
@ -374,7 +378,7 @@ TEST_F(DecoderTest, ReadU32v_off_end1) {
|
||||
static const byte data[] = {U32V_1(11)};
|
||||
unsigned length = 0;
|
||||
decoder.Reset(data, data);
|
||||
decoder.read_u32v<true>(decoder.start(), &length);
|
||||
decoder.read_u32v<Decoder::kValidate>(decoder.start(), &length);
|
||||
EXPECT_EQ(0u, length);
|
||||
EXPECT_FALSE(decoder.ok());
|
||||
}
|
||||
@ -384,7 +388,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<true>(decoder.start(), &length);
|
||||
decoder.read_u32v<Decoder::kValidate>(decoder.start(), &length);
|
||||
EXPECT_EQ(i, length);
|
||||
EXPECT_FALSE(decoder.ok());
|
||||
}
|
||||
@ -395,7 +399,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<true>(decoder.start(), &length);
|
||||
decoder.read_u32v<Decoder::kValidate>(decoder.start(), &length);
|
||||
EXPECT_EQ(i, length);
|
||||
EXPECT_FALSE(decoder.ok());
|
||||
}
|
||||
@ -406,7 +410,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<true>(decoder.start(), &length);
|
||||
decoder.read_u32v<Decoder::kValidate>(decoder.start(), &length);
|
||||
EXPECT_EQ(i, length);
|
||||
EXPECT_FALSE(decoder.ok());
|
||||
}
|
||||
@ -417,7 +421,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<true>(decoder.start(), &length);
|
||||
decoder.read_u32v<Decoder::kValidate>(decoder.start(), &length);
|
||||
EXPECT_EQ(i, length);
|
||||
EXPECT_FALSE(decoder.ok());
|
||||
}
|
||||
@ -429,7 +433,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<true>(decoder.start(), &length);
|
||||
decoder.read_u32v<Decoder::kValidate>(decoder.start(), &length);
|
||||
EXPECT_EQ(5u, length);
|
||||
EXPECT_FALSE(decoder.ok());
|
||||
}
|
||||
@ -440,7 +444,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<true>(decoder.start(), &length);
|
||||
decoder.read_i32v<Decoder::kValidate>(decoder.start(), &length);
|
||||
EXPECT_EQ(5u, length);
|
||||
EXPECT_TRUE(decoder.ok());
|
||||
}
|
||||
@ -450,7 +454,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<true>(decoder.start(), &length);
|
||||
decoder.read_i32v<Decoder::kValidate>(decoder.start(), &length);
|
||||
EXPECT_EQ(5u, length);
|
||||
EXPECT_FALSE(decoder.ok());
|
||||
}
|
||||
@ -485,7 +489,7 @@ 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<true>(data, &rlen);
|
||||
uint32_t result = decoder.read_u32v<Decoder::kValidate>(data, &rlen);
|
||||
if (limit < length) {
|
||||
EXPECT_FALSE(decoder.ok());
|
||||
} else {
|
||||
@ -541,7 +545,7 @@ 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<true>(data, &length);
|
||||
uint64_t result = decoder.read_u64v<Decoder::kValidate>(data, &length);
|
||||
if (limit <= index) {
|
||||
EXPECT_FALSE(decoder.ok());
|
||||
} else {
|
||||
@ -582,7 +586,7 @@ 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<true>(data, &rlen);
|
||||
uint64_t result = decoder.read_u64v<Decoder::kValidate>(data, &rlen);
|
||||
if (limit < length) {
|
||||
EXPECT_FALSE(decoder.ok());
|
||||
} else {
|
||||
@ -624,7 +628,7 @@ 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<true>(data, &rlen);
|
||||
int64_t result = decoder.read_i64v<Decoder::kValidate>(data, &rlen);
|
||||
if (limit < length) {
|
||||
EXPECT_FALSE(decoder.ok());
|
||||
} else {
|
||||
@ -643,7 +647,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<true>(decoder.start(), &length);
|
||||
decoder.read_u64v<Decoder::kValidate>(decoder.start(), &length);
|
||||
EXPECT_EQ(10u, length);
|
||||
EXPECT_FALSE(decoder.ok());
|
||||
}
|
||||
@ -654,7 +658,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<true>(decoder.start(), &length);
|
||||
decoder.read_i64v<Decoder::kValidate>(decoder.start(), &length);
|
||||
EXPECT_EQ(10u, length);
|
||||
EXPECT_TRUE(decoder.ok());
|
||||
}
|
||||
@ -664,7 +668,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<true>(decoder.start(), &length);
|
||||
decoder.read_i64v<Decoder::kValidate>(decoder.start(), &length);
|
||||
EXPECT_EQ(10u, length);
|
||||
EXPECT_FALSE(decoder.ok());
|
||||
}
|
||||
|
@ -2533,15 +2533,15 @@ class BranchTableIteratorTest : public TestWithZone {
|
||||
BranchTableIteratorTest() : TestWithZone() {}
|
||||
void CheckBrTableSize(const byte* start, const byte* end) {
|
||||
Decoder decoder(start, end);
|
||||
BranchTableOperand<true> operand(&decoder, start);
|
||||
BranchTableIterator<true> iterator(&decoder, operand);
|
||||
BranchTableOperand<Decoder::kValidate> operand(&decoder, start);
|
||||
BranchTableIterator<Decoder::kValidate> iterator(&decoder, operand);
|
||||
EXPECT_EQ(end - start - 1u, iterator.length());
|
||||
EXPECT_TRUE(decoder.ok());
|
||||
}
|
||||
void CheckBrTableError(const byte* start, const byte* end) {
|
||||
Decoder decoder(start, end);
|
||||
BranchTableOperand<true> operand(&decoder, start);
|
||||
BranchTableIterator<true> iterator(&decoder, operand);
|
||||
BranchTableOperand<Decoder::kValidate> operand(&decoder, start);
|
||||
BranchTableIterator<Decoder::kValidate> iterator(&decoder, operand);
|
||||
iterator.length();
|
||||
EXPECT_FALSE(decoder.ok());
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ TEST_F(LEBHelperTest, sizeof_i32v) {
|
||||
static_cast<size_t>(ptr - buffer)); \
|
||||
Decoder decoder(buffer, buffer + kSize); \
|
||||
unsigned length = 0; \
|
||||
ctype result = decoder.read_##name<false>(buffer, &length); \
|
||||
ctype result = decoder.read_##name<Decoder::kNoValidate>(buffer, &length); \
|
||||
EXPECT_EQ(val, result); \
|
||||
EXPECT_EQ(LEBHelper::sizeof_##name(val), static_cast<size_t>(length)); \
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user