WebAssemblyModule.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #pragma once
  6. #ifdef ENABLE_WASM
  7. #include "../WasmReader/WasmParseTree.h"
  8. namespace Wasm
  9. {
  10. class WasmSignature;
  11. class WasmFunctionInfo;
  12. class WasmBinaryReader;
  13. class WasmDataSegment;
  14. class WasmElementSegment;
  15. class WasmGlobal;
  16. class WasmCompilationException;
  17. struct WasmImport;
  18. struct WasmExport;
  19. struct CustomSection;
  20. struct MemorySectionLimits;
  21. struct TableSectionLimits;
  22. }
  23. namespace Js
  24. {
  25. typedef HeapAllocator::AutoFreeArray<char16> AutoFreeExceptionMessage;
  26. class WebAssemblyModule : public DynamicObject
  27. {
  28. protected:
  29. DEFINE_VTABLE_CTOR(WebAssemblyModule, DynamicObject);
  30. DEFINE_MARSHAL_OBJECT_TO_SCRIPT_CONTEXT(WebAssemblyModule);
  31. public:
  32. class EntryInfo
  33. {
  34. public:
  35. static FunctionInfo NewInstance;
  36. static FunctionInfo Exports;
  37. static FunctionInfo Imports;
  38. static FunctionInfo CustomSections;
  39. };
  40. static Var NewInstance(RecyclableObject* function, CallInfo callInfo, ...);
  41. static Var EntryExports(RecyclableObject* function, CallInfo callInfo, ...);
  42. static Var EntryImports(RecyclableObject* function, CallInfo callInfo, ...);
  43. static Var EntryCustomSections(RecyclableObject* function, CallInfo callInfo, ...);
  44. static WebAssemblyModule * CreateModule(
  45. ScriptContext* scriptContext,
  46. class WebAssemblySource* src);
  47. static bool ValidateModule(
  48. ScriptContext* scriptContext,
  49. class WebAssemblySource* src);
  50. public:
  51. WebAssemblyModule(Js::ScriptContext* scriptContext, const byte* binaryBuffer, uint binaryBufferLength, DynamicType * type);
  52. const byte* GetBinaryBuffer() const { return m_binaryBuffer; }
  53. uint GetBinaryBufferLength() const { return m_binaryBufferLength; }
  54. // The index used by those methods is the function index as describe by the WebAssembly design, ie: imports first then wasm functions
  55. uint32 GetMaxFunctionIndex() const;
  56. Wasm::FunctionIndexTypes::Type GetFunctionIndexType(uint32 funcIndex) const;
  57. void InitializeMemory(_In_ Wasm::MemorySectionLimits* memoryLimits);
  58. WebAssemblyMemory * CreateMemory() const;
  59. bool HasMemory() const { return m_hasMemory; }
  60. bool HasMemoryImport() const { return m_memImport != nullptr; }
  61. bool IsSharedMemory() const { return m_memoryIsShared; }
  62. uint32 GetMemoryInitSize() const { return m_memoryInitSize; }
  63. uint32 GetMemoryMaxSize() const { return m_memoryMaxSize; }
  64. Wasm::WasmSignature * GetSignatures() const;
  65. bool IsSignatureIndexValid(uint32 index) const;
  66. Wasm::WasmSignature* GetSignature(uint32 index) const;
  67. void SetSignatureCount(uint32 count);
  68. uint32 GetSignatureCount() const;
  69. uint32 GetEquivalentSignatureId(uint32 sigId) const;
  70. void InitializeTable(_In_ Wasm::TableSectionLimits* tableLimits);
  71. WebAssemblyTable * CreateTable() const;
  72. bool HasTable() const { return m_hasTable; }
  73. bool HasTableImport() const { return m_tableImport != nullptr; }
  74. uint32 GetTableInitSize() const { return m_tableInitSize; }
  75. uint32 GetTableMaxSize() const { return m_tableMaxSize; }
  76. uint GetWasmFunctionCount() const;
  77. Wasm::WasmFunctionInfo* AddWasmFunctionInfo(Wasm::WasmSignature* funsig);
  78. Wasm::WasmFunctionInfo* GetWasmFunctionInfo(uint index) const;
  79. void SwapWasmFunctionInfo(uint i1, uint i2);
  80. #if ENABLE_DEBUG_CONFIG_OPTIONS
  81. void AttachCustomInOutTracingReader(Wasm::WasmFunctionInfo* func, uint callIndex);
  82. #endif
  83. void AllocateFunctionExports(uint32 entries);
  84. uint GetExportCount() const { return m_exportCount; }
  85. void SetExport(uint32 iExport, uint32 funcIndex, const char16* exportName, uint32 nameLength, Wasm::ExternalKinds kind);
  86. Wasm::WasmExport* GetExport(uint32 iExport) const;
  87. uint32 GetImportCount() const;
  88. Wasm::WasmImport* GetImport(uint32 i) const;
  89. void AddFunctionImport(uint32 sigId, const char16* modName, uint32 modNameLen, const char16* fnName, uint32 fnNameLen);
  90. void AddGlobalImport(const char16* modName, uint32 modNameLen, const char16* importName, uint32 importNameLen);
  91. void AddMemoryImport(const char16* modName, uint32 modNameLen, const char16* importName, uint32 importNameLen);
  92. void AddTableImport(const char16* modName, uint32 modNameLen, const char16* importName, uint32 importNameLen);
  93. uint32 GetImportedFunctionCount() const { return m_importedFunctionCount; }
  94. uint GetOffsetFromInit(const Wasm::WasmNode& initExpr, const class WebAssemblyEnvironment* env) const;
  95. void ValidateInitExportForOffset(const Wasm::WasmNode& initExpr) const;
  96. void AddGlobal(Wasm::GlobalReferenceTypes::Type refType, Wasm::WasmTypes::WasmType type, bool isMutable, Wasm::WasmNode init);
  97. uint32 GetGlobalCount() const;
  98. Wasm::WasmGlobal* GetGlobal(uint32 index) const;
  99. void AllocateDataSegs(uint32 count);
  100. void SetDataSeg(Wasm::WasmDataSegment* seg, uint32 index);
  101. Wasm::WasmDataSegment* GetDataSeg(uint32 index) const;
  102. uint32 GetDataSegCount() const { return m_datasegCount; }
  103. void AllocateElementSegs(uint32 count);
  104. void SetElementSeg(Wasm::WasmElementSegment* seg, uint32 index);
  105. Wasm::WasmElementSegment* GetElementSeg(uint32 index) const;
  106. uint32 GetElementSegCount() const { return m_elementsegCount; }
  107. void SetStartFunction(uint32 i);
  108. uint32 GetStartFunction() const;
  109. uint32 GetModuleEnvironmentSize() const;
  110. // elements at known offsets
  111. static uint GetMemoryOffset() { return 0; }
  112. static uint GetImportFuncOffset() { return GetMemoryOffset() + 1; }
  113. // elements at instance dependent offsets
  114. uint GetFuncOffset() const { return GetImportFuncOffset() + GetImportedFunctionCount(); }
  115. uint GetTableEnvironmentOffset() const { return GetFuncOffset() + GetWasmFunctionCount(); }
  116. uint GetGlobalOffset() const { return GetTableEnvironmentOffset() + 1; }
  117. uint GetOffsetForGlobal(Wasm::WasmGlobal* global) const;
  118. uint AddGlobalByteSizeToOffset(Wasm::WasmTypes::WasmType type, uint32 offset) const;
  119. uint GetGlobalsByteSize() const;
  120. void AddCustomSection(Wasm::CustomSection customSection);
  121. uint32 GetCustomSectionCount() const;
  122. Wasm::CustomSection GetCustomSection(uint32 index) const;
  123. Wasm::WasmBinaryReader* GetReader() const { return m_reader; }
  124. static char16* FormatExceptionMessage(Wasm::WasmCompilationException* ex, AutoFreeExceptionMessage* autoClean, WebAssemblyModule* wasmModule = nullptr, FunctionBody* body = nullptr);
  125. virtual void Finalize(bool isShutdown) override;
  126. virtual void Dispose(bool isShutdown) override;
  127. virtual void Mark(Recycler * recycler) override;
  128. private:
  129. static JavascriptString * GetExternalKindString(ScriptContext * scriptContext, Wasm::ExternalKinds kind);
  130. Field(bool) m_hasTable : 1;
  131. Field(bool) m_hasMemory : 1;
  132. Field(bool) m_memoryIsShared : 1;
  133. // The binary buffer is recycler allocated, tied the lifetime of the buffer to the module
  134. Field(const byte*) m_binaryBuffer;
  135. Field(uint) m_binaryBufferLength;
  136. Field(uint32) m_memoryInitSize;
  137. Field(uint32) m_memoryMaxSize;
  138. Field(uint32) m_tableInitSize;
  139. Field(uint32) m_tableMaxSize;
  140. Field(Wasm::WasmSignature*) m_signatures;
  141. Field(uint32*) m_indirectfuncs;
  142. Field(Wasm::WasmElementSegment**) m_elementsegs;
  143. typedef JsUtil::List<Wasm::WasmFunctionInfo*, Recycler> WasmFunctionInfosList;
  144. Field(WasmFunctionInfosList*) m_functionsInfo;
  145. Field(Wasm::WasmExport*) m_exports;
  146. typedef JsUtil::List<Wasm::WasmImport*, ArenaAllocator> WasmImportsList;
  147. Field(WasmImportsList*) m_imports;
  148. Field(Wasm::WasmImport*) m_memImport;
  149. Field(Wasm::WasmImport*) m_tableImport;
  150. Field(uint32) m_importedFunctionCount;
  151. Field(Wasm::WasmDataSegment**) m_datasegs;
  152. Field(Wasm::WasmBinaryReader*) m_reader;
  153. Field(uint32*) m_equivalentSignatureMap;
  154. typedef JsUtil::List<Wasm::CustomSection, ArenaAllocator> CustomSectionsList;
  155. Field(CustomSectionsList*) m_customSections;
  156. Field(uint) m_globalCounts[Wasm::WasmTypes::Limit];
  157. typedef JsUtil::List<Wasm::WasmGlobal*, ArenaAllocator> WasmGlobalsList;
  158. Field(WasmGlobalsList *) m_globals;
  159. Field(uint) m_signaturesCount;
  160. Field(uint) m_exportCount;
  161. Field(uint32) m_datasegCount;
  162. Field(uint32) m_elementsegCount;
  163. Field(uint32) m_startFuncIndex;
  164. FieldNoBarrier(ArenaAllocator*) m_alloc;
  165. };
  166. template <> inline bool VarIsImpl<WebAssemblyModule>(RecyclableObject* obj)
  167. {
  168. return JavascriptOperators::GetTypeId(obj) == TypeIds_WebAssemblyModule;
  169. }
  170. } // namespace Js
  171. #endif