Op.h 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443
  1. /*
  2. * Copyright (c) 2021-2023, Andreas Kling <kling@serenityos.org>
  3. * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
  4. * Copyright (c) 2021, Gunnar Beutner <gbeutner@serenityos.org>
  5. *
  6. * SPDX-License-Identifier: BSD-2-Clause
  7. */
  8. #pragma once
  9. #include <AK/StdLibExtras.h>
  10. #include <LibCrypto/BigInt/SignedBigInteger.h>
  11. #include <LibJS/Bytecode/IdentifierTable.h>
  12. #include <LibJS/Bytecode/Instruction.h>
  13. #include <LibJS/Bytecode/Label.h>
  14. #include <LibJS/Bytecode/RegexTable.h>
  15. #include <LibJS/Bytecode/Register.h>
  16. #include <LibJS/Bytecode/StringTable.h>
  17. #include <LibJS/Heap/Cell.h>
  18. #include <LibJS/Runtime/Environment.h>
  19. #include <LibJS/Runtime/Iterator.h>
  20. #include <LibJS/Runtime/Value.h>
  21. #include <LibJS/Runtime/ValueTraits.h>
  22. namespace JS {
  23. class FunctionExpression;
  24. }
  25. namespace JS::Bytecode::Op {
  26. class Load final : public Instruction {
  27. public:
  28. explicit Load(Register src)
  29. : Instruction(Type::Load, sizeof(*this))
  30. , m_src(src)
  31. {
  32. }
  33. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  34. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  35. Register src() const { return m_src; }
  36. private:
  37. Register m_src;
  38. };
  39. class LoadImmediate final : public Instruction {
  40. public:
  41. explicit LoadImmediate(Value value)
  42. : Instruction(Type::LoadImmediate, sizeof(*this))
  43. , m_value(value)
  44. {
  45. }
  46. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  47. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  48. Value value() const { return m_value; }
  49. private:
  50. Value m_value;
  51. };
  52. class Store final : public Instruction {
  53. public:
  54. explicit Store(Register dst)
  55. : Instruction(Type::Store, sizeof(*this))
  56. , m_dst(dst)
  57. {
  58. }
  59. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  60. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  61. Register dst() const { return m_dst; }
  62. private:
  63. Register m_dst;
  64. };
  65. #define JS_ENUMERATE_COMMON_BINARY_OPS(O) \
  66. O(Add, add) \
  67. O(Sub, sub) \
  68. O(Mul, mul) \
  69. O(Div, div) \
  70. O(Exp, exp) \
  71. O(Mod, mod) \
  72. O(In, in) \
  73. O(InstanceOf, instance_of) \
  74. O(GreaterThan, greater_than) \
  75. O(GreaterThanEquals, greater_than_equals) \
  76. O(LessThan, less_than) \
  77. O(LessThanEquals, less_than_equals) \
  78. O(LooselyInequals, abstract_inequals) \
  79. O(LooselyEquals, abstract_equals) \
  80. O(StrictlyInequals, typed_inequals) \
  81. O(StrictlyEquals, typed_equals) \
  82. O(BitwiseAnd, bitwise_and) \
  83. O(BitwiseOr, bitwise_or) \
  84. O(BitwiseXor, bitwise_xor) \
  85. O(LeftShift, left_shift) \
  86. O(RightShift, right_shift) \
  87. O(UnsignedRightShift, unsigned_right_shift)
  88. #define JS_DECLARE_COMMON_BINARY_OP(OpTitleCase, op_snake_case) \
  89. class OpTitleCase final : public Instruction { \
  90. public: \
  91. explicit OpTitleCase(Register lhs_reg) \
  92. : Instruction(Type::OpTitleCase, sizeof(*this)) \
  93. , m_lhs_reg(lhs_reg) \
  94. { \
  95. } \
  96. \
  97. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; \
  98. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const; \
  99. \
  100. private: \
  101. Register m_lhs_reg; \
  102. };
  103. JS_ENUMERATE_COMMON_BINARY_OPS(JS_DECLARE_COMMON_BINARY_OP)
  104. #undef JS_DECLARE_COMMON_BINARY_OP
  105. #define JS_ENUMERATE_COMMON_UNARY_OPS(O) \
  106. O(BitwiseNot, bitwise_not) \
  107. O(Not, not_) \
  108. O(UnaryPlus, unary_plus) \
  109. O(UnaryMinus, unary_minus) \
  110. O(Typeof, typeof_)
  111. #define JS_DECLARE_COMMON_UNARY_OP(OpTitleCase, op_snake_case) \
  112. class OpTitleCase final : public Instruction { \
  113. public: \
  114. OpTitleCase() \
  115. : Instruction(Type::OpTitleCase, sizeof(*this)) \
  116. { \
  117. } \
  118. \
  119. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; \
  120. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const; \
  121. };
  122. JS_ENUMERATE_COMMON_UNARY_OPS(JS_DECLARE_COMMON_UNARY_OP)
  123. #undef JS_DECLARE_COMMON_UNARY_OP
  124. class NewString final : public Instruction {
  125. public:
  126. explicit NewString(StringTableIndex string)
  127. : Instruction(Type::NewString, sizeof(*this))
  128. , m_string(string)
  129. {
  130. }
  131. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  132. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  133. private:
  134. StringTableIndex m_string;
  135. };
  136. class NewObject final : public Instruction {
  137. public:
  138. NewObject()
  139. : Instruction(Type::NewObject, sizeof(*this))
  140. {
  141. }
  142. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  143. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  144. };
  145. class NewRegExp final : public Instruction {
  146. public:
  147. NewRegExp(StringTableIndex source_index, StringTableIndex flags_index, RegexTableIndex regex_index)
  148. : Instruction(Type::NewRegExp, sizeof(*this))
  149. , m_source_index(source_index)
  150. , m_flags_index(flags_index)
  151. , m_regex_index(regex_index)
  152. {
  153. }
  154. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  155. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  156. private:
  157. StringTableIndex m_source_index;
  158. StringTableIndex m_flags_index;
  159. RegexTableIndex m_regex_index;
  160. };
  161. #define JS_ENUMERATE_NEW_BUILTIN_ERROR_OPS(O) \
  162. O(TypeError)
  163. #define JS_DECLARE_NEW_BUILTIN_ERROR_OP(ErrorName) \
  164. class New##ErrorName final : public Instruction { \
  165. public: \
  166. explicit New##ErrorName(StringTableIndex error_string) \
  167. : Instruction(Type::New##ErrorName, sizeof(*this)) \
  168. , m_error_string(error_string) \
  169. { \
  170. } \
  171. \
  172. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; \
  173. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const; \
  174. \
  175. private: \
  176. StringTableIndex m_error_string; \
  177. };
  178. JS_ENUMERATE_NEW_BUILTIN_ERROR_OPS(JS_DECLARE_NEW_BUILTIN_ERROR_OP)
  179. #undef JS_DECLARE_NEW_BUILTIN_ERROR_OP
  180. // NOTE: This instruction is variable-width depending on the number of excluded names
  181. class CopyObjectExcludingProperties final : public Instruction {
  182. public:
  183. CopyObjectExcludingProperties(Register from_object, Vector<Register> const& excluded_names)
  184. : Instruction(Type::CopyObjectExcludingProperties, length_impl(excluded_names.size()))
  185. , m_from_object(from_object)
  186. , m_excluded_names_count(excluded_names.size())
  187. {
  188. for (size_t i = 0; i < m_excluded_names_count; i++)
  189. m_excluded_names[i] = excluded_names[i];
  190. }
  191. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  192. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  193. size_t length_impl(size_t excluded_names_count) const
  194. {
  195. return round_up_to_power_of_two(alignof(void*), sizeof(*this) + sizeof(Register) * excluded_names_count);
  196. }
  197. private:
  198. Register m_from_object;
  199. size_t m_excluded_names_count { 0 };
  200. Register m_excluded_names[];
  201. };
  202. class NewBigInt final : public Instruction {
  203. public:
  204. explicit NewBigInt(Crypto::SignedBigInteger bigint)
  205. : Instruction(Type::NewBigInt, sizeof(*this))
  206. , m_bigint(move(bigint))
  207. {
  208. }
  209. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  210. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  211. private:
  212. Crypto::SignedBigInteger m_bigint;
  213. };
  214. // NOTE: This instruction is variable-width depending on the number of elements!
  215. class NewArray final : public Instruction {
  216. public:
  217. NewArray()
  218. : Instruction(Type::NewArray, length_impl(0))
  219. , m_element_count(0)
  220. {
  221. }
  222. explicit NewArray(AK::Array<Register, 2> const& elements_range)
  223. : Instruction(Type::NewArray, length_impl(elements_range[1].index() - elements_range[0].index() + 1))
  224. , m_element_count(elements_range[1].index() - elements_range[0].index() + 1)
  225. {
  226. m_elements[0] = elements_range[0];
  227. m_elements[1] = elements_range[1];
  228. }
  229. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  230. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  231. size_t length_impl(size_t element_count) const
  232. {
  233. return round_up_to_power_of_two(alignof(void*), sizeof(*this) + sizeof(Register) * (element_count == 0 ? 0 : 2));
  234. }
  235. Register start() const
  236. {
  237. VERIFY(m_element_count);
  238. return m_elements[0];
  239. }
  240. Register end() const
  241. {
  242. VERIFY(m_element_count);
  243. return m_elements[1];
  244. }
  245. size_t element_count() const { return m_element_count; }
  246. private:
  247. size_t m_element_count { 0 };
  248. Register m_elements[];
  249. };
  250. class Append final : public Instruction {
  251. public:
  252. Append(Register lhs, bool is_spread)
  253. : Instruction(Type::Append, sizeof(*this))
  254. , m_lhs(lhs)
  255. , m_is_spread(is_spread)
  256. {
  257. }
  258. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  259. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  260. private:
  261. Register m_lhs;
  262. bool m_is_spread = false;
  263. };
  264. class ImportCall final : public Instruction {
  265. public:
  266. ImportCall(Register specifier, Register options)
  267. : Instruction(Type::ImportCall, sizeof(*this))
  268. , m_specifier(specifier)
  269. , m_options(options)
  270. {
  271. }
  272. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  273. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  274. private:
  275. Register m_specifier;
  276. Register m_options;
  277. };
  278. class IteratorToArray final : public Instruction {
  279. public:
  280. IteratorToArray()
  281. : Instruction(Type::IteratorToArray, sizeof(*this))
  282. {
  283. }
  284. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  285. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  286. };
  287. class ConcatString final : public Instruction {
  288. public:
  289. explicit ConcatString(Register lhs)
  290. : Instruction(Type::ConcatString, sizeof(*this))
  291. , m_lhs(lhs)
  292. {
  293. }
  294. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  295. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  296. private:
  297. Register m_lhs;
  298. };
  299. enum class EnvironmentMode {
  300. Lexical,
  301. Var,
  302. };
  303. class CreateLexicalEnvironment final : public Instruction {
  304. public:
  305. explicit CreateLexicalEnvironment()
  306. : Instruction(Type::CreateLexicalEnvironment, sizeof(*this))
  307. {
  308. }
  309. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  310. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  311. };
  312. class EnterObjectEnvironment final : public Instruction {
  313. public:
  314. explicit EnterObjectEnvironment()
  315. : Instruction(Type::EnterObjectEnvironment, sizeof(*this))
  316. {
  317. }
  318. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  319. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  320. };
  321. class CreateVariable final : public Instruction {
  322. public:
  323. explicit CreateVariable(IdentifierTableIndex identifier, EnvironmentMode mode, bool is_immutable, bool is_global = false, bool is_strict = false)
  324. : Instruction(Type::CreateVariable, sizeof(*this))
  325. , m_identifier(identifier)
  326. , m_mode(mode)
  327. , m_is_immutable(is_immutable)
  328. , m_is_global(is_global)
  329. , m_is_strict(is_strict)
  330. {
  331. }
  332. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  333. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  334. private:
  335. IdentifierTableIndex m_identifier;
  336. EnvironmentMode m_mode;
  337. bool m_is_immutable : 4 { false };
  338. bool m_is_global : 4 { false };
  339. bool m_is_strict { false };
  340. };
  341. class SetVariable final : public Instruction {
  342. public:
  343. enum class InitializationMode {
  344. Initialize,
  345. Set,
  346. };
  347. explicit SetVariable(IdentifierTableIndex identifier, InitializationMode initialization_mode = InitializationMode::Set, EnvironmentMode mode = EnvironmentMode::Lexical)
  348. : Instruction(Type::SetVariable, sizeof(*this))
  349. , m_identifier(identifier)
  350. , m_mode(mode)
  351. , m_initialization_mode(initialization_mode)
  352. {
  353. }
  354. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  355. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  356. IdentifierTableIndex identifier() const { return m_identifier; }
  357. private:
  358. IdentifierTableIndex m_identifier;
  359. EnvironmentMode m_mode;
  360. InitializationMode m_initialization_mode { InitializationMode::Set };
  361. };
  362. class SetLocal final : public Instruction {
  363. public:
  364. explicit SetLocal(size_t index)
  365. : Instruction(Type::SetLocal, sizeof(*this))
  366. , m_index(index)
  367. {
  368. }
  369. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  370. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  371. size_t index() const { return m_index; }
  372. private:
  373. size_t m_index;
  374. };
  375. class GetCalleeAndThisFromEnvironment final : public Instruction {
  376. public:
  377. explicit GetCalleeAndThisFromEnvironment(IdentifierTableIndex identifier, Register callee_reg, Register this_reg, u32 cache_index)
  378. : Instruction(Type::GetCalleeAndThisFromEnvironment, sizeof(*this))
  379. , m_identifier(identifier)
  380. , m_callee_reg(callee_reg)
  381. , m_this_reg(this_reg)
  382. , m_cache_index(cache_index)
  383. {
  384. }
  385. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  386. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  387. IdentifierTableIndex identifier() const { return m_identifier; }
  388. u32 cache_index() const { return m_cache_index; }
  389. private:
  390. IdentifierTableIndex m_identifier;
  391. Register m_callee_reg;
  392. Register m_this_reg;
  393. u32 m_cache_index { 0 };
  394. };
  395. class GetVariable final : public Instruction {
  396. public:
  397. explicit GetVariable(IdentifierTableIndex identifier, u32 cache_index)
  398. : Instruction(Type::GetVariable, sizeof(*this))
  399. , m_identifier(identifier)
  400. , m_cache_index(cache_index)
  401. {
  402. }
  403. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  404. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  405. IdentifierTableIndex identifier() const { return m_identifier; }
  406. u32 cache_index() const { return m_cache_index; }
  407. private:
  408. IdentifierTableIndex m_identifier;
  409. u32 m_cache_index { 0 };
  410. };
  411. class GetGlobal final : public Instruction {
  412. public:
  413. explicit GetGlobal(IdentifierTableIndex identifier, u32 cache_index)
  414. : Instruction(Type::GetGlobal, sizeof(*this))
  415. , m_identifier(identifier)
  416. , m_cache_index(cache_index)
  417. {
  418. }
  419. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  420. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  421. private:
  422. IdentifierTableIndex m_identifier;
  423. u32 m_cache_index { 0 };
  424. };
  425. class GetLocal final : public Instruction {
  426. public:
  427. explicit GetLocal(size_t index)
  428. : Instruction(Type::GetLocal, sizeof(*this))
  429. , m_index(index)
  430. {
  431. }
  432. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  433. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  434. size_t index() const { return m_index; }
  435. private:
  436. size_t m_index;
  437. };
  438. class DeleteVariable final : public Instruction {
  439. public:
  440. explicit DeleteVariable(IdentifierTableIndex identifier)
  441. : Instruction(Type::DeleteVariable, sizeof(*this))
  442. , m_identifier(identifier)
  443. {
  444. }
  445. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  446. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  447. IdentifierTableIndex identifier() const { return m_identifier; }
  448. private:
  449. IdentifierTableIndex m_identifier;
  450. };
  451. class GetById final : public Instruction {
  452. public:
  453. GetById(IdentifierTableIndex property, u32 cache_index)
  454. : Instruction(Type::GetById, sizeof(*this))
  455. , m_property(property)
  456. , m_cache_index(cache_index)
  457. {
  458. }
  459. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  460. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  461. private:
  462. IdentifierTableIndex m_property;
  463. u32 m_cache_index { 0 };
  464. };
  465. class GetByIdWithThis final : public Instruction {
  466. public:
  467. GetByIdWithThis(IdentifierTableIndex property, Register this_value, u32 cache_index)
  468. : Instruction(Type::GetByIdWithThis, sizeof(*this))
  469. , m_property(property)
  470. , m_this_value(this_value)
  471. , m_cache_index(cache_index)
  472. {
  473. }
  474. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  475. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  476. private:
  477. IdentifierTableIndex m_property;
  478. Register m_this_value;
  479. u32 m_cache_index { 0 };
  480. };
  481. class GetPrivateById final : public Instruction {
  482. public:
  483. explicit GetPrivateById(IdentifierTableIndex property)
  484. : Instruction(Type::GetPrivateById, sizeof(*this))
  485. , m_property(property)
  486. {
  487. }
  488. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  489. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  490. private:
  491. IdentifierTableIndex m_property;
  492. };
  493. class HasPrivateId final : public Instruction {
  494. public:
  495. explicit HasPrivateId(IdentifierTableIndex property)
  496. : Instruction(Type::HasPrivateId, sizeof(*this))
  497. , m_property(property)
  498. {
  499. }
  500. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  501. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  502. private:
  503. IdentifierTableIndex m_property;
  504. };
  505. enum class PropertyKind {
  506. Getter,
  507. Setter,
  508. KeyValue,
  509. DirectKeyValue, // Used for Object expressions. Always sets an own property, never calls a setter.
  510. Spread,
  511. ProtoSetter,
  512. };
  513. class PutById final : public Instruction {
  514. public:
  515. explicit PutById(Register base, IdentifierTableIndex property, PropertyKind kind = PropertyKind::KeyValue)
  516. : Instruction(Type::PutById, sizeof(*this))
  517. , m_base(base)
  518. , m_property(property)
  519. , m_kind(kind)
  520. {
  521. }
  522. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  523. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  524. private:
  525. Register m_base;
  526. IdentifierTableIndex m_property;
  527. PropertyKind m_kind;
  528. };
  529. class PutByIdWithThis final : public Instruction {
  530. public:
  531. PutByIdWithThis(Register base, Register this_value, IdentifierTableIndex property, PropertyKind kind = PropertyKind::KeyValue)
  532. : Instruction(Type::PutByIdWithThis, sizeof(*this))
  533. , m_base(base)
  534. , m_this_value(this_value)
  535. , m_property(property)
  536. , m_kind(kind)
  537. {
  538. }
  539. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  540. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  541. private:
  542. Register m_base;
  543. Register m_this_value;
  544. IdentifierTableIndex m_property;
  545. PropertyKind m_kind;
  546. };
  547. class PutPrivateById final : public Instruction {
  548. public:
  549. explicit PutPrivateById(Register base, IdentifierTableIndex property, PropertyKind kind = PropertyKind::KeyValue)
  550. : Instruction(Type::PutPrivateById, sizeof(*this))
  551. , m_base(base)
  552. , m_property(property)
  553. , m_kind(kind)
  554. {
  555. }
  556. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  557. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  558. private:
  559. Register m_base;
  560. IdentifierTableIndex m_property;
  561. PropertyKind m_kind;
  562. };
  563. class DeleteById final : public Instruction {
  564. public:
  565. explicit DeleteById(IdentifierTableIndex property)
  566. : Instruction(Type::DeleteById, sizeof(*this))
  567. , m_property(property)
  568. {
  569. }
  570. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  571. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  572. private:
  573. IdentifierTableIndex m_property;
  574. };
  575. class DeleteByIdWithThis final : public Instruction {
  576. public:
  577. DeleteByIdWithThis(Register this_value, IdentifierTableIndex property)
  578. : Instruction(Type::DeleteByIdWithThis, sizeof(*this))
  579. , m_this_value(this_value)
  580. , m_property(property)
  581. {
  582. }
  583. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  584. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  585. private:
  586. Register m_this_value;
  587. IdentifierTableIndex m_property;
  588. };
  589. class GetByValue final : public Instruction {
  590. public:
  591. explicit GetByValue(Register base)
  592. : Instruction(Type::GetByValue, sizeof(*this))
  593. , m_base(base)
  594. {
  595. }
  596. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  597. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  598. private:
  599. Register m_base;
  600. };
  601. class GetByValueWithThis final : public Instruction {
  602. public:
  603. GetByValueWithThis(Register base, Register this_value)
  604. : Instruction(Type::GetByValueWithThis, sizeof(*this))
  605. , m_base(base)
  606. , m_this_value(this_value)
  607. {
  608. }
  609. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  610. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  611. private:
  612. Register m_base;
  613. Register m_this_value;
  614. };
  615. class PutByValue final : public Instruction {
  616. public:
  617. PutByValue(Register base, Register property, PropertyKind kind = PropertyKind::KeyValue)
  618. : Instruction(Type::PutByValue, sizeof(*this))
  619. , m_base(base)
  620. , m_property(property)
  621. , m_kind(kind)
  622. {
  623. }
  624. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  625. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  626. private:
  627. Register m_base;
  628. Register m_property;
  629. PropertyKind m_kind;
  630. };
  631. class PutByValueWithThis final : public Instruction {
  632. public:
  633. PutByValueWithThis(Register base, Register property, Register this_value, PropertyKind kind = PropertyKind::KeyValue)
  634. : Instruction(Type::PutByValueWithThis, sizeof(*this))
  635. , m_base(base)
  636. , m_property(property)
  637. , m_this_value(this_value)
  638. , m_kind(kind)
  639. {
  640. }
  641. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  642. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  643. private:
  644. Register m_base;
  645. Register m_property;
  646. Register m_this_value;
  647. PropertyKind m_kind;
  648. };
  649. class DeleteByValue final : public Instruction {
  650. public:
  651. DeleteByValue(Register base)
  652. : Instruction(Type::DeleteByValue, sizeof(*this))
  653. , m_base(base)
  654. {
  655. }
  656. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  657. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  658. private:
  659. Register m_base;
  660. };
  661. class DeleteByValueWithThis final : public Instruction {
  662. public:
  663. DeleteByValueWithThis(Register base, Register this_value)
  664. : Instruction(Type::DeleteByValueWithThis, sizeof(*this))
  665. , m_base(base)
  666. , m_this_value(this_value)
  667. {
  668. }
  669. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  670. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  671. private:
  672. Register m_base;
  673. Register m_this_value;
  674. };
  675. class Jump : public Instruction {
  676. public:
  677. constexpr static bool IsTerminator = true;
  678. explicit Jump(Type type, Label taken_target, Optional<Label> nontaken_target = {})
  679. : Instruction(type, sizeof(*this))
  680. , m_true_target(move(taken_target))
  681. , m_false_target(move(nontaken_target))
  682. {
  683. }
  684. explicit Jump(Label taken_target, Optional<Label> nontaken_target = {})
  685. : Instruction(Type::Jump, sizeof(*this))
  686. , m_true_target(move(taken_target))
  687. , m_false_target(move(nontaken_target))
  688. {
  689. }
  690. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  691. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  692. auto& true_target() const { return m_true_target; }
  693. auto& false_target() const { return m_false_target; }
  694. protected:
  695. Optional<Label> m_true_target;
  696. Optional<Label> m_false_target;
  697. };
  698. class JumpConditional final : public Jump {
  699. public:
  700. explicit JumpConditional(Label true_target, Label false_target)
  701. : Jump(Type::JumpConditional, move(true_target), move(false_target))
  702. {
  703. }
  704. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  705. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  706. };
  707. class JumpNullish final : public Jump {
  708. public:
  709. explicit JumpNullish(Label true_target, Label false_target)
  710. : Jump(Type::JumpNullish, move(true_target), move(false_target))
  711. {
  712. }
  713. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  714. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  715. };
  716. class JumpUndefined final : public Jump {
  717. public:
  718. explicit JumpUndefined(Label true_target, Label false_target)
  719. : Jump(Type::JumpUndefined, move(true_target), move(false_target))
  720. {
  721. }
  722. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  723. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  724. };
  725. enum class CallType {
  726. Call,
  727. Construct,
  728. DirectEval,
  729. };
  730. class Call final : public Instruction {
  731. public:
  732. Call(CallType type, Register callee, Register this_value, Register first_argument, u32 argument_count, Optional<StringTableIndex> expression_string = {})
  733. : Instruction(Type::Call, sizeof(*this))
  734. , m_callee(callee)
  735. , m_this_value(this_value)
  736. , m_first_argument(first_argument)
  737. , m_argument_count(argument_count)
  738. , m_type(type)
  739. , m_expression_string(expression_string)
  740. {
  741. }
  742. CallType call_type() const { return m_type; }
  743. Register callee() const { return m_callee; }
  744. Register this_value() const { return m_this_value; }
  745. Optional<StringTableIndex> const& expression_string() const { return m_expression_string; }
  746. Register first_argument() const { return m_first_argument; }
  747. u32 argument_count() const { return m_argument_count; }
  748. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  749. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  750. private:
  751. Register m_callee;
  752. Register m_this_value;
  753. Register m_first_argument;
  754. u32 m_argument_count { 0 };
  755. CallType m_type;
  756. Optional<StringTableIndex> m_expression_string;
  757. };
  758. class CallWithArgumentArray final : public Instruction {
  759. public:
  760. CallWithArgumentArray(CallType type, Register callee, Register this_value, Optional<StringTableIndex> expression_string = {})
  761. : Instruction(Type::CallWithArgumentArray, sizeof(*this))
  762. , m_callee(callee)
  763. , m_this_value(this_value)
  764. , m_type(type)
  765. , m_expression_string(expression_string)
  766. {
  767. }
  768. CallType call_type() const { return m_type; }
  769. Register callee() const { return m_callee; }
  770. Register this_value() const { return m_this_value; }
  771. Optional<StringTableIndex> const& expression_string() const { return m_expression_string; }
  772. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  773. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  774. private:
  775. Register m_callee;
  776. Register m_this_value;
  777. CallType m_type;
  778. Optional<StringTableIndex> m_expression_string;
  779. };
  780. class SuperCallWithArgumentArray : public Instruction {
  781. public:
  782. explicit SuperCallWithArgumentArray(bool is_synthetic)
  783. : Instruction(Type::SuperCallWithArgumentArray, sizeof(*this))
  784. , m_is_synthetic(is_synthetic)
  785. {
  786. }
  787. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  788. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  789. private:
  790. bool m_is_synthetic;
  791. };
  792. class NewClass final : public Instruction {
  793. public:
  794. explicit NewClass(ClassExpression const& class_expression, Optional<IdentifierTableIndex> lhs_name)
  795. : Instruction(Type::NewClass, sizeof(*this))
  796. , m_class_expression(class_expression)
  797. , m_lhs_name(lhs_name)
  798. {
  799. }
  800. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  801. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  802. private:
  803. ClassExpression const& m_class_expression;
  804. Optional<IdentifierTableIndex> m_lhs_name;
  805. };
  806. class NewFunction final : public Instruction {
  807. public:
  808. explicit NewFunction(FunctionExpression const& function_node, Optional<IdentifierTableIndex> lhs_name, Optional<Register> home_object = {})
  809. : Instruction(Type::NewFunction, sizeof(*this))
  810. , m_function_node(function_node)
  811. , m_lhs_name(lhs_name)
  812. , m_home_object(move(home_object))
  813. {
  814. }
  815. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  816. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  817. private:
  818. FunctionExpression const& m_function_node;
  819. Optional<IdentifierTableIndex> m_lhs_name;
  820. Optional<Register> m_home_object;
  821. };
  822. class BlockDeclarationInstantiation final : public Instruction {
  823. public:
  824. explicit BlockDeclarationInstantiation(ScopeNode const& scope_node)
  825. : Instruction(Type::BlockDeclarationInstantiation, sizeof(*this))
  826. , m_scope_node(scope_node)
  827. {
  828. }
  829. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  830. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  831. private:
  832. ScopeNode const& m_scope_node;
  833. };
  834. class Return final : public Instruction {
  835. public:
  836. constexpr static bool IsTerminator = true;
  837. Return()
  838. : Instruction(Type::Return, sizeof(*this))
  839. {
  840. }
  841. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  842. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  843. };
  844. class Increment final : public Instruction {
  845. public:
  846. Increment()
  847. : Instruction(Type::Increment, sizeof(*this))
  848. {
  849. }
  850. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  851. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  852. };
  853. class Decrement final : public Instruction {
  854. public:
  855. Decrement()
  856. : Instruction(Type::Decrement, sizeof(*this))
  857. {
  858. }
  859. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  860. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  861. };
  862. class ToNumeric final : public Instruction {
  863. public:
  864. ToNumeric()
  865. : Instruction(Type::ToNumeric, sizeof(*this))
  866. {
  867. }
  868. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  869. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  870. };
  871. class Throw final : public Instruction {
  872. public:
  873. constexpr static bool IsTerminator = true;
  874. Throw()
  875. : Instruction(Type::Throw, sizeof(*this))
  876. {
  877. }
  878. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  879. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  880. };
  881. class ThrowIfNotObject final : public Instruction {
  882. public:
  883. ThrowIfNotObject()
  884. : Instruction(Type::ThrowIfNotObject, sizeof(*this))
  885. {
  886. }
  887. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  888. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  889. };
  890. class ThrowIfNullish final : public Instruction {
  891. public:
  892. ThrowIfNullish()
  893. : Instruction(Type::ThrowIfNullish, sizeof(*this))
  894. {
  895. }
  896. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  897. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  898. };
  899. class EnterUnwindContext final : public Instruction {
  900. public:
  901. constexpr static bool IsTerminator = true;
  902. EnterUnwindContext(Label entry_point, Optional<Label> handler_target, Optional<Label> finalizer_target)
  903. : Instruction(Type::EnterUnwindContext, sizeof(*this))
  904. , m_entry_point(move(entry_point))
  905. , m_handler_target(move(handler_target))
  906. , m_finalizer_target(move(finalizer_target))
  907. {
  908. }
  909. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  910. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  911. auto& entry_point() const { return m_entry_point; }
  912. auto& handler_target() const { return m_handler_target; }
  913. auto& finalizer_target() const { return m_finalizer_target; }
  914. private:
  915. Label m_entry_point;
  916. Optional<Label> m_handler_target;
  917. Optional<Label> m_finalizer_target;
  918. };
  919. class ScheduleJump final : public Instruction {
  920. public:
  921. // Note: We use this instruction to tell the next `finally` block to
  922. // continue execution with a specific break/continue target;
  923. // FIXME: We currently don't clear the interpreter internal flag, when we change
  924. // the control-flow (`break`, `continue`) in a finally-block,
  925. // FIXME: .NET on x86_64 uses a call to the finally instead, which could make this
  926. // easier, at the cost of making control-flow changes (`break`, `continue`, `return`)
  927. // in the finally-block more difficult, but as stated above, those
  928. // aren't handled 100% correctly at the moment anyway
  929. // It might be worth investigating a similar mechanism
  930. constexpr static bool IsTerminator = true;
  931. ScheduleJump(Label target)
  932. : Instruction(Type::ScheduleJump, sizeof(*this))
  933. , m_target(target)
  934. {
  935. }
  936. Label target() const { return m_target; }
  937. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  938. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  939. private:
  940. Label m_target;
  941. };
  942. class LeaveLexicalEnvironment final : public Instruction {
  943. public:
  944. LeaveLexicalEnvironment()
  945. : Instruction(Type::LeaveLexicalEnvironment, sizeof(*this))
  946. {
  947. }
  948. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  949. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  950. };
  951. class LeaveUnwindContext final : public Instruction {
  952. public:
  953. LeaveUnwindContext()
  954. : Instruction(Type::LeaveUnwindContext, sizeof(*this))
  955. {
  956. }
  957. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  958. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  959. };
  960. class ContinuePendingUnwind final : public Instruction {
  961. public:
  962. constexpr static bool IsTerminator = true;
  963. explicit ContinuePendingUnwind(Label resume_target)
  964. : Instruction(Type::ContinuePendingUnwind, sizeof(*this))
  965. , m_resume_target(resume_target)
  966. {
  967. }
  968. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  969. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  970. auto& resume_target() const { return m_resume_target; }
  971. private:
  972. Label m_resume_target;
  973. };
  974. class Yield final : public Instruction {
  975. public:
  976. constexpr static bool IsTerminator = true;
  977. explicit Yield(Label continuation_label)
  978. : Instruction(Type::Yield, sizeof(*this))
  979. , m_continuation_label(continuation_label)
  980. {
  981. }
  982. explicit Yield(nullptr_t)
  983. : Instruction(Type::Yield, sizeof(*this))
  984. {
  985. }
  986. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  987. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  988. auto& continuation() const { return m_continuation_label; }
  989. private:
  990. Optional<Label> m_continuation_label;
  991. };
  992. class Await final : public Instruction {
  993. public:
  994. constexpr static bool IsTerminator = true;
  995. explicit Await(Label continuation_label)
  996. : Instruction(Type::Await, sizeof(*this))
  997. , m_continuation_label(continuation_label)
  998. {
  999. }
  1000. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  1001. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  1002. auto& continuation() const { return m_continuation_label; }
  1003. private:
  1004. Label m_continuation_label;
  1005. };
  1006. class PushDeclarativeEnvironment final : public Instruction {
  1007. public:
  1008. explicit PushDeclarativeEnvironment(HashMap<u32, Variable> variables)
  1009. : Instruction(Type::PushDeclarativeEnvironment, sizeof(*this))
  1010. , m_variables(move(variables))
  1011. {
  1012. }
  1013. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  1014. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  1015. private:
  1016. HashMap<u32, Variable> m_variables;
  1017. };
  1018. class GetIterator final : public Instruction {
  1019. public:
  1020. GetIterator(IteratorHint hint = IteratorHint::Sync)
  1021. : Instruction(Type::GetIterator, sizeof(*this))
  1022. , m_hint(hint)
  1023. {
  1024. }
  1025. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  1026. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  1027. private:
  1028. IteratorHint m_hint { IteratorHint::Sync };
  1029. };
  1030. class GetMethod final : public Instruction {
  1031. public:
  1032. GetMethod(IdentifierTableIndex property)
  1033. : Instruction(Type::GetMethod, sizeof(*this))
  1034. , m_property(property)
  1035. {
  1036. }
  1037. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  1038. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  1039. private:
  1040. IdentifierTableIndex m_property;
  1041. };
  1042. class GetObjectPropertyIterator final : public Instruction {
  1043. public:
  1044. GetObjectPropertyIterator()
  1045. : Instruction(Type::GetObjectPropertyIterator, sizeof(*this))
  1046. {
  1047. }
  1048. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  1049. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  1050. };
  1051. class IteratorClose final : public Instruction {
  1052. public:
  1053. IteratorClose(Completion::Type completion_type, Optional<Value> completion_value)
  1054. : Instruction(Type::IteratorClose, sizeof(*this))
  1055. , m_completion_type(completion_type)
  1056. , m_completion_value(completion_value)
  1057. {
  1058. }
  1059. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  1060. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  1061. private:
  1062. Completion::Type m_completion_type { Completion::Type::Normal };
  1063. Optional<Value> m_completion_value;
  1064. };
  1065. class AsyncIteratorClose final : public Instruction {
  1066. public:
  1067. AsyncIteratorClose(Completion::Type completion_type, Optional<Value> completion_value)
  1068. : Instruction(Type::AsyncIteratorClose, sizeof(*this))
  1069. , m_completion_type(completion_type)
  1070. , m_completion_value(completion_value)
  1071. {
  1072. }
  1073. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  1074. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  1075. private:
  1076. Completion::Type m_completion_type { Completion::Type::Normal };
  1077. Optional<Value> m_completion_value;
  1078. };
  1079. class IteratorNext final : public Instruction {
  1080. public:
  1081. IteratorNext()
  1082. : Instruction(Type::IteratorNext, sizeof(*this))
  1083. {
  1084. }
  1085. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  1086. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  1087. };
  1088. class IteratorResultDone final : public Instruction {
  1089. public:
  1090. IteratorResultDone()
  1091. : Instruction(Type::IteratorResultDone, sizeof(*this))
  1092. {
  1093. }
  1094. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  1095. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  1096. };
  1097. class IteratorResultValue final : public Instruction {
  1098. public:
  1099. IteratorResultValue()
  1100. : Instruction(Type::IteratorResultValue, sizeof(*this))
  1101. {
  1102. }
  1103. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  1104. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  1105. };
  1106. class ResolveThisBinding final : public Instruction {
  1107. public:
  1108. explicit ResolveThisBinding()
  1109. : Instruction(Type::ResolveThisBinding, sizeof(*this))
  1110. {
  1111. }
  1112. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  1113. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  1114. };
  1115. class ResolveSuperBase final : public Instruction {
  1116. public:
  1117. explicit ResolveSuperBase()
  1118. : Instruction(Type::ResolveSuperBase, sizeof(*this))
  1119. {
  1120. }
  1121. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  1122. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  1123. };
  1124. class GetNewTarget final : public Instruction {
  1125. public:
  1126. explicit GetNewTarget()
  1127. : Instruction(Type::GetNewTarget, sizeof(*this))
  1128. {
  1129. }
  1130. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  1131. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  1132. };
  1133. class GetImportMeta final : public Instruction {
  1134. public:
  1135. explicit GetImportMeta()
  1136. : Instruction(Type::GetImportMeta, sizeof(*this))
  1137. {
  1138. }
  1139. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  1140. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  1141. };
  1142. class TypeofVariable final : public Instruction {
  1143. public:
  1144. explicit TypeofVariable(IdentifierTableIndex identifier)
  1145. : Instruction(Type::TypeofVariable, sizeof(*this))
  1146. , m_identifier(identifier)
  1147. {
  1148. }
  1149. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  1150. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  1151. private:
  1152. IdentifierTableIndex m_identifier;
  1153. };
  1154. class TypeofLocal final : public Instruction {
  1155. public:
  1156. explicit TypeofLocal(size_t index)
  1157. : Instruction(Type::TypeofLocal, sizeof(*this))
  1158. , m_index(index)
  1159. {
  1160. }
  1161. ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
  1162. DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
  1163. private:
  1164. size_t m_index;
  1165. };
  1166. }
  1167. namespace JS::Bytecode {
  1168. ALWAYS_INLINE ThrowCompletionOr<void> Instruction::execute(Bytecode::Interpreter& interpreter) const
  1169. {
  1170. #define __BYTECODE_OP(op) \
  1171. case Instruction::Type::op: \
  1172. return static_cast<Bytecode::Op::op const&>(*this).execute_impl(interpreter);
  1173. switch (type()) {
  1174. ENUMERATE_BYTECODE_OPS(__BYTECODE_OP)
  1175. default:
  1176. VERIFY_NOT_REACHED();
  1177. }
  1178. #undef __BYTECODE_OP
  1179. }
  1180. }