Chromium Code Reviews| 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_}. |