Op.h 49 KB

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