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/flags.h" | 9 #include "src/flags.h" |
10 #include "src/macro-assembler.h" | 10 #include "src/macro-assembler.h" |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 } | 173 } |
174 }; | 174 }; |
175 | 175 |
176 // The main logic for decoding the bytes of a module. | 176 // The main logic for decoding the bytes of a module. |
177 class ModuleDecoder : public Decoder { | 177 class ModuleDecoder : public Decoder { |
178 public: | 178 public: |
179 ModuleDecoder(Zone* zone, const byte* module_start, const byte* module_end, | 179 ModuleDecoder(Zone* zone, const byte* module_start, const byte* module_end, |
180 ModuleOrigin origin) | 180 ModuleOrigin origin) |
181 : Decoder(module_start, module_end), module_zone(zone), origin_(origin) { | 181 : Decoder(module_start, module_end), module_zone(zone), origin_(origin) { |
182 result_.start = start_; | 182 result_.start = start_; |
183 if (limit_ < start_) { | 183 if (end_ < start_) { |
184 error(start_, "end is less than start"); | 184 error(start_, "end is less than start"); |
185 limit_ = start_; | 185 end_ = start_; |
186 } | 186 } |
187 } | 187 } |
188 | 188 |
189 virtual void onFirstError() { | 189 virtual void onFirstError() { |
190 pc_ = limit_; // On error, terminate section decoding loop. | 190 pc_ = end_; // On error, terminate section decoding loop. |
191 } | 191 } |
192 | 192 |
193 void DumpModule(const ModuleResult& result) { | 193 void DumpModule(const ModuleResult& result) { |
194 std::string path; | 194 std::string path; |
195 if (FLAG_dump_wasm_module_path) { | 195 if (FLAG_dump_wasm_module_path) { |
196 path = FLAG_dump_wasm_module_path; | 196 path = FLAG_dump_wasm_module_path; |
197 if (path.size() && | 197 if (path.size() && |
198 !base::OS::isDirectorySeparator(path[path.size() - 1])) { | 198 !base::OS::isDirectorySeparator(path[path.size() - 1])) { |
199 path += base::OS::DirectorySeparator(); | 199 path += base::OS::DirectorySeparator(); |
200 } | 200 } |
201 } | 201 } |
202 // File are named `HASH.{ok,failed}.wasm`. | 202 // File are named `HASH.{ok,failed}.wasm`. |
203 size_t hash = base::hash_range(start_, limit_); | 203 size_t hash = base::hash_range(start_, end_); |
204 char buf[32] = {'\0'}; | 204 char buf[32] = {'\0'}; |
205 #if V8_OS_WIN && _MSC_VER < 1900 | 205 #if V8_OS_WIN && _MSC_VER < 1900 |
206 #define snprintf sprintf_s | 206 #define snprintf sprintf_s |
207 #endif | 207 #endif |
208 snprintf(buf, sizeof(buf) - 1, "%016zx.%s.wasm", hash, | 208 snprintf(buf, sizeof(buf) - 1, "%016zx.%s.wasm", hash, |
209 result.ok() ? "ok" : "failed"); | 209 result.ok() ? "ok" : "failed"); |
210 std::string name(buf); | 210 std::string name(buf); |
211 if (FILE* wasm_file = base::OS::FOpen((path + name).c_str(), "wb")) { | 211 if (FILE* wasm_file = base::OS::FOpen((path + name).c_str(), "wb")) { |
212 fwrite(start_, limit_ - start_, 1, wasm_file); | 212 fwrite(start_, end_ - start_, 1, wasm_file); |
213 fclose(wasm_file); | 213 fclose(wasm_file); |
214 } | 214 } |
215 } | 215 } |
216 | 216 |
217 // Decodes an entire module. | 217 // Decodes an entire module. |
218 ModuleResult DecodeModule(bool verify_functions = true) { | 218 ModuleResult DecodeModule(bool verify_functions = true) { |
219 pc_ = start_; | 219 pc_ = start_; |
220 WasmModule* module = new WasmModule(module_zone); | 220 WasmModule* module = new WasmModule(module_zone); |
221 module->min_mem_pages = 0; | 221 module->min_mem_pages = 0; |
222 module->max_mem_pages = 0; | 222 module->max_mem_pages = 0; |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
565 functions_count, module->num_declared_functions); | 565 functions_count, module->num_declared_functions); |
566 } | 566 } |
567 for (uint32_t i = 0; ok() && i < functions_count; ++i) { | 567 for (uint32_t i = 0; ok() && i < functions_count; ++i) { |
568 WasmFunction* function = | 568 WasmFunction* function = |
569 &module->functions[i + module->num_imported_functions]; | 569 &module->functions[i + module->num_imported_functions]; |
570 uint32_t size = consume_u32v("body size"); | 570 uint32_t size = consume_u32v("body size"); |
571 function->code_start_offset = pc_offset(); | 571 function->code_start_offset = pc_offset(); |
572 function->code_end_offset = pc_offset() + size; | 572 function->code_end_offset = pc_offset() + size; |
573 if (verify_functions) { | 573 if (verify_functions) { |
574 ModuleBytesEnv module_env(module, nullptr, | 574 ModuleBytesEnv module_env(module, nullptr, |
575 ModuleWireBytes(start_, limit_)); | 575 ModuleWireBytes(start_, end_)); |
576 VerifyFunctionBody(i + module->num_imported_functions, &module_env, | 576 VerifyFunctionBody(i + module->num_imported_functions, &module_env, |
577 function); | 577 function); |
578 } | 578 } |
579 consume_bytes(size, "function body"); | 579 consume_bytes(size, "function body"); |
580 } | 580 } |
581 section_iter.advance(); | 581 section_iter.advance(); |
582 } | 582 } |
583 | 583 |
584 // ===== Data section ==================================================== | 584 // ===== Data section ==================================================== |
585 if (section_iter.section_code() == kDataSectionCode) { | 585 if (section_iter.section_code() == kDataSectionCode) { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
644 } | 644 } |
645 | 645 |
646 // Decodes a single anonymous function starting at {start_}. | 646 // Decodes a single anonymous function starting at {start_}. |
647 FunctionResult DecodeSingleFunction(ModuleBytesEnv* module_env, | 647 FunctionResult DecodeSingleFunction(ModuleBytesEnv* module_env, |
648 WasmFunction* function) { | 648 WasmFunction* function) { |
649 pc_ = start_; | 649 pc_ = start_; |
650 function->sig = consume_sig(); // read signature | 650 function->sig = consume_sig(); // read signature |
651 function->name_offset = 0; // ---- name | 651 function->name_offset = 0; // ---- name |
652 function->name_length = 0; // ---- name length | 652 function->name_length = 0; // ---- name length |
653 function->code_start_offset = off(pc_); // ---- code start | 653 function->code_start_offset = off(pc_); // ---- code start |
654 function->code_end_offset = off(limit_); // ---- code end | 654 function->code_end_offset = off(end_); // ---- code end |
655 | 655 |
656 if (ok()) VerifyFunctionBody(0, module_env, function); | 656 if (ok()) VerifyFunctionBody(0, module_env, function); |
657 | 657 |
658 FunctionResult result; | 658 FunctionResult result; |
659 result.MoveFrom(result_); // Copy error code and location. | 659 result.MoveFrom(result_); // Copy error code and location. |
660 result.val = function; | 660 result.val = function; |
661 return result; | 661 return result; |
662 } | 662 } |
663 | 663 |
664 // Decodes a single function signature at {start}. | 664 // Decodes a single function signature at {start}. |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
722 | 722 |
723 // Decodes a single data segment entry inside a module starting at {pc_}. | 723 // Decodes a single data segment entry inside a module starting at {pc_}. |
724 void DecodeDataSegmentInModule(WasmModule* module, WasmDataSegment* segment) { | 724 void DecodeDataSegmentInModule(WasmModule* module, WasmDataSegment* segment) { |
725 const byte* start = pc_; | 725 const byte* start = pc_; |
726 expect_u8("linear memory index", 0); | 726 expect_u8("linear memory index", 0); |
727 segment->dest_addr = consume_init_expr(module, kWasmI32); | 727 segment->dest_addr = consume_init_expr(module, kWasmI32); |
728 segment->source_size = consume_u32v("source size"); | 728 segment->source_size = consume_u32v("source size"); |
729 segment->source_offset = static_cast<uint32_t>(pc_ - start_); | 729 segment->source_offset = static_cast<uint32_t>(pc_ - start_); |
730 | 730 |
731 // Validate the data is in the module. | 731 // Validate the data is in the module. |
732 uint32_t module_limit = static_cast<uint32_t>(limit_ - start_); | 732 uint32_t module_limit = static_cast<uint32_t>(end_ - start_); |
733 if (!IsWithinLimit(module_limit, segment->source_offset, | 733 if (!IsWithinLimit(module_limit, segment->source_offset, |
734 segment->source_size)) { | 734 segment->source_size)) { |
735 error(start, "segment out of bounds of module"); | 735 error(start, "segment out of bounds of module"); |
736 } | 736 } |
737 | 737 |
738 consume_bytes(segment->source_size, "segment data"); | 738 consume_bytes(segment->source_size, "segment data"); |
739 } | 739 } |
740 | 740 |
741 // Calculate individual global offsets and total size of globals table. | 741 // Calculate individual global offsets and total size of globals table. |
742 void CalculateGlobalOffsets(WasmModule* module) { | 742 void CalculateGlobalOffsets(WasmModule* module) { |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1223 table.push_back(std::move(func_asm_offsets)); | 1223 table.push_back(std::move(func_asm_offsets)); |
1224 } | 1224 } |
1225 if (decoder.more()) decoder.error("unexpected additional bytes"); | 1225 if (decoder.more()) decoder.error("unexpected additional bytes"); |
1226 | 1226 |
1227 return decoder.toResult(std::move(table)); | 1227 return decoder.toResult(std::move(table)); |
1228 } | 1228 } |
1229 | 1229 |
1230 } // namespace wasm | 1230 } // namespace wasm |
1231 } // namespace internal | 1231 } // namespace internal |
1232 } // namespace v8 | 1232 } // namespace v8 |
OLD | NEW |