mirror of
https://github.com/RGBCube/serenity
synced 2025-06-01 03:18:11 +00:00
LibJS: Introduce AbstractOperations.{cpp,h} and move various AOs there
Value.{cpp,h} has become a dumping ground, let's change that. Things that are directly related to Values (e.g. bitwise/binary ops, equality related functions) can remain, but everything else that's not a Value or Object method and globally required (not just a static function somewhere) is being moved. Also convert to east-const while we're here. I haven't touched IteratorOperations.{cpp,h}, it seems fine to still have those separately.
This commit is contained in:
parent
c03a3dc5b7
commit
55db9539a5
18 changed files with 153 additions and 100 deletions
|
@ -7,13 +7,13 @@
|
|||
|
||||
#include <AK/AllOf.h>
|
||||
#include <AK/FlyString.h>
|
||||
#include <AK/Result.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <AK/Utf8View.h>
|
||||
#include <LibCrypto/BigInt/SignedBigInteger.h>
|
||||
#include <LibCrypto/NumberTheory/ModularFunctions.h>
|
||||
#include <LibJS/Heap/Heap.h>
|
||||
#include <LibJS/Runtime/AbstractOperations.h>
|
||||
#include <LibJS/Runtime/Accessor.h>
|
||||
#include <LibJS/Runtime/Array.h>
|
||||
#include <LibJS/Runtime/BigInt.h>
|
||||
|
@ -38,7 +38,7 @@
|
|||
namespace JS {
|
||||
|
||||
// Used in various abstract operations to make it obvious when a non-optional return value must be discarded.
|
||||
static const double INVALID { 0 };
|
||||
static constexpr double INVALID { 0 };
|
||||
|
||||
static inline bool same_type_for_equality(const Value& lhs, const Value& rhs)
|
||||
{
|
||||
|
@ -1495,97 +1495,4 @@ TriState abstract_relation(GlobalObject& global_object, bool left_first, Value l
|
|||
return TriState::False;
|
||||
}
|
||||
|
||||
// 7.3.10 GetMethod ( V, P ), https://tc39.es/ecma262/#sec-getmethod
|
||||
Function* get_method(GlobalObject& global_object, Value value, const PropertyName& property_name)
|
||||
{
|
||||
auto& vm = global_object.vm();
|
||||
auto* object = value.to_object(global_object);
|
||||
if (vm.exception())
|
||||
return nullptr;
|
||||
auto property_value = object->get(property_name);
|
||||
if (vm.exception())
|
||||
return nullptr;
|
||||
if (property_value.is_empty() || property_value.is_nullish())
|
||||
return nullptr;
|
||||
if (!property_value.is_function()) {
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotAFunction, property_value.to_string_without_side_effects());
|
||||
return nullptr;
|
||||
}
|
||||
return &property_value.as_function();
|
||||
}
|
||||
|
||||
// 7.3.18 LengthOfArrayLike ( obj ), https://tc39.es/ecma262/#sec-lengthofarraylike
|
||||
size_t length_of_array_like(GlobalObject& global_object, const Object& object)
|
||||
{
|
||||
auto& vm = global_object.vm();
|
||||
auto result = object.get(vm.names.length).value_or(js_undefined());
|
||||
if (vm.exception())
|
||||
return INVALID;
|
||||
return result.to_length(global_object);
|
||||
}
|
||||
|
||||
// 7.3.22 SpeciesConstructor ( O, defaultConstructor ), https://tc39.es/ecma262/#sec-speciesconstructor
|
||||
Function* species_constructor(GlobalObject& global_object, const Object& object, Function& default_constructor)
|
||||
{
|
||||
auto& vm = global_object.vm();
|
||||
auto constructor = object.get(vm.names.constructor).value_or(js_undefined());
|
||||
if (vm.exception())
|
||||
return nullptr;
|
||||
if (constructor.is_undefined())
|
||||
return &default_constructor;
|
||||
if (!constructor.is_object()) {
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotAConstructor, constructor.to_string_without_side_effects());
|
||||
return nullptr;
|
||||
}
|
||||
auto species = constructor.as_object().get(vm.well_known_symbol_species()).value_or(js_undefined());
|
||||
if (species.is_nullish())
|
||||
return &default_constructor;
|
||||
if (species.is_constructor())
|
||||
return &species.as_function();
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotAConstructor, species.to_string_without_side_effects());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// 7.2.1 RequireObjectCoercible ( argument ), https://tc39.es/ecma262/#sec-requireobjectcoercible
|
||||
Value require_object_coercible(GlobalObject& global_object, Value value)
|
||||
{
|
||||
auto& vm = global_object.vm();
|
||||
if (value.is_nullish()) {
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotObjectCoercible, value.to_string_without_side_effects());
|
||||
return {};
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
// 7.3.19 CreateListFromArrayLike ( obj [ , elementTypes ] ), https://tc39.es/ecma262/#sec-createlistfromarraylike
|
||||
MarkedValueList create_list_from_array_like(GlobalObject& global_object, Value value, AK::Function<Result<void, ErrorType>(Value)> check_value)
|
||||
{
|
||||
auto& vm = global_object.vm();
|
||||
auto& heap = global_object.heap();
|
||||
if (!value.is_object()) {
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotAnObject, value.to_string_without_side_effects());
|
||||
return MarkedValueList { heap };
|
||||
}
|
||||
auto& array_like = value.as_object();
|
||||
auto length = length_of_array_like(global_object, array_like);
|
||||
if (vm.exception())
|
||||
return MarkedValueList { heap };
|
||||
auto list = MarkedValueList { heap };
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
auto index_name = String::number(i);
|
||||
auto next = array_like.get(index_name).value_or(js_undefined());
|
||||
if (vm.exception())
|
||||
return MarkedValueList { heap };
|
||||
if (check_value) {
|
||||
auto result = check_value(next);
|
||||
if (result.is_error()) {
|
||||
vm.throw_exception<TypeError>(global_object, result.release_error());
|
||||
return MarkedValueList { heap };
|
||||
}
|
||||
}
|
||||
list.append(next);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue