mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 06:37:43 +00:00
LibJS: Implement the CreateListFromArrayLike() abstract operation
We already have two separate implementations of this, so let's do it properly. The optional value type check is done by a callback function that returns Result<void, ErrorType> - value type accepted or message for TypeError, that is.
This commit is contained in:
parent
5da94b30eb
commit
ad7aa05cc6
3 changed files with 36 additions and 0 deletions
|
@ -111,6 +111,7 @@ class Cell;
|
|||
class Console;
|
||||
class DeferGC;
|
||||
class Error;
|
||||
class ErrorType;
|
||||
class Exception;
|
||||
class Expression;
|
||||
class Accessor;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <AK/AllOf.h>
|
||||
#include <AK/FlyString.h>
|
||||
#include <AK/Result.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <AK/Utf8View.h>
|
||||
|
@ -1418,4 +1419,35 @@ Value require_object_coercible(GlobalObject& global_object, Value value)
|
|||
return value;
|
||||
}
|
||||
|
||||
// 7.3.19 CreateListFromArrayLike, 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#include <AK/BitCast.h>
|
||||
#include <AK/Format.h>
|
||||
#include <AK/Forward.h>
|
||||
#include <AK/Function.h>
|
||||
#include <AK/Result.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/Types.h>
|
||||
#include <LibJS/Forward.h>
|
||||
|
@ -372,6 +374,7 @@ Function* get_method(GlobalObject& global_object, Value, const PropertyName&);
|
|||
size_t length_of_array_like(GlobalObject&, const Object&);
|
||||
Object* species_constructor(GlobalObject&, const Object&, Object& default_constructor);
|
||||
Value require_object_coercible(GlobalObject&, Value);
|
||||
MarkedValueList create_list_from_array_like(GlobalObject&, Value, AK::Function<Result<void, ErrorType>(Value)> = {});
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue