OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |