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/wasm/module-decoder.h" | 5 #include "src/wasm/module-decoder.h" |
6 | 6 |
7 #include "src/base/functional.h" | 7 #include "src/base/functional.h" |
8 #include "src/base/platform/platform.h" | 8 #include "src/base/platform/platform.h" |
9 #include "src/macro-assembler.h" | 9 #include "src/macro-assembler.h" |
10 #include "src/objects.h" | 10 #include "src/objects.h" |
11 #include "src/v8.h" | 11 #include "src/v8.h" |
12 | 12 |
13 #include "src/wasm/decoder.h" | 13 #include "src/wasm/decoder.h" |
14 | 14 |
15 namespace v8 { | 15 namespace v8 { |
16 namespace internal { | 16 namespace internal { |
17 namespace wasm { | 17 namespace wasm { |
18 | 18 |
19 #if DEBUG | 19 #if DEBUG |
20 #define TRACE(...) \ | 20 #define TRACE(...) \ |
21 do { \ | 21 do { \ |
22 if (FLAG_trace_wasm_decoder) PrintF(__VA_ARGS__); \ | 22 if (FLAG_trace_wasm_decoder) PrintF(__VA_ARGS__); \ |
23 } while (false) | 23 } while (false) |
24 #else | 24 #else |
25 #define TRACE(...) | 25 #define TRACE(...) |
26 #endif | 26 #endif |
27 | 27 |
| 28 namespace { |
| 29 |
28 // The main logic for decoding the bytes of a module. | 30 // The main logic for decoding the bytes of a module. |
29 class ModuleDecoder : public Decoder { | 31 class ModuleDecoder : public Decoder { |
30 public: | 32 public: |
31 ModuleDecoder(Zone* zone, const byte* module_start, const byte* module_end, | 33 ModuleDecoder(Zone* zone, const byte* module_start, const byte* module_end, |
32 ModuleOrigin origin) | 34 ModuleOrigin origin) |
33 : Decoder(module_start, module_end), module_zone(zone), origin_(origin) { | 35 : Decoder(module_start, module_end), module_zone(zone), origin_(origin) { |
34 result_.start = start_; | 36 result_.start = start_; |
35 if (limit_ < start_) { | 37 if (limit_ < start_) { |
36 error(start_, "end is less than start"); | 38 error(start_, "end is less than start"); |
37 limit_ = start_; | 39 limit_ = start_; |
(...skipping 674 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
712 explicit FunctionError(const char* msg) { | 714 explicit FunctionError(const char* msg) { |
713 error_code = kError; | 715 error_code = kError; |
714 size_t len = strlen(msg) + 1; | 716 size_t len = strlen(msg) + 1; |
715 char* result = new char[len]; | 717 char* result = new char[len]; |
716 strncpy(result, msg, len); | 718 strncpy(result, msg, len); |
717 result[len - 1] = 0; | 719 result[len - 1] = 0; |
718 error_msg.Reset(result); | 720 error_msg.Reset(result); |
719 } | 721 } |
720 }; | 722 }; |
721 | 723 |
| 724 Vector<const byte> FindSection(const byte* module_start, const byte* module_end, |
| 725 WasmSection::Code code) { |
| 726 Decoder decoder(module_start, module_end); |
| 727 |
| 728 uint32_t magic_word = decoder.consume_u32("wasm magic"); |
| 729 if (magic_word != kWasmMagic) decoder.error("wrong magic word"); |
| 730 |
| 731 uint32_t magic_version = decoder.consume_u32("wasm version"); |
| 732 if (magic_version != kWasmVersion) decoder.error("wrong wasm version"); |
| 733 |
| 734 while (decoder.more() && decoder.ok()) { |
| 735 // Read the section name. |
| 736 int string_leb_length = 0; |
| 737 uint32_t string_length = |
| 738 decoder.consume_u32v(&string_leb_length, "section name length"); |
| 739 const byte* section_name_start = decoder.pc(); |
| 740 decoder.consume_bytes(string_length); |
| 741 if (decoder.failed()) break; |
| 742 |
| 743 WasmSection::Code section = |
| 744 WasmSection::lookup(section_name_start, string_length); |
| 745 |
| 746 // Read and check the section size. |
| 747 int section_leb_length = 0; |
| 748 uint32_t section_length = |
| 749 decoder.consume_u32v(§ion_leb_length, "section length"); |
| 750 |
| 751 const byte* section_start = decoder.pc(); |
| 752 decoder.consume_bytes(section_length); |
| 753 if (section == code && decoder.ok()) { |
| 754 return Vector<const uint8_t>(section_start, section_length); |
| 755 } |
| 756 } |
| 757 |
| 758 return Vector<const uint8_t>(); |
| 759 } |
| 760 |
| 761 } // namespace |
| 762 |
722 ModuleResult DecodeWasmModule(Isolate* isolate, Zone* zone, | 763 ModuleResult DecodeWasmModule(Isolate* isolate, Zone* zone, |
723 const byte* module_start, const byte* module_end, | 764 const byte* module_start, const byte* module_end, |
724 bool verify_functions, ModuleOrigin origin) { | 765 bool verify_functions, ModuleOrigin origin) { |
725 size_t decode_memory_start = zone->allocation_size(); | 766 size_t decode_memory_start = zone->allocation_size(); |
726 HistogramTimerScope wasm_decode_module_time_scope( | 767 HistogramTimerScope wasm_decode_module_time_scope( |
727 isolate->counters()->wasm_decode_module_time()); | 768 isolate->counters()->wasm_decode_module_time()); |
728 size_t size = module_end - module_start; | 769 size_t size = module_end - module_start; |
729 if (module_start > module_end) return ModuleError("start > end"); | 770 if (module_start > module_end) return ModuleError("start > end"); |
730 if (size >= kMaxModuleSize) return ModuleError("size > maximum module size"); | 771 if (size >= kMaxModuleSize) return ModuleError("size > maximum module size"); |
731 // TODO(bradnelson): Improve histogram handling of size_t. | 772 // TODO(bradnelson): Improve histogram handling of size_t. |
(...skipping 23 matching lines...) Expand all Loading... |
755 size_t size = function_end - function_start; | 796 size_t size = function_end - function_start; |
756 if (function_start > function_end) return FunctionError("start > end"); | 797 if (function_start > function_end) return FunctionError("start > end"); |
757 if (size > kMaxFunctionSize) | 798 if (size > kMaxFunctionSize) |
758 return FunctionError("size > maximum function size"); | 799 return FunctionError("size > maximum function size"); |
759 isolate->counters()->wasm_function_size_bytes()->AddSample( | 800 isolate->counters()->wasm_function_size_bytes()->AddSample( |
760 static_cast<int>(size)); | 801 static_cast<int>(size)); |
761 WasmFunction* function = new WasmFunction(); | 802 WasmFunction* function = new WasmFunction(); |
762 ModuleDecoder decoder(zone, function_start, function_end, kWasmOrigin); | 803 ModuleDecoder decoder(zone, function_start, function_end, kWasmOrigin); |
763 return decoder.DecodeSingleFunction(module_env, function); | 804 return decoder.DecodeSingleFunction(module_env, function); |
764 } | 805 } |
| 806 |
| 807 FunctionOffsetsResult DecodeWasmFunctionOffsets(const byte* module_start, |
| 808 const byte* module_end) { |
| 809 Vector<const byte> code_section = |
| 810 FindSection(module_start, module_end, WasmSection::Code::FunctionBodies); |
| 811 Decoder decoder(code_section.start(), code_section.end()); |
| 812 if (!code_section.start()) decoder.error("no code section"); |
| 813 |
| 814 int length; |
| 815 uint32_t functions_count = decoder.consume_u32v(&length, "functions count"); |
| 816 FunctionOffsets table; |
| 817 // Take care of invalid input here. |
| 818 if (functions_count < static_cast<unsigned>(code_section.length()) / 2) |
| 819 table.reserve(functions_count); |
| 820 int section_offset = static_cast<int>(code_section.start() - module_start); |
| 821 DCHECK_LE(0, section_offset); |
| 822 for (uint32_t i = 0; i < functions_count && decoder.ok(); i++) { |
| 823 uint32_t size = decoder.consume_u32v(&length, "body size"); |
| 824 int offset = static_cast<int>(section_offset + decoder.pc_offset()); |
| 825 table.push_back(std::make_pair(offset, static_cast<int>(size))); |
| 826 DCHECK(table.back().first >= 0 && table.back().second >= 0); |
| 827 decoder.consume_bytes(size); |
| 828 } |
| 829 if (decoder.more()) decoder.error("unexpected additional bytes"); |
| 830 |
| 831 return decoder.toResult(std::move(table)); |
| 832 } |
| 833 |
765 } // namespace wasm | 834 } // namespace wasm |
766 } // namespace internal | 835 } // namespace internal |
767 } // namespace v8 | 836 } // namespace v8 |
OLD | NEW |