 Chromium Code Reviews
 Chromium Code Reviews Issue 1816583003:
  wasm: add flag to dump modules  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master
    
  
    Issue 1816583003:
  wasm: add flag to dump modules  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master| 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_}. |