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" |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 BYTES(kWasmVersion), BYTES(magic_version)); | 100 BYTES(kWasmVersion), BYTES(magic_version)); |
101 goto done; | 101 goto done; |
102 } | 102 } |
103 } | 103 } |
104 | 104 |
105 // Decode the module sections. | 105 // Decode the module sections. |
106 while (pc_ < limit_) { | 106 while (pc_ < limit_) { |
107 TRACE("DecodeSection\n"); | 107 TRACE("DecodeSection\n"); |
108 pos = pc_; | 108 pos = pc_; |
109 | 109 |
110 // Read and check the section size. | |
111 int section_leb_length = 0; | |
112 uint32_t section_length = | |
113 consume_u32v(§ion_leb_length, "section length"); | |
114 if (!checkAvailable(section_length)) { | |
115 // The section would extend beyond the end of the module. | |
116 break; | |
117 } | |
118 const byte* section_start = pc_; | |
119 const byte* expected_section_end = pc_ + section_length; | |
120 | |
121 // Read the section name. | 110 // Read the section name. |
122 int string_leb_length = 0; | 111 int string_leb_length = 0; |
123 uint32_t string_length = | 112 uint32_t string_length = |
124 consume_u32v(&string_leb_length, "section name length"); | 113 consume_u32v(&string_leb_length, "section name length"); |
125 const byte* section_name_start = pc_; | 114 const byte* section_name_start = pc_; |
126 consume_bytes(string_length); | 115 consume_bytes(string_length); |
127 if (failed()) { | 116 if (failed()) { |
128 TRACE("Section name of length %u couldn't be read\n", string_length); | 117 TRACE("Section name of length %u couldn't be read\n", string_length); |
129 break; | 118 break; |
130 } | 119 } |
131 if (pc_ > expected_section_end) { | |
132 error(section_name_start, pc_, | |
133 "section name string %u longer than total section bytes %u", | |
134 string_length, section_length); | |
135 } | |
136 | 120 |
137 WasmSection::Code section = | 121 WasmSection::Code section = |
138 WasmSection::lookup(section_name_start, string_length); | 122 WasmSection::lookup(section_name_start, string_length); |
139 | 123 |
| 124 // Read and check the section size. |
| 125 int section_leb_length = 0; |
| 126 uint32_t section_length = |
| 127 consume_u32v(§ion_leb_length, "section length"); |
| 128 if (!checkAvailable(section_length)) { |
| 129 // The section would extend beyond the end of the module. |
| 130 break; |
| 131 } |
| 132 const byte* section_start = pc_; |
| 133 const byte* expected_section_end = pc_ + section_length; |
| 134 |
140 current_order = CheckSectionOrder(current_order, section); | 135 current_order = CheckSectionOrder(current_order, section); |
141 | 136 |
142 switch (section) { | 137 switch (section) { |
143 case WasmSection::Code::End: | 138 case WasmSection::Code::End: |
144 // Terminate section decoding. | 139 // Terminate section decoding. |
145 limit_ = pc_; | 140 limit_ = pc_; |
146 break; | 141 break; |
147 case WasmSection::Code::Memory: | 142 case WasmSection::Code::Memory: { |
148 int length; | 143 int length; |
149 module->min_mem_pages = consume_u32v(&length, "min memory"); | 144 module->min_mem_pages = consume_u32v(&length, "min memory"); |
150 module->max_mem_pages = consume_u32v(&length, "max memory"); | 145 module->max_mem_pages = consume_u32v(&length, "max memory"); |
151 module->mem_export = consume_u8("export memory") != 0; | 146 module->mem_export = consume_u8("export memory") != 0; |
152 break; | 147 break; |
| 148 } |
153 case WasmSection::Code::Signatures: { | 149 case WasmSection::Code::Signatures: { |
154 int length; | 150 int length; |
155 uint32_t signatures_count = consume_u32v(&length, "signatures count"); | 151 uint32_t signatures_count = consume_u32v(&length, "signatures count"); |
156 module->signatures.reserve(SafeReserve(signatures_count)); | 152 module->signatures.reserve(SafeReserve(signatures_count)); |
157 // Decode signatures. | 153 // Decode signatures. |
158 for (uint32_t i = 0; i < signatures_count; i++) { | 154 for (uint32_t i = 0; i < signatures_count; i++) { |
159 if (failed()) break; | 155 if (failed()) break; |
160 TRACE("DecodeSignature[%d] module+%d\n", i, | 156 TRACE("DecodeSignature[%d] module+%d\n", i, |
161 static_cast<int>(pc_ - start_)); | 157 static_cast<int>(pc_ - start_)); |
162 FunctionSig* s = consume_sig(); // read function sig. | 158 FunctionSig* s = consume_sig(); |
163 module->signatures.push_back(s); | 159 module->signatures.push_back(s); |
164 } | 160 } |
165 break; | 161 break; |
166 } | 162 } |
167 case WasmSection::Code::FunctionSignatures: { | 163 case WasmSection::Code::FunctionSignatures: { |
168 int length; | 164 int length; |
169 uint32_t functions_count = consume_u32v(&length, "functions count"); | 165 uint32_t functions_count = consume_u32v(&length, "functions count"); |
170 module->functions.reserve(SafeReserve(functions_count)); | 166 module->functions.reserve(SafeReserve(functions_count)); |
171 for (uint32_t i = 0; i < functions_count; i++) { | 167 for (uint32_t i = 0; i < functions_count; i++) { |
172 module->functions.push_back( | 168 module->functions.push_back( |
(...skipping 22 matching lines...) Expand all Loading... |
195 | 191 |
196 TRACE(" +%d %-20s: (%d bytes)\n", pc_offset(), "function body", | 192 TRACE(" +%d %-20s: (%d bytes)\n", pc_offset(), "function body", |
197 size); | 193 size); |
198 pc_ += size; | 194 pc_ += size; |
199 if (pc_ > limit_) { | 195 if (pc_ > limit_) { |
200 error(pc_, "function body extends beyond end of file"); | 196 error(pc_, "function body extends beyond end of file"); |
201 } | 197 } |
202 } | 198 } |
203 break; | 199 break; |
204 } | 200 } |
205 case WasmSection::Code::Functions: { | 201 case WasmSection::Code::OldFunctions: { |
206 int length; | 202 int length; |
207 uint32_t functions_count = consume_u32v(&length, "functions count"); | 203 uint32_t functions_count = consume_u32v(&length, "functions count"); |
208 module->functions.reserve(SafeReserve(functions_count)); | 204 module->functions.reserve(SafeReserve(functions_count)); |
209 // Set up module environment for verification. | 205 // Set up module environment for verification. |
210 ModuleEnv menv; | 206 ModuleEnv menv; |
211 menv.module = module; | 207 menv.module = module; |
212 menv.instance = nullptr; | 208 menv.instance = nullptr; |
213 menv.origin = origin_; | 209 menv.origin = origin_; |
214 // Decode functions. | 210 // Decode functions. |
215 for (uint32_t i = 0; i < functions_count; i++) { | 211 for (uint32_t i = 0; i < functions_count; i++) { |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 } | 374 } |
379 break; | 375 break; |
380 } | 376 } |
381 case WasmSection::Code::Max: | 377 case WasmSection::Code::Max: |
382 // Skip unknown sections. | 378 // Skip unknown sections. |
383 TRACE("Unknown section: '"); | 379 TRACE("Unknown section: '"); |
384 for (uint32_t i = 0; i != string_length; ++i) { | 380 for (uint32_t i = 0; i != string_length; ++i) { |
385 TRACE("%c", *(section_name_start + i)); | 381 TRACE("%c", *(section_name_start + i)); |
386 } | 382 } |
387 TRACE("'\n"); | 383 TRACE("'\n"); |
388 consume_bytes(section_length - string_length - string_leb_length); | 384 consume_bytes(section_length); |
389 break; | 385 break; |
390 } | 386 } |
391 | 387 |
392 if (pc_ != expected_section_end) { | 388 if (pc_ != expected_section_end) { |
393 const char* diff = pc_ < expected_section_end ? "shorter" : "longer"; | 389 const char* diff = pc_ < expected_section_end ? "shorter" : "longer"; |
394 size_t expected_length = static_cast<size_t>(section_length); | 390 size_t expected_length = static_cast<size_t>(section_length); |
395 size_t actual_length = static_cast<size_t>(pc_ - section_start); | 391 size_t actual_length = static_cast<size_t>(pc_ - section_start); |
396 error(pc_, pc_, | 392 error(pc_, pc_, |
397 "section \"%s\" %s (%zu bytes) than specified (%zu bytes)", | 393 "section \"%s\" %s (%zu bytes) than specified (%zu bytes)", |
398 WasmSection::getName(section), diff, actual_length, | 394 WasmSection::getName(section), diff, actual_length, |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
693 case kMemF32: | 689 case kMemF32: |
694 return MachineType::Float32(); | 690 return MachineType::Float32(); |
695 case kMemF64: | 691 case kMemF64: |
696 return MachineType::Float64(); | 692 return MachineType::Float64(); |
697 default: | 693 default: |
698 error(pc_ - 1, "invalid memory type"); | 694 error(pc_ - 1, "invalid memory type"); |
699 return MachineType::None(); | 695 return MachineType::None(); |
700 } | 696 } |
701 } | 697 } |
702 | 698 |
703 // Parses an inline function signature. | 699 // Parses a type entry, which is currently limited to functions only. |
704 FunctionSig* consume_sig() { | 700 FunctionSig* consume_sig() { |
| 701 const byte* pos = pc_; |
| 702 byte form = consume_u8("type form"); |
| 703 if (form != kWasmFunctionTypeForm) { |
| 704 error(pos, pos, "expected function type form (0x%02x), got: 0x%02x", |
| 705 kWasmFunctionTypeForm, form); |
| 706 return nullptr; |
| 707 } |
705 int length; | 708 int length; |
706 byte count = consume_u32v(&length, "param count"); | 709 // parse parameter types |
707 LocalType ret = consume_local_type(); | 710 uint32_t param_count = consume_u32v(&length, "param count"); |
708 FunctionSig::Builder builder(module_zone, ret == kAstStmt ? 0 : 1, count); | 711 std::vector<LocalType> params; |
709 if (ret != kAstStmt) builder.AddReturn(ret); | 712 for (uint32_t i = 0; i < param_count; i++) { |
710 | |
711 for (int i = 0; i < count; i++) { | |
712 LocalType param = consume_local_type(); | 713 LocalType param = consume_local_type(); |
713 if (param == kAstStmt) error(pc_ - 1, "invalid void parameter type"); | 714 if (param == kAstStmt) error(pc_ - 1, "invalid void parameter type"); |
714 builder.AddParam(param); | 715 params.push_back(param); |
715 } | 716 } |
716 return builder.Build(); | 717 |
| 718 // parse return types |
| 719 const byte* pt = pc_; |
| 720 uint32_t return_count = consume_u32v(&length, "return count"); |
| 721 if (return_count > kMaxReturnCount) { |
| 722 error(pt, pt, "return count of %u exceeds maximum of %u", return_count, |
| 723 kMaxReturnCount); |
| 724 return nullptr; |
| 725 } |
| 726 std::vector<LocalType> returns; |
| 727 for (uint32_t i = 0; i < return_count; i++) { |
| 728 LocalType ret = consume_local_type(); |
| 729 if (ret == kAstStmt) error(pc_ - 1, "invalid void return type"); |
| 730 returns.push_back(ret); |
| 731 } |
| 732 |
| 733 // FunctionSig stores the return types first. |
| 734 LocalType* buffer = |
| 735 module_zone->NewArray<LocalType>(param_count + return_count); |
| 736 uint32_t b = 0; |
| 737 for (uint32_t i = 0; i < return_count; i++) buffer[b++] = returns[i]; |
| 738 for (uint32_t i = 0; i < param_count; i++) buffer[b++] = params[i]; |
| 739 |
| 740 return new (module_zone) FunctionSig(return_count, param_count, buffer); |
717 } | 741 } |
718 }; | 742 }; |
719 | 743 |
720 | 744 |
721 // Helpers for nice error messages. | 745 // Helpers for nice error messages. |
722 class ModuleError : public ModuleResult { | 746 class ModuleError : public ModuleResult { |
723 public: | 747 public: |
724 explicit ModuleError(const char* msg) { | 748 explicit ModuleError(const char* msg) { |
725 error_code = kError; | 749 error_code = kError; |
726 size_t len = strlen(msg) + 1; | 750 size_t len = strlen(msg) + 1; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
785 return FunctionError("size > maximum function size"); | 809 return FunctionError("size > maximum function size"); |
786 isolate->counters()->wasm_function_size_bytes()->AddSample( | 810 isolate->counters()->wasm_function_size_bytes()->AddSample( |
787 static_cast<int>(size)); | 811 static_cast<int>(size)); |
788 WasmFunction* function = new WasmFunction(); | 812 WasmFunction* function = new WasmFunction(); |
789 ModuleDecoder decoder(zone, function_start, function_end, kWasmOrigin); | 813 ModuleDecoder decoder(zone, function_start, function_end, kWasmOrigin); |
790 return decoder.DecodeSingleFunction(module_env, function); | 814 return decoder.DecodeSingleFunction(module_env, function); |
791 } | 815 } |
792 } // namespace wasm | 816 } // namespace wasm |
793 } // namespace internal | 817 } // namespace internal |
794 } // namespace v8 | 818 } // namespace v8 |
OLD | NEW |