diff options
author | Matheus Marchini <mmarchini@netflix.com> | 2020-03-05 10:49:19 -0800 |
---|---|---|
committer | Matheus Marchini <mmarchini@netflix.com> | 2020-03-18 16:23:22 -0700 |
commit | 2883c855e0105b51e5c8020d21458af109ffe3d4 (patch) | |
tree | 26777aad0a398e9f7755c8b65ac76827fe352a81 /deps/v8/src/wasm/module-decoder.cc | |
parent | 5f0af2af2a67216e00fe07ccda11e889d14abfcd (diff) | |
download | node-new-2883c855e0105b51e5c8020d21458af109ffe3d4.tar.gz |
deps: update V8 to 8.1.307.20
PR-URL: https://github.com/nodejs/node/pull/32116
Reviewed-By: Michaƫl Zasso <targos@protonmail.com>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Diffstat (limited to 'deps/v8/src/wasm/module-decoder.cc')
-rw-r--r-- | deps/v8/src/wasm/module-decoder.cc | 169 |
1 files changed, 98 insertions, 71 deletions
diff --git a/deps/v8/src/wasm/module-decoder.cc b/deps/v8/src/wasm/module-decoder.cc index b89d06b881..bc8260cd9b 100644 --- a/deps/v8/src/wasm/module-decoder.cc +++ b/deps/v8/src/wasm/module-decoder.cc @@ -291,14 +291,15 @@ class ModuleDecoderImpl : public Decoder { size_t hash = base::hash_range(module_bytes.begin(), module_bytes.end()); EmbeddedVector<char, 32> buf; SNPrintF(buf, "%016zx.%s.wasm", hash, ok() ? "ok" : "failed"); - std::string name(buf.begin()); - if (FILE* wasm_file = base::OS::FOpen((path + name).c_str(), "wb")) { - if (fwrite(module_bytes.begin(), module_bytes.length(), 1, wasm_file) != - 1) { - OFStream os(stderr); - os << "Error while dumping wasm file" << std::endl; - } - fclose(wasm_file); + path += buf.begin(); + size_t rv = 0; + if (FILE* file = base::OS::FOpen(path.c_str(), "wb")) { + rv = fwrite(module_bytes.begin(), module_bytes.length(), 1, file); + fclose(file); + } + if (rv != 1) { + OFStream os(stderr); + os << "Error while dumping wasm file to " << path << std::endl; } } @@ -467,7 +468,7 @@ class ModuleDecoderImpl : public Decoder { consume_bytes(static_cast<uint32_t>(end_ - start_), ".debug_info"); break; case kCompilationHintsSectionCode: - if (enabled_features_.compilation_hints) { + if (enabled_features_.has_compilation_hints()) { DecodeCompilationHintsSection(); } else { // Ignore this section when feature was disabled. It is an optional @@ -476,14 +477,14 @@ class ModuleDecoderImpl : public Decoder { } break; case kDataCountSectionCode: - if (enabled_features_.bulk_memory) { + if (enabled_features_.has_bulk_memory()) { DecodeDataCountSection(); } else { errorf(pc(), "unexpected section <%s>", SectionName(section_code)); } break; case kExceptionSectionCode: - if (enabled_features_.eh) { + if (enabled_features_.has_eh()) { DecodeExceptionSection(); } else { errorf(pc(), "unexpected section <%s>", SectionName(section_code)); @@ -562,7 +563,7 @@ class ModuleDecoderImpl : public Decoder { WasmTable* table = &module_->tables.back(); table->imported = true; ValueType type = consume_reference_type(); - if (!enabled_features_.anyref) { + if (!enabled_features_.has_anyref()) { if (type != kWasmFuncRef) { error(pc_ - 1, "invalid table type"); break; @@ -601,7 +602,7 @@ class ModuleDecoderImpl : public Decoder { } case kExternalException: { // ===== Imported exception ========================================== - if (!enabled_features_.eh) { + if (!enabled_features_.has_eh()) { errorf(pos, "unknown import kind 0x%02x", import->kind); break; } @@ -648,7 +649,8 @@ class ModuleDecoderImpl : public Decoder { void DecodeTableSection() { // TODO(ahaas): Set the correct limit to {kV8MaxWasmTables} once the // implementation of AnyRef landed. - uint32_t max_count = enabled_features_.anyref ? 100000 : kV8MaxWasmTables; + uint32_t max_count = + enabled_features_.has_anyref() ? 100000 : kV8MaxWasmTables; uint32_t table_count = consume_count("table count", max_count); for (uint32_t i = 0; ok() && i < table_count; i++) { @@ -745,7 +747,7 @@ class ModuleDecoderImpl : public Decoder { break; } case kExternalException: { - if (!enabled_features_.eh) { + if (!enabled_features_.has_eh()) { errorf(pos, "invalid export kind 0x%02x", exp->kind); break; } @@ -966,7 +968,9 @@ class ModuleDecoderImpl : public Decoder { // Function and local names will be decoded when needed. if (name_type == NameSectionKindCode::kModule) { WireBytesRef name = consume_string(&inner, false, "module name"); - if (inner.ok() && validate_utf8(&inner, name)) module_->name = name; + if (inner.ok() && validate_utf8(&inner, name)) { + module_->name = name; + } } else { inner.consume_bytes(name_payload_len, "name subsection payload"); } @@ -1236,7 +1240,7 @@ class ModuleDecoderImpl : public Decoder { } bool AddTable(WasmModule* module) { - if (enabled_features_.anyref) return true; + if (enabled_features_.has_anyref()) return true; if (module->tables.size() > 0) { error("At most one table is supported"); return false; @@ -1329,7 +1333,7 @@ class ModuleDecoderImpl : public Decoder { wasm_decode, function_time); TimedHistogramScope wasm_decode_function_time_scope(time_counter); - WasmFeatures unused_detected_features; + WasmFeatures unused_detected_features = WasmFeatures::None(); result = VerifyWasmCode(allocator, enabled_features_, module, &unused_detected_features, body); } @@ -1424,7 +1428,7 @@ class ModuleDecoderImpl : public Decoder { uint8_t flags = consume_u8("resizable limits flags"); const byte* pos = pc(); *has_shared_memory = false; - if (enabled_features_.threads) { + if (enabled_features_.has_threads()) { if (flags & 0xFC) { errorf(pos - 1, "invalid memory limits flags"); } else if (flags == 3) { @@ -1542,7 +1546,7 @@ class ModuleDecoderImpl : public Decoder { break; } case kExprRefNull: { - if (enabled_features_.anyref || enabled_features_.eh) { + if (enabled_features_.has_anyref() || enabled_features_.has_eh()) { expr.kind = WasmInitExpr::kRefNullConst; len = 0; break; @@ -1550,7 +1554,7 @@ class ModuleDecoderImpl : public Decoder { V8_FALLTHROUGH; } case kExprRefFunc: { - if (enabled_features_.anyref) { + if (enabled_features_.has_anyref()) { FunctionIndexImmediate<Decoder::kValidate> imm(this, pc() - 1); if (module->functions.size() <= imm.index) { errorf(pc() - 1, "invalid function index: %u", imm.index); @@ -1605,16 +1609,19 @@ class ModuleDecoderImpl : public Decoder { if (origin_ == kWasmOrigin) { switch (t) { case kLocalS128: - if (enabled_features_.simd) return kWasmS128; + if (enabled_features_.has_simd()) return kWasmS128; break; case kLocalFuncRef: - if (enabled_features_.anyref) return kWasmFuncRef; + if (enabled_features_.has_anyref()) return kWasmFuncRef; break; case kLocalAnyRef: - if (enabled_features_.anyref) return kWasmAnyRef; + if (enabled_features_.has_anyref()) return kWasmAnyRef; + break; + case kLocalNullRef: + if (enabled_features_.has_anyref()) return kWasmNullRef; break; case kLocalExnRef: - if (enabled_features_.eh) return kWasmExnRef; + if (enabled_features_.has_eh()) return kWasmExnRef; break; default: break; @@ -1633,11 +1640,24 @@ class ModuleDecoderImpl : public Decoder { case kLocalFuncRef: return kWasmFuncRef; case kLocalAnyRef: - if (!enabled_features_.anyref) { + if (!enabled_features_.has_anyref()) { error(pc_ - 1, "Invalid type. Set --experimental-wasm-anyref to use 'AnyRef'"); } return kWasmAnyRef; + case kLocalNullRef: + if (!enabled_features_.has_anyref()) { + error( + pc_ - 1, + "Invalid type. Set --experimental-wasm-anyref to use 'NullRef'"); + } + return kWasmNullRef; + case kLocalExnRef: + if (!enabled_features_.has_eh()) { + error(pc_ - 1, + "Invalid type. Set --experimental-wasm-eh to use 'ExnRef'"); + } + return kWasmExnRef; default: break; } @@ -1658,7 +1678,7 @@ class ModuleDecoderImpl : public Decoder { } std::vector<ValueType> returns; // parse return types - const size_t max_return_count = enabled_features_.mv + const size_t max_return_count = enabled_features_.has_mv() ? kV8MaxWasmFunctionMultiReturns : kV8MaxWasmFunctionReturns; uint32_t return_count = consume_count("return count", max_return_count); @@ -1696,7 +1716,7 @@ class ModuleDecoderImpl : public Decoder { WasmInitExpr* offset) { const byte* pos = pc(); uint8_t flag; - if (enabled_features_.bulk_memory || enabled_features_.anyref) { + if (enabled_features_.has_bulk_memory() || enabled_features_.has_anyref()) { flag = consume_u8("flag"); } else { uint32_t table_index = consume_u32v("table index"); @@ -1727,18 +1747,18 @@ class ModuleDecoderImpl : public Decoder { *functions_as_elements = flag & kFunctionsAsElementsMask; bool has_table_index = flag & kHasTableIndexMask; - if (is_passive && !enabled_features_.bulk_memory) { + if (is_passive && !enabled_features_.has_bulk_memory()) { error("Passive element segments require --experimental-wasm-bulk-memory"); return; } - if (*functions_as_elements && !enabled_features_.bulk_memory) { + if (*functions_as_elements && !enabled_features_.has_bulk_memory()) { error( "Illegal segment flag. Did you forget " "--experimental-wasm-bulk-memory?"); return; } - if (flag != 0 && !enabled_features_.bulk_memory && - !enabled_features_.anyref) { + if (flag != 0 && !enabled_features_.has_bulk_memory() && + !enabled_features_.has_anyref()) { error( "Invalid segment flag. Did you forget " "--experimental-wasm-bulk-memory or --experimental-wasm-anyref?"); @@ -1792,13 +1812,14 @@ class ModuleDecoderImpl : public Decoder { // Some flag values are only valid for specific proposals. if (flag == SegmentFlags::kPassive) { - if (!enabled_features_.bulk_memory) { + if (!enabled_features_.has_bulk_memory()) { error( "Passive element segments require --experimental-wasm-bulk-memory"); return; } } else if (flag == SegmentFlags::kActiveWithIndex) { - if (!(enabled_features_.bulk_memory || enabled_features_.anyref)) { + if (!(enabled_features_.has_bulk_memory() || + enabled_features_.has_anyref())) { error( "Element segments with table indices require " "--experimental-wasm-bulk-memory or --experimental-wasm-anyref"); @@ -2009,29 +2030,26 @@ FunctionResult DecodeWasmFunctionForTesting( std::make_unique<WasmFunction>()); } -AsmJsOffsetsResult DecodeAsmJsOffsets(const byte* tables_start, - const byte* tables_end) { - AsmJsOffsets table; +AsmJsOffsetsResult DecodeAsmJsOffsets(Vector<const uint8_t> encoded_offsets) { + std::vector<AsmJsOffsetFunctionEntries> functions; - Decoder decoder(tables_start, tables_end); + Decoder decoder(encoded_offsets); uint32_t functions_count = decoder.consume_u32v("functions count"); - // Reserve space for the entries, taking care of invalid input. - if (functions_count < static_cast<uint32_t>(tables_end - tables_start)) { - table.reserve(functions_count); - } + // Sanity check. + DCHECK_GE(encoded_offsets.size(), functions_count); + functions.reserve(functions_count); - for (uint32_t i = 0; i < functions_count && decoder.ok(); ++i) { + for (uint32_t i = 0; i < functions_count; ++i) { uint32_t size = decoder.consume_u32v("table size"); if (size == 0) { - table.emplace_back(); + functions.emplace_back(); continue; } - if (!decoder.checkAvailable(size)) { - decoder.error("illegal asm function offset table size"); - } + DCHECK(decoder.checkAvailable(size)); const byte* table_end = decoder.pc() + size; uint32_t locals_size = decoder.consume_u32v("locals size"); int function_start_position = decoder.consume_u32v("function start pos"); + int function_end_position = function_start_position; int last_byte_offset = locals_size; int last_asm_position = function_start_position; std::vector<AsmJsOffsetEntry> func_asm_offsets; @@ -2039,24 +2057,32 @@ AsmJsOffsetsResult DecodeAsmJsOffsets(const byte* tables_start, // Add an entry for the stack check, associated with position 0. func_asm_offsets.push_back( {0, function_start_position, function_start_position}); - while (decoder.ok() && decoder.pc() < table_end) { + while (decoder.pc() < table_end) { + DCHECK(decoder.ok()); last_byte_offset += decoder.consume_u32v("byte offset delta"); int call_position = last_asm_position + decoder.consume_i32v("call position delta"); int to_number_position = call_position + decoder.consume_i32v("to_number position delta"); last_asm_position = to_number_position; - func_asm_offsets.push_back( - {last_byte_offset, call_position, to_number_position}); - } - if (decoder.pc() != table_end) { - decoder.error("broken asm offset table"); + if (decoder.pc() == table_end) { + // The last entry is the function end marker. + DCHECK_EQ(call_position, to_number_position); + function_end_position = call_position; + } else { + func_asm_offsets.push_back( + {last_byte_offset, call_position, to_number_position}); + } } - table.push_back(std::move(func_asm_offsets)); + DCHECK_EQ(decoder.pc(), table_end); + functions.emplace_back(AsmJsOffsetFunctionEntries{ + function_start_position, function_end_position, + std::move(func_asm_offsets)}); } - if (decoder.more()) decoder.error("unexpected additional bytes"); + DCHECK(decoder.ok()); + DCHECK(!decoder.more()); - return decoder.toResult(std::move(table)); + return decoder.toResult(AsmJsOffsets{std::move(functions)}); } std::vector<CustomSectionOffset> DecodeCustomSections(const byte* start, @@ -2151,14 +2177,11 @@ void DecodeFunctionNames(const byte* module_start, const byte* module_end, } } -void DecodeLocalNames(const byte* module_start, const byte* module_end, - LocalNames* result) { - DCHECK_NOT_NULL(result); - DCHECK(result->names.empty()); - - Decoder decoder(module_start, module_end); - if (!FindNameSection(&decoder)) return; +LocalNames DecodeLocalNames(Vector<const uint8_t> module_bytes) { + Decoder decoder(module_bytes); + if (!FindNameSection(&decoder)) return LocalNames{{}}; + std::vector<LocalNamesPerFunction> functions; while (decoder.ok() && decoder.more()) { uint8_t name_type = decoder.consume_u8("name type"); if (name_type & 0x80) break; // no varuint7 @@ -2175,22 +2198,26 @@ void DecodeLocalNames(const byte* module_start, const byte* module_end, for (uint32_t i = 0; i < local_names_count; ++i) { uint32_t func_index = decoder.consume_u32v("function index"); if (func_index > kMaxInt) continue; - result->names.emplace_back(static_cast<int>(func_index)); - LocalNamesPerFunction& func_names = result->names.back(); - result->max_function_index = - std::max(result->max_function_index, func_names.function_index); + std::vector<LocalName> names; uint32_t num_names = decoder.consume_u32v("namings count"); for (uint32_t k = 0; k < num_names; ++k) { uint32_t local_index = decoder.consume_u32v("local index"); - WireBytesRef name = consume_string(&decoder, true, "local name"); + WireBytesRef name = consume_string(&decoder, false, "local name"); if (!decoder.ok()) break; if (local_index > kMaxInt) continue; - func_names.max_local_index = - std::max(func_names.max_local_index, static_cast<int>(local_index)); - func_names.names.emplace_back(static_cast<int>(local_index), name); + // Ignore non-utf8 names. + if (!validate_utf8(&decoder, name)) continue; + names.emplace_back(static_cast<int>(local_index), name); } + // Use stable sort to get deterministic names (the first one declared) + // even in the presence of duplicates. + std::stable_sort(names.begin(), names.end(), LocalName::IndexLess{}); + functions.emplace_back(static_cast<int>(func_index), std::move(names)); } } + std::stable_sort(functions.begin(), functions.end(), + LocalNamesPerFunction::FunctionIndexLess{}); + return LocalNames{std::move(functions)}; } #undef TRACE |