Commit 02b4d0e6 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[wasm] [decoder] Merge checked_read_leb and consume_leb

Both methods decoded a LEB128 encoded integer, but only consume_leb
incremented the pc pointer accordingly.
This CL implements consume_leb by using checked_read_leb.

It also refactors a few things:
1) It removes error_pt, which was only avaible in checked_read_leb.
2) It renames the error method to errorf, since it receives a format
   string. This also avoids a name clash.
3) It implements sign extension directly in checked_read_leb instead of
   doing this in the caller.

R=ahaas@chromium.org
BUG=v8:5822

Change-Id: I8058f57418493861e5df26d4949041f6766d5138
Reviewed-on: https://chromium-review.googlesource.com/467150
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#44405}
parent 0ed2f178
......@@ -23,8 +23,13 @@ namespace wasm {
do { \
if (FLAG_trace_wasm_decoder) PrintF(__VA_ARGS__); \
} while (false)
#define TRACE_IF(cond, ...) \
do { \
if (FLAG_trace_wasm_decoder && (cond)) PrintF(__VA_ARGS__); \
} while (false)
#else
#define TRACE(...)
#define TRACE_IF(...)
#endif
// A helper utility to decode bytes, integers, fields, varints, etc, from
......@@ -32,94 +37,67 @@ namespace wasm {
class Decoder {
public:
Decoder(const byte* start, const byte* end)
: start_(start),
pc_(start),
end_(end),
error_pc_(nullptr),
error_pt_(nullptr) {}
: start_(start), pc_(start), end_(end), error_pc_(nullptr) {}
Decoder(const byte* start, const byte* pc, const byte* end)
: start_(start),
pc_(pc),
end_(end),
error_pc_(nullptr),
error_pt_(nullptr) {}
: start_(start), pc_(pc), end_(end), error_pc_(nullptr) {}
virtual ~Decoder() {}
inline bool check(const byte* base, unsigned offset, unsigned length,
const char* msg) {
DCHECK_GE(base, start_);
if ((base + offset + length) > end_) {
error(base, base + offset, "%s", msg);
inline bool check(const byte* pc, unsigned length, const char* msg) {
DCHECK_LE(start_, pc);
if (V8_UNLIKELY(pc + length > end_)) {
error(pc, msg);
return false;
}
return true;
}
// Reads a single 8-bit byte, reporting an error if out of bounds.
inline uint8_t checked_read_u8(const byte* base, unsigned offset,
inline uint8_t checked_read_u8(const byte* pc,
const char* msg = "expected 1 byte") {
return check(base, offset, 1, msg) ? base[offset] : 0;
return check(pc, 1, msg) ? *pc : 0;
}
// Reads 16-bit word, reporting an error if out of bounds.
inline uint16_t checked_read_u16(const byte* base, unsigned offset,
inline uint16_t checked_read_u16(const byte* pc,
const char* msg = "expected 2 bytes") {
return check(base, offset, 2, msg) ? read_u16(base + offset) : 0;
return check(pc, 2, msg) ? read_u16(pc) : 0;
}
// Reads 32-bit word, reporting an error if out of bounds.
inline uint32_t checked_read_u32(const byte* base, unsigned offset,
inline uint32_t checked_read_u32(const byte* pc,
const char* msg = "expected 4 bytes") {
return check(base, offset, 4, msg) ? read_u32(base + offset) : 0;
return check(pc, 4, msg) ? read_u32(pc) : 0;
}
// Reads 64-bit word, reporting an error if out of bounds.
inline uint64_t checked_read_u64(const byte* base, unsigned offset,
inline uint64_t checked_read_u64(const byte* pc,
const char* msg = "expected 8 bytes") {
return check(base, offset, 8, msg) ? read_u64(base + offset) : 0;
return check(pc, 8, msg) ? read_u64(pc) : 0;
}
// Reads a variable-length unsigned integer (little endian).
uint32_t checked_read_u32v(const byte* base, unsigned offset,
unsigned* length,
const char* msg = "expected LEB32") {
return checked_read_leb<uint32_t, false>(base, offset, length, msg);
uint32_t checked_read_u32v(const byte* pc, unsigned* length,
const char* name = "LEB32") {
return checked_read_leb<uint32_t, false, false>(pc, length, name);
}
// Reads a variable-length signed integer (little endian).
int32_t checked_read_i32v(const byte* base, unsigned offset, unsigned* length,
const char* msg = "expected SLEB32") {
uint32_t result =
checked_read_leb<uint32_t, true>(base, offset, length, msg);
if (*length == 5) return bit_cast<int32_t>(result);
if (*length > 0) {
int shift = 32 - 7 * *length;
// Perform sign extension.
return bit_cast<int32_t>(result << shift) >> shift;
}
return 0;
int32_t checked_read_i32v(const byte* pc, unsigned* length,
const char* name = "signed LEB32") {
return checked_read_leb<int32_t, false, false>(pc, length, name);
}
// Reads a variable-length unsigned integer (little endian).
uint64_t checked_read_u64v(const byte* base, unsigned offset,
unsigned* length,
const char* msg = "expected LEB64") {
return checked_read_leb<uint64_t, false>(base, offset, length, msg);
uint64_t checked_read_u64v(const byte* pc, unsigned* length,
const char* name = "LEB64") {
return checked_read_leb<uint64_t, false, false>(pc, length, name);
}
// Reads a variable-length signed integer (little endian).
int64_t checked_read_i64v(const byte* base, unsigned offset, unsigned* length,
const char* msg = "expected SLEB64") {
uint64_t result =
checked_read_leb<uint64_t, true>(base, offset, length, msg);
if (*length == 10) return bit_cast<int64_t>(result);
if (*length > 0) {
int shift = 64 - 7 * *length;
// Perform sign extension.
return bit_cast<int64_t>(result << shift) >> shift;
}
return 0;
int64_t checked_read_i64v(const byte* pc, unsigned* length,
const char* name = "signed LEB64") {
return checked_read_leb<int64_t, false, false>(pc, length, name);
}
// Reads a single 16-bit unsigned integer (little endian).
......@@ -149,7 +127,7 @@ class Decoder {
TRACE("%02x = %d\n", val, val);
return val;
}
return traceOffEnd<uint8_t>();
return traceOffEnd<uint8_t, true>();
}
// Reads a 16-bit unsigned integer (little endian) and advances {pc_}.
......@@ -162,7 +140,7 @@ class Decoder {
pc_ += 2;
return val;
}
return traceOffEnd<uint16_t>();
return traceOffEnd<uint16_t, true>();
}
// Reads a single 32-bit unsigned integer (little endian) and advances {pc_}.
......@@ -175,28 +153,26 @@ class Decoder {
pc_ += 4;
return val;
}
return traceOffEnd<uint32_t>();
return traceOffEnd<uint32_t, true>();
}
// Reads a LEB128 variable-length unsigned 32-bit integer and advances {pc_}.
uint32_t consume_u32v(const char* name = nullptr) {
return consume_leb<uint32_t, false>(name);
unsigned length = 0;
return checked_read_leb<uint32_t, true, true>(pc_, &length, name);
}
// Reads a LEB128 variable-length signed 32-bit integer and advances {pc_}.
int32_t consume_i32v(const char* name = nullptr) {
return consume_leb<int32_t, true>(name);
unsigned length = 0;
return checked_read_leb<int32_t, true, true>(pc_, &length, name);
}
// Consume {size} bytes and send them to the bit bucket, advancing {pc_}.
void consume_bytes(uint32_t size, const char* name = "skip") {
#if DEBUG
if (name) {
// Only trace if the name is not null.
TRACE(" +%d %-20s: %d bytes\n", static_cast<int>(pc_ - start_), name,
size);
}
#endif
// Only trace if the name is not null.
TRACE_IF(name, " +%d %-20s: %d bytes\n", static_cast<int>(pc_ - start_),
name, size);
if (checkAvailable(size)) {
pc_ += size;
} else {
......@@ -208,55 +184,52 @@ class Decoder {
bool checkAvailable(int size) {
intptr_t pc_overflow_value = std::numeric_limits<intptr_t>::max() - size;
if (size < 0 || (intptr_t)pc_ > pc_overflow_value) {
error(pc_, nullptr, "reading %d bytes would underflow/overflow", size);
errorf(pc_, "reading %d bytes would underflow/overflow", size);
return false;
} else if (pc_ < start_ || end_ < (pc_ + size)) {
error(pc_, nullptr, "expected %d bytes, fell off end", size);
errorf(pc_, "expected %d bytes, fell off end", size);
return false;
} else {
return true;
}
}
void error(const char* msg) { error(pc_, nullptr, "%s", msg); }
void error(const char* msg) { errorf(pc_, "%s", msg); }
void error(const byte* pc, const char* msg) { error(pc, nullptr, "%s", msg); }
void error(const byte* pc, const char* msg) { errorf(pc, "%s", msg); }
// Sets internal error state.
void PRINTF_FORMAT(4, 5)
error(const byte* pc, const byte* pt, const char* format, ...) {
if (ok()) {
void PRINTF_FORMAT(3, 4) errorf(const byte* pc, const char* format, ...) {
// Only report the first error.
if (!ok()) return;
#if DEBUG
if (FLAG_wasm_break_on_decoder_error) {
base::OS::DebugBreak();
}
#endif
const int kMaxErrorMsg = 256;
char* buffer = new char[kMaxErrorMsg];
va_list arguments;
va_start(arguments, format);
base::OS::VSNPrintF(buffer, kMaxErrorMsg - 1, format, arguments);
va_end(arguments);
error_msg_.reset(buffer);
error_pc_ = pc;
error_pt_ = pt;
onFirstError();
if (FLAG_wasm_break_on_decoder_error) {
base::OS::DebugBreak();
}
#endif
const int kMaxErrorMsg = 256;
char* buffer = new char[kMaxErrorMsg];
va_list arguments;
va_start(arguments, format);
base::OS::VSNPrintF(buffer, kMaxErrorMsg - 1, format, arguments);
va_end(arguments);
error_msg_.reset(buffer);
error_pc_ = pc;
onFirstError();
}
// Behavior triggered on first error, overridden in subclasses.
virtual void onFirstError() {}
// Debugging helper to print bytes up to the end.
template <typename T>
template <typename T, bool update_pc>
T traceOffEnd() {
T t = 0;
for (const byte* ptr = pc_; ptr < end_; ptr++) {
TRACE("%02x ", *ptr);
}
TRACE("<end>\n");
pc_ = end_;
return t;
if (update_pc) pc_ = end_;
return T{0};
}
// Converts the given value to a {Result}, copying the error if necessary.
......@@ -268,7 +241,6 @@ class Decoder {
result.error_code = kError;
result.start = start_;
result.error_pc = error_pc_;
result.error_pt = error_pt_;
// transfer ownership of the error to the result.
result.error_msg.reset(error_msg_.release());
} else {
......@@ -284,7 +256,6 @@ class Decoder {
pc_ = start;
end_ = end;
error_pc_ = nullptr;
error_pt_ = nullptr;
error_msg_.reset();
}
......@@ -302,104 +273,64 @@ class Decoder {
const byte* pc_;
const byte* end_;
const byte* error_pc_;
const byte* error_pt_;
std::unique_ptr<char[]> error_msg_;
private:
template <typename IntType, bool is_signed>
IntType checked_read_leb(const byte* base, unsigned offset, unsigned* length,
const char* msg) {
if (!check(base, offset, 1, msg)) {
*length = 0;
return 0;
}
const int kMaxLength = (sizeof(IntType) * 8 + 6) / 7;
const byte* ptr = base + offset;
const byte* end = ptr + kMaxLength;
if (end > end_) end = end_;
template <typename IntType, bool advance_pc, bool trace>
inline IntType checked_read_leb(const byte* pc, unsigned* length,
const char* name = "varint") {
DCHECK_IMPLIES(advance_pc, pc == pc_);
constexpr bool is_signed = std::is_signed<IntType>::value;
TRACE_IF(trace, " +%d %-20s: ", static_cast<int>(pc - start_), name);
constexpr int kMaxLength = (sizeof(IntType) * 8 + 6) / 7;
const byte* ptr = pc;
const byte* end = Min(end_, ptr + kMaxLength);
int shift = 0;
byte b = 0;
IntType result = 0;
while (ptr < end) {
for (;;) {
if (V8_UNLIKELY(ptr >= end)) {
TRACE_IF(trace, "<end> ");
errorf(ptr, "expected %s", name);
break;
}
b = *ptr++;
result = result | (static_cast<IntType>(b & 0x7F) << shift);
if ((b & 0x80) == 0) break;
TRACE_IF(trace, "%02x ", b);
result = result | ((static_cast<IntType>(b) & 0x7F) << shift);
shift += 7;
if ((b & 0x80) == 0) break;
}
DCHECK_LE(ptr - (base + offset), kMaxLength);
*length = static_cast<unsigned>(ptr - (base + offset));
if (ptr == end) {
// Check there are no bits set beyond the bitwidth of {IntType}.
const int kExtraBits = (1 + kMaxLength * 7) - (sizeof(IntType) * 8);
const byte kExtraBitsMask =
static_cast<byte>((0xFF << (8 - kExtraBits)) & 0xFF);
int extra_bits_value;
if (is_signed) {
// A signed-LEB128 must sign-extend the final byte, excluding its
// most-signifcant bit. e.g. for a 32-bit LEB128:
// kExtraBits = 4
// kExtraBitsMask = 0xf0
// If b is 0x0f, the value is negative, so extra_bits_value is 0x70.
// If b is 0x03, the value is positive, so extra_bits_value is 0x00.
extra_bits_value = (static_cast<int8_t>(b << kExtraBits) >> 8) &
kExtraBitsMask & ~0x80;
} else {
extra_bits_value = 0;
}
if (*length == kMaxLength && (b & kExtraBitsMask) != extra_bits_value) {
error(base, ptr, "extra bits in varint");
return 0;
}
if ((b & 0x80) != 0) {
error(base, ptr, "%s", msg);
DCHECK_LE(ptr - pc, kMaxLength);
*length = static_cast<unsigned>(ptr - pc);
if (advance_pc) pc_ = ptr;
if (*length == kMaxLength) {
// A signed-LEB128 must sign-extend the final byte, excluding its
// most-significant bit; e.g. for a 32-bit LEB128:
// kExtraBits = 4 (== 32 - (5-1) * 7)
// For unsigned values, the extra bits must be all zero.
// For signed values, the extra bits *plus* the most significant bit must
// either be 0, or all ones.
constexpr int kExtraBits = (sizeof(IntType) * 8) - ((kMaxLength - 1) * 7);
constexpr int kSignExtBits = kExtraBits - (is_signed ? 1 : 0);
const byte checked_bits = b & (0xFF << kSignExtBits);
constexpr byte kSignExtendedExtraBits = 0x7f & (0xFF << kSignExtBits);
if (checked_bits != 0 &&
(!is_signed || checked_bits != kSignExtendedExtraBits)) {
error(ptr, "extra bits in varint");
return 0;
}
}
return result;
}
template <typename IntType, bool is_signed>
IntType consume_leb(const char* name = nullptr) {
TRACE(" +%d %-20s: ", static_cast<int>(pc_ - start_),
name ? name : "varint");
if (checkAvailable(1)) {
const int kMaxLength = (sizeof(IntType) * 8 + 6) / 7;
const byte* pos = pc_;
const byte* end = pc_ + kMaxLength;
if (end > end_) end = end_;
IntType result = 0;
int shift = 0;
byte b = 0;
while (pc_ < end) {
b = *pc_++;
TRACE("%02x ", b);
result = result | (static_cast<IntType>(b & 0x7F) << shift);
shift += 7;
if ((b & 0x80) == 0) break;
}
int length = static_cast<int>(pc_ - pos);
if (pc_ == end && (b & 0x80)) {
TRACE("\n");
error(pc_ - 1, "varint too large");
} else if (length == 0) {
TRACE("\n");
error(pc_, "varint of length 0");
} else if (is_signed) {
if (length < kMaxLength) {
int sign_ext_shift = 8 * sizeof(IntType) - shift;
// Perform sign extension.
result = (result << sign_ext_shift) >> sign_ext_shift;
}
TRACE("= %" PRIi64 "\n", static_cast<int64_t>(result));
} else {
TRACE("= %" PRIu64 "\n", static_cast<uint64_t>(result));
}
return result;
if (is_signed && *length < kMaxLength) {
int sign_ext_shift = 8 * sizeof(IntType) - shift;
// Perform sign extension.
result = (result << sign_ext_shift) >> sign_ext_shift;
}
if (trace && is_signed) {
TRACE("= %" PRIi64 "\n", static_cast<int64_t>(result));
} else if (trace) {
TRACE("= %" PRIu64 "\n", static_cast<uint64_t>(result));
}
return traceOffEnd<uint32_t>();
return result;
}
};
......
......@@ -21,7 +21,7 @@ struct LocalIndexOperand {
unsigned length;
inline LocalIndexOperand(Decoder* decoder, const byte* pc) {
index = decoder->checked_read_u32v(pc, 1, &length, "local index");
index = decoder->checked_read_u32v(pc + 1, &length, "local index");
type = kWasmStmt;
}
};
......@@ -30,7 +30,7 @@ struct ImmI32Operand {
int32_t value;
unsigned length;
inline ImmI32Operand(Decoder* decoder, const byte* pc) {
value = decoder->checked_read_i32v(pc, 1, &length, "immi32");
value = decoder->checked_read_i32v(pc + 1, &length, "immi32");
}
};
......@@ -38,7 +38,7 @@ struct ImmI64Operand {
int64_t value;
unsigned length;
inline ImmI64Operand(Decoder* decoder, const byte* pc) {
value = decoder->checked_read_i64v(pc, 1, &length, "immi64");
value = decoder->checked_read_i64v(pc + 1, &length, "immi64");
}
};
......@@ -47,7 +47,7 @@ struct ImmF32Operand {
unsigned length;
inline ImmF32Operand(Decoder* decoder, const byte* pc) {
// Avoid bit_cast because it might not preserve the signalling bit of a NaN.
uint32_t tmp = decoder->checked_read_u32(pc, 1, "immf32");
uint32_t tmp = decoder->checked_read_u32(pc + 1, "immf32");
memcpy(&value, &tmp, sizeof(value));
length = 4;
}
......@@ -58,7 +58,7 @@ struct ImmF64Operand {
unsigned length;
inline ImmF64Operand(Decoder* decoder, const byte* pc) {
// Avoid bit_cast because it might not preserve the signalling bit of a NaN.
uint64_t tmp = decoder->checked_read_u64(pc, 1, "immf64");
uint64_t tmp = decoder->checked_read_u64(pc + 1, "immf64");
memcpy(&value, &tmp, sizeof(value));
length = 8;
}
......@@ -71,7 +71,7 @@ struct GlobalIndexOperand {
unsigned length;
inline GlobalIndexOperand(Decoder* decoder, const byte* pc) {
index = decoder->checked_read_u32v(pc, 1, &length, "global index");
index = decoder->checked_read_u32v(pc + 1, &length, "global index");
global = nullptr;
type = kWasmStmt;
}
......@@ -83,7 +83,7 @@ struct BlockTypeOperand {
unsigned length;
inline BlockTypeOperand(Decoder* decoder, const byte* pc) {
uint8_t val = decoder->checked_read_u8(pc, 1, "block type");
uint8_t val = decoder->checked_read_u8(pc + 1, "block type");
ValueType type = kWasmStmt;
length = 1;
arity = 0;
......@@ -94,16 +94,16 @@ struct BlockTypeOperand {
} else {
// Handle multi-value blocks.
if (!FLAG_wasm_mv_prototype) {
decoder->error(pc, pc + 1, "invalid block arity > 1");
decoder->error(pc + 1, "invalid block arity > 1");
return;
}
if (val != kMultivalBlock) {
decoder->error(pc, pc + 1, "invalid block type");
decoder->error(pc + 1, "invalid block type");
return;
}
// Decode and check the types vector of the block.
unsigned len = 0;
uint32_t count = decoder->checked_read_u32v(pc, 2, &len, "block arity");
uint32_t count = decoder->checked_read_u32v(pc + 2, &len, "block arity");
// {count} is encoded as {arity-2}, so that a {0} count here corresponds
// to a block with 2 values. This makes invalid/redundant encodings
// impossible.
......@@ -113,10 +113,10 @@ struct BlockTypeOperand {
for (uint32_t i = 0; i < arity; i++) {
uint32_t offset = 1 + 1 + len + i;
val = decoder->checked_read_u8(pc, offset, "block type");
val = decoder->checked_read_u8(pc + offset, "block type");
decode_local_type(val, &type);
if (type == kWasmStmt) {
decoder->error(pc, pc + offset, "invalid block type");
decoder->error(pc + offset, "invalid block type");
return;
}
}
......@@ -172,7 +172,7 @@ struct BreakDepthOperand {
Control* target;
unsigned length;
inline BreakDepthOperand(Decoder* decoder, const byte* pc) {
depth = decoder->checked_read_u32v(pc, 1, &length, "break depth");
depth = decoder->checked_read_u32v(pc + 1, &length, "break depth");
target = nullptr;
}
};
......@@ -184,11 +184,11 @@ struct CallIndirectOperand {
unsigned length;
inline CallIndirectOperand(Decoder* decoder, const byte* pc) {
unsigned len = 0;
index = decoder->checked_read_u32v(pc, 1, &len, "signature index");
table_index = decoder->checked_read_u8(pc, 1 + len, "table index");
index = decoder->checked_read_u32v(pc + 1, &len, "signature index");
table_index = decoder->checked_read_u8(pc + 1 + len, "table index");
if (table_index != 0) {
decoder->error(pc, pc + 1 + len, "expected table index 0, found %u",
table_index);
decoder->errorf(pc + 1 + len, "expected table index 0, found %u",
table_index);
}
length = 1 + len;
sig = nullptr;
......@@ -200,7 +200,7 @@ struct CallFunctionOperand {
FunctionSig* sig;
unsigned length;
inline CallFunctionOperand(Decoder* decoder, const byte* pc) {
index = decoder->checked_read_u32v(pc, 1, &length, "function index");
index = decoder->checked_read_u32v(pc + 1, &length, "function index");
sig = nullptr;
}
};
......@@ -209,9 +209,9 @@ struct MemoryIndexOperand {
uint32_t index;
unsigned length;
inline MemoryIndexOperand(Decoder* decoder, const byte* pc) {
index = decoder->checked_read_u8(pc, 1, "memory index");
index = decoder->checked_read_u8(pc + 1, "memory index");
if (index != 0) {
decoder->error(pc, pc + 1, "expected memory index 0, found %u", index);
decoder->errorf(pc + 1, "expected memory index 0, found %u", index);
}
length = 1;
}
......@@ -222,10 +222,10 @@ struct BranchTableOperand {
const byte* start;
const byte* table;
inline BranchTableOperand(Decoder* decoder, const byte* pc) {
DCHECK_EQ(kExprBrTable, decoder->checked_read_u8(pc, 0, "opcode"));
DCHECK_EQ(kExprBrTable, decoder->checked_read_u8(pc, "opcode"));
start = pc + 1;
unsigned len1 = 0;
table_count = decoder->checked_read_u32v(pc, 1, &len1, "table count");
table_count = decoder->checked_read_u32v(pc + 1, &len1, "table count");
if (table_count > (UINT_MAX / sizeof(uint32_t)) - 1 ||
len1 > UINT_MAX - (table_count + 1) * sizeof(uint32_t)) {
decoder->error(pc, "branch table size overflow");
......@@ -244,7 +244,7 @@ class BranchTableIterator {
index_++;
unsigned length = 0;
uint32_t result =
decoder_->checked_read_u32v(pc_, 0, &length, "branch table entry");
decoder_->checked_read_u32v(pc_, &length, "branch table entry");
pc_ += length;
return result;
}
......@@ -279,15 +279,15 @@ struct MemoryAccessOperand {
uint32_t max_alignment) {
unsigned alignment_length;
alignment =
decoder->checked_read_u32v(pc, 1, &alignment_length, "alignment");
decoder->checked_read_u32v(pc + 1, &alignment_length, "alignment");
if (max_alignment < alignment) {
decoder->error(pc, pc + 1,
"invalid alignment; expected maximum alignment is %u, "
"actual alignment is %u",
max_alignment, alignment);
decoder->errorf(pc + 1,
"invalid alignment; expected maximum alignment is %u, "
"actual alignment is %u",
max_alignment, alignment);
}
unsigned offset_length;
offset = decoder->checked_read_u32v(pc, 1 + alignment_length,
offset = decoder->checked_read_u32v(pc + 1 + alignment_length,
&offset_length, "offset");
length = alignment_length + offset_length;
}
......@@ -299,7 +299,7 @@ struct SimdLaneOperand {
unsigned length;
inline SimdLaneOperand(Decoder* decoder, const byte* pc) {
lane = decoder->checked_read_u8(pc, 2, "lane");
lane = decoder->checked_read_u8(pc + 2, "lane");
length = 1;
}
};
......@@ -310,7 +310,7 @@ struct SimdShiftOperand {
unsigned length;
inline SimdShiftOperand(Decoder* decoder, const byte* pc) {
shift = decoder->checked_read_u8(pc, 2, "shift");
shift = decoder->checked_read_u8(pc + 2, "shift");
length = 1;
}
};
......
......@@ -283,7 +283,7 @@ class WasmDecoder : public Decoder {
}
return true;
}
error(pc, pc + 1, "invalid local index: %u", operand.index);
errorf(pc + 1, "invalid local index: %u", operand.index);
return false;
}
......@@ -293,7 +293,7 @@ class WasmDecoder : public Decoder {
operand.type = operand.global->type;
return true;
}
error(pc, pc + 1, "invalid global index: %u", operand.index);
errorf(pc + 1, "invalid global index: %u", operand.index);
return false;
}
......@@ -309,7 +309,7 @@ class WasmDecoder : public Decoder {
if (Complete(pc, operand)) {
return true;
}
error(pc, pc + 1, "invalid function index: %u", operand.index);
errorf(pc + 1, "invalid function index: %u", operand.index);
return false;
}
......@@ -329,7 +329,7 @@ class WasmDecoder : public Decoder {
if (Complete(pc, operand)) {
return true;
}
error(pc, pc + 1, "invalid signature index: #%u", operand.index);
errorf(pc + 1, "invalid signature index: #%u", operand.index);
return false;
}
......@@ -339,7 +339,7 @@ class WasmDecoder : public Decoder {
operand.target = &control[control.size() - operand.depth - 1];
return true;
}
error(pc, pc + 1, "invalid break depth: %u", operand.depth);
errorf(pc + 1, "invalid break depth: %u", operand.depth);
return false;
}
......@@ -372,7 +372,7 @@ class WasmDecoder : public Decoder {
break;
}
if (operand.lane < 0 || operand.lane >= num_lanes) {
error(pc_, pc_ + 2, "invalid lane index");
error(pc_ + 2, "invalid lane index");
return false;
} else {
return true;
......@@ -403,7 +403,7 @@ class WasmDecoder : public Decoder {
break;
}
if (operand.shift < 0 || operand.shift >= max_shift) {
error(pc_, pc_ + 2, "invalid shift amount");
error(pc_ + 2, "invalid shift amount");
return false;
} else {
return true;
......@@ -478,7 +478,7 @@ class WasmDecoder : public Decoder {
case kExprF64Const:
return 9;
case kSimdPrefix: {
byte simd_index = decoder->checked_read_u8(pc, 1, "simd_index");
byte simd_index = decoder->checked_read_u8(pc + 1, "simd_index");
WasmOpcode opcode =
static_cast<WasmOpcode>(kSimdPrefix << 8 | simd_index);
switch (opcode) {
......@@ -548,7 +548,7 @@ class WasmFullDecoder : public WasmDecoder {
// Generate a better error message whether the unterminated control
// structure is the function body block or an innner structure.
if (control_.size() > 1) {
error(pc_, control_.back().pc, "unterminated control structure");
error(control_.back().pc, "unterminated control structure");
} else {
error("function body must end with \"end\" opcode.");
}
......@@ -840,11 +840,11 @@ class WasmFullDecoder : public WasmDecoder {
}
Control* c = &control_.back();
if (!c->is_if()) {
error(pc_, c->pc, "else does not match an if");
error(pc_, "else does not match an if");
break;
}
if (c->false_env == nullptr) {
error(pc_, c->pc, "else already present for if");
error(pc_, "else already present for if");
break;
}
FallThruTo(c);
......@@ -901,7 +901,7 @@ class WasmFullDecoder : public WasmDecoder {
if (control_.size() == 1) {
// If at the last (implicit) control, check we are at end.
if (pc_ + 1 != end_) {
error(pc_, pc_ + 1, "trailing code after function end");
error(pc_ + 1, "trailing code after function end");
break;
}
last_end_found_ = true;
......@@ -992,17 +992,18 @@ class WasmFullDecoder : public WasmDecoder {
if (i == 0) {
merge = &c->merge;
} else if (merge->arity != c->merge.arity) {
error(pos, pos, "inconsistent arity in br_table target %d"
" (previous was %u, this one %u)",
i, merge->arity, c->merge.arity);
errorf(pos,
"inconsistent arity in br_table target %d"
" (previous was %u, this one %u)",
i, merge->arity, c->merge.arity);
} else if (control_.back().unreachable) {
for (uint32_t j = 0; ok() && j < merge->arity; ++j) {
if ((*merge)[j].type != c->merge[j].type) {
error(pos, pos,
"type error in br_table target %d operand %d"
" (previous expected %s, this one %s)", i, j,
WasmOpcodes::TypeName((*merge)[j].type),
WasmOpcodes::TypeName(c->merge[j].type));
errorf(pos,
"type error in br_table target %d operand %d"
" (previous expected %s, this one %s)",
i, j, WasmOpcodes::TypeName((*merge)[j].type),
WasmOpcodes::TypeName(c->merge[j].type));
}
}
}
......@@ -1108,8 +1109,8 @@ class WasmFullDecoder : public WasmDecoder {
Value val = Pop(0, operand.type);
BUILD(SetGlobal, operand.index, val.node);
} else {
error(pc_, pc_ + 1, "immutable global #%u cannot be assigned",
operand.index);
errorf(pc_, "immutable global #%u cannot be assigned",
operand.index);
}
}
len = 1 + operand.length;
......@@ -1239,7 +1240,7 @@ class WasmFullDecoder : public WasmDecoder {
case kSimdPrefix: {
CHECK_PROTOTYPE_OPCODE(wasm_simd_prototype);
len++;
byte simd_index = checked_read_u8(pc_, 1, "simd index");
byte simd_index = checked_read_u8(pc_ + 1, "simd index");
opcode = static_cast<WasmOpcode>(opcode << 8 | simd_index);
TRACE(" @%-4d #%-20s|", startrel(pc_),
WasmOpcodes::OpcodeName(opcode));
......@@ -1256,7 +1257,7 @@ class WasmFullDecoder : public WasmDecoder {
break;
}
len = 2;
byte atomic_opcode = checked_read_u8(pc_, 1, "atomic index");
byte atomic_opcode = checked_read_u8(pc_ + 1, "atomic index");
opcode = static_cast<WasmOpcode>(opcode << 8 | atomic_opcode);
sig = WasmOpcodes::AtomicSignature(opcode);
if (sig) {
......@@ -1575,9 +1576,9 @@ class WasmFullDecoder : public WasmDecoder {
Value Pop(int index, ValueType expected) {
Value val = Pop();
if (val.type != expected && val.type != kWasmVar && expected != kWasmVar) {
error(pc_, val.pc, "%s[%d] expected type %s, found %s of type %s",
SafeOpcodeNameAt(pc_), index, WasmOpcodes::TypeName(expected),
SafeOpcodeNameAt(val.pc), WasmOpcodes::TypeName(val.type));
errorf(val.pc, "%s[%d] expected type %s, found %s of type %s",
SafeOpcodeNameAt(pc_), index, WasmOpcodes::TypeName(expected),
SafeOpcodeNameAt(val.pc), WasmOpcodes::TypeName(val.type));
}
return val;
}
......@@ -1588,7 +1589,7 @@ class WasmFullDecoder : public WasmDecoder {
// Popping past the current control start in reachable code.
Value val = {pc_, nullptr, kWasmVar};
if (!control_.back().unreachable) {
error(pc_, pc_, "%s found empty stack", SafeOpcodeNameAt(pc_));
errorf(pc_, "%s found empty stack", SafeOpcodeNameAt(pc_));
}
return val;
}
......@@ -1612,8 +1613,8 @@ class WasmFullDecoder : public WasmDecoder {
// Merge the value(s) into the end of the block.
size_t expected = control_.back().stack_depth + c->merge.arity;
if (stack_.size() < expected && !control_.back().unreachable) {
error(
pc_, pc_,
errorf(
pc_,
"expected at least %u values on the stack for br to @%d, found %d",
c->merge.arity, startrel(c->pc),
static_cast<int>(stack_.size() - c->stack_depth));
......@@ -1633,8 +1634,8 @@ class WasmFullDecoder : public WasmDecoder {
c->unreachable = false;
return;
}
error(pc_, pc_, "expected %u elements on the stack for fallthru to @%d",
c->merge.arity, startrel(c->pc));
errorf(pc_, "expected %u elements on the stack for fallthru to @%d",
c->merge.arity, startrel(c->pc));
}
inline Value& GetMergeValueFromStack(Control* c, size_t i) {
......@@ -1647,8 +1648,8 @@ class WasmFullDecoder : public WasmDecoder {
int arity = static_cast<int>(c->merge.arity);
if (c->stack_depth + arity < stack_.size() ||
(c->stack_depth + arity != stack_.size() && !c->unreachable)) {
error(pc_, pc_, "expected %d elements on the stack for fallthru to @%d",
arity, startrel(c->pc));
errorf(pc_, "expected %d elements on the stack for fallthru to @%d",
arity, startrel(c->pc));
return;
}
// Typecheck the values left on the stack.
......@@ -1658,8 +1659,9 @@ class WasmFullDecoder : public WasmDecoder {
Value& val = GetMergeValueFromStack(c, i);
Value& old = c->merge[i];
if (val.type != old.type) {
error(pc_, pc_, "type error in merge[%zu] (expected %s, got %s)", i,
WasmOpcodes::TypeName(old.type), WasmOpcodes::TypeName(val.type));
errorf(pc_, "type error in merge[%zu] (expected %s, got %s)", i,
WasmOpcodes::TypeName(old.type),
WasmOpcodes::TypeName(val.type));
return;
}
}
......@@ -1677,8 +1679,9 @@ class WasmFullDecoder : public WasmDecoder {
Value& val = GetMergeValueFromStack(c, i);
Value& old = c->merge[i];
if (val.type != old.type && val.type != kWasmVar) {
error(pc_, pc_, "type error in merge[%zu] (expected %s, got %s)", i,
WasmOpcodes::TypeName(old.type), WasmOpcodes::TypeName(val.type));
errorf(pc_, "type error in merge[%zu] (expected %s, got %s)", i,
WasmOpcodes::TypeName(old.type),
WasmOpcodes::TypeName(val.type));
return;
}
if (builder_ && reachable) {
......
......@@ -170,8 +170,7 @@ class V8_EXPORT_PRIVATE BytecodeIterator : public NON_EXPORTED_BASE(Decoder) {
}
WasmOpcode current() {
return static_cast<WasmOpcode>(
checked_read_u8(pc_, 0, "expected bytecode"));
return static_cast<WasmOpcode>(checked_read_u8(pc_, "expected bytecode"));
}
void next() {
......
......@@ -127,11 +127,11 @@ class WasmSectionIterator {
void advance() {
if (decoder_.pc() != section_end_) {
const char* msg = decoder_.pc() < section_end_ ? "shorter" : "longer";
decoder_.error(decoder_.pc(), decoder_.pc(),
"section was %s than expected size "
"(%u bytes expected, %zu decoded)",
msg, section_length(),
static_cast<size_t>(decoder_.pc() - section_start_));
decoder_.errorf(decoder_.pc(),
"section was %s than expected size "
"(%u bytes expected, %zu decoded)",
msg, section_length(),
static_cast<size_t>(decoder_.pc() - section_start_));
}
next();
}
......@@ -188,8 +188,8 @@ class WasmSectionIterator {
section_code = kUnknownSectionCode;
}
} else if (!IsValidSectionCode(section_code)) {
decoder_.error(decoder_.pc(), decoder_.pc(),
"unknown section code #0x%02x", section_code);
decoder_.errorf(decoder_.pc(), "unknown section code #0x%02x",
section_code);
section_code = kUnknownSectionCode;
}
section_code_ = static_cast<WasmSectionCode>(section_code);
......@@ -265,20 +265,20 @@ class ModuleDecoder : public Decoder {
uint32_t magic_word = consume_u32("wasm magic");
#define BYTES(x) (x & 0xff), (x >> 8) & 0xff, (x >> 16) & 0xff, (x >> 24) & 0xff
if (magic_word != kWasmMagic) {
error(pos, pos,
"expected magic word %02x %02x %02x %02x, "
"found %02x %02x %02x %02x",
BYTES(kWasmMagic), BYTES(magic_word));
errorf(pos,
"expected magic word %02x %02x %02x %02x, "
"found %02x %02x %02x %02x",
BYTES(kWasmMagic), BYTES(magic_word));
}
pos = pc_;
{
uint32_t magic_version = consume_u32("wasm version");
if (magic_version != kWasmVersion) {
error(pos, pos,
"expected version %02x %02x %02x %02x, "
"found %02x %02x %02x %02x",
BYTES(kWasmVersion), BYTES(magic_version));
errorf(pos,
"expected version %02x %02x %02x %02x, "
"found %02x %02x %02x %02x",
BYTES(kWasmVersion), BYTES(magic_version));
}
}
......@@ -379,7 +379,7 @@ class ModuleDecoder : public Decoder {
break;
}
default:
error(pos, pos, "unknown import kind 0x%02x", import->kind);
errorf(pos, "unknown import kind 0x%02x", import->kind);
break;
}
}
......@@ -515,7 +515,7 @@ class ModuleDecoder : public Decoder {
break;
}
default:
error(pos, pos, "invalid export kind 0x%02x", exp->kind);
errorf(pos, "invalid export kind 0x%02x", exp->kind);
break;
}
}
......@@ -539,9 +539,8 @@ class ModuleDecoder : public Decoder {
DCHECK(!cmp_less(*it, *last)); // Vector must be sorted.
if (!cmp_less(*last, *it)) {
const byte* pc = start_ + it->name_offset;
error(pc, pc,
"Duplicate export name '%.*s' for functions %d and %d",
it->name_length, pc, last->index, it->index);
errorf(pc, "Duplicate export name '%.*s' for functions %d and %d",
it->name_length, pc, last->index, it->index);
break;
}
}
......@@ -570,11 +569,11 @@ class ModuleDecoder : public Decoder {
const byte* pos = pc();
uint32_t table_index = consume_u32v("table index");
if (table_index != 0) {
error(pos, pos, "illegal table index %u != 0", table_index);
errorf(pos, "illegal table index %u != 0", table_index);
}
WasmIndirectFunctionTable* table = nullptr;
if (table_index >= module->function_tables.size()) {
error(pos, pos, "out of bounds table index %u", table_index);
errorf(pos, "out of bounds table index %u", table_index);
break;
}
table = &module->function_tables[table_index];
......@@ -604,8 +603,8 @@ class ModuleDecoder : public Decoder {
const byte* pos = pc_;
uint32_t functions_count = consume_u32v("functions count");
if (functions_count != module->num_declared_functions) {
error(pos, pos, "function body count %u mismatch (%u expected)",
functions_count, module->num_declared_functions);
errorf(pos, "function body count %u mismatch (%u expected)",
functions_count, module->num_declared_functions);
}
for (uint32_t i = 0; ok() && i < functions_count; ++i) {
WasmFunction* function =
......@@ -677,8 +676,8 @@ class ModuleDecoder : public Decoder {
// ===== Remaining sections ==============================================
if (section_iter.more() && ok()) {
error(pc(), pc(), "unexpected section: %s",
SectionName(section_iter.section_code()));
errorf(pc(), "unexpected section: %s",
SectionName(section_iter.section_code()));
}
if (ok()) {
......@@ -760,25 +759,25 @@ class ModuleDecoder : public Decoder {
case WasmInitExpr::kGlobalIndex: {
uint32_t other_index = global->init.val.global_index;
if (other_index >= index) {
error(pos, pos,
"invalid global index in init expression, "
"index %u, other_index %u",
index, other_index);
errorf(pos,
"invalid global index in init expression, "
"index %u, other_index %u",
index, other_index);
} else if (module->globals[other_index].type != global->type) {
error(pos, pos,
"type mismatch in global initialization "
"(from global #%u), expected %s, got %s",
other_index, WasmOpcodes::TypeName(global->type),
WasmOpcodes::TypeName(module->globals[other_index].type));
errorf(pos,
"type mismatch in global initialization "
"(from global #%u), expected %s, got %s",
other_index, WasmOpcodes::TypeName(global->type),
WasmOpcodes::TypeName(module->globals[other_index].type));
}
break;
}
default:
if (global->type != TypeOf(module, global->init)) {
error(pos, pos,
"type error in global initialization, expected %s, got %s",
WasmOpcodes::TypeName(global->type),
WasmOpcodes::TypeName(TypeOf(module, global->init)));
errorf(pos,
"type error in global initialization, expected %s, got %s",
WasmOpcodes::TypeName(global->type),
WasmOpcodes::TypeName(TypeOf(module, global->init)));
}
}
}
......@@ -881,8 +880,8 @@ class ModuleDecoder : public Decoder {
const byte* pos = pc_;
uint32_t sig_index = consume_u32v("signature index");
if (sig_index >= module->signatures.size()) {
error(pos, pos, "signature index %u out of bounds (%d signatures)",
sig_index, static_cast<int>(module->signatures.size()));
errorf(pos, "signature index %u out of bounds (%d signatures)", sig_index,
static_cast<int>(module->signatures.size()));
*sig = nullptr;
return 0;
}
......@@ -894,8 +893,7 @@ class ModuleDecoder : public Decoder {
const byte* p = pc_;
uint32_t count = consume_u32v(name);
if (count > maximum) {
error(p, p, "%s of %u exceeds internal limit of %zu", name, count,
maximum);
errorf(p, "%s of %u exceeds internal limit of %zu", name, count, maximum);
return static_cast<uint32_t>(maximum);
}
return count;
......@@ -919,8 +917,8 @@ class ModuleDecoder : public Decoder {
const byte* pos = pc_;
uint32_t index = consume_u32v(name);
if (index >= vector.size()) {
error(pos, pos, "%s %u out of bounds (%d entries)", name, index,
static_cast<int>(vector.size()));
errorf(pos, "%s %u out of bounds (%d entries)", name, index,
static_cast<int>(vector.size()));
*ptr = nullptr;
return 0;
}
......@@ -937,23 +935,23 @@ class ModuleDecoder : public Decoder {
*initial = consume_u32v("initial size");
*has_max = false;
if (*initial > max_initial) {
error(pos, pos,
"initial %s size (%u %s) is larger than implementation limit (%u)",
name, *initial, units, max_initial);
errorf(pos,
"initial %s size (%u %s) is larger than implementation limit (%u)",
name, *initial, units, max_initial);
}
if (flags & 1) {
*has_max = true;
pos = pc();
*maximum = consume_u32v("maximum size");
if (*maximum > max_maximum) {
error(
pos, pos,
errorf(
pos,
"maximum %s size (%u %s) is larger than implementation limit (%u)",
name, *maximum, units, max_maximum);
}
if (*maximum < *initial) {
error(pos, pos, "maximum %s size (%u %s) is less than initial (%u %s)",
name, *maximum, units, *initial, units);
errorf(pos, "maximum %s size (%u %s) is less than initial (%u %s)",
name, *maximum, units, *initial, units);
}
} else {
*has_max = false;
......@@ -965,7 +963,7 @@ class ModuleDecoder : public Decoder {
const byte* pos = pc();
uint8_t value = consume_u8(name);
if (value != expected) {
error(pos, pos, "expected %s 0x%02x, got 0x%02x", name, expected, value);
errorf(pos, "expected %s 0x%02x, got 0x%02x", name, expected, value);
return false;
}
return true;
......@@ -1038,9 +1036,9 @@ class ModuleDecoder : public Decoder {
expr.kind = WasmInitExpr::kNone;
}
if (expected != kWasmStmt && TypeOf(module, expr) != kWasmI32) {
error(pos, pos, "type error in init expression, expected %s, got %s",
WasmOpcodes::TypeName(expected),
WasmOpcodes::TypeName(TypeOf(module, expr)));
errorf(pos, "type error in init expression, expected %s, got %s",
WasmOpcodes::TypeName(expected),
WasmOpcodes::TypeName(TypeOf(module, expr)));
}
return expr;
}
......
......@@ -40,7 +40,6 @@ struct Result {
ErrorCode error_code;
const byte* start;
const byte* error_pc;
const byte* error_pt;
std::unique_ptr<char[]> error_msg;
bool ok() const { return error_code == kSuccess; }
......@@ -51,7 +50,6 @@ struct Result {
error_code = that.error_code;
start = that.start;
error_pc = that.error_pc;
error_pt = that.error_pt;
error_msg = std::move(that.error_msg);
}
......
......@@ -387,11 +387,9 @@ inline void TestBuildingGraph(Zone* zone, JSGraph* jsgraph, ModuleEnv* module,
}
ptrdiff_t pc = result.error_pc - result.start;
ptrdiff_t pt = result.error_pt - result.start;
std::ostringstream str;
str << "Verification failed: " << result.error_code << " pc = +" << pc;
if (result.error_pt) str << ", pt = +" << pt;
str << ", msg = " << result.error_msg.get();
str << "Verification failed: " << result.error_code << " pc = +" << pc
<< ", msg = " << result.error_msg.get();
FATAL(str.str().c_str());
}
builder.Int64LoweringForTesting();
......
......@@ -25,7 +25,7 @@ class DecoderTest : public TestWithZone {
decoder.Reset(data, data + sizeof(data)); \
unsigned length; \
EXPECT_EQ(static_cast<uint32_t>(expected), \
decoder.checked_read_u32v(decoder.start(), 0, &length)); \
decoder.checked_read_u32v(decoder.start(), &length)); \
EXPECT_EQ(static_cast<unsigned>(expected_length), length); \
EXPECT_EQ(data, decoder.pc()); \
EXPECT_TRUE(decoder.ok()); \
......@@ -33,38 +33,36 @@ class DecoderTest : public TestWithZone {
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.checked_read_i32v(decoder.start(), 0, &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.checked_read_i32v(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.checked_read_u64v(decoder.start(), 0, &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.checked_read_u64v(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.checked_read_i64v(decoder.start(), 0, &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.checked_read_i64v(decoder.start(), &length)); \
EXPECT_EQ(static_cast<unsigned>(expected_length), length); \
} while (false)
TEST_F(DecoderTest, ReadU32v_OneByte) {
......@@ -376,7 +374,7 @@ TEST_F(DecoderTest, ReadU32v_off_end1) {
static const byte data[] = {U32V_1(11)};
unsigned length = 0;
decoder.Reset(data, data);
decoder.checked_read_u32v(decoder.start(), 0, &length);
decoder.checked_read_u32v(decoder.start(), &length);
EXPECT_EQ(0u, length);
EXPECT_FALSE(decoder.ok());
}
......@@ -386,7 +384,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.checked_read_u32v(decoder.start(), 0, &length);
decoder.checked_read_u32v(decoder.start(), &length);
EXPECT_EQ(i, length);
EXPECT_FALSE(decoder.ok());
}
......@@ -397,7 +395,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.checked_read_u32v(decoder.start(), 0, &length);
decoder.checked_read_u32v(decoder.start(), &length);
EXPECT_EQ(i, length);
EXPECT_FALSE(decoder.ok());
}
......@@ -408,7 +406,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.checked_read_u32v(decoder.start(), 0, &length);
decoder.checked_read_u32v(decoder.start(), &length);
EXPECT_EQ(i, length);
EXPECT_FALSE(decoder.ok());
}
......@@ -419,7 +417,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.checked_read_u32v(decoder.start(), 0, &length);
decoder.checked_read_u32v(decoder.start(), &length);
EXPECT_EQ(i, length);
EXPECT_FALSE(decoder.ok());
}
......@@ -431,7 +429,7 @@ TEST_F(DecoderTest, ReadU32v_extra_bits) {
data[4] = static_cast<byte>(i << 4);
unsigned length = 0;
decoder.Reset(data, data + sizeof(data));
decoder.checked_read_u32v(decoder.start(), 0, &length);
decoder.checked_read_u32v(decoder.start(), &length);
EXPECT_EQ(5u, length);
EXPECT_FALSE(decoder.ok());
}
......@@ -442,7 +440,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.checked_read_i32v(decoder.start(), 0, &length);
decoder.checked_read_i32v(decoder.start(), &length);
EXPECT_EQ(5u, length);
EXPECT_TRUE(decoder.ok());
}
......@@ -452,7 +450,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.checked_read_i32v(decoder.start(), 0, &length);
decoder.checked_read_i32v(decoder.start(), &length);
EXPECT_EQ(5u, length);
EXPECT_FALSE(decoder.ok());
}
......@@ -487,7 +485,7 @@ TEST_F(DecoderTest, ReadU32v_Bits) {
for (unsigned limit = 0; limit <= kMaxSize; limit++) {
decoder.Reset(data, data + limit);
unsigned rlen;
uint32_t result = decoder.checked_read_u32v(data, 0, &rlen);
uint32_t result = decoder.checked_read_u32v(data, &rlen);
if (limit < length) {
EXPECT_FALSE(decoder.ok());
} else {
......@@ -543,7 +541,7 @@ TEST_F(DecoderTest, ReadU64v_PowerOf2) {
for (unsigned limit = 0; limit <= kMaxSize; limit++) {
decoder.Reset(data, data + limit);
unsigned length;
uint64_t result = decoder.checked_read_u64v(data, 0, &length);
uint64_t result = decoder.checked_read_u64v(data, &length);
if (limit <= index) {
EXPECT_FALSE(decoder.ok());
} else {
......@@ -584,7 +582,7 @@ TEST_F(DecoderTest, ReadU64v_Bits) {
for (unsigned limit = 0; limit <= kMaxSize; limit++) {
decoder.Reset(data, data + limit);
unsigned rlen;
uint64_t result = decoder.checked_read_u64v(data, 0, &rlen);
uint64_t result = decoder.checked_read_u64v(data, &rlen);
if (limit < length) {
EXPECT_FALSE(decoder.ok());
} else {
......@@ -626,7 +624,7 @@ TEST_F(DecoderTest, ReadI64v_Bits) {
for (unsigned limit = 0; limit <= kMaxSize; limit++) {
decoder.Reset(data, data + limit);
unsigned rlen;
int64_t result = decoder.checked_read_i64v(data, 0, &rlen);
int64_t result = decoder.checked_read_i64v(data, &rlen);
if (limit < length) {
EXPECT_FALSE(decoder.ok());
} else {
......@@ -645,7 +643,7 @@ TEST_F(DecoderTest, ReadU64v_extra_bits) {
data[9] = static_cast<byte>(i << 1);
unsigned length = 0;
decoder.Reset(data, data + sizeof(data));
decoder.checked_read_u64v(decoder.start(), 0, &length);
decoder.checked_read_u64v(decoder.start(), &length);
EXPECT_EQ(10u, length);
EXPECT_FALSE(decoder.ok());
}
......@@ -656,7 +654,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.checked_read_i64v(decoder.start(), 0, &length);
decoder.checked_read_i64v(decoder.start(), &length);
EXPECT_EQ(10u, length);
EXPECT_TRUE(decoder.ok());
}
......@@ -666,7 +664,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.checked_read_i64v(decoder.start(), 0, &length);
decoder.checked_read_i64v(decoder.start(), &length);
EXPECT_EQ(10u, length);
EXPECT_FALSE(decoder.ok());
}
......
......@@ -137,18 +137,15 @@ class FunctionBodyDecoderTest : public TestWithZone {
if (result.error_code != expected) {
ptrdiff_t pc = result.error_pc - result.start;
ptrdiff_t pt = result.error_pt - result.start;
std::ostringstream str;
if (expected == kSuccess) {
str << "Verification failed: " << result.error_code << " pc = +" << pc;
if (result.error_pt) str << ", pt = +" << pt;
str << ", msg = " << result.error_msg.get();
str << "Verification failed: " << result.error_code << " pc = +" << pc
<< ", msg = " << result.error_msg.get();
} else {
str << "Verification expected: " << expected << ", but got "
<< result.error_code;
if (result.error_code != kSuccess) {
str << " pc = +" << pc;
if (result.error_pt) str << ", pt = +" << pt;
}
}
EXPECT_TRUE(false) << str.str().c_str();
......
......@@ -92,13 +92,13 @@ TEST_F(LEBHelperTest, sizeof_i32v) {
static void CheckEncodeDecode_##name(ctype val) { \
static const int kSize = 16; \
static byte buffer[kSize]; \
byte *ptr = buffer; \
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.checked_read_##name(buffer, 0, &length); \
ctype result = decoder.checked_read_##name(buffer, &length); \
EXPECT_EQ(val, result); \
EXPECT_EQ(LEBHelper::sizeof_##name(val), static_cast<size_t>(length)); \
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment