[wasm] Fix misaligned accesses and endianness issues in decoders.

R=ahaas@chromium.org,bradnelson@chromium.org
BUG=

Review URL: https://codereview.chromium.org/1644023002

Cr-Commit-Position: refs/heads/master@{#33595}
This commit is contained in:
titzer 2016-01-28 11:24:04 -08:00 committed by Commit bot
parent 6399fce56b
commit 716bc803a3
5 changed files with 170 additions and 204 deletions

View File

@ -112,28 +112,28 @@ class WasmDecoder : public Decoder {
function_env_ = function_env;
}
// Load an operand at [pc + 1].
template <typename V>
V Operand(const byte* pc) {
if ((limit_ - pc) < static_cast<int>(1 + sizeof(V))) {
const char* msg = "Expected operand following opcode";
switch (sizeof(V)) {
case 1:
msg = "Expected 1-byte operand following opcode";
break;
case 2:
msg = "Expected 2-byte operand following opcode";
break;
case 4:
msg = "Expected 4-byte operand following opcode";
break;
default:
break;
}
byte ByteOperand(const byte* pc, const char* msg = "missing 1-byte operand") {
if ((pc + sizeof(byte)) >= limit_) {
error(pc, msg);
return -1;
return 0;
}
return *reinterpret_cast<const V*>(pc + 1);
return pc[1];
}
uint32_t Uint32Operand(const byte* pc) {
if ((pc + sizeof(uint32_t)) >= limit_) {
error(pc, "missing 4-byte operand");
return 0;
}
return read_u32(pc + 1);
}
uint64_t Uint64Operand(const byte* pc) {
if ((pc + sizeof(uint64_t)) >= limit_) {
error(pc, "missing 8-byte operand");
return 0;
}
return read_u64(pc + 1);
}
LocalType LocalOperand(const byte* pc, uint32_t* index, int* length) {
@ -185,7 +185,7 @@ class WasmDecoder : public Decoder {
}
void MemoryAccessOperand(const byte* pc, int* length, uint32_t* offset) {
byte bitfield = Operand<uint8_t>(pc);
byte bitfield = ByteOperand(pc, "missing memory access operand");
if (MemoryAccess::OffsetField::decode(bitfield)) {
*offset = UnsignedLEB128Operand(pc + 1, length);
(*length)++; // to account for the memory access byte
@ -431,7 +431,7 @@ class LR_WasmDecoder : public WasmDecoder {
Leaf(kAstStmt);
break;
case kExprBlock: {
int length = Operand<uint8_t>(pc_);
int length = ByteOperand(pc_);
if (length < 1) {
Leaf(kAstStmt);
} else {
@ -445,7 +445,7 @@ class LR_WasmDecoder : public WasmDecoder {
break;
}
case kExprLoop: {
int length = Operand<uint8_t>(pc_);
int length = ByteOperand(pc_);
if (length < 1) {
Leaf(kAstStmt);
} else {
@ -474,7 +474,7 @@ class LR_WasmDecoder : public WasmDecoder {
Shift(kAstStmt, 3); // Result type is typeof(x) in {c ? x : y}.
break;
case kExprBr: {
uint32_t depth = Operand<uint8_t>(pc_);
uint32_t depth = ByteOperand(pc_);
Shift(kAstEnd, 1);
if (depth >= blocks_.size()) {
error("improperly nested branch");
@ -483,7 +483,7 @@ class LR_WasmDecoder : public WasmDecoder {
break;
}
case kExprBrIf: {
uint32_t depth = Operand<uint8_t>(pc_);
uint32_t depth = ByteOperand(pc_);
Shift(kAstStmt, 2);
if (depth >= blocks_.size()) {
error("improperly nested conditional branch");
@ -496,8 +496,8 @@ class LR_WasmDecoder : public WasmDecoder {
error("expected #tableswitch <cases> <table>, fell off end");
break;
}
uint16_t case_count = *reinterpret_cast<const uint16_t*>(pc_ + 1);
uint16_t table_count = *reinterpret_cast<const uint16_t*>(pc_ + 3);
uint16_t case_count = read_u16(pc_ + 1);
uint16_t table_count = read_u16(pc_ + 3);
len = 5 + table_count * 2;
if (table_count == 0) {
@ -514,8 +514,7 @@ class LR_WasmDecoder : public WasmDecoder {
// Verify table.
for (int i = 0; i < table_count; i++) {
uint16_t target =
*reinterpret_cast<const uint16_t*>(pc_ + 5 + i * 2);
uint16_t target = read_u16(pc_ + 5 + i * 2);
if (target >= 0x8000) {
size_t depth = target - 0x8000;
if (depth > blocks_.size()) {
@ -547,31 +546,31 @@ class LR_WasmDecoder : public WasmDecoder {
break;
}
case kExprI8Const: {
int32_t value = Operand<int8_t>(pc_);
int32_t value = bit_cast<int8_t>(ByteOperand(pc_));
Leaf(kAstI32, BUILD(Int32Constant, value));
len = 2;
break;
}
case kExprI32Const: {
int32_t value = Operand<int32_t>(pc_);
uint32_t value = Uint32Operand(pc_);
Leaf(kAstI32, BUILD(Int32Constant, value));
len = 5;
break;
}
case kExprI64Const: {
int64_t value = Operand<int64_t>(pc_);
uint64_t value = Uint64Operand(pc_);
Leaf(kAstI64, BUILD(Int64Constant, value));
len = 9;
break;
}
case kExprF32Const: {
float value = Operand<float>(pc_);
float value = bit_cast<float>(Uint32Operand(pc_));
Leaf(kAstF32, BUILD(Float32Constant, value));
len = 5;
break;
}
case kExprF64Const: {
double value = Operand<double>(pc_);
double value = bit_cast<double>(Uint64Operand(pc_));
Leaf(kAstF64, BUILD(Float64Constant, value));
len = 9;
break;
@ -877,7 +876,7 @@ class LR_WasmDecoder : public WasmDecoder {
break;
}
case kExprBr: {
uint32_t depth = Operand<uint8_t>(p->pc());
uint32_t depth = ByteOperand(p->pc());
if (depth >= blocks_.size()) {
error("improperly nested branch");
break;
@ -890,7 +889,7 @@ class LR_WasmDecoder : public WasmDecoder {
if (p->index == 1) {
TypeCheckLast(p, kAstI32);
} else if (p->done()) {
uint32_t depth = Operand<uint8_t>(p->pc());
uint32_t depth = ByteOperand(p->pc());
if (depth >= blocks_.size()) {
error("improperly nested branch");
break;
@ -911,8 +910,7 @@ class LR_WasmDecoder : public WasmDecoder {
// Switch key finished.
TypeCheckLast(p, kAstI32);
uint16_t table_count =
*reinterpret_cast<const uint16_t*>(p->pc() + 3);
uint16_t table_count = read_u16(p->pc() + 3);
// Build the switch only if it has more than just a default target.
bool build_switch = table_count > 1;
@ -920,7 +918,7 @@ class LR_WasmDecoder : public WasmDecoder {
if (build_switch) sw = BUILD(Switch, table_count, p->last()->node);
// Allocate environments for each case.
uint16_t case_count = *reinterpret_cast<const uint16_t*>(p->pc() + 1);
uint16_t case_count = read_u16(p->pc() + 1);
SsaEnv** case_envs = zone_->NewArray<SsaEnv*>(case_count);
for (int i = 0; i < case_count; i++) case_envs[i] = UnreachableEnv();
@ -931,10 +929,8 @@ class LR_WasmDecoder : public WasmDecoder {
ssa_env_ = copy;
// Build the environments for each case based on the table.
const uint16_t* table =
reinterpret_cast<const uint16_t*>(p->pc() + 5);
for (int i = 0; i < table_count; i++) {
uint16_t target = table[i];
uint16_t target = read_u16(p->pc() + 5 + i * 2);
SsaEnv* env = copy;
if (build_switch) {
env = Split(env);

View File

@ -24,6 +24,12 @@ namespace wasm {
#define TRACE(...)
#endif
#if !(V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM)
#define UNALIGNED_ACCESS_OK 1
#else
#define UNALIGNED_ACCESS_OK 0
#endif
// A helper utility to decode bytes, integers, fields, varints, etc, from
// a buffer of bytes.
class Decoder {
@ -32,107 +38,126 @@ class Decoder {
: start_(start),
pc_(start),
limit_(end),
end_(end),
error_pc_(nullptr),
error_pt_(nullptr) {}
virtual ~Decoder() {}
// Reads a single 16-bit unsigned integer (little endian).
inline uint16_t read_u16(const byte* ptr) {
DCHECK(ptr >= start_ && (ptr + 2) <= end_);
#if V8_TARGET_LITTLE_ENDIAN && UNALIGNED_ACCESS_OK
return *reinterpret_cast<const uint16_t*>(ptr);
#else
uint16_t b0 = ptr[0];
uint16_t b1 = ptr[1];
return (b1 << 8) | b0;
#endif
}
// Reads a single 32-bit unsigned integer (little endian).
inline uint32_t read_u32(const byte* ptr) {
DCHECK(ptr >= start_ && (ptr + 4) <= end_);
#if V8_TARGET_LITTLE_ENDIAN && UNALIGNED_ACCESS_OK
return *reinterpret_cast<const uint32_t*>(ptr);
#else
uint32_t b0 = ptr[0];
uint32_t b1 = ptr[1];
uint32_t b2 = ptr[2];
uint32_t b3 = ptr[3];
return (b3 << 24) | (b2 << 16) | (b1 << 8) | b0;
#endif
}
// Reads a single 64-bit unsigned integer (little endian).
inline uint64_t read_u64(const byte* ptr) {
DCHECK(ptr >= start_ && (ptr + 8) <= end_);
#if V8_TARGET_LITTLE_ENDIAN && UNALIGNED_ACCESS_OK
return *reinterpret_cast<const uint64_t*>(ptr);
#else
uint32_t b0 = ptr[0];
uint32_t b1 = ptr[1];
uint32_t b2 = ptr[2];
uint32_t b3 = ptr[3];
uint32_t low = (b3 << 24) | (b2 << 16) | (b1 << 8) | b0;
uint32_t b4 = ptr[4];
uint32_t b5 = ptr[5];
uint32_t b6 = ptr[6];
uint32_t b7 = ptr[7];
uint64_t high = (b7 << 24) | (b6 << 16) | (b5 << 8) | b4;
return (high << 32) | low;
#endif
}
// Reads a 8-bit unsigned integer (byte) and advances {pc_}.
uint8_t u8(const char* name = nullptr) {
uint8_t consume_u8(const char* name = nullptr) {
TRACE(" +%d %-20s: ", static_cast<int>(pc_ - start_),
name ? name : "uint8_t");
if (checkAvailable(1)) {
byte val = *(pc_++);
TRACE("%02x = %d\n", val, val);
return val;
} else {
error("expected 1 byte, but fell off end");
return traceOffEnd<uint8_t>();
}
return traceOffEnd<uint8_t>();
}
// Reads a 16-bit unsigned integer (little endian) and advances {pc_}.
uint16_t u16(const char* name = nullptr) {
uint16_t consume_u16(const char* name = nullptr) {
TRACE(" +%d %-20s: ", static_cast<int>(pc_ - start_),
name ? name : "uint16_t");
if (checkAvailable(2)) {
#ifdef V8_TARGET_LITTLE_ENDIAN
byte b0 = pc_[0];
byte b1 = pc_[1];
#else
byte b1 = pc_[0];
byte b0 = pc_[1];
#endif
uint16_t val = static_cast<uint16_t>(b1 << 8) | b0;
uint16_t val = read_u16(pc_);
TRACE("%02x %02x = %d\n", pc_[0], pc_[1], val);
pc_ += 2;
return val;
} else {
error("expected 2 bytes, but fell off end");
return traceOffEnd<uint16_t>();
}
return traceOffEnd<uint16_t>();
}
// Reads a single 32-bit unsigned integer (little endian) and advances {pc_}.
uint32_t u32(const char* name = nullptr) {
uint32_t consume_u32(const char* name = nullptr) {
TRACE(" +%d %-20s: ", static_cast<int>(pc_ - start_),
name ? name : "uint32_t");
if (checkAvailable(4)) {
#ifdef V8_TARGET_LITTLE_ENDIAN
byte b0 = pc_[0];
byte b1 = pc_[1];
byte b2 = pc_[2];
byte b3 = pc_[3];
#else
byte b3 = pc_[0];
byte b2 = pc_[1];
byte b1 = pc_[2];
byte b0 = pc_[3];
#endif
uint32_t val = static_cast<uint32_t>(b3 << 24) |
static_cast<uint32_t>(b2 << 16) |
static_cast<uint32_t>(b1 << 8) | b0;
uint32_t val = read_u32(pc_);
TRACE("%02x %02x %02x %02x = %u\n", pc_[0], pc_[1], pc_[2], pc_[3], val);
pc_ += 4;
return val;
} else {
error("expected 4 bytes, but fell off end");
return traceOffEnd<uint32_t>();
}
return traceOffEnd<uint32_t>();
}
// Reads a LEB128 variable-length 32-bit integer and advances {pc_}.
uint32_t u32v(int* length, const char* name = nullptr) {
uint32_t consume_u32v(int* length, const char* name = nullptr) {
TRACE(" +%d %-20s: ", static_cast<int>(pc_ - start_),
name ? name : "varint");
if (!checkAvailable(1)) {
error("expected at least 1 byte, but fell off end");
return traceOffEnd<uint32_t>();
}
if (checkAvailable(1)) {
const byte* pos = pc_;
const byte* end = pc_ + 5;
if (end > limit_) end = limit_;
const byte* pos = pc_;
const byte* end = pc_ + 5;
if (end > limit_) end = limit_;
uint32_t result = 0;
int shift = 0;
byte b = 0;
while (pc_ < end) {
b = *pc_++;
TRACE("%02x ", b);
result = result | ((b & 0x7F) << shift);
if ((b & 0x80) == 0) break;
shift += 7;
}
uint32_t result = 0;
int shift = 0;
byte b = 0;
while (pc_ < end) {
b = *pc_++;
TRACE("%02x ", b);
result = result | ((b & 0x7F) << shift);
if ((b & 0x80) == 0) break;
shift += 7;
*length = static_cast<int>(pc_ - pos);
if (pc_ == end && (b & 0x80)) {
error(pc_ - 1, "varint too large");
} else {
TRACE("= %u\n", result);
}
return result;
}
*length = static_cast<int>(pc_ - pos);
if (pc_ == end && (b & 0x80)) {
error(pc_ - 1, "varint too large");
} else {
TRACE("= %u\n", result);
}
return result;
return traceOffEnd<uint32_t>();
}
// Check that at least {size} bytes exist between {pc_} and {limit_}.
@ -208,6 +233,7 @@ class Decoder {
start_ = start;
pc_ = start;
limit_ = end;
end_ = end;
error_pc_ = nullptr;
error_pt_ = nullptr;
error_msg_.Reset(nullptr);
@ -220,6 +246,7 @@ class Decoder {
const byte* start_;
const byte* pc_;
const byte* limit_;
const byte* end_;
const byte* error_pc_;
const byte* error_pt_;
base::SmartArrayPointer<char> error_msg_;

View File

@ -62,7 +62,7 @@ class ModuleDecoder : public Decoder {
while (pc_ < limit_) {
TRACE("DecodeSection\n");
WasmSectionDeclCode section =
static_cast<WasmSectionDeclCode>(u8("section"));
static_cast<WasmSectionDeclCode>(consume_u8("section"));
// Each section should appear at most once.
if (section < kMaxModuleSectionCode) {
CheckForPreviousSection(sections, section, false);
@ -75,20 +75,20 @@ class ModuleDecoder : public Decoder {
limit_ = pc_;
break;
case kDeclMemory:
module->min_mem_size_log2 = u8("min memory");
module->max_mem_size_log2 = u8("max memory");
module->mem_export = u8("export memory") != 0;
module->min_mem_size_log2 = consume_u8("min memory");
module->max_mem_size_log2 = consume_u8("max memory");
module->mem_export = consume_u8("export memory") != 0;
break;
case kDeclSignatures: {
int length;
uint32_t signatures_count = u32v(&length, "signatures count");
uint32_t signatures_count = consume_u32v(&length, "signatures count");
module->signatures->reserve(SafeReserve(signatures_count));
// Decode signatures.
for (uint32_t i = 0; i < signatures_count; i++) {
if (failed()) break;
TRACE("DecodeSignature[%d] module+%d\n", i,
static_cast<int>(pc_ - start_));
FunctionSig* s = sig(); // read function sig.
FunctionSig* s = consume_sig(); // read function sig.
module->signatures->push_back(s);
}
break;
@ -97,7 +97,7 @@ class ModuleDecoder : public Decoder {
// Functions require a signature table first.
CheckForPreviousSection(sections, kDeclSignatures, true);
int length;
uint32_t functions_count = u32v(&length, "functions count");
uint32_t functions_count = consume_u32v(&length, "functions count");
module->functions->reserve(SafeReserve(functions_count));
// Set up module environment for verification.
ModuleEnv menv;
@ -130,7 +130,7 @@ class ModuleDecoder : public Decoder {
}
case kDeclGlobals: {
int length;
uint32_t globals_count = u32v(&length, "globals count");
uint32_t globals_count = consume_u32v(&length, "globals count");
module->globals->reserve(SafeReserve(globals_count));
// Decode globals.
for (uint32_t i = 0; i < globals_count; i++) {
@ -145,7 +145,8 @@ class ModuleDecoder : public Decoder {
}
case kDeclDataSegments: {
int length;
uint32_t data_segments_count = u32v(&length, "data segments count");
uint32_t data_segments_count =
consume_u32v(&length, "data segments count");
module->data_segments->reserve(SafeReserve(data_segments_count));
// Decode data segments.
for (uint32_t i = 0; i < data_segments_count; i++) {
@ -162,14 +163,15 @@ class ModuleDecoder : public Decoder {
// An indirect function table requires functions first.
CheckForPreviousSection(sections, kDeclFunctions, true);
int length;
uint32_t function_table_count = u32v(&length, "function table count");
uint32_t function_table_count =
consume_u32v(&length, "function table count");
module->function_table->reserve(SafeReserve(function_table_count));
// Decode function table.
for (uint32_t i = 0; i < function_table_count; i++) {
if (failed()) break;
TRACE("DecodeFunctionTable[%d] module+%d\n", i,
static_cast<int>(pc_ - start_));
uint16_t index = u16();
uint16_t index = consume_u16();
if (index >= module->functions->size()) {
error(pc_ - 2, "invalid function index");
break;
@ -184,7 +186,7 @@ class ModuleDecoder : public Decoder {
// information. This section does not affect the semantics of the code
// and can be ignored by the runtime. https://github.com/JSStats/wll
int length = 0;
uint32_t section_size = u32v(&length, "section size");
uint32_t section_size = consume_u32v(&length, "section size");
if (pc_ + section_size > limit_ || pc_ + section_size < pc_) {
error(pc_ - length, "invalid section size");
break;
@ -246,14 +248,14 @@ class ModuleDecoder : public Decoder {
FunctionResult DecodeSingleFunction(ModuleEnv* module_env,
WasmFunction* function) {
pc_ = start_;
function->sig = sig(); // read signature
function->sig = consume_sig(); // read signature
function->name_offset = 0; // ---- name
function->code_start_offset = off(pc_ + 8); // ---- code start
function->code_end_offset = off(limit_); // ---- code end
function->local_int32_count = u16(); // read u16
function->local_int64_count = u16(); // read u16
function->local_float32_count = u16(); // read u16
function->local_float64_count = u16(); // read u16
function->local_int32_count = consume_u16(); // read u16
function->local_int64_count = consume_u16(); // read u16
function->local_float32_count = consume_u16(); // read u16
function->local_float64_count = consume_u16(); // read u16
function->exported = false; // ---- exported
function->external = false; // ---- external
@ -268,7 +270,7 @@ class ModuleDecoder : public Decoder {
// Decodes a single function signature at {start}.
FunctionSig* DecodeFunctionSignature(const byte* start) {
pc_ = start;
FunctionSig* result = sig();
FunctionSig* result = consume_sig();
return ok() ? result : nullptr;
}
@ -281,19 +283,19 @@ class ModuleDecoder : public Decoder {
// Decodes a single global entry inside a module starting at {pc_}.
void DecodeGlobalInModule(WasmGlobal* global) {
global->name_offset = string("global name");
global->name_offset = consume_string("global name");
global->type = mem_type();
global->offset = 0;
global->exported = u8("exported") != 0;
global->exported = consume_u8("exported") != 0;
}
// Decodes a single function entry inside a module starting at {pc_}.
void DecodeFunctionInModule(WasmModule* module, WasmFunction* function,
bool verify_body = true) {
byte decl_bits = u8("function decl");
byte decl_bits = consume_u8("function decl");
const byte* sigpos = pc_;
function->sig_index = u16("signature index");
function->sig_index = consume_u16("signature index");
if (function->sig_index >= module->signatures->size()) {
return error(sigpos, "invalid signature index");
@ -310,7 +312,7 @@ class ModuleDecoder : public Decoder {
(decl_bits & kDeclFunctionImport) == 0 ? " body" : "");
if (decl_bits & kDeclFunctionName) {
function->name_offset = string("function name");
function->name_offset = consume_string("function name");
}
function->exported = decl_bits & kDeclFunctionExport;
@ -322,13 +324,13 @@ class ModuleDecoder : public Decoder {
}
if (decl_bits & kDeclFunctionLocals) {
function->local_int32_count = u16("int32 count");
function->local_int64_count = u16("int64 count");
function->local_float32_count = u16("float32 count");
function->local_float64_count = u16("float64 count");
function->local_int32_count = consume_u16("int32 count");
function->local_int64_count = consume_u16("int64 count");
function->local_float32_count = consume_u16("float32 count");
function->local_float64_count = consume_u16("float64 count");
}
uint16_t size = u16("body size");
uint16_t size = consume_u16("body size");
if (ok()) {
if ((pc_ + size) > limit_) {
return error(pc_, limit_,
@ -350,10 +352,10 @@ class ModuleDecoder : public Decoder {
// Decodes a single data segment entry inside a module starting at {pc_}.
void DecodeDataSegmentInModule(WasmModule* module, WasmDataSegment* segment) {
segment->dest_addr = u32("destination");
segment->source_offset = offset("source offset");
segment->source_size = u32("source size");
segment->init = u8("init");
segment->dest_addr = consume_u32("destination");
segment->source_offset = consume_offset("source offset");
segment->source_size = consume_u32("source size");
segment->init = consume_u8("init");
// Validate the data is in the module.
uint32_t module_limit = static_cast<uint32_t>(limit_ - start_);
@ -416,8 +418,8 @@ class ModuleDecoder : public Decoder {
// Reads a single 32-bit unsigned integer interpreted as an offset, checking
// the offset is within bounds and advances.
uint32_t offset(const char* name = nullptr) {
uint32_t offset = u32(name ? name : "offset");
uint32_t consume_offset(const char* name = nullptr) {
uint32_t offset = consume_u32(name ? name : "offset");
if (offset > static_cast<uint32_t>(limit_ - start_)) {
error(pc_ - sizeof(uint32_t), "offset out of bounds of module");
}
@ -426,13 +428,14 @@ class ModuleDecoder : public Decoder {
// Reads a single 32-bit unsigned integer interpreted as an offset into the
// data and validating the string there and advances.
uint32_t string(const char* name = nullptr) {
return offset(name ? name : "string"); // TODO(titzer): validate string
uint32_t consume_string(const char* name = nullptr) {
// TODO(titzer): validate string
return consume_offset(name ? name : "string");
}
// Reads a single 8-bit integer, interpreting it as a local type.
LocalType local_type() {
byte val = u8("local type");
LocalType consume_local_type() {
byte val = consume_u8("local type");
LocalTypeCode t = static_cast<LocalTypeCode>(val);
switch (t) {
case kLocalVoid:
@ -453,7 +456,7 @@ class ModuleDecoder : public Decoder {
// Reads a single 8-bit integer, interpreting it as a memory type.
MachineType mem_type() {
byte val = u8("memory type");
byte val = consume_u8("memory type");
MemTypeCode t = static_cast<MemTypeCode>(val);
switch (t) {
case kMemI8:
@ -483,14 +486,14 @@ class ModuleDecoder : public Decoder {
}
// Parses an inline function signature.
FunctionSig* sig() {
byte count = u8("param count");
LocalType ret = local_type();
FunctionSig* consume_sig() {
byte count = consume_u8("param count");
LocalType ret = consume_local_type();
FunctionSig::Builder builder(module_zone, ret == kAstStmt ? 0 : 1, count);
if (ret != kAstStmt) builder.AddReturn(ret);
for (int i = 0; i < count; i++) {
LocalType param = local_type();
LocalType param = consume_local_type();
if (param == kAstStmt) error(pc_ - 1, "invalid void parameter type");
builder.AddParam(param);
}

View File

@ -2378,9 +2378,6 @@ TEST(Run_WasmCallEmpty) {
}
// TODO(tizer): Fix on arm and reenable.
#if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64
TEST(Run_WasmCallF32StackParameter) {
// Build the target function.
LocalType param_types[20];
@ -2432,8 +2429,6 @@ TEST(Run_WasmCallF64StackParameter) {
CHECK_EQ(256.5, result);
}
#endif
TEST(Run_WasmCallVoid) {
const byte kMemOffset = 8;

View File

@ -251,9 +251,6 @@ TEST_F(WasmDecoderTest, Int64Const) {
}
// TODO(tizer): Fix on arm and reenable.
#if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64
TEST_F(WasmDecoderTest, Float32Const) {
byte code[] = {kExprF32Const, 0, 0, 0, 0};
float* ptr = reinterpret_cast<float*>(code + 1);
@ -273,8 +270,6 @@ TEST_F(WasmDecoderTest, Float64Const) {
}
}
#endif
TEST_F(WasmDecoderTest, Int32Const_off_end) {
byte code[] = {kExprI32Const, 0xaa, 0xbb, 0xcc, 0x44};
@ -532,16 +527,11 @@ TEST_F(WasmDecoderTest, ExprBlock1b) {
}
// TODO(tizer): Fix on arm and reenable.
#if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64
TEST_F(WasmDecoderTest, ExprBlock1c) {
static const byte code[] = {kExprBlock, 1, kExprF32Const, 0, 0, 0, 0};
EXPECT_VERIFIES(&env_f_ff, code);
}
#endif
TEST_F(WasmDecoderTest, IfEmpty) {
static const byte code[] = {kExprIf, kExprGetLocal, 0, kExprNop};
@ -704,9 +694,6 @@ TEST_F(WasmDecoderTest, ReturnVoid2) {
}
// TODO(tizer): Fix on arm and reenable.
#if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64
TEST_F(WasmDecoderTest, ReturnVoid3) {
EXPECT_VERIFIES_INLINE(&env_v_v, kExprI8Const, 0);
EXPECT_VERIFIES_INLINE(&env_v_v, kExprI32Const, 0, 0, 0, 0);
@ -717,8 +704,6 @@ TEST_F(WasmDecoderTest, ReturnVoid3) {
EXPECT_VERIFIES_INLINE(&env_v_i, kExprGetLocal, 0);
}
#endif
TEST_F(WasmDecoderTest, Unreachable1) {
EXPECT_VERIFIES_INLINE(&env_v_v, kExprUnreachable);
@ -881,9 +866,6 @@ TEST_F(WasmDecoderTest, MacrosStmt) {
}
// TODO(tizer): Fix on arm and reenable.
#if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64
TEST_F(WasmDecoderTest, MacrosBreak) {
EXPECT_VERIFIES_INLINE(&env_v_v, WASM_LOOP(1, WASM_BREAK(0)));
@ -895,8 +877,6 @@ TEST_F(WasmDecoderTest, MacrosBreak) {
WASM_LOOP(1, WASM_BREAKV(0, WASM_F64(0.0))));
}
#endif
TEST_F(WasmDecoderTest, MacrosContinue) {
EXPECT_VERIFIES_INLINE(&env_v_v, WASM_LOOP(1, WASM_CONTINUE(0)));
@ -1263,9 +1243,6 @@ TEST_F(WasmDecoderTest, CallsWithTooFewArguments) {
}
// TODO(tizer): Fix on arm and reenable.
#if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64
TEST_F(WasmDecoderTest, CallsWithSpilloverArgs) {
static LocalType a_i_ff[] = {kAstI32, kAstF32, kAstF32};
FunctionSig sig_i_ff(1, 2, a_i_ff);
@ -1329,8 +1306,6 @@ TEST_F(WasmDecoderTest, CallsWithMismatchedSigs3) {
EXPECT_FAILURE_INLINE(env, WASM_CALL_FUNCTION(1, WASM_F32(17.6)));
}
#endif
TEST_F(WasmDecoderTest, SimpleIndirectCalls) {
FunctionEnv* env = &env_i_i;
@ -1573,9 +1548,6 @@ TEST_F(WasmDecoderTest, BreakNesting3) {
}
// TODO(tizer): Fix on arm and reenable.
#if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64
TEST_F(WasmDecoderTest, BreaksWithMultipleTypes) {
EXPECT_FAILURE_INLINE(
&env_i_i,
@ -1593,8 +1565,6 @@ TEST_F(WasmDecoderTest, BreaksWithMultipleTypes) {
WASM_BRV_IF(0, WASM_ZERO, WASM_I8(11))));
}
#endif
TEST_F(WasmDecoderTest, BreakNesting_6_levels) {
for (int mask = 0; mask < 64; mask++) {
@ -1628,9 +1598,6 @@ TEST_F(WasmDecoderTest, BreakNesting_6_levels) {
}
// TODO(tizer): Fix on arm and reenable.
#if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64
TEST_F(WasmDecoderTest, ExprBreak_TypeCheck) {
FunctionEnv* envs[] = {&env_i_i, &env_l_l, &env_f_ff, &env_d_dd};
for (size_t i = 0; i < arraysize(envs); i++) {
@ -1653,8 +1620,6 @@ TEST_F(WasmDecoderTest, ExprBreak_TypeCheck) {
WASM_F64(1.2)));
}
#endif
TEST_F(WasmDecoderTest, ExprBreak_TypeCheckAll) {
byte code1[] = {WASM_BLOCK(2,
@ -1835,9 +1800,6 @@ TEST_F(WasmDecoderTest, TableSwitch2) {
}
// TODO(tizer): Fix on arm and reenable.
#if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64
TEST_F(WasmDecoderTest, TableSwitch1b) {
EXPECT_VERIFIES_INLINE(&env_i_i, WASM_TABLESWITCH_OP(1, 1, WASM_CASE(0)),
WASM_TABLESWITCH_BODY(WASM_GET_LOCAL(0), WASM_ZERO));
@ -1849,8 +1811,6 @@ TEST_F(WasmDecoderTest, TableSwitch1b) {
WASM_TABLESWITCH_BODY(WASM_ZERO, WASM_F64(0.0)));
}
#endif
TEST_F(WasmDecoderTest, TableSwitch_br1) {
for (int depth = 0; depth < 2; depth++) {
byte code[] = {WASM_BLOCK(1, WASM_TABLESWITCH_OP(0, 1, WASM_CASE_BR(depth)),
@ -1882,17 +1842,12 @@ TEST_F(WasmDecoderTest, TableSwitch_invalid_case_ref) {
}
// TODO(tizer): Fix on arm and reenable.
#if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64
TEST_F(WasmDecoderTest, TableSwitch1_br) {
EXPECT_VERIFIES_INLINE(
&env_i_i, WASM_TABLESWITCH_OP(1, 1, WASM_CASE(0)),
WASM_TABLESWITCH_BODY(WASM_GET_LOCAL(0), WASM_BRV(0, WASM_ZERO)));
}
#endif
TEST_F(WasmDecoderTest, TableSwitch2_br) {
EXPECT_VERIFIES_INLINE(
@ -1916,9 +1871,6 @@ TEST_F(WasmDecoderTest, TableSwitch2x2) {
}
// TODO(tizer): Fix on arm and reenable.
#if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64
TEST_F(WasmDecoderTest, ExprBreakNesting1) {
EXPECT_VERIFIES_INLINE(&env_v_v, WASM_BLOCK(1, WASM_BRV(0, WASM_ZERO)));
EXPECT_VERIFIES_INLINE(&env_v_v, WASM_BLOCK(1, WASM_BR(0)));
@ -1936,8 +1888,6 @@ TEST_F(WasmDecoderTest, ExprBreakNesting1) {
EXPECT_VERIFIES_INLINE(&env_v_v, WASM_LOOP(1, WASM_BR(1)));
}
#endif
TEST_F(WasmDecoderTest, Select) {
EXPECT_VERIFIES_INLINE(
@ -1946,9 +1896,6 @@ TEST_F(WasmDecoderTest, Select) {
}
// TODO(tizer): Fix on arm and reenable.
#if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64
TEST_F(WasmDecoderTest, Select_TypeCheck) {
EXPECT_FAILURE_INLINE(&env_i_i, WASM_SELECT(WASM_F32(9.9), WASM_GET_LOCAL(0),
WASM_GET_LOCAL(0)));
@ -1960,8 +1907,6 @@ TEST_F(WasmDecoderTest, Select_TypeCheck) {
&env_i_i, WASM_SELECT(WASM_F32(9.9), WASM_GET_LOCAL(0), WASM_I64(0)));
}
#endif
class WasmOpcodeLengthTest : public TestWithZone {
public: