| 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 |