Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Side by Side Diff: src/wasm/module-decoder.cc

Issue 1816583003: wasm: add flag to dump modules (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/base/functional.h"
6 #include "src/base/platform/platform.h"
5 #include "src/macro-assembler.h" 7 #include "src/macro-assembler.h"
6 #include "src/objects.h" 8 #include "src/objects.h"
7 #include "src/v8.h" 9 #include "src/v8.h"
8 10
9 #include "src/wasm/decoder.h" 11 #include "src/wasm/decoder.h"
10 #include "src/wasm/module-decoder.h" 12 #include "src/wasm/module-decoder.h"
11 13
12 namespace v8 { 14 namespace v8 {
13 namespace internal { 15 namespace internal {
14 namespace wasm { 16 namespace wasm {
(...skipping 29 matching lines...) Expand all
44 ModuleResult DecodeModule(WasmModule* module, bool verify_functions = true) { 46 ModuleResult DecodeModule(WasmModule* module, bool verify_functions = true) {
45 pc_ = start_; 47 pc_ = start_;
46 module->module_start = start_; 48 module->module_start = start_;
47 module->module_end = limit_; 49 module->module_end = limit_;
48 module->min_mem_pages = 0; 50 module->min_mem_pages = 0;
49 module->max_mem_pages = 0; 51 module->max_mem_pages = 0;
50 module->mem_export = false; 52 module->mem_export = false;
51 module->mem_external = false; 53 module->mem_external = false;
52 module->origin = origin_; 54 module->origin = origin_;
53 55
56 ModuleResult result = DecodeModuleImpl(module, verify_functions);
57
58 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
59 std::string path;
60 if (FLAG_dump_wasm_module_path) {
61 path = FLAG_dump_wasm_module_path;
62 if (path.size() && !base::OS::isDirectorySeparator(path.back())) {
63 path += base::OS::DirectorySeparator();
64 }
65 }
66 // File are named `HASH.{ok,failed}.wasm`.
67 auto name = std::to_string(base::hash_range(module->module_start,
68 module->module_end)) +
69 (result.ok() ? ".ok.wasm" : ".failed.wasm");
70 FILE* wasm_file = base::OS::FOpen((path + name).c_str(), "wb");
71 if (wasm_file) {
72 fwrite(module->module_start, module->module_end - module->module_start,
73 1, wasm_file);
74 fclose(wasm_file);
75 }
76 }
77
78 return result;
79 }
80
81 uint32_t SafeReserve(uint32_t count) {
82 // Avoid OOM by only reserving up to a certain size.
83 const uint32_t kMaxReserve = 20000;
84 return count < kMaxReserve ? count : kMaxReserve;
85 }
86
87 void CheckForFunctions(WasmModule* module, WasmSection::Code section) {
88 if (module->functions.size() == 0) {
89 error(pc_ - 1, nullptr, "functions must appear before section %s",
90 WasmSection::getName(section));
91 }
92 }
93
94 void CheckForPreviousSection(bool* sections, WasmSection::Code section,
95 bool present) {
96 if (section >= WasmSection::Code::Max) return;
97 if (sections[(size_t)section] == present) return;
98 if (present) {
99 error(pc_ - 1, nullptr, "required %s section missing",
100 WasmSection::getName(section));
101 } else {
102 error(pc_ - 1, nullptr, "%s section already present",
103 WasmSection::getName(section));
104 }
105 }
106
107 // Decodes a single anonymous function starting at {start_}.
108 FunctionResult DecodeSingleFunction(ModuleEnv* module_env,
109 WasmFunction* function) {
110 pc_ = start_;
111 function->sig = consume_sig(); // read signature
112 function->name_offset = 0; // ---- name
113 function->name_length = 0; // ---- name length
114 function->code_start_offset = off(pc_); // ---- code start
115 function->code_end_offset = off(limit_); // ---- code end
116 function->exported = false; // ---- exported
117 function->external = false; // ---- external
118
119 if (ok()) VerifyFunctionBody(0, module_env, function);
120
121 FunctionResult result;
122 result.CopyFrom(result_); // Copy error code and location.
123 result.val = function;
124 return result;
125 }
126
127 // Decodes a single function signature at {start}.
128 FunctionSig* DecodeFunctionSignature(const byte* start) {
129 pc_ = start;
130 FunctionSig* result = consume_sig();
131 return ok() ? result : nullptr;
132 }
133
134 private:
135 Zone* module_zone;
136 ModuleResult result_;
137 ModuleOrigin origin_;
138
139 ModuleResult DecodeModuleImpl(WasmModule* module, bool verify_functions) {
54 bool sections[(size_t)WasmSection::Code::Max] = {false}; 140 bool sections[(size_t)WasmSection::Code::Max] = {false};
55 141
56 const byte* pos = pc_; 142 const byte* pos = pc_;
57 uint32_t magic_word = consume_u32("wasm magic"); 143 uint32_t magic_word = consume_u32("wasm magic");
58 #define BYTES(x) (x & 0xff), (x >> 8) & 0xff, (x >> 16) & 0xff, (x >> 24) & 0xff 144 #define BYTES(x) (x & 0xff), (x >> 8) & 0xff, (x >> 16) & 0xff, (x >> 24) & 0xff
59 if (magic_word != kWasmMagic) { 145 if (magic_word != kWasmMagic) {
60 error(pos, pos, 146 error(pos, pos,
61 "expected magic word %02x %02x %02x %02x, " 147 "expected magic word %02x %02x %02x %02x, "
62 "found %02x %02x %02x %02x", 148 "found %02x %02x %02x %02x",
63 BYTES(kWasmMagic), BYTES(magic_word)); 149 BYTES(kWasmMagic), BYTES(magic_word));
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 break; 448 break;
363 } 449 }
364 case WasmSection::Code::Max: 450 case WasmSection::Code::Max:
365 UNREACHABLE(); // Already skipped unknown sections. 451 UNREACHABLE(); // Already skipped unknown sections.
366 } 452 }
367 } 453 }
368 454
369 return toResult(module); 455 return toResult(module);
370 } 456 }
371 457
372 uint32_t SafeReserve(uint32_t count) {
373 // Avoid OOM by only reserving up to a certain size.
374 const uint32_t kMaxReserve = 20000;
375 return count < kMaxReserve ? count : kMaxReserve;
376 }
377
378 void CheckForFunctions(WasmModule* module, WasmSection::Code section) {
379 if (module->functions.size() == 0) {
380 error(pc_ - 1, nullptr, "functions must appear before section %s",
381 WasmSection::getName(section));
382 }
383 }
384
385 void CheckForPreviousSection(bool* sections, WasmSection::Code section,
386 bool present) {
387 if (section >= WasmSection::Code::Max) return;
388 if (sections[(size_t)section] == present) return;
389 if (present) {
390 error(pc_ - 1, nullptr, "required %s section missing",
391 WasmSection::getName(section));
392 } else {
393 error(pc_ - 1, nullptr, "%s section already present",
394 WasmSection::getName(section));
395 }
396 }
397
398 // Decodes a single anonymous function starting at {start_}.
399 FunctionResult DecodeSingleFunction(ModuleEnv* module_env,
400 WasmFunction* function) {
401 pc_ = start_;
402 function->sig = consume_sig(); // read signature
403 function->name_offset = 0; // ---- name
404 function->name_length = 0; // ---- name length
405 function->code_start_offset = off(pc_); // ---- code start
406 function->code_end_offset = off(limit_); // ---- code end
407 function->exported = false; // ---- exported
408 function->external = false; // ---- external
409
410 if (ok()) VerifyFunctionBody(0, module_env, function);
411
412 FunctionResult result;
413 result.CopyFrom(result_); // Copy error code and location.
414 result.val = function;
415 return result;
416 }
417
418 // Decodes a single function signature at {start}.
419 FunctionSig* DecodeFunctionSignature(const byte* start) {
420 pc_ = start;
421 FunctionSig* result = consume_sig();
422 return ok() ? result : nullptr;
423 }
424
425 private:
426 Zone* module_zone;
427 ModuleResult result_;
428 ModuleOrigin origin_;
429
430 uint32_t off(const byte* ptr) { return static_cast<uint32_t>(ptr - start_); } 458 uint32_t off(const byte* ptr) { return static_cast<uint32_t>(ptr - start_); }
431 459
432 // Decodes a single global entry inside a module starting at {pc_}. 460 // Decodes a single global entry inside a module starting at {pc_}.
433 void DecodeGlobalInModule(WasmGlobal* global) { 461 void DecodeGlobalInModule(WasmGlobal* global) {
434 global->name_offset = consume_string(&global->name_length, "global name"); 462 global->name_offset = consume_string(&global->name_length, "global name");
435 global->type = mem_type(); 463 global->type = mem_type();
436 global->offset = 0; 464 global->offset = 0;
437 global->exported = consume_u8("exported") != 0; 465 global->exported = consume_u8("exported") != 0;
438 } 466 }
439 467
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
756 if (function_start > function_end) return FunctionError("start > end"); 784 if (function_start > function_end) return FunctionError("start > end");
757 if (size > kMaxFunctionSize) 785 if (size > kMaxFunctionSize)
758 return FunctionError("size > maximum function size"); 786 return FunctionError("size > maximum function size");
759 WasmFunction* function = new WasmFunction(); 787 WasmFunction* function = new WasmFunction();
760 ModuleDecoder decoder(zone, function_start, function_end, kWasmOrigin); 788 ModuleDecoder decoder(zone, function_start, function_end, kWasmOrigin);
761 return decoder.DecodeSingleFunction(module_env, function); 789 return decoder.DecodeSingleFunction(module_env, function);
762 } 790 }
763 } // namespace wasm 791 } // namespace wasm
764 } // namespace internal 792 } // namespace internal
765 } // namespace v8 793 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698