AbstractOperations.cpp 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019
  1. /*
  2. * Copyright (c) 2020-2021, Linus Groh <linusg@serenityos.org>
  3. * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include <AK/CharacterTypes.h>
  8. #include <AK/Function.h>
  9. #include <AK/Optional.h>
  10. #include <AK/TemporaryChange.h>
  11. #include <AK/Utf16View.h>
  12. #include <LibJS/Bytecode/Interpreter.h>
  13. #include <LibJS/Interpreter.h>
  14. #include <LibJS/Parser.h>
  15. #include <LibJS/Runtime/AbstractOperations.h>
  16. #include <LibJS/Runtime/Accessor.h>
  17. #include <LibJS/Runtime/ArgumentsObject.h>
  18. #include <LibJS/Runtime/Array.h>
  19. #include <LibJS/Runtime/BoundFunction.h>
  20. #include <LibJS/Runtime/Completion.h>
  21. #include <LibJS/Runtime/DeclarativeEnvironment.h>
  22. #include <LibJS/Runtime/ECMAScriptFunctionObject.h>
  23. #include <LibJS/Runtime/ErrorTypes.h>
  24. #include <LibJS/Runtime/FunctionEnvironment.h>
  25. #include <LibJS/Runtime/FunctionObject.h>
  26. #include <LibJS/Runtime/GlobalObject.h>
  27. #include <LibJS/Runtime/Object.h>
  28. #include <LibJS/Runtime/ObjectEnvironment.h>
  29. #include <LibJS/Runtime/PropertyDescriptor.h>
  30. #include <LibJS/Runtime/PropertyKey.h>
  31. #include <LibJS/Runtime/ProxyObject.h>
  32. #include <LibJS/Runtime/Reference.h>
  33. namespace JS {
  34. // 7.2.1 RequireObjectCoercible ( argument ), https://tc39.es/ecma262/#sec-requireobjectcoercible
  35. ThrowCompletionOr<Value> require_object_coercible(GlobalObject& global_object, Value value)
  36. {
  37. auto& vm = global_object.vm();
  38. if (value.is_nullish())
  39. return vm.throw_completion<TypeError>(global_object, ErrorType::NotObjectCoercible, value.to_string_without_side_effects());
  40. return value;
  41. }
  42. // 7.3.14 Call ( F, V [ , argumentsList ] ), https://tc39.es/ecma262/#sec-call
  43. ThrowCompletionOr<Value> call_impl(GlobalObject& global_object, Value function, Value this_value, Optional<MarkedValueList> arguments_list)
  44. {
  45. auto& vm = global_object.vm();
  46. // 1. If argumentsList is not present, set argumentsList to a new empty List.
  47. if (!arguments_list.has_value())
  48. arguments_list = MarkedValueList { global_object.heap() };
  49. // 2. If IsCallable(F) is false, throw a TypeError exception.
  50. if (!function.is_function())
  51. return vm.throw_completion<TypeError>(global_object, ErrorType::NotAFunction, function.to_string_without_side_effects());
  52. // 3. Return ? F.[[Call]](V, argumentsList).
  53. return function.as_function().internal_call(this_value, move(*arguments_list));
  54. }
  55. // 7.3.15 Construct ( F [ , argumentsList [ , newTarget ] ] ), https://tc39.es/ecma262/#sec-construct
  56. ThrowCompletionOr<Object*> construct(GlobalObject& global_object, FunctionObject& function, Optional<MarkedValueList> arguments_list, FunctionObject* new_target)
  57. {
  58. // 1. If newTarget is not present, set newTarget to F.
  59. if (!new_target)
  60. new_target = &function;
  61. // 2. If argumentsList is not present, set argumentsList to a new empty List.
  62. if (!arguments_list.has_value())
  63. arguments_list = MarkedValueList { global_object.heap() };
  64. // 3. Return ? F.[[Construct]](argumentsList, newTarget).
  65. return function.internal_construct(move(*arguments_list), *new_target);
  66. }
  67. // 7.3.19 LengthOfArrayLike ( obj ), https://tc39.es/ecma262/#sec-lengthofarraylike
  68. ThrowCompletionOr<size_t> length_of_array_like(GlobalObject& global_object, Object const& object)
  69. {
  70. auto& vm = global_object.vm();
  71. auto result = TRY(object.get(vm.names.length));
  72. return result.to_length(global_object);
  73. }
  74. // 7.3.20 CreateListFromArrayLike ( obj [ , elementTypes ] ), https://tc39.es/ecma262/#sec-createlistfromarraylike
  75. ThrowCompletionOr<MarkedValueList> create_list_from_array_like(GlobalObject& global_object, Value value, Function<ThrowCompletionOr<void>(Value)> check_value)
  76. {
  77. auto& vm = global_object.vm();
  78. auto& heap = global_object.heap();
  79. // 1. If elementTypes is not present, set elementTypes to « Undefined, Null, Boolean, String, Symbol, Number, BigInt, Object ».
  80. // 2. If Type(obj) is not Object, throw a TypeError exception.
  81. if (!value.is_object())
  82. return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObject, value.to_string_without_side_effects());
  83. auto& array_like = value.as_object();
  84. // 3. Let len be ? LengthOfArrayLike(obj).
  85. auto length = TRY(length_of_array_like(global_object, array_like));
  86. // 4. Let list be a new empty List.
  87. auto list = MarkedValueList { heap };
  88. // 5. Let index be 0.
  89. // 6. Repeat, while index < len,
  90. for (size_t i = 0; i < length; ++i) {
  91. // a. Let indexName be ! ToString(𝔽(index)).
  92. auto index_name = PropertyKey { i };
  93. // b. Let next be ? Get(obj, indexName).
  94. auto next = TRY(array_like.get(index_name));
  95. // c. If Type(next) is not an element of elementTypes, throw a TypeError exception.
  96. if (check_value)
  97. TRY(check_value(next));
  98. // d. Append next as the last element of list.
  99. list.append(next);
  100. }
  101. // 7. Return list.
  102. return ThrowCompletionOr(move(list));
  103. }
  104. // 7.3.23 SpeciesConstructor ( O, defaultConstructor ), https://tc39.es/ecma262/#sec-speciesconstructor
  105. ThrowCompletionOr<FunctionObject*> species_constructor(GlobalObject& global_object, Object const& object, FunctionObject& default_constructor)
  106. {
  107. auto& vm = global_object.vm();
  108. // 1. Let C be ? Get(O, "constructor").
  109. auto constructor = TRY(object.get(vm.names.constructor));
  110. // 2. If C is undefined, return defaultConstructor.
  111. if (constructor.is_undefined())
  112. return &default_constructor;
  113. // 3. If Type(C) is not Object, throw a TypeError exception.
  114. if (!constructor.is_object())
  115. return vm.throw_completion<TypeError>(global_object, ErrorType::NotAConstructor, constructor.to_string_without_side_effects());
  116. // 4. Let S be ? Get(C, @@species).
  117. auto species = TRY(constructor.as_object().get(*vm.well_known_symbol_species()));
  118. // 5. If S is either undefined or null, return defaultConstructor.
  119. if (species.is_nullish())
  120. return &default_constructor;
  121. // 6. If IsConstructor(S) is true, return S.
  122. if (species.is_constructor())
  123. return &species.as_function();
  124. // 7. Throw a TypeError exception.
  125. return vm.throw_completion<TypeError>(global_object, ErrorType::NotAConstructor, species.to_string_without_side_effects());
  126. }
  127. // 7.3.25 GetFunctionRealm ( obj ), https://tc39.es/ecma262/#sec-getfunctionrealm
  128. ThrowCompletionOr<Realm*> get_function_realm(GlobalObject& global_object, FunctionObject const& function)
  129. {
  130. auto& vm = global_object.vm();
  131. // 1. Assert: ! IsCallable(obj) is true.
  132. // 2. If obj has a [[Realm]] internal slot, then
  133. if (function.realm()) {
  134. // a. Return obj.[[Realm]].
  135. return function.realm();
  136. }
  137. // 3. If obj is a bound function exotic object, then
  138. if (is<BoundFunction>(function)) {
  139. auto& bound_function = static_cast<BoundFunction const&>(function);
  140. // a. Let target be obj.[[BoundTargetFunction]].
  141. auto& target = bound_function.bound_target_function();
  142. // b. Return ? GetFunctionRealm(target).
  143. return get_function_realm(global_object, target);
  144. }
  145. // 4. If obj is a Proxy exotic object, then
  146. if (is<ProxyObject>(function)) {
  147. auto& proxy = static_cast<ProxyObject const&>(function);
  148. // a. If obj.[[ProxyHandler]] is null, throw a TypeError exception.
  149. if (proxy.is_revoked())
  150. return vm.throw_completion<TypeError>(global_object, ErrorType::ProxyRevoked);
  151. // b. Let proxyTarget be obj.[[ProxyTarget]].
  152. auto& proxy_target = proxy.target();
  153. // c. Return ? GetFunctionRealm(proxyTarget).
  154. VERIFY(proxy_target.is_function());
  155. return get_function_realm(global_object, static_cast<FunctionObject const&>(proxy_target));
  156. }
  157. // 5. Return the current Realm Record.
  158. return vm.current_realm();
  159. }
  160. // 8.5.2.1 InitializeBoundName ( name, value, environment ), 8.5.2.1 InitializeBoundName ( name, value, environment )
  161. ThrowCompletionOr<void> initialize_bound_name(GlobalObject& global_object, FlyString const& name, Value value, Environment* environment)
  162. {
  163. auto& vm = global_object.vm();
  164. // 1. If environment is not undefined, then
  165. if (environment) {
  166. // a. Perform environment.InitializeBinding(name, value).
  167. MUST(environment->initialize_binding(global_object, name, value));
  168. // b. Return NormalCompletion(undefined).
  169. return {};
  170. }
  171. // 2. Else,
  172. else {
  173. // a. Let lhs be ResolveBinding(name).
  174. auto lhs = vm.resolve_binding(name);
  175. // b. Return ? PutValue(lhs, value).
  176. return TRY(lhs.put_value(global_object, value));
  177. }
  178. VERIFY_NOT_REACHED();
  179. }
  180. // 10.1.6.2 IsCompatiblePropertyDescriptor ( Extensible, Desc, Current ), https://tc39.es/ecma262/#sec-iscompatiblepropertydescriptor
  181. bool is_compatible_property_descriptor(bool extensible, PropertyDescriptor const& descriptor, Optional<PropertyDescriptor> const& current)
  182. {
  183. // 1. Return ValidateAndApplyPropertyDescriptor(undefined, undefined, Extensible, Desc, Current).
  184. return validate_and_apply_property_descriptor(nullptr, {}, extensible, descriptor, current);
  185. }
  186. // 10.1.6.3 ValidateAndApplyPropertyDescriptor ( O, P, extensible, Desc, current ), https://tc39.es/ecma262/#sec-validateandapplypropertydescriptor
  187. bool validate_and_apply_property_descriptor(Object* object, PropertyKey const& property_name, bool extensible, PropertyDescriptor const& descriptor, Optional<PropertyDescriptor> const& current)
  188. {
  189. // 1. Assert: If O is not undefined, then IsPropertyKey(P) is true.
  190. if (object)
  191. VERIFY(property_name.is_valid());
  192. // 2. If current is undefined, then
  193. if (!current.has_value()) {
  194. // a. If extensible is false, return false.
  195. if (!extensible)
  196. return false;
  197. // b. Assert: extensible is true.
  198. // c. If IsGenericDescriptor(Desc) is true or IsDataDescriptor(Desc) is true, then
  199. if (descriptor.is_generic_descriptor() || descriptor.is_data_descriptor()) {
  200. // i. If O is not undefined, create an own data property named P of object O whose [[Value]], [[Writable]],
  201. // [[Enumerable]], and [[Configurable]] attribute values are described by Desc.
  202. // If the value of an attribute field of Desc is absent, the attribute of the newly created property is set
  203. // to its default value.
  204. if (object) {
  205. auto value = descriptor.value.value_or(js_undefined());
  206. object->storage_set(property_name, { value, descriptor.attributes() });
  207. }
  208. }
  209. // d. Else,
  210. else {
  211. // i. Assert: ! IsAccessorDescriptor(Desc) is true.
  212. VERIFY(descriptor.is_accessor_descriptor());
  213. // ii. If O is not undefined, create an own accessor property named P of object O whose [[Get]], [[Set]],
  214. // [[Enumerable]], and [[Configurable]] attribute values are described by Desc.
  215. // If the value of an attribute field of Desc is absent, the attribute of the newly created property is set
  216. // to its default value.
  217. if (object) {
  218. auto accessor = Accessor::create(object->vm(), descriptor.get.value_or(nullptr), descriptor.set.value_or(nullptr));
  219. object->storage_set(property_name, { accessor, descriptor.attributes() });
  220. }
  221. }
  222. // e. Return true.
  223. return true;
  224. }
  225. // 3. If every field in Desc is absent, return true.
  226. if (descriptor.is_empty())
  227. return true;
  228. // 4. If current.[[Configurable]] is false, then
  229. if (!*current->configurable) {
  230. // a. If Desc.[[Configurable]] is present and its value is true, return false.
  231. if (descriptor.configurable.has_value() && *descriptor.configurable)
  232. return false;
  233. // b. If Desc.[[Enumerable]] is present and ! SameValue(Desc.[[Enumerable]], current.[[Enumerable]]) is false, return false.
  234. if (descriptor.enumerable.has_value() && *descriptor.enumerable != *current->enumerable)
  235. return false;
  236. }
  237. // 5. If ! IsGenericDescriptor(Desc) is true, then
  238. if (descriptor.is_generic_descriptor()) {
  239. // a. NOTE: No further validation is required.
  240. }
  241. // 6. Else if ! SameValue(! IsDataDescriptor(current), ! IsDataDescriptor(Desc)) is false, then
  242. else if (current->is_data_descriptor() != descriptor.is_data_descriptor()) {
  243. // a. If current.[[Configurable]] is false, return false.
  244. if (!*current->configurable)
  245. return false;
  246. // b. If IsDataDescriptor(current) is true, then
  247. if (current->is_data_descriptor()) {
  248. // If O is not undefined, convert the property named P of object O from a data property to an accessor property.
  249. // Preserve the existing values of the converted property's [[Configurable]] and [[Enumerable]] attributes and
  250. // set the rest of the property's attributes to their default values.
  251. if (object) {
  252. auto accessor = Accessor::create(object->vm(), nullptr, nullptr);
  253. object->storage_set(property_name, { accessor, current->attributes() });
  254. }
  255. }
  256. // c. Else,
  257. else {
  258. // If O is not undefined, convert the property named P of object O from an accessor property to a data property.
  259. // Preserve the existing values of the converted property's [[Configurable]] and [[Enumerable]] attributes and
  260. // set the rest of the property's attributes to their default values.
  261. if (object) {
  262. auto value = js_undefined();
  263. object->storage_set(property_name, { value, current->attributes() });
  264. }
  265. }
  266. }
  267. // 7. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) are both true, then
  268. else if (current->is_data_descriptor() && descriptor.is_data_descriptor()) {
  269. // a. If current.[[Configurable]] is false and current.[[Writable]] is false, then
  270. if (!*current->configurable && !*current->writable) {
  271. // i. If Desc.[[Writable]] is present and Desc.[[Writable]] is true, return false.
  272. if (descriptor.writable.has_value() && *descriptor.writable)
  273. return false;
  274. // ii. If Desc.[[Value]] is present and SameValue(Desc.[[Value]], current.[[Value]]) is false, return false.
  275. if (descriptor.value.has_value() && !same_value(*descriptor.value, *current->value))
  276. return false;
  277. // iii. Return true.
  278. return true;
  279. }
  280. }
  281. // 8. Else,
  282. else {
  283. // a. Assert: ! IsAccessorDescriptor(current) and ! IsAccessorDescriptor(Desc) are both true.
  284. VERIFY(current->is_accessor_descriptor());
  285. VERIFY(descriptor.is_accessor_descriptor());
  286. // b. If current.[[Configurable]] is false, then
  287. if (!*current->configurable) {
  288. // i. If Desc.[[Set]] is present and SameValue(Desc.[[Set]], current.[[Set]]) is false, return false.
  289. if (descriptor.set.has_value() && *descriptor.set != *current->set)
  290. return false;
  291. // ii. If Desc.[[Get]] is present and SameValue(Desc.[[Get]], current.[[Get]]) is false, return false.
  292. if (descriptor.get.has_value() && *descriptor.get != *current->get)
  293. return false;
  294. // iii. Return true.
  295. return true;
  296. }
  297. }
  298. // 9. If O is not undefined, then
  299. if (object) {
  300. // a. For each field of Desc that is present, set the corresponding attribute of the property named P of object O to the value of the field.
  301. Value value;
  302. if (descriptor.is_accessor_descriptor() || (current->is_accessor_descriptor() && !descriptor.is_data_descriptor())) {
  303. auto* getter = descriptor.get.value_or(current->get.value_or(nullptr));
  304. auto* setter = descriptor.set.value_or(current->set.value_or(nullptr));
  305. value = Accessor::create(object->vm(), getter, setter);
  306. } else {
  307. value = descriptor.value.value_or(current->value.value_or({}));
  308. }
  309. PropertyAttributes attributes;
  310. attributes.set_writable(descriptor.writable.value_or(current->writable.value_or(false)));
  311. attributes.set_enumerable(descriptor.enumerable.value_or(current->enumerable.value_or(false)));
  312. attributes.set_configurable(descriptor.configurable.value_or(current->configurable.value_or(false)));
  313. object->storage_set(property_name, { value, attributes });
  314. }
  315. // 10. Return true.
  316. return true;
  317. }
  318. // 10.1.14 GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto ), https://tc39.es/ecma262/#sec-getprototypefromconstructor
  319. ThrowCompletionOr<Object*> get_prototype_from_constructor(GlobalObject& global_object, FunctionObject const& constructor, Object* (GlobalObject::*intrinsic_default_prototype)())
  320. {
  321. auto& vm = global_object.vm();
  322. // 1. Assert: intrinsicDefaultProto is this specification's name of an intrinsic object. The corresponding object must be an intrinsic that is intended to be used as the [[Prototype]] value of an object.
  323. // 2. Let proto be ? Get(constructor, "prototype").
  324. auto prototype = TRY(constructor.get(vm.names.prototype));
  325. // 3. If Type(proto) is not Object, then
  326. if (!prototype.is_object()) {
  327. // a. Let realm be ? GetFunctionRealm(constructor).
  328. auto* realm = TRY(get_function_realm(global_object, constructor));
  329. // b. Set proto to realm's intrinsic object named intrinsicDefaultProto.
  330. prototype = (realm->global_object().*intrinsic_default_prototype)();
  331. }
  332. // 4. Return proto.
  333. return &prototype.as_object();
  334. }
  335. // 9.1.2.2 NewDeclarativeEnvironment ( E ), https://tc39.es/ecma262/#sec-newdeclarativeenvironment
  336. DeclarativeEnvironment* new_declarative_environment(Environment& environment)
  337. {
  338. auto& global_object = environment.global_object();
  339. return global_object.heap().allocate<DeclarativeEnvironment>(global_object, &environment);
  340. }
  341. // 9.1.2.3 NewObjectEnvironment ( O, W, E ), https://tc39.es/ecma262/#sec-newobjectenvironment
  342. ObjectEnvironment* new_object_environment(Object& object, bool is_with_environment, Environment* environment)
  343. {
  344. auto& global_object = object.global_object();
  345. return global_object.heap().allocate<ObjectEnvironment>(global_object, object, is_with_environment ? ObjectEnvironment::IsWithEnvironment::Yes : ObjectEnvironment::IsWithEnvironment::No, environment);
  346. }
  347. // 9.1.2.4 NewFunctionEnvironment ( F, newTarget ), https://tc39.es/ecma262/#sec-newfunctionenvironment
  348. FunctionEnvironment* new_function_environment(ECMAScriptFunctionObject& function, Object* new_target)
  349. {
  350. auto& global_object = function.global_object();
  351. // 1. Let env be a new function Environment Record containing no bindings.
  352. auto* env = global_object.heap().allocate<FunctionEnvironment>(global_object, function.environment());
  353. // 2. Set env.[[FunctionObject]] to F.
  354. env->set_function_object(function);
  355. // 3. If F.[[ThisMode]] is lexical, set env.[[ThisBindingStatus]] to lexical.
  356. if (function.this_mode() == ECMAScriptFunctionObject::ThisMode::Lexical)
  357. env->set_this_binding_status(FunctionEnvironment::ThisBindingStatus::Lexical);
  358. // 4. Else, set env.[[ThisBindingStatus]] to uninitialized.
  359. else
  360. env->set_this_binding_status(FunctionEnvironment::ThisBindingStatus::Uninitialized);
  361. // 5. Set env.[[NewTarget]] to newTarget.
  362. env->set_new_target(new_target ?: js_undefined());
  363. // 6. Set env.[[OuterEnv]] to F.[[Environment]].
  364. // NOTE: Done in step 1 via the FunctionEnvironment constructor.
  365. // 7. Return env.
  366. return env;
  367. }
  368. PrivateEnvironment* new_private_environment(VM& vm, PrivateEnvironment* outer)
  369. {
  370. return vm.heap().allocate<PrivateEnvironment>(vm.current_realm()->global_object(), outer);
  371. }
  372. // 9.4.3 GetThisEnvironment ( ), https://tc39.es/ecma262/#sec-getthisenvironment
  373. Environment& get_this_environment(VM& vm)
  374. {
  375. for (auto* env = vm.lexical_environment(); env; env = env->outer_environment()) {
  376. if (env->has_this_binding())
  377. return *env;
  378. }
  379. VERIFY_NOT_REACHED();
  380. }
  381. // 13.3.7.2 GetSuperConstructor ( ), https://tc39.es/ecma262/#sec-getsuperconstructor
  382. Object* get_super_constructor(VM& vm)
  383. {
  384. // 1. Let envRec be GetThisEnvironment().
  385. auto& env = get_this_environment(vm);
  386. // 2. Assert: envRec is a function Environment Record.
  387. // 3. Let activeFunction be envRec.[[FunctionObject]].
  388. // 4. Assert: activeFunction is an ECMAScript function object.
  389. auto& active_function = verify_cast<FunctionEnvironment>(env).function_object();
  390. // 5. Let superConstructor be ! activeFunction.[[GetPrototypeOf]]().
  391. auto* super_constructor = MUST(active_function.internal_get_prototype_of());
  392. // 6. Return superConstructor.
  393. return super_constructor;
  394. }
  395. // 13.3.7.3 MakeSuperPropertyReference ( actualThis, propertyKey, strict ), https://tc39.es/ecma262/#sec-makesuperpropertyreference
  396. ThrowCompletionOr<Reference> make_super_property_reference(GlobalObject& global_object, Value actual_this, PropertyKey const& property_key, bool strict)
  397. {
  398. auto& vm = global_object.vm();
  399. // 1. Let env be GetThisEnvironment().
  400. auto& env = verify_cast<FunctionEnvironment>(get_this_environment(vm));
  401. // 2. Assert: env.HasSuperBinding() is true.
  402. VERIFY(env.has_super_binding());
  403. // 3. Let baseValue be ? env.GetSuperBase().
  404. auto base_value = TRY(env.get_super_base());
  405. // 4. Let bv be ? RequireObjectCoercible(baseValue).
  406. auto bv = TRY(require_object_coercible(global_object, base_value));
  407. // 5. Return the Reference Record { [[Base]]: bv, [[ReferencedName]]: propertyKey, [[Strict]]: strict, [[ThisValue]]: actualThis }.
  408. // 6. NOTE: This returns a Super Reference Record.
  409. return Reference { bv, property_key, actual_this, strict };
  410. }
  411. // 19.2.1.1 PerformEval ( x, callerRealm, strictCaller, direct ), https://tc39.es/ecma262/#sec-performeval
  412. ThrowCompletionOr<Value> perform_eval(Value x, GlobalObject& caller_realm, CallerMode strict_caller, EvalMode direct)
  413. {
  414. VERIFY(direct == EvalMode::Direct || strict_caller == CallerMode::NonStrict);
  415. if (!x.is_string())
  416. return x;
  417. auto& vm = caller_realm.vm();
  418. auto& eval_realm = vm.running_execution_context().realm;
  419. auto& code_string = x.as_string();
  420. Parser parser { Lexer { code_string.string() } };
  421. auto program = parser.parse_program(strict_caller == CallerMode::Strict);
  422. if (parser.has_errors()) {
  423. auto& error = parser.errors()[0];
  424. return vm.throw_completion<SyntaxError>(caller_realm, error.to_string());
  425. }
  426. auto strict_eval = strict_caller == CallerMode::Strict;
  427. if (program->is_strict_mode())
  428. strict_eval = true;
  429. auto& running_context = vm.running_execution_context();
  430. Environment* lexical_environment;
  431. Environment* variable_environment;
  432. PrivateEnvironment* private_environment;
  433. if (direct == EvalMode::Direct) {
  434. lexical_environment = new_declarative_environment(*running_context.lexical_environment);
  435. variable_environment = running_context.variable_environment;
  436. private_environment = running_context.private_environment;
  437. } else {
  438. lexical_environment = new_declarative_environment(eval_realm->global_environment());
  439. variable_environment = &eval_realm->global_environment();
  440. private_environment = nullptr;
  441. }
  442. if (strict_eval)
  443. variable_environment = lexical_environment;
  444. if (direct == EvalMode::Direct && !strict_eval) {
  445. // NOTE: Non-strict direct eval() forces us to deoptimize variable accesses.
  446. // Mark the variable environment chain as screwed since we will not be able
  447. // to rely on cached environment coordinates from this point on.
  448. variable_environment->set_permanently_screwed_by_eval();
  449. }
  450. // 18. If runningContext is not already suspended, suspend runningContext.
  451. // FIXME: We don't have this concept yet.
  452. ExecutionContext eval_context(vm.heap());
  453. eval_context.realm = eval_realm;
  454. eval_context.variable_environment = variable_environment;
  455. eval_context.lexical_environment = lexical_environment;
  456. eval_context.private_environment = private_environment;
  457. TRY(vm.push_execution_context(eval_context, eval_realm->global_object()));
  458. ScopeGuard pop_guard = [&] {
  459. vm.pop_execution_context();
  460. };
  461. TRY(eval_declaration_instantiation(vm, eval_realm->global_object(), program, variable_environment, lexical_environment, private_environment, strict_eval));
  462. TemporaryChange scope_change_strict(vm.running_execution_context().is_strict_mode, strict_eval);
  463. Value eval_result;
  464. if (auto* bytecode_interpreter = Bytecode::Interpreter::current()) {
  465. auto executable = JS::Bytecode::Generator::generate(program);
  466. executable.name = "eval"sv;
  467. if (JS::Bytecode::g_dump_bytecode)
  468. executable.dump();
  469. eval_result = TRY(bytecode_interpreter->run(executable));
  470. } else {
  471. auto& ast_interpreter = vm.interpreter();
  472. // FIXME: We need to use evaluate_statements() here because Program::execute() calls global_declaration_instantiation() when it shouldn't
  473. eval_result = program->evaluate_statements(ast_interpreter, caller_realm);
  474. }
  475. if (auto* exception = vm.exception())
  476. return throw_completion(exception->value());
  477. else
  478. return eval_result.value_or(js_undefined());
  479. }
  480. // 19.2.1.3 EvalDeclarationInstantiation ( body, varEnv, lexEnv, privateEnv, strict ), https://tc39.es/ecma262/#sec-evaldeclarationinstantiation
  481. ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, GlobalObject& global_object, Program const& program, Environment* variable_environment, Environment* lexical_environment, PrivateEnvironment* private_environment, bool strict)
  482. {
  483. // FIXME: I'm not sure if the global object is correct here. And this is quite a crucial spot!
  484. GlobalEnvironment* global_var_environment = variable_environment->is_global_environment() ? static_cast<GlobalEnvironment*>(variable_environment) : nullptr;
  485. if (!strict) {
  486. if (global_var_environment) {
  487. program.for_each_var_declared_name([&](auto const& name) {
  488. if (global_var_environment->has_lexical_declaration(name)) {
  489. vm.throw_exception<SyntaxError>(global_object, ErrorType::TopLevelVariableAlreadyDeclared, name);
  490. return IterationDecision::Break;
  491. }
  492. return IterationDecision::Continue;
  493. });
  494. }
  495. auto* this_environment = lexical_environment;
  496. while (this_environment != variable_environment) {
  497. if (!is<ObjectEnvironment>(*this_environment)) {
  498. program.for_each_var_declared_name([&](auto const& name) {
  499. if (MUST(this_environment->has_binding(name))) {
  500. vm.throw_exception<SyntaxError>(global_object, ErrorType::TopLevelVariableAlreadyDeclared, name);
  501. return IterationDecision::Break;
  502. }
  503. // FIXME: NOTE: Annex B.3.4 defines alternate semantics for the above step.
  504. // In particular it only throw the syntax error if it is not an environment from a catchclause.
  505. return IterationDecision::Continue;
  506. });
  507. if (auto* exception = vm.exception())
  508. return throw_completion(exception->value());
  509. }
  510. this_environment = this_environment->outer_environment();
  511. VERIFY(this_environment);
  512. }
  513. }
  514. // FIXME: Add Private identifiers check here.
  515. HashTable<FlyString> declared_function_names;
  516. Vector<FunctionDeclaration const&> functions_to_initialize;
  517. program.for_each_var_function_declaration_in_reverse_order([&](FunctionDeclaration const& function) {
  518. if (declared_function_names.set(function.name()) != AK::HashSetResult::InsertedNewEntry)
  519. return IterationDecision::Continue;
  520. if (global_var_environment) {
  521. auto function_definable = global_var_environment->can_declare_global_function(function.name());
  522. if (vm.exception())
  523. return IterationDecision::Break;
  524. if (!function_definable) {
  525. vm.throw_exception<TypeError>(global_object, ErrorType::CannotDeclareGlobalFunction, function.name());
  526. return IterationDecision::Break;
  527. }
  528. }
  529. functions_to_initialize.append(function);
  530. return IterationDecision::Continue;
  531. });
  532. if (auto* exception = vm.exception())
  533. return throw_completion(exception->value());
  534. if (!strict) {
  535. // The spec here uses 'declaredVarNames' but that has not been declared yet.
  536. HashTable<FlyString> hoisted_functions;
  537. program.for_each_function_hoistable_with_annexB_extension([&](FunctionDeclaration& function_declaration) {
  538. auto& function_name = function_declaration.name();
  539. auto* this_environment = lexical_environment;
  540. while (this_environment != variable_environment) {
  541. if (!is<ObjectEnvironment>(*this_environment) && MUST(this_environment->has_binding(function_name)))
  542. return IterationDecision::Continue;
  543. this_environment = this_environment->outer_environment();
  544. VERIFY(this_environment);
  545. }
  546. if (global_var_environment) {
  547. if (global_var_environment->has_lexical_declaration(function_name))
  548. return IterationDecision::Continue;
  549. auto var_definable_or_error = global_var_environment->can_declare_global_var(function_name);
  550. if (var_definable_or_error.is_error())
  551. return IterationDecision::Break;
  552. auto var_definable = var_definable_or_error.release_value();
  553. if (!var_definable)
  554. return IterationDecision::Continue;
  555. }
  556. if (!declared_function_names.contains(function_name) && !hoisted_functions.contains(function_name)) {
  557. if (global_var_environment) {
  558. global_var_environment->create_global_var_binding(function_name, true);
  559. if (vm.exception())
  560. return IterationDecision::Break;
  561. } else {
  562. if (!MUST(variable_environment->has_binding(function_name))) {
  563. MUST(variable_environment->create_mutable_binding(global_object, function_name, true));
  564. MUST(variable_environment->initialize_binding(global_object, function_name, js_undefined()));
  565. }
  566. }
  567. hoisted_functions.set(function_name);
  568. }
  569. function_declaration.set_should_do_additional_annexB_steps();
  570. return IterationDecision::Continue;
  571. });
  572. if (auto* exception = vm.exception())
  573. return throw_completion(exception->value());
  574. }
  575. HashTable<FlyString> declared_var_names;
  576. program.for_each_var_scoped_variable_declaration([&](VariableDeclaration const& declaration) {
  577. declaration.for_each_bound_name([&](auto const& name) {
  578. if (!declared_function_names.contains(name)) {
  579. if (global_var_environment) {
  580. auto variable_definable_or_error = global_var_environment->can_declare_global_var(name);
  581. if (variable_definable_or_error.is_error())
  582. return IterationDecision::Break;
  583. auto variable_definable = variable_definable_or_error.release_value();
  584. if (!variable_definable) {
  585. vm.throw_exception<TypeError>(global_object, ErrorType::CannotDeclareGlobalVariable, name);
  586. return IterationDecision::Break;
  587. }
  588. }
  589. declared_var_names.set(name);
  590. }
  591. return IterationDecision::Continue;
  592. });
  593. if (vm.exception())
  594. return IterationDecision::Break;
  595. return IterationDecision::Continue;
  596. });
  597. if (auto* exception = vm.exception())
  598. return throw_completion(exception->value());
  599. // 14. NOTE: No abnormal terminations occur after this algorithm step unless varEnv is a global Environment Record and the global object is a Proxy exotic object.
  600. program.for_each_lexically_scoped_declaration([&](Declaration const& declaration) {
  601. declaration.for_each_bound_name([&](auto const& name) {
  602. if (declaration.is_constant_declaration())
  603. (void)lexical_environment->create_immutable_binding(global_object, name, true);
  604. else
  605. (void)lexical_environment->create_mutable_binding(global_object, name, false);
  606. if (vm.exception())
  607. return IterationDecision::Break;
  608. return IterationDecision::Continue;
  609. });
  610. if (vm.exception())
  611. return IterationDecision::Break;
  612. return IterationDecision::Continue;
  613. });
  614. if (auto* exception = vm.exception())
  615. return throw_completion(exception->value());
  616. for (auto& declaration : functions_to_initialize) {
  617. auto* function = ECMAScriptFunctionObject::create(global_object, declaration.name(), declaration.body(), declaration.parameters(), declaration.function_length(), lexical_environment, private_environment, declaration.kind(), declaration.is_strict_mode(), declaration.might_need_arguments_object());
  618. if (global_var_environment) {
  619. global_var_environment->create_global_function_binding(declaration.name(), function, true);
  620. if (auto* exception = vm.exception())
  621. return throw_completion(exception->value());
  622. } else {
  623. auto binding_exists = MUST(variable_environment->has_binding(declaration.name()));
  624. if (!binding_exists) {
  625. TRY(variable_environment->create_mutable_binding(global_object, declaration.name(), true));
  626. TRY(variable_environment->initialize_binding(global_object, declaration.name(), function));
  627. } else {
  628. TRY(variable_environment->set_mutable_binding(global_object, declaration.name(), function, false));
  629. }
  630. }
  631. }
  632. for (auto& var_name : declared_var_names) {
  633. if (global_var_environment) {
  634. global_var_environment->create_global_var_binding(var_name, true);
  635. if (auto* exception = vm.exception())
  636. return throw_completion(exception->value());
  637. } else {
  638. auto binding_exists = MUST(variable_environment->has_binding(var_name));
  639. if (!binding_exists) {
  640. TRY(variable_environment->create_mutable_binding(global_object, var_name, true));
  641. TRY(variable_environment->initialize_binding(global_object, var_name, js_undefined()));
  642. }
  643. }
  644. }
  645. return {};
  646. }
  647. // 10.4.4.6 CreateUnmappedArgumentsObject ( argumentsList ), https://tc39.es/ecma262/#sec-createunmappedargumentsobject
  648. Object* create_unmapped_arguments_object(GlobalObject& global_object, Span<Value> arguments)
  649. {
  650. auto& vm = global_object.vm();
  651. // 1. Let len be the number of elements in argumentsList.
  652. auto length = arguments.size();
  653. // 2. Let obj be ! OrdinaryObjectCreate(%Object.prototype%, « [[ParameterMap]] »).
  654. // 3. Set obj.[[ParameterMap]] to undefined.
  655. auto* object = Object::create(global_object, global_object.object_prototype());
  656. object->set_has_parameter_map();
  657. // 4. Perform DefinePropertyOrThrow(obj, "length", PropertyDescriptor { [[Value]]: 𝔽(len), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }).
  658. MUST(object->define_property_or_throw(vm.names.length, { .value = Value(length), .writable = true, .enumerable = false, .configurable = true }));
  659. // 5. Let index be 0.
  660. // 6. Repeat, while index < len,
  661. for (size_t index = 0; index < length; ++index) {
  662. // a. Let val be argumentsList[index].
  663. auto value = arguments[index];
  664. // b. Perform ! CreateDataPropertyOrThrow(obj, ! ToString(𝔽(index)), val).
  665. MUST(object->create_data_property_or_throw(index, value));
  666. // c. Set index to index + 1.
  667. }
  668. // 7. Perform ! DefinePropertyOrThrow(obj, @@iterator, PropertyDescriptor { [[Value]]: %Array.prototype.values%, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }).
  669. auto* array_prototype_values = global_object.array_prototype_values_function();
  670. MUST(object->define_property_or_throw(*vm.well_known_symbol_iterator(), { .value = array_prototype_values, .writable = true, .enumerable = false, .configurable = true }));
  671. // 8. Perform ! DefinePropertyOrThrow(obj, "callee", PropertyDescriptor { [[Get]]: %ThrowTypeError%, [[Set]]: %ThrowTypeError%, [[Enumerable]]: false, [[Configurable]]: false }).
  672. auto* throw_type_error = global_object.throw_type_error_function();
  673. MUST(object->define_property_or_throw(vm.names.callee, { .get = throw_type_error, .set = throw_type_error, .enumerable = false, .configurable = false }));
  674. // 9. Return obj.
  675. return object;
  676. }
  677. // 10.4.4.7 CreateMappedArgumentsObject ( func, formals, argumentsList, env ), https://tc39.es/ecma262/#sec-createmappedargumentsobject
  678. Object* create_mapped_arguments_object(GlobalObject& global_object, FunctionObject& function, Vector<FunctionNode::Parameter> const& formals, Span<Value> arguments, Environment& environment)
  679. {
  680. auto& vm = global_object.vm();
  681. // 1. Assert: formals does not contain a rest parameter, any binding patterns, or any initializers. It may contain duplicate identifiers.
  682. // 2. Let len be the number of elements in argumentsList.
  683. VERIFY(arguments.size() <= NumericLimits<i32>::max());
  684. i32 length = static_cast<i32>(arguments.size());
  685. // 3. Let obj be ! MakeBasicObject(« [[Prototype]], [[Extensible]], [[ParameterMap]] »).
  686. // 4. Set obj.[[GetOwnProperty]] as specified in 10.4.4.1.
  687. // 5. Set obj.[[DefineOwnProperty]] as specified in 10.4.4.2.
  688. // 6. Set obj.[[Get]] as specified in 10.4.4.3.
  689. // 7. Set obj.[[Set]] as specified in 10.4.4.4.
  690. // 8. Set obj.[[Delete]] as specified in 10.4.4.5.
  691. // 9. Set obj.[[Prototype]] to %Object.prototype%.
  692. auto* object = vm.heap().allocate<ArgumentsObject>(global_object, global_object, environment);
  693. VERIFY(!vm.exception());
  694. // 14. Let index be 0.
  695. // 15. Repeat, while index < len,
  696. for (i32 index = 0; index < length; ++index) {
  697. // a. Let val be argumentsList[index].
  698. auto value = arguments[index];
  699. // b. Perform ! CreateDataPropertyOrThrow(obj, ! ToString(𝔽(index)), val).
  700. MUST(object->create_data_property_or_throw(index, value));
  701. // c. Set index to index + 1.
  702. }
  703. // 16. Perform ! DefinePropertyOrThrow(obj, "length", PropertyDescriptor { [[Value]]: 𝔽(len), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }).
  704. MUST(object->define_property_or_throw(vm.names.length, { .value = Value(length), .writable = true, .enumerable = false, .configurable = true }));
  705. // 17. Let mappedNames be a new empty List.
  706. HashTable<FlyString> mapped_names;
  707. // 18. Set index to numberOfParameters - 1.
  708. // 19. Repeat, while index ≥ 0,
  709. VERIFY(formals.size() <= NumericLimits<i32>::max());
  710. for (i32 index = static_cast<i32>(formals.size()) - 1; index >= 0; --index) {
  711. // a. Let name be parameterNames[index].
  712. auto const& name = formals[index].binding.get<FlyString>();
  713. // b. If name is not an element of mappedNames, then
  714. if (mapped_names.contains(name))
  715. continue;
  716. // i. Add name as an element of the list mappedNames.
  717. mapped_names.set(name);
  718. // ii. If index < len, then
  719. if (index < length) {
  720. // 1. Let g be MakeArgGetter(name, env).
  721. // 2. Let p be MakeArgSetter(name, env).
  722. // 3. Perform map.[[DefineOwnProperty]](! ToString(𝔽(index)), PropertyDescriptor { [[Set]]: p, [[Get]]: g, [[Enumerable]]: false, [[Configurable]]: true }).
  723. object->parameter_map().define_native_accessor(
  724. PropertyKey { index },
  725. [&environment, name](VM&, GlobalObject& global_object_getter) -> JS::ThrowCompletionOr<Value> {
  726. return MUST(environment.get_binding_value(global_object_getter, name, false));
  727. },
  728. [&environment, name](VM& vm, GlobalObject& global_object_setter) {
  729. MUST(environment.set_mutable_binding(global_object_setter, name, vm.argument(0), false));
  730. return js_undefined();
  731. },
  732. Attribute::Configurable);
  733. }
  734. }
  735. // 20. Perform ! DefinePropertyOrThrow(obj, @@iterator, PropertyDescriptor { [[Value]]: %Array.prototype.values%, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }).
  736. auto* array_prototype_values = global_object.array_prototype_values_function();
  737. MUST(object->define_property_or_throw(*vm.well_known_symbol_iterator(), { .value = array_prototype_values, .writable = true, .enumerable = false, .configurable = true }));
  738. // 21. Perform ! DefinePropertyOrThrow(obj, "callee", PropertyDescriptor { [[Value]]: func, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }).
  739. MUST(object->define_property_or_throw(vm.names.callee, { .value = &function, .writable = true, .enumerable = false, .configurable = true }));
  740. // 22. Return obj.
  741. return object;
  742. }
  743. // 7.1.21 CanonicalNumericIndexString ( argument ), https://tc39.es/ecma262/#sec-canonicalnumericindexstring
  744. Value canonical_numeric_index_string(GlobalObject& global_object, PropertyKey const& property_name)
  745. {
  746. // NOTE: If the property name is a number type (An implementation-defined optimized
  747. // property key type), it can be treated as a string property that has already been
  748. // converted successfully into a canonical numeric index.
  749. VERIFY(property_name.is_string() || property_name.is_number());
  750. if (property_name.is_number())
  751. return Value(property_name.as_number());
  752. // 1. Assert: Type(argument) is String.
  753. auto argument = Value(js_string(global_object.vm(), property_name.as_string()));
  754. // 2. If argument is "-0", return -0𝔽.
  755. if (argument.as_string().string() == "-0")
  756. return Value(-0.0);
  757. // 3. Let n be ! ToNumber(argument).
  758. auto n = MUST(argument.to_number(global_object));
  759. // 4. If SameValue(! ToString(n), argument) is false, return undefined.
  760. if (!same_value(MUST(n.to_primitive_string(global_object)), argument))
  761. return js_undefined();
  762. // 5. Return n.
  763. return n;
  764. }
  765. // 22.1.3.17.1 GetSubstitution ( matched, str, position, captures, namedCaptures, replacement ), https://tc39.es/ecma262/#sec-getsubstitution
  766. ThrowCompletionOr<String> get_substitution(GlobalObject& global_object, Utf16View const& matched, Utf16View const& str, size_t position, Span<Value> captures, Value named_captures, Value replacement)
  767. {
  768. auto replace_string = TRY(replacement.to_utf16_string(global_object));
  769. auto replace_view = replace_string.view();
  770. StringBuilder result;
  771. for (size_t i = 0; i < replace_view.length_in_code_units(); ++i) {
  772. u16 curr = replace_view.code_unit_at(i);
  773. if ((curr != '$') || (i + 1 >= replace_view.length_in_code_units())) {
  774. result.append(curr);
  775. continue;
  776. }
  777. u16 next = replace_view.code_unit_at(i + 1);
  778. if (next == '$') {
  779. result.append('$');
  780. ++i;
  781. } else if (next == '&') {
  782. result.append(matched);
  783. ++i;
  784. } else if (next == '`') {
  785. auto substring = str.substring_view(0, position);
  786. result.append(substring);
  787. ++i;
  788. } else if (next == '\'') {
  789. auto tail_pos = position + matched.length_in_code_units();
  790. if (tail_pos < str.length_in_code_units()) {
  791. auto substring = str.substring_view(tail_pos);
  792. result.append(substring);
  793. }
  794. ++i;
  795. } else if (is_ascii_digit(next)) {
  796. bool is_two_digits = (i + 2 < replace_view.length_in_code_units()) && is_ascii_digit(replace_view.code_unit_at(i + 2));
  797. auto capture_postition_string = replace_view.substring_view(i + 1, is_two_digits ? 2 : 1).to_utf8();
  798. auto capture_position = capture_postition_string.to_uint();
  799. if (capture_position.has_value() && (*capture_position > 0) && (*capture_position <= captures.size())) {
  800. auto& value = captures[*capture_position - 1];
  801. if (!value.is_undefined()) {
  802. auto value_string = TRY(value.to_string(global_object));
  803. result.append(value_string);
  804. }
  805. i += is_two_digits ? 2 : 1;
  806. } else {
  807. result.append(curr);
  808. }
  809. } else if (next == '<') {
  810. auto start_position = i + 2;
  811. Optional<size_t> end_position;
  812. for (size_t j = start_position; j < replace_view.length_in_code_units(); ++j) {
  813. if (replace_view.code_unit_at(j) == '>') {
  814. end_position = j;
  815. break;
  816. }
  817. }
  818. if (named_captures.is_undefined() || !end_position.has_value()) {
  819. result.append(curr);
  820. } else {
  821. auto group_name_view = replace_view.substring_view(start_position, *end_position - start_position);
  822. auto group_name = group_name_view.to_utf8(Utf16View::AllowInvalidCodeUnits::Yes);
  823. auto capture = TRY(named_captures.as_object().get(group_name));
  824. if (!capture.is_undefined()) {
  825. auto capture_string = TRY(capture.to_string(global_object));
  826. result.append(capture_string);
  827. }
  828. i = *end_position;
  829. }
  830. } else {
  831. result.append(curr);
  832. }
  833. }
  834. return result.build();
  835. }
  836. }