Instruction.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /*
  2. * Copyright (c) 2021-2024, Andreas Kling <andreas@ladybird.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Forward.h>
  8. #include <AK/Function.h>
  9. #include <AK/Span.h>
  10. #include <LibJS/Bytecode/Executable.h>
  11. #include <LibJS/Forward.h>
  12. #include <LibJS/SourceRange.h>
  13. #define ENUMERATE_BYTECODE_OPS(O) \
  14. O(Add) \
  15. O(AddPrivateName) \
  16. O(ArrayAppend) \
  17. O(AsyncIteratorClose) \
  18. O(Await) \
  19. O(BitwiseAnd) \
  20. O(BitwiseNot) \
  21. O(BitwiseOr) \
  22. O(BitwiseXor) \
  23. O(BlockDeclarationInstantiation) \
  24. O(Call) \
  25. O(CallBuiltin) \
  26. O(CallConstruct) \
  27. O(CallDirectEval) \
  28. O(CallWithArgumentArray) \
  29. O(Catch) \
  30. O(ConcatString) \
  31. O(ContinuePendingUnwind) \
  32. O(CopyObjectExcludingProperties) \
  33. O(CreateArguments) \
  34. O(CreateLexicalEnvironment) \
  35. O(CreatePrivateEnvironment) \
  36. O(CreateRestParams) \
  37. O(CreateVariable) \
  38. O(CreateVariableEnvironment) \
  39. O(Decrement) \
  40. O(DeleteById) \
  41. O(DeleteByIdWithThis) \
  42. O(DeleteByValue) \
  43. O(DeleteByValueWithThis) \
  44. O(DeleteVariable) \
  45. O(Div) \
  46. O(Dump) \
  47. O(End) \
  48. O(EnterObjectEnvironment) \
  49. O(EnterUnwindContext) \
  50. O(Exp) \
  51. O(GetArgument) \
  52. O(GetById) \
  53. O(GetByIdWithThis) \
  54. O(GetByValue) \
  55. O(GetByValueWithThis) \
  56. O(GetCalleeAndThisFromEnvironment) \
  57. O(GetGlobal) \
  58. O(GetImportMeta) \
  59. O(GetIterator) \
  60. O(GetLength) \
  61. O(GetLengthWithThis) \
  62. O(GetMethod) \
  63. O(GetNewTarget) \
  64. O(GetNextMethodFromIteratorRecord) \
  65. O(GetObjectFromIteratorRecord) \
  66. O(GetObjectPropertyIterator) \
  67. O(GetPrivateById) \
  68. O(GetBinding) \
  69. O(GreaterThan) \
  70. O(GreaterThanEquals) \
  71. O(HasPrivateId) \
  72. O(ImportCall) \
  73. O(In) \
  74. O(Increment) \
  75. O(InitializeLexicalBinding) \
  76. O(InitializeVariableBinding) \
  77. O(InstanceOf) \
  78. O(IteratorClose) \
  79. O(IteratorNext) \
  80. O(IteratorToArray) \
  81. O(Jump) \
  82. O(JumpFalse) \
  83. O(JumpGreaterThan) \
  84. O(JumpGreaterThanEquals) \
  85. O(JumpIf) \
  86. O(JumpLessThan) \
  87. O(JumpLessThanEquals) \
  88. O(JumpLooselyEquals) \
  89. O(JumpLooselyInequals) \
  90. O(JumpNullish) \
  91. O(JumpStrictlyEquals) \
  92. O(JumpStrictlyInequals) \
  93. O(JumpTrue) \
  94. O(JumpUndefined) \
  95. O(LeaveFinally) \
  96. O(LeaveLexicalEnvironment) \
  97. O(LeavePrivateEnvironment) \
  98. O(LeaveUnwindContext) \
  99. O(LeftShift) \
  100. O(LessThan) \
  101. O(LessThanEquals) \
  102. O(LooselyEquals) \
  103. O(LooselyInequals) \
  104. O(Mod) \
  105. O(Mov) \
  106. O(Mul) \
  107. O(NewArray) \
  108. O(NewClass) \
  109. O(NewFunction) \
  110. O(NewObject) \
  111. O(NewPrimitiveArray) \
  112. O(NewRegExp) \
  113. O(NewTypeError) \
  114. O(Not) \
  115. O(PrepareYield) \
  116. O(PostfixDecrement) \
  117. O(PostfixIncrement) \
  118. O(PutById) \
  119. O(PutByIdWithThis) \
  120. O(PutByValue) \
  121. O(PutByValueWithThis) \
  122. O(PutPrivateById) \
  123. O(ResolveSuperBase) \
  124. O(ResolveThisBinding) \
  125. O(RestoreScheduledJump) \
  126. O(Return) \
  127. O(RightShift) \
  128. O(ScheduleJump) \
  129. O(SetArgument) \
  130. O(SetLexicalBinding) \
  131. O(SetVariableBinding) \
  132. O(StrictlyEquals) \
  133. O(StrictlyInequals) \
  134. O(Sub) \
  135. O(SuperCallWithArgumentArray) \
  136. O(Throw) \
  137. O(ThrowIfNotObject) \
  138. O(ThrowIfNullish) \
  139. O(ThrowIfTDZ) \
  140. O(Typeof) \
  141. O(TypeofBinding) \
  142. O(UnaryMinus) \
  143. O(UnaryPlus) \
  144. O(UnsignedRightShift) \
  145. O(Yield)
  146. namespace JS::Bytecode {
  147. class alignas(void*) Instruction {
  148. public:
  149. constexpr static bool IsTerminator = false;
  150. static constexpr bool IsVariableLength = false;
  151. enum class Type {
  152. #define __BYTECODE_OP(op) \
  153. op,
  154. ENUMERATE_BYTECODE_OPS(__BYTECODE_OP)
  155. #undef __BYTECODE_OP
  156. };
  157. Type type() const { return m_type; }
  158. size_t length() const;
  159. ByteString to_byte_string(Bytecode::Executable const&) const;
  160. void visit_labels(Function<void(Label&)> visitor);
  161. void visit_operands(Function<void(Operand&)> visitor);
  162. static void destroy(Instruction&);
  163. protected:
  164. explicit Instruction(Type type)
  165. : m_type(type)
  166. {
  167. }
  168. void visit_labels_impl(Function<void(Label&)>) { }
  169. void visit_operands_impl(Function<void(Operand&)>) { }
  170. private:
  171. Type m_type {};
  172. };
  173. class InstructionStreamIterator {
  174. public:
  175. InstructionStreamIterator(ReadonlyBytes bytes, Executable const* executable = nullptr, size_t offset = 0)
  176. : m_begin(bytes.data())
  177. , m_end(bytes.data() + bytes.size())
  178. , m_ptr(bytes.data() + offset)
  179. , m_executable(executable)
  180. {
  181. }
  182. size_t offset() const { return m_ptr - m_begin; }
  183. bool at_end() const { return m_ptr >= m_end; }
  184. Instruction const& operator*() const { return dereference(); }
  185. ALWAYS_INLINE void operator++()
  186. {
  187. m_ptr += dereference().length();
  188. }
  189. UnrealizedSourceRange source_range() const;
  190. RefPtr<SourceCode> source_code() const;
  191. Executable const* executable() const { return m_executable; }
  192. private:
  193. Instruction const& dereference() const { return *reinterpret_cast<Instruction const*>(m_ptr); }
  194. u8 const* m_begin { nullptr };
  195. u8 const* m_end { nullptr };
  196. u8 const* m_ptr { nullptr };
  197. GCPtr<Executable const> m_executable;
  198. };
  199. }