diff options
author | Michaël Zasso <targos@protonmail.com> | 2017-06-06 10:28:14 +0200 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2017-06-07 10:33:31 +0200 |
commit | 3dc8c3bed4cf3a77607edbb0b015e33f8b60fc09 (patch) | |
tree | 9dee56e142638b34f1eccbd0ad88c3bce5377c29 /deps/v8/src/wasm/module-decoder.cc | |
parent | 91a1bbe3055a660194ca4d403795aa0c03e9d056 (diff) | |
download | node-new-3dc8c3bed4cf3a77607edbb0b015e33f8b60fc09.tar.gz |
deps: update V8 to 5.9.211.32
PR-URL: https://github.com/nodejs/node/pull/13263
Reviewed-By: Gibson Fahnestock <gibfahn@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Diffstat (limited to 'deps/v8/src/wasm/module-decoder.cc')
-rw-r--r-- | deps/v8/src/wasm/module-decoder.cc | 402 |
1 files changed, 170 insertions, 232 deletions
diff --git a/deps/v8/src/wasm/module-decoder.cc b/deps/v8/src/wasm/module-decoder.cc index 440e5dcbb9..2b58065e77 100644 --- a/deps/v8/src/wasm/module-decoder.cc +++ b/deps/v8/src/wasm/module-decoder.cc @@ -30,7 +30,7 @@ namespace wasm { #define TRACE(...) #endif -const char* SectionName(WasmSectionCode code) { +const char* SectionName(SectionCode code) { switch (code) { case kUnknownSectionCode: return "Unknown"; @@ -90,6 +90,24 @@ ValueType TypeOf(const WasmModule* module, const WasmInitExpr& expr) { } } +// Reads a length-prefixed string, checking that it is within bounds. Returns +// the offset of the string, and the length as an out parameter. +uint32_t consume_string(Decoder& decoder, uint32_t* length, bool validate_utf8, + const char* name) { + *length = decoder.consume_u32v("string length"); + uint32_t offset = decoder.pc_offset(); + const byte* string_start = decoder.pc(); + // Consume bytes before validation to guarantee that the string is not oob. + if (*length > 0) { + decoder.consume_bytes(*length, name); + if (decoder.ok() && validate_utf8 && + !unibrow::Utf8::Validate(string_start, *length)) { + decoder.errorf(string_start, "%s: no valid UTF-8 string", name); + } + } + return offset; +} + // An iterator over the sections in a WASM binary module. // Automatically skips all unknown sections. class WasmSectionIterator { @@ -106,7 +124,7 @@ class WasmSectionIterator { return section_code_ != kUnknownSectionCode && decoder_.more(); } - inline WasmSectionCode section_code() const { return section_code_; } + inline SectionCode section_code() const { return section_code_; } inline const byte* section_start() const { return section_start_; } @@ -127,24 +145,24 @@ 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(); } private: Decoder& decoder_; - WasmSectionCode section_code_; + SectionCode section_code_; const byte* section_start_; const byte* payload_start_; const byte* section_end_; // Reads the section code/name at the current position and sets up - // the internal fields. + // the embedder fields. void next() { while (true) { if (!decoder_.more()) { @@ -166,14 +184,14 @@ class WasmSectionIterator { if (section_code == kUnknownSectionCode) { // Check for the known "name" section. - uint32_t string_length = decoder_.consume_u32v("section name length"); - const byte* section_name_start = decoder_.pc(); - decoder_.consume_bytes(string_length, "section name"); + uint32_t string_length; + uint32_t string_offset = wasm::consume_string(decoder_, &string_length, + true, "section name"); if (decoder_.failed() || decoder_.pc() > section_end_) { - TRACE("Section name of length %u couldn't be read\n", string_length); section_code_ = kUnknownSectionCode; return; } + const byte* section_name_start = decoder_.start() + string_offset; payload_start_ = decoder_.pc(); TRACE(" +%d section name : \"%.*s\"\n", @@ -184,15 +202,15 @@ class WasmSectionIterator { strncmp(reinterpret_cast<const char*>(section_name_start), kNameString, kNameStringLength) == 0) { section_code = kNameSectionCode; - } else { - 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); + section_code_ = decoder_.failed() + ? kUnknownSectionCode + : static_cast<SectionCode>(section_code); TRACE("Section: %s\n", SectionName(section_code_)); if (section_code_ == kUnknownSectionCode && @@ -215,9 +233,8 @@ class ModuleDecoder : public Decoder { ModuleDecoder(Zone* zone, const byte* module_start, const byte* module_end, ModuleOrigin origin) : Decoder(module_start, module_end), - module_zone(zone), + module_zone_(zone), origin_(FLAG_assume_asmjs_origin ? kAsmJsOrigin : origin) { - result_.start = start_; if (end_ < start_) { error(start_, "end is less than start"); end_ = start_; @@ -255,30 +272,30 @@ class ModuleDecoder : public Decoder { // Decodes an entire module. ModuleResult DecodeModule(bool verify_functions = true) { pc_ = start_; - WasmModule* module = new WasmModule(module_zone); + WasmModule* module = new WasmModule(module_zone_); module->min_mem_pages = 0; module->max_mem_pages = 0; module->mem_export = false; - module->origin = origin_; + module->set_origin(origin_); const byte* pos = pc_; 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)); } } @@ -317,9 +334,9 @@ class ModuleDecoder : public Decoder { WasmImport* import = &module->import_table.back(); const byte* pos = pc_; import->module_name_offset = - consume_string(&import->module_name_length, true); + consume_string(&import->module_name_length, true, "module name"); import->field_name_offset = - consume_string(&import->field_name_length, true); + consume_string(&import->field_name_length, true, "field name"); import->kind = static_cast<WasmExternalKind>(consume_u8("import kind")); switch (import->kind) { @@ -379,7 +396,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; } } @@ -476,7 +493,8 @@ class ModuleDecoder : public Decoder { }); WasmExport* exp = &module->export_table.back(); - exp->name_offset = consume_string(&exp->name_length, true); + exp->name_offset = + consume_string(&exp->name_length, true, "field name"); const byte* pos = pc(); exp->kind = static_cast<WasmExternalKind>(consume_u8("export kind")); switch (exp->kind) { @@ -515,7 +533,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 +557,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,14 +587,14 @@ 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); - } else { - table = &module->function_tables[table_index]; + errorf(pos, "out of bounds table index %u", table_index); + break; } + table = &module->function_tables[table_index]; WasmInitExpr offset = consume_init_expr(module, kWasmI32); uint32_t num_elem = consume_count("number of elements", kV8MaxWasmTableEntries); @@ -587,11 +604,12 @@ class ModuleDecoder : public Decoder { for (uint32_t j = 0; ok() && j < num_elem; j++) { WasmFunction* func = nullptr; uint32_t index = consume_func_index(module, &func); + DCHECK_EQ(func != nullptr, ok()); + if (!func) break; + DCHECK_EQ(index, func->func_index); init->entries.push_back(index); - if (table && index < module->functions.size()) { - // Canonicalize signature indices during decoding. - table->map.FindOrInsert(module->functions[index].sig); - } + // Canonicalize signature indices during decoding. + table->map.FindOrInsert(func->sig); } } @@ -603,8 +621,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 = @@ -651,22 +669,37 @@ class ModuleDecoder : public Decoder { // TODO(titzer): find a way to report name errors as warnings. // Use an inner decoder so that errors don't fail the outer decoder. Decoder inner(start_, pc_, end_); - uint32_t functions_count = inner.consume_u32v("functions count"); - - for (uint32_t i = 0; inner.ok() && i < functions_count; ++i) { - uint32_t function_name_length = 0; - uint32_t name_offset = - consume_string(inner, &function_name_length, false); - uint32_t func_index = i; - if (inner.ok() && func_index < module->functions.size()) { - module->functions[func_index].name_offset = name_offset; - module->functions[func_index].name_length = function_name_length; - } - - uint32_t local_names_count = inner.consume_u32v("local names count"); - for (uint32_t j = 0; inner.ok() && j < local_names_count; j++) { - uint32_t length = inner.consume_u32v("string length"); - inner.consume_bytes(length, "string"); + // Decode all name subsections. + // Be lenient with their order. + while (inner.ok() && inner.more()) { + uint8_t name_type = inner.consume_u8("name type"); + if (name_type & 0x80) inner.error("name type if not varuint7"); + + uint32_t name_payload_len = inner.consume_u32v("name payload length"); + if (!inner.checkAvailable(name_payload_len)) break; + + // Decode function names, ignore the rest. + // Local names will be decoded when needed. + if (name_type == NameSectionType::kFunction) { + uint32_t functions_count = inner.consume_u32v("functions count"); + + for (; inner.ok() && functions_count > 0; --functions_count) { + uint32_t function_index = inner.consume_u32v("function index"); + uint32_t name_length = 0; + uint32_t name_offset = wasm::consume_string(inner, &name_length, + false, "function name"); + // Be lenient with errors in the name section: Ignore illegal + // or out-of-order indexes and non-UTF8 names. You can even assign + // to the same function multiple times (last valid one wins). + if (inner.ok() && function_index < module->functions.size() && + unibrow::Utf8::Validate(inner.start() + name_offset, + name_length)) { + module->functions[function_index].name_offset = name_offset; + module->functions[function_index].name_length = name_length; + } + } + } else { + inner.consume_bytes(name_payload_len, "name subsection payload"); } } // Skip the whole names section in the outer decoder. @@ -676,8 +709,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()) { @@ -686,7 +719,8 @@ class ModuleDecoder : public Decoder { const WasmModule* finished_module = module; ModuleResult result = toResult(finished_module); if (verify_functions && result.ok()) { - result.MoveFrom(result_); // Copy error code and location. + // Copy error code and location. + result.MoveErrorFrom(intermediate_result_); } if (FLAG_dump_wasm_module) DumpModule(result); return result; @@ -705,7 +739,8 @@ class ModuleDecoder : public Decoder { if (ok()) VerifyFunctionBody(0, module_env, function); FunctionResult result; - result.MoveFrom(result_); // Copy error code and location. + // Copy error code and location. + result.MoveErrorFrom(intermediate_result_); result.val = function; return result; } @@ -723,8 +758,8 @@ class ModuleDecoder : public Decoder { } private: - Zone* module_zone; - ModuleResult result_; + Zone* module_zone_; + Result<bool> intermediate_result_; ModuleOrigin origin_; uint32_t off(const byte* ptr) { return static_cast<uint32_t>(ptr - start_); } @@ -759,25 +794,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))); } } } @@ -836,52 +871,31 @@ class ModuleDecoder : public Decoder { start_ + function->code_start_offset, start_ + function->code_end_offset}; DecodeResult result = VerifyWasmCode( - module_zone->allocator(), + module_zone_->allocator(), menv == nullptr ? nullptr : menv->module_env.module, body); if (result.failed()) { // Wrap the error message from the function decoder. std::ostringstream str; - str << "in function " << func_name << ": "; - str << result; - std::string strval = str.str(); - const char* raw = strval.c_str(); - size_t len = strlen(raw); - char* buffer = new char[len]; - strncpy(buffer, raw, len); - buffer[len - 1] = 0; + str << "in function " << func_name << ": " << result.error_msg; - // Copy error code and location. - result_.MoveFrom(result); - result_.error_msg.reset(buffer); + // Set error code and location, if this is the first error. + if (intermediate_result_.ok()) { + intermediate_result_.MoveErrorFrom(result); + } } } - uint32_t consume_string(uint32_t* length, bool validate_utf8) { - return consume_string(*this, length, validate_utf8); - } - - // Reads a length-prefixed string, checking that it is within bounds. Returns - // the offset of the string, and the length as an out parameter. - uint32_t consume_string(Decoder& decoder, uint32_t* length, - bool validate_utf8) { - *length = decoder.consume_u32v("string length"); - uint32_t offset = decoder.pc_offset(); - const byte* string_start = decoder.pc(); - // Consume bytes before validation to guarantee that the string is not oob. - if (*length > 0) decoder.consume_bytes(*length, "string"); - if (decoder.ok() && validate_utf8 && - !unibrow::Utf8::Validate(string_start, *length)) { - decoder.error(string_start, "no valid UTF-8 string"); - } - return offset; + uint32_t consume_string(uint32_t* length, bool validate_utf8, + const char* name) { + return wasm::consume_string(*this, length, validate_utf8, name); } uint32_t consume_sig_index(WasmModule* module, FunctionSig** sig) { 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; } @@ -893,8 +907,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; @@ -918,8 +931,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 entr%s)", name, index, + static_cast<int>(vector.size()), vector.size() == 1 ? "y" : "ies"); *ptr = nullptr; return 0; } @@ -936,23 +949,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; @@ -964,7 +977,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; @@ -977,7 +990,7 @@ class ModuleDecoder : public Decoder { unsigned len = 0; switch (opcode) { case kExprGetGlobal: { - GlobalIndexOperand operand(this, pc() - 1); + GlobalIndexOperand<true> operand(this, pc() - 1); if (module->globals.size() <= operand.index) { error("global index is out of bounds"); expr.kind = WasmInitExpr::kNone; @@ -999,28 +1012,28 @@ class ModuleDecoder : public Decoder { break; } case kExprI32Const: { - ImmI32Operand operand(this, pc() - 1); + ImmI32Operand<true> operand(this, pc() - 1); expr.kind = WasmInitExpr::kI32Const; expr.val.i32_const = operand.value; len = operand.length; break; } case kExprF32Const: { - ImmF32Operand operand(this, pc() - 1); + ImmF32Operand<true> operand(this, pc() - 1); expr.kind = WasmInitExpr::kF32Const; expr.val.f32_const = operand.value; len = operand.length; break; } case kExprI64Const: { - ImmI64Operand operand(this, pc() - 1); + ImmI64Operand<true> operand(this, pc() - 1); expr.kind = WasmInitExpr::kI64Const; expr.val.i64_const = operand.value; len = operand.length; break; } case kExprF64Const: { - ImmF64Operand operand(this, pc() - 1); + ImmF64Operand<true> operand(this, pc() - 1); expr.kind = WasmInitExpr::kF64Const; expr.val.f64_const = operand.value; len = operand.length; @@ -1037,9 +1050,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; } @@ -1113,80 +1126,31 @@ class ModuleDecoder : public Decoder { // FunctionSig stores the return types first. ValueType* buffer = - module_zone->NewArray<ValueType>(param_count + return_count); + module_zone_->NewArray<ValueType>(param_count + return_count); uint32_t b = 0; for (uint32_t i = 0; i < return_count; ++i) buffer[b++] = returns[i]; for (uint32_t i = 0; i < param_count; ++i) buffer[b++] = params[i]; - return new (module_zone) FunctionSig(return_count, param_count, buffer); - } -}; - -// Helpers for nice error messages. -class ModuleError : public ModuleResult { - public: - explicit ModuleError(const char* msg) { - error_code = kError; - size_t len = strlen(msg) + 1; - char* result = new char[len]; - strncpy(result, msg, len); - result[len - 1] = 0; - error_msg.reset(result); + return new (module_zone_) FunctionSig(return_count, param_count, buffer); } }; -// Helpers for nice error messages. -class FunctionError : public FunctionResult { - public: - explicit FunctionError(const char* msg) { - error_code = kError; - size_t len = strlen(msg) + 1; - char* result = new char[len]; - strncpy(result, msg, len); - result[len - 1] = 0; - error_msg.reset(result); - } -}; - -// Find section with given section code. Return Vector of the payload, or null -// Vector if section is not found or module bytes are invalid. -Vector<const byte> FindSection(const byte* module_start, const byte* module_end, - WasmSectionCode code) { - Decoder decoder(module_start, module_end); - - uint32_t magic_word = decoder.consume_u32("wasm magic"); - if (magic_word != kWasmMagic) decoder.error("wrong magic word"); - - uint32_t magic_version = decoder.consume_u32("wasm version"); - if (magic_version != kWasmVersion) decoder.error("wrong wasm version"); - - WasmSectionIterator section_iter(decoder); - while (section_iter.more()) { - if (section_iter.section_code() == code) { - return Vector<const uint8_t>(section_iter.payload_start(), - section_iter.payload_length()); - } - decoder.consume_bytes(section_iter.payload_length(), "section payload"); - section_iter.advance(); - } - - return Vector<const uint8_t>(); -} - } // namespace ModuleResult DecodeWasmModule(Isolate* isolate, const byte* module_start, const byte* module_end, bool verify_functions, ModuleOrigin origin) { HistogramTimerScope wasm_decode_module_time_scope( - isolate->counters()->wasm_decode_module_time()); + IsWasm(origin) ? isolate->counters()->wasm_decode_wasm_module_time() + : isolate->counters()->wasm_decode_asm_module_time()); size_t size = module_end - module_start; - if (module_start > module_end) return ModuleError("start > end"); + if (module_start > module_end) return ModuleResult::Error("start > end"); if (size >= kV8MaxWasmModuleSize) - return ModuleError("size > maximum module size"); + return ModuleResult::Error("size > maximum module size: %zu", size); // TODO(bradnelson): Improve histogram handling of size_t. - isolate->counters()->wasm_module_size_bytes()->AddSample( - static_cast<int>(size)); + (IsWasm(origin) ? isolate->counters()->wasm_wasm_module_size_bytes() + : isolate->counters()->wasm_asm_module_size_bytes()) + ->AddSample(static_cast<int>(size)); // Signatures are stored in zone memory, which have the same lifetime // as the {module}. Zone* zone = new Zone(isolate->allocator(), ZONE_NAME); @@ -1196,8 +1160,10 @@ ModuleResult DecodeWasmModule(Isolate* isolate, const byte* module_start, // TODO(titzer): this isn't accurate, since it doesn't count the data // allocated on the C++ heap. // https://bugs.chromium.org/p/chromium/issues/detail?id=657320 - isolate->counters()->wasm_decode_module_peak_memory_bytes()->AddSample( - static_cast<int>(zone->allocation_size())); + (IsWasm(origin) + ? isolate->counters()->wasm_decode_wasm_module_peak_memory_bytes() + : isolate->counters()->wasm_decode_asm_module_peak_memory_bytes()) + ->AddSample(static_cast<int>(zone->allocation_size())); return result; } @@ -1218,51 +1184,23 @@ FunctionResult DecodeWasmFunction(Isolate* isolate, Zone* zone, ModuleBytesEnv* module_env, const byte* function_start, const byte* function_end) { + bool is_wasm = module_env->module_env.is_wasm(); HistogramTimerScope wasm_decode_function_time_scope( - isolate->counters()->wasm_decode_function_time()); + is_wasm ? isolate->counters()->wasm_decode_wasm_function_time() + : isolate->counters()->wasm_decode_asm_function_time()); size_t size = function_end - function_start; - if (function_start > function_end) return FunctionError("start > end"); + if (function_start > function_end) + return FunctionResult::Error("start > end"); if (size > kV8MaxWasmFunctionSize) - return FunctionError("size > maximum function size"); - isolate->counters()->wasm_function_size_bytes()->AddSample( - static_cast<int>(size)); + return FunctionResult::Error("size > maximum function size: %zu", size); + (is_wasm ? isolate->counters()->wasm_wasm_function_size_bytes() + : isolate->counters()->wasm_asm_function_size_bytes()) + ->AddSample(static_cast<int>(size)); WasmFunction* function = new WasmFunction(); ModuleDecoder decoder(zone, function_start, function_end, kWasmOrigin); return decoder.DecodeSingleFunction(module_env, function); } -FunctionOffsetsResult DecodeWasmFunctionOffsets(const byte* module_start, - const byte* module_end) { - // Find and decode the code section. - Vector<const byte> code_section = - FindSection(module_start, module_end, kCodeSectionCode); - Decoder decoder(code_section.start(), code_section.end()); - FunctionOffsets table; - if (!code_section.start()) { - decoder.error("no code section"); - return decoder.toResult(std::move(table)); - } - - uint32_t functions_count = decoder.consume_u32v("functions count"); - // Reserve space for the entries, taking care of invalid input. - if (functions_count < static_cast<unsigned>(code_section.length()) / 2) { - table.reserve(functions_count); - } - - int section_offset = static_cast<int>(code_section.start() - module_start); - DCHECK_LE(0, section_offset); - for (uint32_t i = 0; i < functions_count && decoder.ok(); ++i) { - uint32_t size = decoder.consume_u32v("body size"); - int offset = static_cast<int>(section_offset + decoder.pc_offset()); - table.emplace_back(offset, static_cast<int>(size)); - DCHECK(table.back().first >= 0 && table.back().second >= 0); - decoder.consume_bytes(size); - } - if (decoder.more()) decoder.error("unexpected additional bytes"); - - return decoder.toResult(std::move(table)); -} - AsmJsOffsetsResult DecodeAsmJsOffsets(const byte* tables_start, const byte* tables_end) { AsmJsOffsets table; |