Op.h 45 KB

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