Op.h 10 KB

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