Instruction.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /*
  2. * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Forward.h>
  8. #include <LibJS/Bytecode/Block.h>
  9. #include <LibJS/Forward.h>
  10. #define ENUMERATE_BYTECODE_OPS(O) \
  11. O(Load) \
  12. O(LoadImmediate) \
  13. O(Store) \
  14. O(Add) \
  15. O(Sub) \
  16. O(Mul) \
  17. O(Div) \
  18. O(Mod) \
  19. O(Exp) \
  20. O(GreaterThan) \
  21. O(GreaterThanEquals) \
  22. O(LessThan) \
  23. O(LessThanEquals) \
  24. O(AbstractInequals) \
  25. O(AbstractEquals) \
  26. O(TypedInequals) \
  27. O(TypedEquals) \
  28. O(NewBigInt) \
  29. O(NewString) \
  30. O(NewObject) \
  31. O(GetVariable) \
  32. O(SetVariable) \
  33. O(PutById) \
  34. O(GetById) \
  35. O(Jump) \
  36. O(JumpIfFalse) \
  37. O(JumpIfTrue) \
  38. O(JumpIfNotNullish) \
  39. O(Call) \
  40. O(EnterScope) \
  41. O(Return) \
  42. O(BitwiseAnd) \
  43. O(BitwiseOr) \
  44. O(BitwiseXor) \
  45. O(BitwiseNot) \
  46. O(Not) \
  47. O(UnaryPlus) \
  48. O(UnaryMinus) \
  49. O(Typeof) \
  50. O(LeftShift) \
  51. O(RightShift) \
  52. O(UnsignedRightShift) \
  53. O(In) \
  54. O(InstanceOf) \
  55. O(ConcatString)
  56. namespace JS::Bytecode {
  57. class Instruction {
  58. public:
  59. enum class Type {
  60. #define __BYTECODE_OP(op) \
  61. op,
  62. ENUMERATE_BYTECODE_OPS(__BYTECODE_OP)
  63. #undef __BYTECODE_OP
  64. };
  65. Type type() const { return m_type; }
  66. size_t length() const;
  67. String to_string() const;
  68. void execute(Bytecode::Interpreter&) const;
  69. static void destroy(Instruction&);
  70. protected:
  71. explicit Instruction(Type type)
  72. : m_type(type)
  73. {
  74. }
  75. private:
  76. Type m_type {};
  77. };
  78. template<typename OpType>
  79. class InstructionHandle {
  80. public:
  81. InstructionHandle() = default;
  82. InstructionHandle(size_t offset, Block* block)
  83. : m_offset(offset)
  84. , m_block(block)
  85. {
  86. }
  87. OpType* operator->() const
  88. {
  89. VERIFY(m_block);
  90. return reinterpret_cast<OpType*>(m_block->buffer().data() + m_offset);
  91. }
  92. OpType& operator*() const
  93. {
  94. VERIFY(m_block);
  95. return *reinterpret_cast<OpType*>(m_block->buffer().data() + m_offset);
  96. }
  97. template<typename T>
  98. InstructionHandle<OpType>& operator=(InstructionHandle<T> const& other) requires(IsBaseOf<OpType, T>)
  99. {
  100. m_offset = other.offset();
  101. m_block = other.block();
  102. return *this;
  103. }
  104. size_t offset() const { return m_offset; }
  105. Block* block() const { return m_block; }
  106. private:
  107. friend class Block;
  108. size_t m_offset { 0 };
  109. Block* m_block { nullptr };
  110. };
  111. }