mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 19:07:35 +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
|
@ -22,6 +22,7 @@ set(SOURCES
|
||||||
Lexer.cpp
|
Lexer.cpp
|
||||||
MarkupGenerator.cpp
|
MarkupGenerator.cpp
|
||||||
Parser.cpp
|
Parser.cpp
|
||||||
|
Runtime/AbstractOperations.cpp
|
||||||
Runtime/AggregateError.cpp
|
Runtime/AggregateError.cpp
|
||||||
Runtime/AggregateErrorConstructor.cpp
|
Runtime/AggregateErrorConstructor.cpp
|
||||||
Runtime/AggregateErrorPrototype.cpp
|
Runtime/AggregateErrorPrototype.cpp
|
||||||
|
|
115
Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp
Normal file
115
Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, Linus Groh <linusg@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <AK/Function.h>
|
||||||
|
#include <AK/Result.h>
|
||||||
|
#include <LibJS/Runtime/AbstractOperations.h>
|
||||||
|
#include <LibJS/Runtime/BoundFunction.h>
|
||||||
|
#include <LibJS/Runtime/ErrorTypes.h>
|
||||||
|
#include <LibJS/Runtime/Function.h>
|
||||||
|
#include <LibJS/Runtime/GlobalObject.h>
|
||||||
|
#include <LibJS/Runtime/Object.h>
|
||||||
|
#include <LibJS/Runtime/PropertyName.h>
|
||||||
|
|
||||||
|
namespace JS {
|
||||||
|
|
||||||
|
// Used in various abstract operations to make it obvious when a non-optional return value must be discarded.
|
||||||
|
static constexpr double INVALID { 0 };
|
||||||
|
|
||||||
|
// 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.10 GetMethod ( V, P ), https://tc39.es/ecma262/#sec-getmethod
|
||||||
|
Function* get_method(GlobalObject& global_object, Value value, PropertyName const& 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, Object const& 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.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 7.3.22 SpeciesConstructor ( O, defaultConstructor ), https://tc39.es/ecma262/#sec-speciesconstructor
|
||||||
|
Function* species_constructor(GlobalObject& global_object, Object const& 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
21
Userland/Libraries/LibJS/Runtime/AbstractOperations.h
Normal file
21
Userland/Libraries/LibJS/Runtime/AbstractOperations.h
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021, Linus Groh <linusg@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/Forward.h>
|
||||||
|
#include <LibJS/Forward.h>
|
||||||
|
#include <LibJS/Runtime/Value.h>
|
||||||
|
|
||||||
|
namespace JS {
|
||||||
|
|
||||||
|
Value require_object_coercible(GlobalObject&, Value);
|
||||||
|
Function* get_method(GlobalObject& global_object, Value, PropertyName const&);
|
||||||
|
size_t length_of_array_like(GlobalObject&, Object const&);
|
||||||
|
MarkedValueList create_list_from_array_like(GlobalObject&, Value, AK::Function<Result<void, ErrorType>(Value)> = {});
|
||||||
|
Function* species_constructor(GlobalObject&, Object const&, Function& default_constructor);
|
||||||
|
|
||||||
|
}
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/Function.h>
|
#include <AK/Function.h>
|
||||||
|
#include <LibJS/Runtime/AbstractOperations.h>
|
||||||
#include <LibJS/Runtime/ArrayBuffer.h>
|
#include <LibJS/Runtime/ArrayBuffer.h>
|
||||||
#include <LibJS/Runtime/ArrayBufferConstructor.h>
|
#include <LibJS/Runtime/ArrayBufferConstructor.h>
|
||||||
#include <LibJS/Runtime/ArrayBufferPrototype.h>
|
#include <LibJS/Runtime/ArrayBufferPrototype.h>
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <AK/HashTable.h>
|
#include <AK/HashTable.h>
|
||||||
#include <AK/ScopeGuard.h>
|
#include <AK/ScopeGuard.h>
|
||||||
#include <AK/StringBuilder.h>
|
#include <AK/StringBuilder.h>
|
||||||
|
#include <LibJS/Runtime/AbstractOperations.h>
|
||||||
#include <LibJS/Runtime/Array.h>
|
#include <LibJS/Runtime/Array.h>
|
||||||
#include <LibJS/Runtime/ArrayIterator.h>
|
#include <LibJS/Runtime/ArrayIterator.h>
|
||||||
#include <LibJS/Runtime/ArrayPrototype.h>
|
#include <LibJS/Runtime/ArrayPrototype.h>
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <AK/StringBuilder.h>
|
#include <AK/StringBuilder.h>
|
||||||
#include <LibJS/AST.h>
|
#include <LibJS/AST.h>
|
||||||
#include <LibJS/Interpreter.h>
|
#include <LibJS/Interpreter.h>
|
||||||
|
#include <LibJS/Runtime/AbstractOperations.h>
|
||||||
#include <LibJS/Runtime/BoundFunction.h>
|
#include <LibJS/Runtime/BoundFunction.h>
|
||||||
#include <LibJS/Runtime/Error.h>
|
#include <LibJS/Runtime/Error.h>
|
||||||
#include <LibJS/Runtime/Function.h>
|
#include <LibJS/Runtime/Function.h>
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <LibJS/Runtime/AbstractOperations.h>
|
||||||
#include <LibJS/Runtime/Error.h>
|
#include <LibJS/Runtime/Error.h>
|
||||||
#include <LibJS/Runtime/GlobalObject.h>
|
#include <LibJS/Runtime/GlobalObject.h>
|
||||||
#include <LibJS/Runtime/IteratorOperations.h>
|
#include <LibJS/Runtime/IteratorOperations.h>
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <AK/JsonObject.h>
|
#include <AK/JsonObject.h>
|
||||||
#include <AK/JsonParser.h>
|
#include <AK/JsonParser.h>
|
||||||
#include <AK/StringBuilder.h>
|
#include <AK/StringBuilder.h>
|
||||||
|
#include <LibJS/Runtime/AbstractOperations.h>
|
||||||
#include <LibJS/Runtime/Array.h>
|
#include <LibJS/Runtime/Array.h>
|
||||||
#include <LibJS/Runtime/BigIntObject.h>
|
#include <LibJS/Runtime/BigIntObject.h>
|
||||||
#include <LibJS/Runtime/BooleanObject.h>
|
#include <LibJS/Runtime/BooleanObject.h>
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/Function.h>
|
#include <AK/Function.h>
|
||||||
|
#include <LibJS/Runtime/AbstractOperations.h>
|
||||||
#include <LibJS/Runtime/Array.h>
|
#include <LibJS/Runtime/Array.h>
|
||||||
#include <LibJS/Runtime/Error.h>
|
#include <LibJS/Runtime/Error.h>
|
||||||
#include <LibJS/Runtime/GlobalObject.h>
|
#include <LibJS/Runtime/GlobalObject.h>
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <AK/Function.h>
|
#include <AK/Function.h>
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
|
#include <LibJS/Runtime/AbstractOperations.h>
|
||||||
#include <LibJS/Runtime/Accessor.h>
|
#include <LibJS/Runtime/Accessor.h>
|
||||||
#include <LibJS/Runtime/BooleanObject.h>
|
#include <LibJS/Runtime/BooleanObject.h>
|
||||||
#include <LibJS/Runtime/Date.h>
|
#include <LibJS/Runtime/Date.h>
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <AK/Function.h>
|
#include <AK/Function.h>
|
||||||
#include <LibJS/Interpreter.h>
|
#include <LibJS/Interpreter.h>
|
||||||
|
#include <LibJS/Runtime/AbstractOperations.h>
|
||||||
#include <LibJS/Runtime/Error.h>
|
#include <LibJS/Runtime/Error.h>
|
||||||
#include <LibJS/Runtime/GlobalObject.h>
|
#include <LibJS/Runtime/GlobalObject.h>
|
||||||
#include <LibJS/Runtime/Promise.h>
|
#include <LibJS/Runtime/Promise.h>
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <LibJS/Runtime/AbstractOperations.h>
|
||||||
#include <LibJS/Runtime/Accessor.h>
|
#include <LibJS/Runtime/Accessor.h>
|
||||||
#include <LibJS/Runtime/Array.h>
|
#include <LibJS/Runtime/Array.h>
|
||||||
#include <LibJS/Runtime/Error.h>
|
#include <LibJS/Runtime/Error.h>
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/Function.h>
|
#include <AK/Function.h>
|
||||||
|
#include <LibJS/Runtime/AbstractOperations.h>
|
||||||
#include <LibJS/Runtime/Array.h>
|
#include <LibJS/Runtime/Array.h>
|
||||||
#include <LibJS/Runtime/Error.h>
|
#include <LibJS/Runtime/Error.h>
|
||||||
#include <LibJS/Runtime/Function.h>
|
#include <LibJS/Runtime/Function.h>
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/Function.h>
|
#include <AK/Function.h>
|
||||||
|
#include <LibJS/Runtime/AbstractOperations.h>
|
||||||
#include <LibJS/Runtime/Array.h>
|
#include <LibJS/Runtime/Array.h>
|
||||||
#include <LibJS/Runtime/Error.h>
|
#include <LibJS/Runtime/Error.h>
|
||||||
#include <LibJS/Runtime/GlobalObject.h>
|
#include <LibJS/Runtime/GlobalObject.h>
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <AK/Function.h>
|
#include <AK/Function.h>
|
||||||
#include <AK/StringBuilder.h>
|
#include <AK/StringBuilder.h>
|
||||||
#include <LibJS/Heap/Heap.h>
|
#include <LibJS/Heap/Heap.h>
|
||||||
|
#include <LibJS/Runtime/AbstractOperations.h>
|
||||||
#include <LibJS/Runtime/Array.h>
|
#include <LibJS/Runtime/Array.h>
|
||||||
#include <LibJS/Runtime/Error.h>
|
#include <LibJS/Runtime/Error.h>
|
||||||
#include <LibJS/Runtime/GlobalObject.h>
|
#include <LibJS/Runtime/GlobalObject.h>
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/Checked.h>
|
#include <AK/Checked.h>
|
||||||
|
#include <LibJS/Runtime/AbstractOperations.h>
|
||||||
#include <LibJS/Runtime/ArrayBuffer.h>
|
#include <LibJS/Runtime/ArrayBuffer.h>
|
||||||
#include <LibJS/Runtime/GlobalObject.h>
|
#include <LibJS/Runtime/GlobalObject.h>
|
||||||
#include <LibJS/Runtime/IteratorOperations.h>
|
#include <LibJS/Runtime/IteratorOperations.h>
|
||||||
|
|
|
@ -7,13 +7,13 @@
|
||||||
|
|
||||||
#include <AK/AllOf.h>
|
#include <AK/AllOf.h>
|
||||||
#include <AK/FlyString.h>
|
#include <AK/FlyString.h>
|
||||||
#include <AK/Result.h>
|
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
#include <AK/StringBuilder.h>
|
#include <AK/StringBuilder.h>
|
||||||
#include <AK/Utf8View.h>
|
#include <AK/Utf8View.h>
|
||||||
#include <LibCrypto/BigInt/SignedBigInteger.h>
|
#include <LibCrypto/BigInt/SignedBigInteger.h>
|
||||||
#include <LibCrypto/NumberTheory/ModularFunctions.h>
|
#include <LibCrypto/NumberTheory/ModularFunctions.h>
|
||||||
#include <LibJS/Heap/Heap.h>
|
#include <LibJS/Heap/Heap.h>
|
||||||
|
#include <LibJS/Runtime/AbstractOperations.h>
|
||||||
#include <LibJS/Runtime/Accessor.h>
|
#include <LibJS/Runtime/Accessor.h>
|
||||||
#include <LibJS/Runtime/Array.h>
|
#include <LibJS/Runtime/Array.h>
|
||||||
#include <LibJS/Runtime/BigInt.h>
|
#include <LibJS/Runtime/BigInt.h>
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
// Used in various abstract operations to make it obvious when a non-optional return value must be discarded.
|
// 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)
|
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;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <AK/Types.h>
|
#include <AK/Types.h>
|
||||||
#include <LibJS/Forward.h>
|
#include <LibJS/Forward.h>
|
||||||
#include <LibJS/Runtime/BigInt.h>
|
#include <LibJS/Runtime/BigInt.h>
|
||||||
|
#include <LibJS/Runtime/PrimitiveString.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
// 2 ** 53 - 1
|
// 2 ** 53 - 1
|
||||||
|
@ -378,11 +379,6 @@ bool same_value(Value lhs, Value rhs);
|
||||||
bool same_value_zero(Value lhs, Value rhs);
|
bool same_value_zero(Value lhs, Value rhs);
|
||||||
bool same_value_non_numeric(Value lhs, Value rhs);
|
bool same_value_non_numeric(Value lhs, Value rhs);
|
||||||
TriState abstract_relation(GlobalObject&, bool left_first, Value lhs, Value rhs);
|
TriState abstract_relation(GlobalObject&, bool left_first, Value lhs, Value rhs);
|
||||||
Function* get_method(GlobalObject& global_object, Value, const PropertyName&);
|
|
||||||
size_t length_of_array_like(GlobalObject&, const Object&);
|
|
||||||
Function* species_constructor(GlobalObject&, const Object&, Function& default_constructor);
|
|
||||||
Value require_object_coercible(GlobalObject&, Value);
|
|
||||||
MarkedValueList create_list_from_array_like(GlobalObject&, Value, AK::Function<Result<void, ErrorType>(Value)> = {});
|
|
||||||
|
|
||||||
struct ValueTraits : public Traits<Value> {
|
struct ValueTraits : public Traits<Value> {
|
||||||
static unsigned hash(Value value)
|
static unsigned hash(Value value)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue