Op.h 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. /*
  2. * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
  3. * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #pragma once
  8. #include <AK/FlyString.h>
  9. #include <LibCrypto/BigInt/SignedBigInteger.h>
  10. #include <LibJS/Bytecode/Instruction.h>
  11. #include <LibJS/Bytecode/Label.h>
  12. #include <LibJS/Bytecode/Register.h>
  13. #include <LibJS/Heap/Cell.h>
  14. #include <LibJS/Runtime/Value.h>
  15. namespace JS::Bytecode::Op {
  16. class Load final : public Instruction {
  17. public:
  18. Load(Register src)
  19. : Instruction(Type::Load)
  20. , m_src(src)
  21. {
  22. }
  23. void execute(Bytecode::Interpreter&) const;
  24. String to_string() const;
  25. private:
  26. Register m_src;
  27. };
  28. class LoadImmediate final : public Instruction {
  29. public:
  30. LoadImmediate(Value value)
  31. : Instruction(Type::LoadImmediate)
  32. , m_value(value)
  33. {
  34. }
  35. void execute(Bytecode::Interpreter&) const;
  36. String to_string() const;
  37. private:
  38. Value m_value;
  39. };
  40. class Store final : public Instruction {
  41. public:
  42. Store(Register dst)
  43. : Instruction(Type::Store)
  44. , m_dst(dst)
  45. {
  46. }
  47. void execute(Bytecode::Interpreter&) const;
  48. String to_string() const;
  49. private:
  50. Register m_dst;
  51. };
  52. #define JS_ENUMERATE_COMMON_BINARY_OPS(O) \
  53. O(Add, add) \
  54. O(Sub, sub) \
  55. O(Mul, mul) \
  56. O(Div, div) \
  57. O(Exp, exp) \
  58. O(Mod, mod) \
  59. O(In, in) \
  60. O(InstanceOf, instance_of) \
  61. O(GreaterThan, greater_than) \
  62. O(GreaterThanEquals, greater_than_equals) \
  63. O(LessThan, less_than) \
  64. O(LessThanEquals, less_than_equals) \
  65. O(AbstractInequals, abstract_inequals) \
  66. O(AbstractEquals, abstract_equals) \
  67. O(TypedInequals, typed_inequals) \
  68. O(TypedEquals, typed_equals) \
  69. O(BitwiseAnd, bitwise_and) \
  70. O(BitwiseOr, bitwise_or) \
  71. O(BitwiseXor, bitwise_xor) \
  72. O(LeftShift, left_shift) \
  73. O(RightShift, right_shift) \
  74. O(UnsignedRightShift, unsigned_right_shift)
  75. #define JS_DECLARE_COMMON_BINARY_OP(OpTitleCase, op_snake_case) \
  76. class OpTitleCase final : public Instruction { \
  77. public: \
  78. OpTitleCase(Register lhs_reg) \
  79. : Instruction(Type::OpTitleCase) \
  80. , m_lhs_reg(lhs_reg) \
  81. { \
  82. } \
  83. \
  84. void execute(Bytecode::Interpreter&) const; \
  85. String to_string() const; \
  86. \
  87. private: \
  88. Register m_lhs_reg; \
  89. };
  90. JS_ENUMERATE_COMMON_BINARY_OPS(JS_DECLARE_COMMON_BINARY_OP)
  91. #undef JS_DECLARE_COMMON_BINARY_OP
  92. #define JS_ENUMERATE_COMMON_UNARY_OPS(O) \
  93. O(BitwiseNot, bitwise_not) \
  94. O(Not, not_) \
  95. O(UnaryPlus, unary_plus) \
  96. O(UnaryMinus, unary_minus) \
  97. O(Typeof, typeof_)
  98. #define JS_DECLARE_COMMON_UNARY_OP(OpTitleCase, op_snake_case) \
  99. class OpTitleCase final : public Instruction { \
  100. public: \
  101. OpTitleCase() \
  102. : Instruction(Type::OpTitleCase) \
  103. { \
  104. } \
  105. \
  106. void execute(Bytecode::Interpreter&) const; \
  107. String to_string() const; \
  108. };
  109. JS_ENUMERATE_COMMON_UNARY_OPS(JS_DECLARE_COMMON_UNARY_OP)
  110. #undef JS_DECLARE_COMMON_UNARY_OP
  111. class NewString final : public Instruction {
  112. public:
  113. NewString(String string)
  114. : Instruction(Type::NewString)
  115. , m_string(move(string))
  116. {
  117. }
  118. void execute(Bytecode::Interpreter&) const;
  119. String to_string() const;
  120. private:
  121. String m_string;
  122. };
  123. class NewObject final : public Instruction {
  124. public:
  125. NewObject()
  126. : Instruction(Type::NewObject)
  127. {
  128. }
  129. void execute(Bytecode::Interpreter&) const;
  130. String to_string() const;
  131. };
  132. class NewBigInt final : public Instruction {
  133. public:
  134. explicit NewBigInt(Crypto::SignedBigInteger bigint)
  135. : Instruction(Type::NewBigInt)
  136. , m_bigint(move(bigint))
  137. {
  138. }
  139. void execute(Bytecode::Interpreter&) const;
  140. String to_string() const;
  141. private:
  142. Crypto::SignedBigInteger m_bigint;
  143. };
  144. class ConcatString final : public Instruction {
  145. public:
  146. ConcatString(Register lhs)
  147. : Instruction(Type::ConcatString)
  148. , m_lhs(lhs)
  149. {
  150. }
  151. void execute(Bytecode::Interpreter&) const;
  152. String to_string() const;
  153. private:
  154. Register m_lhs;
  155. };
  156. class SetVariable final : public Instruction {
  157. public:
  158. SetVariable(FlyString identifier)
  159. : Instruction(Type::SetVariable)
  160. , m_identifier(move(identifier))
  161. {
  162. }
  163. void execute(Bytecode::Interpreter&) const;
  164. String to_string() const;
  165. private:
  166. FlyString m_identifier;
  167. };
  168. class GetVariable final : public Instruction {
  169. public:
  170. GetVariable(FlyString identifier)
  171. : Instruction(Type::GetVariable)
  172. , m_identifier(move(identifier))
  173. {
  174. }
  175. void execute(Bytecode::Interpreter&) const;
  176. String to_string() const;
  177. private:
  178. FlyString m_identifier;
  179. };
  180. class GetById final : public Instruction {
  181. public:
  182. GetById(FlyString property)
  183. : Instruction(Type::GetById)
  184. , m_property(move(property))
  185. {
  186. }
  187. void execute(Bytecode::Interpreter&) const;
  188. String to_string() const;
  189. private:
  190. FlyString m_property;
  191. };
  192. class PutById final : public Instruction {
  193. public:
  194. PutById(Register base, FlyString property)
  195. : Instruction(Type::PutById)
  196. , m_base(base)
  197. , m_property(move(property))
  198. {
  199. }
  200. void execute(Bytecode::Interpreter&) const;
  201. String to_string() const;
  202. private:
  203. Register m_base;
  204. FlyString m_property;
  205. };
  206. class Jump : public Instruction {
  207. public:
  208. explicit Jump(Type type, Optional<Label> target = {})
  209. : Instruction(type)
  210. , m_target(move(target))
  211. {
  212. }
  213. explicit Jump(Optional<Label> target = {})
  214. : Instruction(Type::Jump)
  215. , m_target(move(target))
  216. {
  217. }
  218. void set_target(Optional<Label> target) { m_target = move(target); }
  219. void execute(Bytecode::Interpreter&) const;
  220. String to_string() const;
  221. protected:
  222. Optional<Label> m_target;
  223. };
  224. class JumpIfFalse final : public Jump {
  225. public:
  226. explicit JumpIfFalse(Optional<Label> target = {})
  227. : Jump(Type::JumpIfFalse, move(target))
  228. {
  229. }
  230. void execute(Bytecode::Interpreter&) const;
  231. String to_string() const;
  232. };
  233. class JumpIfTrue : public Jump {
  234. public:
  235. explicit JumpIfTrue(Optional<Label> target = {})
  236. : Jump(Type::JumpIfTrue, move(target))
  237. {
  238. }
  239. void execute(Bytecode::Interpreter&) const;
  240. String to_string() const;
  241. };
  242. class JumpIfNotNullish final : public Jump {
  243. public:
  244. explicit JumpIfNotNullish(Optional<Label> target = {})
  245. : Jump(Type::JumpIfNotNullish, move(target))
  246. {
  247. }
  248. void execute(Bytecode::Interpreter&) const;
  249. String to_string() const;
  250. };
  251. // NOTE: This instruction is variable-width depending on the number of arguments!
  252. class Call final : public Instruction {
  253. public:
  254. Call(Register callee, Register this_value, Vector<Register> const& arguments)
  255. : Instruction(Type::Call)
  256. , m_callee(callee)
  257. , m_this_value(this_value)
  258. , m_argument_count(arguments.size())
  259. {
  260. for (size_t i = 0; i < m_argument_count; ++i)
  261. m_arguments[i] = arguments[i];
  262. }
  263. void execute(Bytecode::Interpreter&) const;
  264. String to_string() const;
  265. size_t length() const { return sizeof(*this) + sizeof(Register) * m_argument_count; }
  266. private:
  267. Register m_callee;
  268. Register m_this_value;
  269. size_t m_argument_count { 0 };
  270. Register m_arguments[];
  271. };
  272. class EnterScope final : public Instruction {
  273. public:
  274. explicit EnterScope(ScopeNode const& scope_node)
  275. : Instruction(Type::EnterScope)
  276. , m_scope_node(scope_node)
  277. {
  278. }
  279. void execute(Bytecode::Interpreter&) const;
  280. String to_string() const;
  281. private:
  282. ScopeNode const& m_scope_node;
  283. };
  284. class Return final : public Instruction {
  285. public:
  286. Return()
  287. : Instruction(Type::Return)
  288. {
  289. }
  290. void execute(Bytecode::Interpreter&) const;
  291. String to_string() const;
  292. };
  293. }