AbstractOperations.cpp 44 KB

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