WasmBinaryReader.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  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. namespace Wasm
  8. {
  9. // Language Types binary encoding with varint7
  10. namespace LanguageTypes
  11. {
  12. const int8 i32 = -0x1;
  13. const int8 i64 = -0x2;
  14. const int8 f32 = -0x3;
  15. const int8 f64 = -0x4;
  16. const int8 v128 = -0x5;
  17. const int8 anyfunc = -0x10;
  18. const int8 func = -0x20;
  19. const int8 emptyBlock = -0x40;
  20. WasmTypes::WasmType ToWasmType(int8);
  21. }
  22. struct SectionHeader
  23. {
  24. SectionCode code;
  25. const byte* start;
  26. const byte* end;
  27. uint32 nameLength;
  28. const char16* name;
  29. };
  30. struct BinaryLocation
  31. {
  32. intptr_t offset;
  33. intptr_t size;
  34. };
  35. static const uint32 binaryVersion = 0x1;
  36. class WasmBinaryReader : public WasmReaderBase
  37. {
  38. public:
  39. WasmBinaryReader(ArenaAllocator* alloc, Js::WebAssemblyModule* module, const byte* source, size_t length);
  40. void InitializeReader();
  41. SectionHeader ReadNextSection();
  42. // Fully read the section in the reader. Return true if the section fully read
  43. bool ProcessCurrentSection();
  44. virtual void SeekToFunctionBody(class WasmFunctionInfo* funcInfo) override;
  45. virtual bool IsCurrentFunctionCompleted() const override;
  46. WasmOp ReadPrefixedOpCode(WasmOp prefix, bool isSupported, const char16* notSupportedMsg);
  47. WasmOp ReadOpCode();
  48. virtual WasmOp ReadExpr() override;
  49. virtual void FunctionEnd() override;
  50. virtual uint32 EstimateCurrentFunctionBytecodeSize() const override;
  51. #if DBG_DUMP
  52. void PrintOps();
  53. #endif
  54. BinaryLocation GetCurrentLocation() const { return {m_pc - m_start, m_end - m_start}; }
  55. private:
  56. struct ReaderState
  57. {
  58. #if ENABLE_DEBUG_CONFIG_OPTIONS
  59. Js::FunctionBody* body = nullptr;
  60. #endif
  61. uint32 count; // current entry
  62. uint32 size; // binary size of the function
  63. };
  64. void BlockNode();
  65. void CallNode();
  66. void CallIndirectNode();
  67. void BrNode();
  68. void BrTableNode();
  69. void MemNode();
  70. void LaneNode();
  71. void ShuffleNode();
  72. void VarNode();
  73. // Module readers
  74. void ValidateModuleHeader();
  75. SectionHeader ReadSectionHeader();
  76. void ReadMemorySection(bool isImportSection);
  77. void ReadSignatureTypeSection();
  78. void ReadFunctionSignatures();
  79. void ReadFunctionHeaders();
  80. void ReadExportSection();
  81. void ReadTableSection(bool isImportSection);
  82. void ReadDataSection();
  83. void ReadImportSection();
  84. void ReadStartFunction();
  85. void ReadNameSection();
  86. void ReadElementSection();
  87. void ReadGlobalSection();
  88. void ReadCustomSection();
  89. // Primitive reader
  90. template <WasmTypes::WasmType type> void ConstNode();
  91. template <typename T> T ReadConst();
  92. ExternalKinds ReadExternalKind() { return (ExternalKinds)ReadConst<uint8>(); }
  93. bool ReadMutableValue();
  94. const char16* ReadInlineName(uint32& length, uint32& nameLength);
  95. template<typename LEBType = uint32, uint32 bits = sizeof(LEBType) * 8>
  96. LEBType LEB128(uint32 &length);
  97. template<typename LEBType = int32, uint32 bits = sizeof(LEBType) * 8>
  98. LEBType SLEB128(uint32 &length)
  99. {
  100. CompileAssert(LEBType(-1) < LEBType(0));
  101. return LEB128<LEBType, bits>(length);
  102. }
  103. WasmNode ReadInitExpr(bool isOffset = false);
  104. template<typename SectionLimitType>
  105. SectionLimitType ReadSectionLimitsBase(uint32 maxInitial, uint32 maxMaximum, const char16* errorMsg);
  106. void CheckBytesLeft(uint32 bytesNeeded);
  107. bool EndOfFunc();
  108. bool EndOfModule();
  109. DECLSPEC_NORETURN void ThrowDecodingError(const char16* msg, ...) const;
  110. Wasm::WasmTypes::WasmType ReadWasmType(uint32& length);
  111. ArenaAllocator* m_alloc;
  112. const byte* m_start, *m_end, *m_pc, *m_curFuncEnd;
  113. SectionHeader m_currentSection;
  114. ReaderState m_funcState; // func AST level
  115. private:
  116. enum
  117. {
  118. READER_STATE_UNKNOWN,
  119. READER_STATE_FUNCTION,
  120. READER_STATE_MODULE
  121. } m_readerState;
  122. Js::WebAssemblyModule* m_module;
  123. #if ENABLE_DEBUG_CONFIG_OPTIONS
  124. Js::FunctionBody* GetFunctionBody() const;
  125. #endif
  126. #if DBG_DUMP
  127. typedef JsUtil::BaseHashSet<WasmOp, ArenaAllocator, PowerOf2SizePolicy> OpSet;
  128. OpSet* m_ops;
  129. #endif
  130. }; // WasmBinaryReader
  131. } // namespace Wasm
  132. #endif // ENABLE_WASM