Index: src/wasm/module-decoder.cc |
diff --git a/src/wasm/module-decoder.cc b/src/wasm/module-decoder.cc |
index 2c5bea4869df21470b5f583af6c71ea22370c5d5..04375285f68273b3f1bafcd857b61fb193fdbb54 100644 |
--- a/src/wasm/module-decoder.cc |
+++ b/src/wasm/module-decoder.cc |
@@ -2,6 +2,8 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
+#include "src/base/functional.h" |
+#include "src/base/platform/platform.h" |
#include "src/macro-assembler.h" |
#include "src/objects.h" |
#include "src/v8.h" |
@@ -51,6 +53,90 @@ class ModuleDecoder : public Decoder { |
module->mem_external = false; |
module->origin = origin_; |
+ ModuleResult result = DecodeModuleImpl(module, verify_functions); |
+ |
+ if (FLAG_dump_wasm_module) { |
titzer
2016/03/21 08:14:37
Can you factor out the dumping logic into its own
JF
2016/03/21 20:11:30
Done.
Inlining DecodeModuleImpl is slightly ugly
|
+ std::string path; |
+ if (FLAG_dump_wasm_module_path) { |
+ path = FLAG_dump_wasm_module_path; |
+ if (path.size() && !base::OS::isDirectorySeparator(path.back())) { |
+ path += base::OS::DirectorySeparator(); |
+ } |
+ } |
+ // File are named `HASH.{ok,failed}.wasm`. |
+ auto name = std::to_string(base::hash_range(module->module_start, |
+ module->module_end)) + |
+ (result.ok() ? ".ok.wasm" : ".failed.wasm"); |
+ FILE* wasm_file = base::OS::FOpen((path + name).c_str(), "wb"); |
+ if (wasm_file) { |
+ fwrite(module->module_start, module->module_end - module->module_start, |
+ 1, wasm_file); |
+ fclose(wasm_file); |
+ } |
+ } |
+ |
+ return result; |
+ } |
+ |
+ uint32_t SafeReserve(uint32_t count) { |
+ // Avoid OOM by only reserving up to a certain size. |
+ const uint32_t kMaxReserve = 20000; |
+ return count < kMaxReserve ? count : kMaxReserve; |
+ } |
+ |
+ void CheckForFunctions(WasmModule* module, WasmSection::Code section) { |
+ if (module->functions.size() == 0) { |
+ error(pc_ - 1, nullptr, "functions must appear before section %s", |
+ WasmSection::getName(section)); |
+ } |
+ } |
+ |
+ void CheckForPreviousSection(bool* sections, WasmSection::Code section, |
+ bool present) { |
+ if (section >= WasmSection::Code::Max) return; |
+ if (sections[(size_t)section] == present) return; |
+ if (present) { |
+ error(pc_ - 1, nullptr, "required %s section missing", |
+ WasmSection::getName(section)); |
+ } else { |
+ error(pc_ - 1, nullptr, "%s section already present", |
+ WasmSection::getName(section)); |
+ } |
+ } |
+ |
+ // Decodes a single anonymous function starting at {start_}. |
+ FunctionResult DecodeSingleFunction(ModuleEnv* module_env, |
+ WasmFunction* function) { |
+ pc_ = start_; |
+ function->sig = consume_sig(); // read signature |
+ function->name_offset = 0; // ---- name |
+ function->name_length = 0; // ---- name length |
+ function->code_start_offset = off(pc_); // ---- code start |
+ function->code_end_offset = off(limit_); // ---- code end |
+ function->exported = false; // ---- exported |
+ function->external = false; // ---- external |
+ |
+ if (ok()) VerifyFunctionBody(0, module_env, function); |
+ |
+ FunctionResult result; |
+ result.CopyFrom(result_); // Copy error code and location. |
+ result.val = function; |
+ return result; |
+ } |
+ |
+ // Decodes a single function signature at {start}. |
+ FunctionSig* DecodeFunctionSignature(const byte* start) { |
+ pc_ = start; |
+ FunctionSig* result = consume_sig(); |
+ return ok() ? result : nullptr; |
+ } |
+ |
+ private: |
+ Zone* module_zone; |
+ ModuleResult result_; |
+ ModuleOrigin origin_; |
+ |
+ ModuleResult DecodeModuleImpl(WasmModule* module, bool verify_functions) { |
bool sections[(size_t)WasmSection::Code::Max] = {false}; |
const byte* pos = pc_; |
@@ -369,64 +455,6 @@ class ModuleDecoder : public Decoder { |
return toResult(module); |
} |
- uint32_t SafeReserve(uint32_t count) { |
- // Avoid OOM by only reserving up to a certain size. |
- const uint32_t kMaxReserve = 20000; |
- return count < kMaxReserve ? count : kMaxReserve; |
- } |
- |
- void CheckForFunctions(WasmModule* module, WasmSection::Code section) { |
- if (module->functions.size() == 0) { |
- error(pc_ - 1, nullptr, "functions must appear before section %s", |
- WasmSection::getName(section)); |
- } |
- } |
- |
- void CheckForPreviousSection(bool* sections, WasmSection::Code section, |
- bool present) { |
- if (section >= WasmSection::Code::Max) return; |
- if (sections[(size_t)section] == present) return; |
- if (present) { |
- error(pc_ - 1, nullptr, "required %s section missing", |
- WasmSection::getName(section)); |
- } else { |
- error(pc_ - 1, nullptr, "%s section already present", |
- WasmSection::getName(section)); |
- } |
- } |
- |
- // Decodes a single anonymous function starting at {start_}. |
- FunctionResult DecodeSingleFunction(ModuleEnv* module_env, |
- WasmFunction* function) { |
- pc_ = start_; |
- function->sig = consume_sig(); // read signature |
- function->name_offset = 0; // ---- name |
- function->name_length = 0; // ---- name length |
- function->code_start_offset = off(pc_); // ---- code start |
- function->code_end_offset = off(limit_); // ---- code end |
- function->exported = false; // ---- exported |
- function->external = false; // ---- external |
- |
- if (ok()) VerifyFunctionBody(0, module_env, function); |
- |
- FunctionResult result; |
- result.CopyFrom(result_); // Copy error code and location. |
- result.val = function; |
- return result; |
- } |
- |
- // Decodes a single function signature at {start}. |
- FunctionSig* DecodeFunctionSignature(const byte* start) { |
- pc_ = start; |
- FunctionSig* result = consume_sig(); |
- return ok() ? result : nullptr; |
- } |
- |
- private: |
- Zone* module_zone; |
- ModuleResult result_; |
- ModuleOrigin origin_; |
- |
uint32_t off(const byte* ptr) { return static_cast<uint32_t>(ptr - start_); } |
// Decodes a single global entry inside a module starting at {pc_}. |