ByteCodeReader.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft Corporation and contributors. 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. namespace Js
  7. {
  8. struct ByteCodeReader
  9. {
  10. static uint32 GetStartLocationOffset() { return offsetof(ByteCodeReader, m_startLocation); }
  11. static uint32 GetCurrentLocationOffset() { return offsetof(ByteCodeReader, m_currentLocation); }
  12. private:
  13. // TODO: (leish)(swb) this is not always stack allocated now
  14. // with ES6 Generator, this can be allocated with recycler
  15. // need to find a good way to set write barrier, or big refactor.
  16. const byte * m_startLocation;
  17. const byte * m_currentLocation;
  18. #if DBG
  19. const byte * m_endLocation;
  20. #endif
  21. public:
  22. void Create(FunctionBody* functionRead, uint startOffset = 0);
  23. void Create(FunctionBody* functionRead, uint startOffset, bool useOriginalByteCode);
  24. #if DBG
  25. void Create(const byte * byteCodeStart, uint startOffset, uint byteCodeLength);
  26. #else
  27. void Create(const byte * byteCodeStart, uint startOffset);
  28. #endif
  29. uint GetCurrentOffset() const;
  30. const byte * SetCurrentOffset(int byteOffset);
  31. const byte * SetCurrentRelativeOffset(const byte * ip, int byteOffset);
  32. template<typename LayoutType> inline const unaligned LayoutType * GetLayout();
  33. template<typename LayoutType> inline const unaligned LayoutType * GetLayout(const byte*& ip);
  34. // Read*Op advance the IP,
  35. // Peek*Op doesn't move the IP
  36. // *ByteOp only read one byte of the opcode,
  37. // *Op interprets and remove the large layout prefix
  38. private:
  39. OpCode ReadOp(const byte *&ip, LayoutSize& layoutSize) const;
  40. OpCode ReadPrefixedOp(const byte *&ip, LayoutSize& layoutSize, OpCode prefix) const;
  41. public:
  42. OpCode ReadOp(LayoutSize& layoutSize);
  43. OpCodeAsmJs ReadAsmJsOp(LayoutSize& layoutSize);
  44. OpCode ReadPrefixedOp(LayoutSize& layoutSize, OpCode prefix);
  45. OpCode PeekOp(LayoutSize& layoutSize) const;
  46. OpCode PeekOp() const { LayoutSize layoutSize; return PeekOp(layoutSize); }
  47. OpCode PeekOp(const byte * ip, LayoutSize& layoutSize);
  48. static OpCode PeekByteOp(const byte* ip);
  49. static OpCode ReadByteOp(const byte*& ip);
  50. static OpCode PeekExtOp(const byte* ip);
  51. static OpCode ReadExtOp(const byte*& ip);
  52. // Declare reading functions
  53. #define LAYOUT_TYPE(layout) \
  54. const unaligned OpLayout##layout* layout(); \
  55. const unaligned OpLayout##layout* layout(const byte*& ip);
  56. #include "LayoutTypes.h"
  57. #ifdef ASMJS_PLAT
  58. #define LAYOUT_TYPE(layout) \
  59. const unaligned OpLayout##layout* layout(); \
  60. const unaligned OpLayout##layout* layout(const byte*& ip);
  61. #define EXCLUDE_DUP_LAYOUT
  62. #include "LayoutTypesAsmJs.h"
  63. #endif
  64. template <typename T>
  65. static AuxArray<T> const * ReadAuxArray(uint offset, FunctionBody * functionBody);
  66. template <typename T>
  67. static AuxArray<T> const * ReadAuxArrayWithLock(uint offset, FunctionBody * functionBody);
  68. static PropertyIdArray const * ReadPropertyIdArray(uint offset, FunctionBody * functionBody);
  69. static PropertyIdArray const * ReadPropertyIdArrayWithLock(uint offset, FunctionBody * functionBody);
  70. static VarArrayVarCount const * ReadVarArrayVarCount(uint offset, FunctionBody * functionBody);
  71. static VarArrayVarCount const * ReadVarArrayVarCountWithLock(uint offset, FunctionBody * functionBody);
  72. const byte* GetIP();
  73. void SetIP(const byte *const ip);
  74. template<class T> const unaligned T* AuxiliaryContext(const byte*& ip, const byte ** content);
  75. #if DBG_DUMP
  76. byte GetRawByte(int i);
  77. #endif
  78. };
  79. template<typename LayoutType>
  80. inline const unaligned LayoutType * ByteCodeReader::GetLayout()
  81. {
  82. size_t layoutSize = sizeof(LayoutType);
  83. AssertMsg((layoutSize > 0) && (layoutSize < 100), "Ensure valid layout size");
  84. const byte * layoutData = m_currentLocation;
  85. m_currentLocation += layoutSize;
  86. Assert(m_currentLocation <= m_endLocation);
  87. return reinterpret_cast<const unaligned LayoutType *>(layoutData);
  88. }
  89. template<>
  90. inline const unaligned OpLayoutEmpty * ByteCodeReader::GetLayout<OpLayoutEmpty>()
  91. {
  92. return nullptr;
  93. }
  94. } // namespace Js