mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 17:27:35 +00:00
LibJS: Bring FlattenIntoArray closer to the specification
This fixes the incorrect exception order and missing exception checks that were caused by the implementation not conforming exactly to the specification.
This commit is contained in:
parent
597cf88c08
commit
271eeadf25
1 changed files with 30 additions and 22 deletions
|
@ -1303,12 +1303,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::keys)
|
|||
}
|
||||
|
||||
// 23.1.3.10.1 FlattenIntoArray ( target, source, sourceLen, start, depth [ , mapperFunction [ , thisArg ] ] ), https://tc39.es/ecma262/#sec-flattenintoarray
|
||||
static size_t flatten_into_array(VM& vm, GlobalObject& global_object, Array& new_array, Object& array, size_t target_index, double depth, Function* mapper_func = {}, Value this_arg = {})
|
||||
static size_t flatten_into_array(GlobalObject& global_object, Object& new_array, Object& array, size_t array_length, size_t target_index, double depth, Function* mapper_func = {}, Value this_arg = {})
|
||||
{
|
||||
VERIFY(!mapper_func || (!this_arg.is_empty() && depth == 1));
|
||||
auto array_length = length_of_array_like(global_object, array);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
auto& vm = global_object.vm();
|
||||
|
||||
for (size_t j = 0; j < array_length; ++j) {
|
||||
auto value_exists = array.has_property(j);
|
||||
|
@ -1328,20 +1326,25 @@ static size_t flatten_into_array(VM& vm, GlobalObject& global_object, Array& new
|
|||
}
|
||||
|
||||
if (depth > 0 && value.is_array(global_object)) {
|
||||
target_index = flatten_into_array(vm, global_object, new_array, value.as_array(), target_index, depth - 1);
|
||||
auto length = length_of_array_like(global_object, value.as_array());
|
||||
if (vm.exception())
|
||||
return {};
|
||||
target_index = flatten_into_array(global_object, new_array, value.as_array(), length, target_index, depth - 1);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
continue;
|
||||
}
|
||||
|
||||
if (target_index >= MAX_ARRAY_LIKE_INDEX) {
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::InvalidIndex);
|
||||
return {};
|
||||
}
|
||||
|
||||
new_array.put(target_index, value);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (!value.is_empty()) {
|
||||
new_array.put(target_index, value);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
++target_index;
|
||||
}
|
||||
++target_index;
|
||||
}
|
||||
return target_index;
|
||||
}
|
||||
|
@ -1353,20 +1356,21 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::flat)
|
|||
if (!this_object)
|
||||
return {};
|
||||
|
||||
auto* new_array = Array::create(global_object);
|
||||
auto length = length_of_array_like(global_object, *this_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
double depth = 1;
|
||||
if (vm.argument_count() > 0) {
|
||||
auto depth_argument = vm.argument(0);
|
||||
if (!depth_argument.is_undefined()) {
|
||||
auto depth_num = depth_argument.to_integer_or_infinity(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
depth = max(depth_num, 0.0);
|
||||
}
|
||||
if (!vm.argument(0).is_undefined()) {
|
||||
auto depth_num = vm.argument(0).to_integer_or_infinity(global_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
depth = max(depth_num, 0.0);
|
||||
}
|
||||
|
||||
flatten_into_array(vm, global_object, *new_array, *this_object, 0, depth);
|
||||
auto* new_array = Array::create(global_object);
|
||||
|
||||
flatten_into_array(global_object, *new_array, *this_object, length, 0, depth);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
return new_array;
|
||||
|
@ -1379,6 +1383,10 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::flat_map)
|
|||
if (!this_object)
|
||||
return {};
|
||||
|
||||
auto length = length_of_array_like(global_object, *this_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
auto* mapper_function = callback_from_args(global_object, "flatMap");
|
||||
if (!mapper_function)
|
||||
return {};
|
||||
|
@ -1388,7 +1396,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::flat_map)
|
|||
// FIXME: Use ArraySpeciesCreate.
|
||||
auto new_array = Array::create(global_object);
|
||||
|
||||
flatten_into_array(vm, global_object, *new_array, *this_object, 0, 1, mapper_function, this_argument);
|
||||
flatten_into_array(global_object, *new_array, *this_object, length, 0, 1, mapper_function, this_argument);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue