| 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/macro-assembler.h" | 5 #include "src/macro-assembler.h" |
| 6 #include "src/objects.h" | 6 #include "src/objects.h" |
| 7 #include "src/v8.h" | 7 #include "src/v8.h" |
| 8 | 8 |
| 9 #include "src/wasm/decoder.h" | 9 #include "src/wasm/decoder.h" |
| 10 #include "src/wasm/module-decoder.h" | 10 #include "src/wasm/module-decoder.h" |
| 11 | 11 |
| 12 namespace v8 { | 12 namespace v8 { |
| 13 namespace internal { | 13 namespace internal { |
| 14 namespace wasm { | 14 namespace wasm { |
| 15 | 15 |
| 16 #if DEBUG | 16 #if DEBUG |
| 17 #define TRACE(...) \ | 17 #define TRACE(...) \ |
| 18 do { \ | 18 do { \ |
| 19 if (FLAG_trace_wasm_decoder) PrintF(__VA_ARGS__); \ | 19 if (FLAG_trace_wasm_decoder) PrintF(__VA_ARGS__); \ |
| 20 } while (false) | 20 } while (false) |
| 21 #else | 21 #else |
| 22 #define TRACE(...) | 22 #define TRACE(...) |
| 23 #endif | 23 #endif |
| 24 | 24 |
| 25 | 25 |
| 26 // The main logic for decoding the bytes of a module. | 26 // The main logic for decoding the bytes of a module. |
| 27 class ModuleDecoder : public Decoder { | 27 class ModuleDecoder : public Decoder { |
| 28 public: | 28 public: |
| 29 ModuleDecoder(Zone* zone, const byte* module_start, const byte* module_end, | 29 ModuleDecoder(Zone* zone, const byte* module_start, const byte* module_end, |
| 30 bool asm_js) | 30 ModuleOrigin origin) |
| 31 : Decoder(module_start, module_end), module_zone(zone), asm_js_(asm_js) { | 31 : Decoder(module_start, module_end), module_zone(zone), origin_(origin) { |
| 32 result_.start = start_; | 32 result_.start = start_; |
| 33 if (limit_ < start_) { | 33 if (limit_ < start_) { |
| 34 error(start_, "end is less than start"); | 34 error(start_, "end is less than start"); |
| 35 limit_ = start_; | 35 limit_ = start_; |
| 36 } | 36 } |
| 37 } | 37 } |
| 38 | 38 |
| 39 virtual void onFirstError() { | 39 virtual void onFirstError() { |
| 40 pc_ = limit_; // On error, terminate section decoding loop. | 40 pc_ = limit_; // On error, terminate section decoding loop. |
| 41 } | 41 } |
| 42 | 42 |
| 43 // Decodes an entire module. | 43 // Decodes an entire module. |
| 44 ModuleResult DecodeModule(WasmModule* module, bool verify_functions = true) { | 44 ModuleResult DecodeModule(WasmModule* module, bool verify_functions = true) { |
| 45 pc_ = start_; | 45 pc_ = start_; |
| 46 module->module_start = start_; | 46 module->module_start = start_; |
| 47 module->module_end = limit_; | 47 module->module_end = limit_; |
| 48 module->min_mem_size_log2 = 0; | 48 module->min_mem_size_log2 = 0; |
| 49 module->max_mem_size_log2 = 0; | 49 module->max_mem_size_log2 = 0; |
| 50 module->mem_export = false; | 50 module->mem_export = false; |
| 51 module->mem_external = false; | 51 module->mem_external = false; |
| 52 module->origin = origin_; |
| 52 module->globals = new std::vector<WasmGlobal>(); | 53 module->globals = new std::vector<WasmGlobal>(); |
| 53 module->signatures = new std::vector<FunctionSig*>(); | 54 module->signatures = new std::vector<FunctionSig*>(); |
| 54 module->functions = new std::vector<WasmFunction>(); | 55 module->functions = new std::vector<WasmFunction>(); |
| 55 module->data_segments = new std::vector<WasmDataSegment>(); | 56 module->data_segments = new std::vector<WasmDataSegment>(); |
| 56 module->function_table = new std::vector<uint16_t>(); | 57 module->function_table = new std::vector<uint16_t>(); |
| 57 module->import_table = new std::vector<WasmImport>(); | 58 module->import_table = new std::vector<WasmImport>(); |
| 58 module->export_table = new std::vector<WasmExport>(); | 59 module->export_table = new std::vector<WasmExport>(); |
| 59 | 60 |
| 60 bool sections[kMaxModuleSectionCode]; | 61 bool sections[kMaxModuleSectionCode]; |
| 61 memset(sections, 0, sizeof(sections)); | 62 memset(sections, 0, sizeof(sections)); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 case kDeclFunctions: { | 99 case kDeclFunctions: { |
| 99 // Functions require a signature table first. | 100 // Functions require a signature table first. |
| 100 CheckForPreviousSection(sections, kDeclSignatures, true); | 101 CheckForPreviousSection(sections, kDeclSignatures, true); |
| 101 int length; | 102 int length; |
| 102 uint32_t functions_count = consume_u32v(&length, "functions count"); | 103 uint32_t functions_count = consume_u32v(&length, "functions count"); |
| 103 module->functions->reserve(SafeReserve(functions_count)); | 104 module->functions->reserve(SafeReserve(functions_count)); |
| 104 // Set up module environment for verification. | 105 // Set up module environment for verification. |
| 105 ModuleEnv menv; | 106 ModuleEnv menv; |
| 106 menv.module = module; | 107 menv.module = module; |
| 107 menv.instance = nullptr; | 108 menv.instance = nullptr; |
| 108 menv.asm_js = asm_js_; | 109 menv.origin = origin_; |
| 109 // Decode functions. | 110 // Decode functions. |
| 110 for (uint32_t i = 0; i < functions_count; i++) { | 111 for (uint32_t i = 0; i < functions_count; i++) { |
| 111 if (failed()) break; | 112 if (failed()) break; |
| 112 TRACE("DecodeFunction[%d] module+%d\n", i, | 113 TRACE("DecodeFunction[%d] module+%d\n", i, |
| 113 static_cast<int>(pc_ - start_)); | 114 static_cast<int>(pc_ - start_)); |
| 114 | 115 |
| 115 module->functions->push_back( | 116 module->functions->push_back( |
| 116 {nullptr, i, 0, 0, 0, 0, 0, 0, false, false}); | 117 {nullptr, i, 0, 0, 0, 0, 0, 0, false, false}); |
| 117 WasmFunction* function = &module->functions->back(); | 118 WasmFunction* function = &module->functions->back(); |
| 118 DecodeFunctionInModule(module, function, false); | 119 DecodeFunctionInModule(module, function, false); |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 353 // Decodes a single function signature at {start}. | 354 // Decodes a single function signature at {start}. |
| 354 FunctionSig* DecodeFunctionSignature(const byte* start) { | 355 FunctionSig* DecodeFunctionSignature(const byte* start) { |
| 355 pc_ = start; | 356 pc_ = start; |
| 356 FunctionSig* result = consume_sig(); | 357 FunctionSig* result = consume_sig(); |
| 357 return ok() ? result : nullptr; | 358 return ok() ? result : nullptr; |
| 358 } | 359 } |
| 359 | 360 |
| 360 private: | 361 private: |
| 361 Zone* module_zone; | 362 Zone* module_zone; |
| 362 ModuleResult result_; | 363 ModuleResult result_; |
| 363 bool asm_js_; | 364 ModuleOrigin origin_; |
| 364 | 365 |
| 365 uint32_t off(const byte* ptr) { return static_cast<uint32_t>(ptr - start_); } | 366 uint32_t off(const byte* ptr) { return static_cast<uint32_t>(ptr - start_); } |
| 366 | 367 |
| 367 // Decodes a single global entry inside a module starting at {pc_}. | 368 // Decodes a single global entry inside a module starting at {pc_}. |
| 368 void DecodeGlobalInModule(WasmGlobal* global) { | 369 void DecodeGlobalInModule(WasmGlobal* global) { |
| 369 global->name_offset = consume_string("global name"); | 370 global->name_offset = consume_string("global name"); |
| 370 global->type = mem_type(); | 371 global->type = mem_type(); |
| 371 global->offset = 0; | 372 global->offset = 0; |
| 372 global->exported = consume_u8("exported") != 0; | 373 global->exported = consume_u8("exported") != 0; |
| 373 } | 374 } |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 601 explicit FunctionError(const char* msg) { | 602 explicit FunctionError(const char* msg) { |
| 602 error_code = kError; | 603 error_code = kError; |
| 603 size_t len = strlen(msg) + 1; | 604 size_t len = strlen(msg) + 1; |
| 604 char* result = new char[len]; | 605 char* result = new char[len]; |
| 605 strncpy(result, msg, len); | 606 strncpy(result, msg, len); |
| 606 result[len - 1] = 0; | 607 result[len - 1] = 0; |
| 607 error_msg.Reset(result); | 608 error_msg.Reset(result); |
| 608 } | 609 } |
| 609 }; | 610 }; |
| 610 | 611 |
| 611 | |
| 612 ModuleResult DecodeWasmModule(Isolate* isolate, Zone* zone, | 612 ModuleResult DecodeWasmModule(Isolate* isolate, Zone* zone, |
| 613 const byte* module_start, const byte* module_end, | 613 const byte* module_start, const byte* module_end, |
| 614 bool verify_functions, bool asm_js) { | 614 bool verify_functions, ModuleOrigin origin) { |
| 615 size_t size = module_end - module_start; | 615 size_t size = module_end - module_start; |
| 616 if (module_start > module_end) return ModuleError("start > end"); | 616 if (module_start > module_end) return ModuleError("start > end"); |
| 617 if (size >= kMaxModuleSize) return ModuleError("size > maximum module size"); | 617 if (size >= kMaxModuleSize) return ModuleError("size > maximum module size"); |
| 618 WasmModule* module = new WasmModule(); | 618 WasmModule* module = new WasmModule(); |
| 619 ModuleDecoder decoder(zone, module_start, module_end, asm_js); | 619 ModuleDecoder decoder(zone, module_start, module_end, origin); |
| 620 return decoder.DecodeModule(module, verify_functions); | 620 return decoder.DecodeModule(module, verify_functions); |
| 621 } | 621 } |
| 622 | 622 |
| 623 | 623 |
| 624 FunctionSig* DecodeWasmSignatureForTesting(Zone* zone, const byte* start, | 624 FunctionSig* DecodeWasmSignatureForTesting(Zone* zone, const byte* start, |
| 625 const byte* end) { | 625 const byte* end) { |
| 626 ModuleDecoder decoder(zone, start, end, false); | 626 ModuleDecoder decoder(zone, start, end, kWasmOrigin); |
| 627 return decoder.DecodeFunctionSignature(start); | 627 return decoder.DecodeFunctionSignature(start); |
| 628 } | 628 } |
| 629 | 629 |
| 630 | 630 |
| 631 FunctionResult DecodeWasmFunction(Isolate* isolate, Zone* zone, | 631 FunctionResult DecodeWasmFunction(Isolate* isolate, Zone* zone, |
| 632 ModuleEnv* module_env, | 632 ModuleEnv* module_env, |
| 633 const byte* function_start, | 633 const byte* function_start, |
| 634 const byte* function_end) { | 634 const byte* function_end) { |
| 635 size_t size = function_end - function_start; | 635 size_t size = function_end - function_start; |
| 636 if (function_start > function_end) return FunctionError("start > end"); | 636 if (function_start > function_end) return FunctionError("start > end"); |
| 637 if (size > kMaxFunctionSize) | 637 if (size > kMaxFunctionSize) |
| 638 return FunctionError("size > maximum function size"); | 638 return FunctionError("size > maximum function size"); |
| 639 WasmFunction* function = new WasmFunction(); | 639 WasmFunction* function = new WasmFunction(); |
| 640 ModuleDecoder decoder(zone, function_start, function_end, false); | 640 ModuleDecoder decoder(zone, function_start, function_end, kWasmOrigin); |
| 641 return decoder.DecodeSingleFunction(module_env, function); | 641 return decoder.DecodeSingleFunction(module_env, function); |
| 642 } | 642 } |
| 643 } // namespace wasm | 643 } // namespace wasm |
| 644 } // namespace internal | 644 } // namespace internal |
| 645 } // namespace v8 | 645 } // namespace v8 |
| OLD | NEW |