summaryrefslogtreecommitdiff
path: root/deps/v8/src/wasm/module-decoder.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/wasm/module-decoder.cc')
-rw-r--r--deps/v8/src/wasm/module-decoder.cc158
1 files changed, 123 insertions, 35 deletions
diff --git a/deps/v8/src/wasm/module-decoder.cc b/deps/v8/src/wasm/module-decoder.cc
index 5280af7374..d7a0156a7b 100644
--- a/deps/v8/src/wasm/module-decoder.cc
+++ b/deps/v8/src/wasm/module-decoder.cc
@@ -237,11 +237,17 @@ class WasmSectionIterator {
}
};
+} // namespace
+
// The main logic for decoding the bytes of a module.
-class ModuleDecoder : public Decoder {
+class ModuleDecoderImpl : public Decoder {
public:
- ModuleDecoder(const byte* module_start, const byte* module_end,
- ModuleOrigin origin)
+ explicit ModuleDecoderImpl(ModuleOrigin origin)
+ : Decoder(nullptr, nullptr),
+ origin_(FLAG_assume_asmjs_origin ? kAsmJsOrigin : origin) {}
+
+ ModuleDecoderImpl(const byte* module_start, const byte* module_end,
+ ModuleOrigin origin)
: Decoder(module_start, module_end),
origin_(FLAG_assume_asmjs_origin ? kAsmJsOrigin : origin) {
if (end_ < start_) {
@@ -265,13 +271,9 @@ class ModuleDecoder : public Decoder {
}
// File are named `HASH.{ok,failed}.wasm`.
size_t hash = base::hash_range(start_, end_);
- char buf[32] = {'\0'};
-#if V8_OS_WIN && _MSC_VER < 1900
-#define snprintf sprintf_s
-#endif
- snprintf(buf, sizeof(buf) - 1, "%016zx.%s.wasm", hash,
- result.ok() ? "ok" : "failed");
- std::string name(buf);
+ EmbeddedVector<char, 32> buf;
+ SNPrintF(buf, "%016zx.%s.wasm", hash, result.ok() ? "ok" : "failed");
+ std::string name(buf.start());
if (FILE* wasm_file = base::OS::FOpen((path + name).c_str(), "wb")) {
if (fwrite(start_, end_ - start_, 1, wasm_file) != 1) {
OFStream os(stderr);
@@ -316,12 +318,16 @@ class ModuleDecoder : public Decoder {
BYTES(kWasmVersion), BYTES(magic_version));
}
}
+#undef BYTES
}
void DecodeSection(SectionCode section_code, Vector<const uint8_t> bytes,
uint32_t offset, bool verify_functions = true) {
if (failed()) return;
Reset(bytes, offset);
+ TRACE("Section: %s\n", SectionName(section_code));
+ TRACE("Decode Section %p - %p\n", static_cast<const void*>(bytes.begin()),
+ static_cast<const void*>(bytes.end()));
// Check if the section is out-of-order.
if (section_code < next_section_) {
@@ -477,7 +483,8 @@ class ModuleDecoder : public Decoder {
consume_resizable_limits(
"memory", "pages", FLAG_wasm_max_mem_pages,
&module_->initial_pages, &module_->has_maximum_pages,
- kSpecMaxWasmMemoryPages, &module_->maximum_pages);
+ kSpecMaxWasmMemoryPages, &module_->maximum_pages,
+ &module_->has_shared_memory);
break;
}
case kExternalGlobal: {
@@ -545,7 +552,7 @@ class ModuleDecoder : public Decoder {
consume_resizable_limits(
"memory", "pages", FLAG_wasm_max_mem_pages, &module_->initial_pages,
&module_->has_maximum_pages, kSpecMaxWasmMemoryPages,
- &module_->maximum_pages);
+ &module_->maximum_pages, &module_->has_shared_memory);
}
}
@@ -561,6 +568,7 @@ class ModuleDecoder : public Decoder {
WasmGlobal* global = &module_->globals.back();
DecodeGlobalInModule(module_.get(), i + imported_globals, global);
}
+ if (ok()) CalculateGlobalOffsets(module_.get());
}
void DecodeExportSection() {
@@ -701,26 +709,42 @@ class ModuleDecoder : public Decoder {
}
void DecodeCodeSection(bool verify_functions) {
- const byte* pos = pc_;
+ uint32_t pos = pc_offset();
uint32_t functions_count = consume_u32v("functions count");
- if (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; i < functions_count; ++i) {
+ CheckFunctionsCount(functions_count, pos);
+ for (uint32_t i = 0; ok() && i < functions_count; ++i) {
uint32_t size = consume_u32v("body size");
uint32_t offset = pc_offset();
consume_bytes(size, "function body");
if (failed()) break;
- WasmFunction* function =
- &module_->functions[i + module_->num_imported_functions];
- function->code = {offset, size};
- if (verify_functions) {
- ModuleWireBytes bytes(start_, end_);
- VerifyFunctionBody(module_->signature_zone->allocator(),
- i + module_->num_imported_functions, bytes,
- module_.get(), function);
- }
+ DecodeFunctionBody(i, size, offset, verify_functions);
+ }
+ }
+
+ bool CheckFunctionsCount(uint32_t functions_count, uint32_t offset) {
+ if (functions_count != module_->num_declared_functions) {
+ Reset(nullptr, nullptr, offset);
+ errorf(nullptr, "function body count %u mismatch (%u expected)",
+ functions_count, module_->num_declared_functions);
+ return false;
+ }
+ return true;
+ }
+
+ void DecodeFunctionBody(uint32_t index, uint32_t length, uint32_t offset,
+ bool verify_functions) {
+ auto size_histogram = module_->is_wasm()
+ ? GetCounters()->wasm_wasm_function_size_bytes()
+ : GetCounters()->wasm_asm_function_size_bytes();
+ size_histogram->AddSample(length);
+ WasmFunction* function =
+ &module_->functions[index + module_->num_imported_functions];
+ function->code = {offset, length};
+ if (verify_functions) {
+ ModuleWireBytes bytes(start_, end_);
+ VerifyFunctionBody(module_->signature_zone->allocator(),
+ index + module_->num_imported_functions, bytes,
+ module_.get(), function);
}
}
@@ -881,6 +905,8 @@ class ModuleDecoder : public Decoder {
return consume_init_expr(nullptr, kWasmStmt);
}
+ WasmModule* module() { return module_.get(); }
+
bool IsWasm() { return origin_ == kWasmOrigin; }
Counters* GetCounters() {
@@ -902,7 +928,7 @@ class ModuleDecoder : public Decoder {
// We store next_section_ as uint8_t instead of SectionCode so that we can
// increment it. This static_assert should make sure that SectionCode does not
// get bigger than uint8_t accidentially.
- static_assert(sizeof(ModuleDecoder::next_section_) == sizeof(SectionCode),
+ static_assert(sizeof(ModuleDecoderImpl::next_section_) == sizeof(SectionCode),
"type mismatch");
Result<bool> intermediate_result_;
ModuleOrigin origin_;
@@ -1085,9 +1111,30 @@ class ModuleDecoder : public Decoder {
void consume_resizable_limits(const char* name, const char* units,
uint32_t max_initial, uint32_t* initial,
bool* has_max, uint32_t max_maximum,
- uint32_t* maximum) {
- uint32_t flags = consume_u32v("resizable limits flags");
+ uint32_t* maximum,
+ bool* has_shared_memory = nullptr) {
+ uint8_t flags = consume_u8("resizable limits flags");
const byte* pos = pc();
+
+ if (FLAG_experimental_wasm_threads) {
+ bool is_memory = (strcmp(name, "memory") == 0);
+ if (flags & 0xfc || (!is_memory && (flags & 0xfe))) {
+ errorf(pos - 1, "invalid %s limits flags", name);
+ }
+ if (flags == 3) {
+ DCHECK_NOT_NULL(has_shared_memory);
+ *has_shared_memory = true;
+ } else if (flags == 2) {
+ errorf(pos - 1,
+ "%s limits flags should have maximum defined if shared is true",
+ name);
+ }
+ } else {
+ if (flags & 0xfe) {
+ errorf(pos - 1, "invalid %s limits flags", name);
+ }
+ }
+
*initial = consume_u32v("initial size");
*has_max = false;
if (*initial > max_initial) {
@@ -1301,7 +1348,7 @@ ModuleResult DecodeWasmModule(Isolate* isolate, const byte* module_start,
size_counter->AddSample(static_cast<int>(size));
// Signatures are stored in zone memory, which have the same lifetime
// as the {module}.
- ModuleDecoder decoder(module_start, module_end, origin);
+ ModuleDecoderImpl decoder(module_start, module_end, origin);
ModuleResult result = decoder.DecodeModule(isolate, verify_functions);
// TODO(bradnelson): Improve histogram handling of size_t.
// TODO(titzer): this isn't accurate, since it doesn't count the data
@@ -1318,7 +1365,43 @@ ModuleResult DecodeWasmModule(Isolate* isolate, const byte* module_start,
return result;
}
-} // namespace
+ModuleDecoder::ModuleDecoder() = default;
+ModuleDecoder::~ModuleDecoder() = default;
+
+WasmModule* ModuleDecoder::module() const { return impl_->module(); }
+
+void ModuleDecoder::StartDecoding(Isolate* isolate, ModuleOrigin origin) {
+ DCHECK_NULL(impl_);
+ impl_.reset(new ModuleDecoderImpl(origin));
+ impl_->StartDecoding(isolate);
+}
+
+void ModuleDecoder::DecodeModuleHeader(Vector<const uint8_t> bytes,
+ uint32_t offset) {
+ impl_->DecodeModuleHeader(bytes, offset);
+}
+
+void ModuleDecoder::DecodeSection(SectionCode section_code,
+ Vector<const uint8_t> bytes, uint32_t offset,
+ bool verify_functions) {
+ impl_->DecodeSection(section_code, bytes, offset, verify_functions);
+}
+
+void ModuleDecoder::DecodeFunctionBody(uint32_t index, uint32_t length,
+ uint32_t offset, bool verify_functions) {
+ impl_->DecodeFunctionBody(index, length, offset, verify_functions);
+}
+
+bool ModuleDecoder::CheckFunctionsCount(uint32_t functions_count,
+ uint32_t offset) {
+ return impl_->CheckFunctionsCount(functions_count, offset);
+}
+
+ModuleResult ModuleDecoder::FinishDecoding(bool verify_functions) {
+ return impl_->FinishDecoding(verify_functions);
+}
+
+bool ModuleDecoder::ok() { return impl_->ok(); }
ModuleResult SyncDecodeWasmModule(Isolate* isolate, const byte* module_start,
const byte* module_end, bool verify_functions,
@@ -1337,13 +1420,13 @@ ModuleResult AsyncDecodeWasmModule(
FunctionSig* DecodeWasmSignatureForTesting(Zone* zone, const byte* start,
const byte* end) {
- ModuleDecoder decoder(start, end, kWasmOrigin);
+ ModuleDecoderImpl decoder(start, end, kWasmOrigin);
return decoder.DecodeFunctionSignature(zone, start);
}
WasmInitExpr DecodeWasmInitExprForTesting(const byte* start, const byte* end) {
AccountingAllocator allocator;
- ModuleDecoder decoder(start, end, kWasmOrigin);
+ ModuleDecoderImpl decoder(start, end, kWasmOrigin);
return decoder.DecodeInitExpr(start);
}
@@ -1358,9 +1441,14 @@ FunctionResult DecodeWasmFunction(Isolate* isolate, Zone* zone,
size_t size = function_end - function_start;
if (function_start > function_end)
return FunctionResult::Error("start > end");
+ auto size_histogram = module->is_wasm()
+ ? counters->wasm_wasm_function_size_bytes()
+ : counters->wasm_asm_function_size_bytes();
+ // TODO(bradnelson): Improve histogram handling of ptrdiff_t.
+ size_histogram->AddSample(static_cast<int>(size));
if (size > kV8MaxWasmFunctionSize)
return FunctionResult::Error("size > maximum function size: %zu", size);
- ModuleDecoder decoder(function_start, function_end, kWasmOrigin);
+ ModuleDecoderImpl decoder(function_start, function_end, kWasmOrigin);
decoder.SetCounters(counters);
return decoder.DecodeSingleFunction(zone, wire_bytes, module,
base::make_unique<WasmFunction>());