| 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 #ifndef V8_WASM_MODULE_H_ | 5 #ifndef V8_WASM_MODULE_H_ |
| 6 #define V8_WASM_MODULE_H_ | 6 #define V8_WASM_MODULE_H_ |
| 7 | 7 |
| 8 #include <memory> | 8 #include <memory> |
| 9 | 9 |
| 10 #include "src/api.h" | 10 #include "src/api.h" |
| 11 #include "src/globals.h" | 11 #include "src/globals.h" |
| 12 #include "src/handles.h" | 12 #include "src/handles.h" |
| 13 #include "src/parsing/preparse-data.h" | 13 #include "src/parsing/preparse-data.h" |
| 14 | 14 |
| 15 #include "src/wasm/managed.h" | 15 #include "src/wasm/managed.h" |
| 16 #include "src/wasm/signature-map.h" | 16 #include "src/wasm/signature-map.h" |
| 17 #include "src/wasm/wasm-opcodes.h" | 17 #include "src/wasm/wasm-opcodes.h" |
| 18 | 18 |
| 19 namespace v8 { | 19 namespace v8 { |
| 20 namespace internal { | 20 namespace internal { |
| 21 | 21 |
| 22 class WasmCompiledModule; |
| 23 class WasmDebugInfo; |
| 24 class WasmModuleObject; |
| 25 |
| 22 namespace compiler { | 26 namespace compiler { |
| 23 class CallDescriptor; | 27 class CallDescriptor; |
| 24 class WasmCompilationUnit; | 28 class WasmCompilationUnit; |
| 25 } | 29 } |
| 26 | 30 |
| 27 namespace wasm { | 31 namespace wasm { |
| 28 class ErrorThrower; | 32 class ErrorThrower; |
| 29 | 33 |
| 30 const size_t kMaxModuleSize = 1024 * 1024 * 1024; | 34 const size_t kMaxModuleSize = 1024 * 1024 * 1024; |
| 31 const size_t kMaxFunctionSize = 128 * 1024; | 35 const size_t kMaxFunctionSize = 128 * 1024; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 51 kDataSectionCode = 11, // Data segments | 55 kDataSectionCode = 11, // Data segments |
| 52 kNameSectionCode = 12, // Name section (encoded as a string) | 56 kNameSectionCode = 12, // Name section (encoded as a string) |
| 53 }; | 57 }; |
| 54 | 58 |
| 55 inline bool IsValidSectionCode(uint8_t byte) { | 59 inline bool IsValidSectionCode(uint8_t byte) { |
| 56 return kTypeSectionCode <= byte && byte <= kDataSectionCode; | 60 return kTypeSectionCode <= byte && byte <= kDataSectionCode; |
| 57 } | 61 } |
| 58 | 62 |
| 59 const char* SectionName(WasmSectionCode code); | 63 const char* SectionName(WasmSectionCode code); |
| 60 | 64 |
| 61 class WasmDebugInfo; | |
| 62 | |
| 63 // Constants for fixed-size elements within a module. | 65 // Constants for fixed-size elements within a module. |
| 64 static const uint32_t kMaxReturnCount = 1; | 66 static const uint32_t kMaxReturnCount = 1; |
| 65 static const uint8_t kResizableMaximumFlag = 1; | 67 static const uint8_t kResizableMaximumFlag = 1; |
| 66 static const int32_t kInvalidFunctionIndex = -1; | 68 static const int32_t kInvalidFunctionIndex = -1; |
| 67 | 69 |
| 68 enum WasmExternalKind { | 70 enum WasmExternalKind { |
| 69 kExternalFunction = 0, | 71 kExternalFunction = 0, |
| 70 kExternalTable = 1, | 72 kExternalTable = 1, |
| 71 kExternalMemory = 2, | 73 kExternalMemory = 2, |
| 72 kExternalGlobal = 3 | 74 kExternalGlobal = 3 |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 // Static representation of a WASM export. | 165 // Static representation of a WASM export. |
| 164 struct WasmExport { | 166 struct WasmExport { |
| 165 uint32_t name_length; // length in bytes of the exported name. | 167 uint32_t name_length; // length in bytes of the exported name. |
| 166 uint32_t name_offset; // offset in module bytes of the name to export. | 168 uint32_t name_offset; // offset in module bytes of the name to export. |
| 167 WasmExternalKind kind; // kind of the export. | 169 WasmExternalKind kind; // kind of the export. |
| 168 uint32_t index; // index into the respective space. | 170 uint32_t index; // index into the respective space. |
| 169 }; | 171 }; |
| 170 | 172 |
| 171 enum ModuleOrigin { kWasmOrigin, kAsmJsOrigin }; | 173 enum ModuleOrigin { kWasmOrigin, kAsmJsOrigin }; |
| 172 | 174 |
| 173 class WasmCompiledModule; | |
| 174 | |
| 175 // Static representation of a module. | 175 // Static representation of a module. |
| 176 struct V8_EXPORT_PRIVATE WasmModule { | 176 struct V8_EXPORT_PRIVATE WasmModule { |
| 177 static const uint32_t kPageSize = 0x10000; // Page size, 64kb. | 177 static const uint32_t kPageSize = 0x10000; // Page size, 64kb. |
| 178 static const uint32_t kMinMemPages = 1; // Minimum memory size = 64kb | 178 static const uint32_t kMinMemPages = 1; // Minimum memory size = 64kb |
| 179 static const size_t kV8MaxPages = 16384; // Maximum memory size = 1gb | 179 static const size_t kV8MaxPages = 16384; // Maximum memory size = 1gb |
| 180 static const size_t kSpecMaxPages = 65536; // Maximum according to the spec | 180 static const size_t kSpecMaxPages = 65536; // Maximum according to the spec |
| 181 static const size_t kV8MaxTableSize = 16 * 1024 * 1024; | 181 static const size_t kV8MaxTableSize = 16 * 1024 * 1024; |
| 182 | 182 |
| 183 Zone* owned_zone; | 183 Zone* owned_zone; |
| 184 const byte* module_start = nullptr; // starting address for the module bytes | 184 const byte* module_start = nullptr; // starting address for the module bytes |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 const WasmFunction* function_; | 346 const WasmFunction* function_; |
| 347 const WasmModule* module_; | 347 const WasmModule* module_; |
| 348 WasmFunctionName(const WasmFunction* function, const ModuleEnv* menv) | 348 WasmFunctionName(const WasmFunction* function, const ModuleEnv* menv) |
| 349 : function_(function), module_(menv ? menv->module : nullptr) {} | 349 : function_(function), module_(menv ? menv->module : nullptr) {} |
| 350 }; | 350 }; |
| 351 | 351 |
| 352 std::ostream& operator<<(std::ostream& os, const WasmModule& module); | 352 std::ostream& operator<<(std::ostream& os, const WasmModule& module); |
| 353 std::ostream& operator<<(std::ostream& os, const WasmFunction& function); | 353 std::ostream& operator<<(std::ostream& os, const WasmFunction& function); |
| 354 std::ostream& operator<<(std::ostream& os, const WasmFunctionName& name); | 354 std::ostream& operator<<(std::ostream& os, const WasmFunctionName& name); |
| 355 | 355 |
| 356 class WasmCompiledModule : public FixedArray { | |
| 357 public: | |
| 358 static WasmCompiledModule* cast(Object* fixed_array) { | |
| 359 SLOW_DCHECK(IsWasmCompiledModule(fixed_array)); | |
| 360 return reinterpret_cast<WasmCompiledModule*>(fixed_array); | |
| 361 } | |
| 362 | |
| 363 #define WCM_OBJECT_OR_WEAK(TYPE, NAME, ID) \ | |
| 364 Handle<TYPE> NAME() const { return handle(ptr_to_##NAME()); } \ | |
| 365 \ | |
| 366 MaybeHandle<TYPE> maybe_##NAME() const { \ | |
| 367 if (has_##NAME()) return NAME(); \ | |
| 368 return MaybeHandle<TYPE>(); \ | |
| 369 } \ | |
| 370 \ | |
| 371 TYPE* ptr_to_##NAME() const { \ | |
| 372 Object* obj = get(ID); \ | |
| 373 if (!obj->Is##TYPE()) return nullptr; \ | |
| 374 return TYPE::cast(obj); \ | |
| 375 } \ | |
| 376 \ | |
| 377 void set_##NAME(Handle<TYPE> value) { set_ptr_to_##NAME(*value); } \ | |
| 378 \ | |
| 379 void set_ptr_to_##NAME(TYPE* value) { set(ID, value); } \ | |
| 380 \ | |
| 381 bool has_##NAME() const { return get(ID)->Is##TYPE(); } \ | |
| 382 \ | |
| 383 void reset_##NAME() { set_undefined(ID); } | |
| 384 | |
| 385 #define WCM_OBJECT(TYPE, NAME) WCM_OBJECT_OR_WEAK(TYPE, NAME, kID_##NAME) | |
| 386 | |
| 387 #define WCM_SMALL_NUMBER(TYPE, NAME) \ | |
| 388 TYPE NAME() const { \ | |
| 389 return static_cast<TYPE>(Smi::cast(get(kID_##NAME))->value()); \ | |
| 390 } \ | |
| 391 void set_##NAME(TYPE value) { set(kID_##NAME, Smi::FromInt(value)); } | |
| 392 | |
| 393 #define WCM_WEAK_LINK(TYPE, NAME) \ | |
| 394 WCM_OBJECT_OR_WEAK(WeakCell, weak_##NAME, kID_##NAME); \ | |
| 395 \ | |
| 396 Handle<TYPE> NAME() const { \ | |
| 397 return handle(TYPE::cast(weak_##NAME()->value())); \ | |
| 398 } | |
| 399 | |
| 400 #define CORE_WCM_PROPERTY_TABLE(MACRO) \ | |
| 401 MACRO(OBJECT, FixedArray, code_table) \ | |
| 402 MACRO(OBJECT, Foreign, module_wrapper) \ | |
| 403 MACRO(OBJECT, SeqOneByteString, module_bytes) \ | |
| 404 MACRO(OBJECT, Script, asm_js_script) \ | |
| 405 MACRO(OBJECT, FixedArray, function_tables) \ | |
| 406 MACRO(OBJECT, FixedArray, empty_function_tables) \ | |
| 407 MACRO(OBJECT, ByteArray, asm_js_offset_tables) \ | |
| 408 MACRO(OBJECT, JSArrayBuffer, memory) \ | |
| 409 MACRO(SMALL_NUMBER, uint32_t, min_mem_pages) \ | |
| 410 MACRO(SMALL_NUMBER, uint32_t, max_mem_pages) \ | |
| 411 MACRO(WEAK_LINK, WasmCompiledModule, next_instance) \ | |
| 412 MACRO(WEAK_LINK, WasmCompiledModule, prev_instance) \ | |
| 413 MACRO(WEAK_LINK, JSObject, owning_instance) \ | |
| 414 MACRO(WEAK_LINK, JSObject, wasm_module) | |
| 415 | |
| 416 #if DEBUG | |
| 417 #define DEBUG_ONLY_TABLE(MACRO) MACRO(SMALL_NUMBER, uint32_t, instance_id) | |
| 418 #else | |
| 419 #define DEBUG_ONLY_TABLE(IGNORE) | |
| 420 uint32_t instance_id() const { return -1; } | |
| 421 #endif | |
| 422 | |
| 423 #define WCM_PROPERTY_TABLE(MACRO) \ | |
| 424 CORE_WCM_PROPERTY_TABLE(MACRO) \ | |
| 425 DEBUG_ONLY_TABLE(MACRO) | |
| 426 | |
| 427 private: | |
| 428 enum PropertyIndices { | |
| 429 #define INDICES(IGNORE1, IGNORE2, NAME) kID_##NAME, | |
| 430 WCM_PROPERTY_TABLE(INDICES) Count | |
| 431 #undef INDICES | |
| 432 }; | |
| 433 | |
| 434 public: | |
| 435 static Handle<WasmCompiledModule> New( | |
| 436 Isolate* isolate, Handle<Managed<WasmModule>> module_wrapper); | |
| 437 | |
| 438 static Handle<WasmCompiledModule> Clone(Isolate* isolate, | |
| 439 Handle<WasmCompiledModule> module) { | |
| 440 Handle<WasmCompiledModule> ret = Handle<WasmCompiledModule>::cast( | |
| 441 isolate->factory()->CopyFixedArray(module)); | |
| 442 ret->InitId(); | |
| 443 ret->reset_weak_owning_instance(); | |
| 444 ret->reset_weak_next_instance(); | |
| 445 ret->reset_weak_prev_instance(); | |
| 446 return ret; | |
| 447 } | |
| 448 | |
| 449 uint32_t mem_size() const { | |
| 450 return has_memory() ? memory()->byte_length()->Number() | |
| 451 : default_mem_size(); | |
| 452 } | |
| 453 | |
| 454 uint32_t default_mem_size() const { | |
| 455 return min_mem_pages() * WasmModule::kPageSize; | |
| 456 } | |
| 457 | |
| 458 #define DECLARATION(KIND, TYPE, NAME) WCM_##KIND(TYPE, NAME) | |
| 459 WCM_PROPERTY_TABLE(DECLARATION) | |
| 460 #undef DECLARATION | |
| 461 | |
| 462 static bool IsWasmCompiledModule(Object* obj); | |
| 463 | |
| 464 void PrintInstancesChain(); | |
| 465 | |
| 466 static void RecreateModuleWrapper(Isolate* isolate, | |
| 467 Handle<FixedArray> compiled_module); | |
| 468 | |
| 469 private: | |
| 470 void InitId(); | |
| 471 | |
| 472 DISALLOW_IMPLICIT_CONSTRUCTORS(WasmCompiledModule); | |
| 473 }; | |
| 474 | |
| 475 // Extract a function name from the given wasm object. | 356 // Extract a function name from the given wasm object. |
| 476 // Returns "<WASM UNNAMED>" if the function is unnamed or the name is not a | 357 // Returns "<WASM UNNAMED>" if the function is unnamed or the name is not a |
| 477 // valid UTF-8 string. | 358 // valid UTF-8 string. |
| 478 Handle<String> GetWasmFunctionName(Isolate* isolate, Handle<Object> wasm, | 359 Handle<String> GetWasmFunctionName(Isolate* isolate, Handle<Object> wasm, |
| 479 uint32_t func_index); | 360 uint32_t func_index); |
| 480 | 361 |
| 481 // Extract a function name from the given wasm object. | 362 // Extract a function name from the given wasm object. |
| 482 // Returns a null handle if the function is unnamed or the name is not a valid | 363 // Returns a null handle if the function is unnamed or the name is not a valid |
| 483 // UTF-8 string. | 364 // UTF-8 string. |
| 484 Handle<Object> GetWasmFunctionNameOrNull(Isolate* isolate, Handle<Object> wasm, | 365 Handle<Object> GetWasmFunctionNameOrNull(Isolate* isolate, Handle<Object> wasm, |
| (...skipping 30 matching lines...) Expand all Loading... |
| 515 bool WasmIsAsmJs(Object* instance, Isolate* isolate); | 396 bool WasmIsAsmJs(Object* instance, Isolate* isolate); |
| 516 | 397 |
| 517 // Get the script for the asm.js origin of the wasm module. | 398 // Get the script for the asm.js origin of the wasm module. |
| 518 Handle<Script> GetAsmWasmScript(Handle<JSObject> instance); | 399 Handle<Script> GetAsmWasmScript(Handle<JSObject> instance); |
| 519 | 400 |
| 520 // Get the asm.js source position for the given byte offset in the given | 401 // Get the asm.js source position for the given byte offset in the given |
| 521 // function. | 402 // function. |
| 522 int GetAsmWasmSourcePosition(Handle<JSObject> instance, int func_index, | 403 int GetAsmWasmSourcePosition(Handle<JSObject> instance, int func_index, |
| 523 int byte_offset); | 404 int byte_offset); |
| 524 | 405 |
| 525 // Constructs a single function table as a FixedArray of double size, | 406 V8_EXPORT_PRIVATE MaybeHandle<WasmModuleObject> CreateModuleObjectFromBytes( |
| 526 // populating it with function signature indices and function indices. | |
| 527 Handle<FixedArray> BuildFunctionTable(Isolate* isolate, uint32_t index, | |
| 528 const WasmModule* module); | |
| 529 | |
| 530 // Populates a function table by replacing function indices with handles to | |
| 531 // the compiled code. | |
| 532 void PopulateFunctionTable(Handle<FixedArray> table, uint32_t table_size, | |
| 533 const std::vector<Handle<Code>>* code_table); | |
| 534 | |
| 535 Handle<JSObject> CreateWasmModuleObject( | |
| 536 Isolate* isolate, Handle<WasmCompiledModule> compiled_module, | |
| 537 ModuleOrigin origin); | |
| 538 | |
| 539 V8_EXPORT_PRIVATE MaybeHandle<JSObject> CreateModuleObjectFromBytes( | |
| 540 Isolate* isolate, const byte* start, const byte* end, ErrorThrower* thrower, | 407 Isolate* isolate, const byte* start, const byte* end, ErrorThrower* thrower, |
| 541 ModuleOrigin origin, Handle<Script> asm_js_script, | 408 ModuleOrigin origin, Handle<Script> asm_js_script, |
| 542 const byte* asm_offset_tables_start, const byte* asm_offset_tables_end); | 409 const byte* asm_offset_tables_start, const byte* asm_offset_tables_end); |
| 543 | 410 |
| 544 V8_EXPORT_PRIVATE bool ValidateModuleBytes(Isolate* isolate, const byte* start, | 411 V8_EXPORT_PRIVATE bool ValidateModuleBytes(Isolate* isolate, const byte* start, |
| 545 const byte* end, | 412 const byte* end, |
| 546 ErrorThrower* thrower, | 413 ErrorThrower* thrower, |
| 547 ModuleOrigin origin); | 414 ModuleOrigin origin); |
| 548 | 415 |
| 549 // Get the number of imported functions for a WASM instance. | 416 // Get the number of imported functions for a WASM instance. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 571 int instance_count); | 438 int instance_count); |
| 572 void ValidateModuleState(Isolate* isolate, Handle<JSObject> wasm_module); | 439 void ValidateModuleState(Isolate* isolate, Handle<JSObject> wasm_module); |
| 573 void ValidateOrphanedInstance(Isolate* isolate, Handle<JSObject> instance); | 440 void ValidateOrphanedInstance(Isolate* isolate, Handle<JSObject> instance); |
| 574 | 441 |
| 575 } // namespace testing | 442 } // namespace testing |
| 576 } // namespace wasm | 443 } // namespace wasm |
| 577 } // namespace internal | 444 } // namespace internal |
| 578 } // namespace v8 | 445 } // namespace v8 |
| 579 | 446 |
| 580 #endif // V8_WASM_MODULE_H_ | 447 #endif // V8_WASM_MODULE_H_ |
| OLD | NEW |