Index: src/wasm/module-decoder.cc |
diff --git a/src/wasm/module-decoder.cc b/src/wasm/module-decoder.cc |
index 2c5bea4869df21470b5f583af6c71ea22370c5d5..558d17c5a6e1117e8cf4f9c37f52faaef43e965d 100644 |
--- a/src/wasm/module-decoder.cc |
+++ b/src/wasm/module-decoder.cc |
@@ -2,12 +2,15 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
+#include "src/wasm/module-decoder.h" |
+ |
+#include "src/base/functional.h" |
+#include "src/base/platform/platform.h" |
#include "src/macro-assembler.h" |
#include "src/objects.h" |
#include "src/v8.h" |
#include "src/wasm/decoder.h" |
-#include "src/wasm/module-decoder.h" |
namespace v8 { |
namespace internal { |
@@ -40,6 +43,31 @@ class ModuleDecoder : public Decoder { |
pc_ = limit_; // On error, terminate section decoding loop. |
} |
+ static void DumpModule(WasmModule* module, ModuleResult result) { |
+ std::string path; |
+ if (FLAG_dump_wasm_module_path) { |
+ path = FLAG_dump_wasm_module_path; |
+ if (path.size() && |
+ !base::OS::isDirectorySeparator(path[path.size() - 1])) { |
+ path += base::OS::DirectorySeparator(); |
+ } |
+ } |
+ // File are named `HASH.{ok,failed}.wasm`. |
+ size_t hash = base::hash_range(module->module_start, module->module_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); |
+ if (FILE* wasm_file = base::OS::FOpen((path + name).c_str(), "wb")) { |
+ fwrite(module->module_start, module->module_end - module->module_start, 1, |
+ wasm_file); |
+ fclose(wasm_file); |
+ } |
+ } |
+ |
// Decodes an entire module. |
ModuleResult DecodeModule(WasmModule* module, bool verify_functions = true) { |
pc_ = start_; |
@@ -61,17 +89,19 @@ class ModuleDecoder : public Decoder { |
"expected magic word %02x %02x %02x %02x, " |
"found %02x %02x %02x %02x", |
BYTES(kWasmMagic), BYTES(magic_word)); |
- return toResult(module); |
+ goto done; |
} |
pos = pc_; |
- uint32_t magic_version = consume_u32("wasm version"); |
- if (magic_version != kWasmVersion) { |
- error(pos, pos, |
- "expected version %02x %02x %02x %02x, " |
- "found %02x %02x %02x %02x", |
- BYTES(kWasmVersion), BYTES(magic_version)); |
- return toResult(module); |
+ { |
+ uint32_t magic_version = consume_u32("wasm version"); |
+ if (magic_version != kWasmVersion) { |
+ error(pos, pos, |
+ "expected version %02x %02x %02x %02x, " |
+ "found %02x %02x %02x %02x", |
+ BYTES(kWasmVersion), BYTES(magic_version)); |
+ goto done; |
+ } |
} |
// Decode the module sections. |
@@ -366,7 +396,12 @@ class ModuleDecoder : public Decoder { |
} |
} |
- return toResult(module); |
+ done: |
+ ModuleResult result = toResult(module); |
+ if (FLAG_dump_wasm_module) { |
+ DumpModule(module, result); |
+ } |
+ return result; |
} |
uint32_t SafeReserve(uint32_t count) { |
@@ -399,13 +434,13 @@ class ModuleDecoder : public Decoder { |
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 |
+ 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); |