diff --git a/Userland/Libraries/LibJS/Forward.h b/Userland/Libraries/LibJS/Forward.h index 2af2650c1c..81404dfa30 100644 --- a/Userland/Libraries/LibJS/Forward.h +++ b/Userland/Libraries/LibJS/Forward.h @@ -111,6 +111,7 @@ class Cell; class Console; class DeferGC; class Error; +class ErrorType; class Exception; class Expression; class Accessor; diff --git a/Userland/Libraries/LibJS/Runtime/Value.cpp b/Userland/Libraries/LibJS/Runtime/Value.cpp index 5120b700ad..df4429f66f 100644 --- a/Userland/Libraries/LibJS/Runtime/Value.cpp +++ b/Userland/Libraries/LibJS/Runtime/Value.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -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(Value)> check_value) +{ + auto& vm = global_object.vm(); + auto& heap = global_object.heap(); + if (!value.is_object()) { + vm.throw_exception(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(global_object, result.release_error()); + return MarkedValueList { heap }; + } + } + list.append(next); + } + return list; +} + } diff --git a/Userland/Libraries/LibJS/Runtime/Value.h b/Userland/Libraries/LibJS/Runtime/Value.h index 7bdfc923d7..601ebe3164 100644 --- a/Userland/Libraries/LibJS/Runtime/Value.h +++ b/Userland/Libraries/LibJS/Runtime/Value.h @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #include #include @@ -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(Value)> = {}); }