mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 00:47:45 +00:00
LibJS: Make Array.prototype.reverse generic
This commit is contained in:
parent
516f6240e8
commit
2ef9df989f
2 changed files with 64 additions and 13 deletions
|
@ -680,26 +680,62 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce_right)
|
||||||
// 23.1.3.23 Array.prototype.reverse ( ), https://tc39.es/ecma262/#sec-array.prototype.reverse
|
// 23.1.3.23 Array.prototype.reverse ( ), https://tc39.es/ecma262/#sec-array.prototype.reverse
|
||||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reverse)
|
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reverse)
|
||||||
{
|
{
|
||||||
auto* array = Array::typed_this(vm, global_object);
|
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||||
if (!array)
|
if (!this_object)
|
||||||
|
return {};
|
||||||
|
auto length = length_of_array_like(global_object, *this_object);
|
||||||
|
if (vm.exception())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
if (array->indexed_properties().is_empty())
|
auto middle = length / 2;
|
||||||
return array;
|
for (size_t lower = 0; lower < middle; ++lower) {
|
||||||
|
auto upper = length - lower - 1;
|
||||||
|
|
||||||
MarkedValueList array_reverse(vm.heap());
|
auto lower_exists = this_object->has_property(lower);
|
||||||
auto size = array->indexed_properties().array_like_size();
|
if (vm.exception())
|
||||||
array_reverse.ensure_capacity(size);
|
return {};
|
||||||
|
Value lower_value;
|
||||||
for (ssize_t i = size - 1; i >= 0; --i) {
|
if (lower_exists) {
|
||||||
array_reverse.append(array->get(i));
|
lower_value = this_object->get(lower).value_or(js_undefined());
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
array->set_indexed_property_elements(move(array_reverse));
|
auto upper_exists = this_object->has_property(upper);
|
||||||
|
if (vm.exception())
|
||||||
|
return {};
|
||||||
|
Value upper_value;
|
||||||
|
if (upper_exists) {
|
||||||
|
upper_value = this_object->get(upper).value_or(js_undefined());
|
||||||
|
if (vm.exception())
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
return array;
|
if (lower_exists && upper_exists) {
|
||||||
|
this_object->put(lower, upper_value);
|
||||||
|
if (vm.exception())
|
||||||
|
return {};
|
||||||
|
this_object->put(upper, lower_value);
|
||||||
|
if (vm.exception())
|
||||||
|
return {};
|
||||||
|
} else if (!lower_exists && upper_exists) {
|
||||||
|
this_object->put(lower, upper_value);
|
||||||
|
if (vm.exception())
|
||||||
|
return {};
|
||||||
|
this_object->delete_property(upper);
|
||||||
|
if (vm.exception())
|
||||||
|
return {};
|
||||||
|
} else if (lower_exists && !upper_exists) {
|
||||||
|
this_object->delete_property(lower);
|
||||||
|
if (vm.exception())
|
||||||
|
return {};
|
||||||
|
this_object->put(upper, lower_value);
|
||||||
|
if (vm.exception())
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this_object;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void array_merge_sort(VM& vm, GlobalObject& global_object, Function* compare_func, MarkedValueList& arr_to_sort)
|
static void array_merge_sort(VM& vm, GlobalObject& global_object, Function* compare_func, MarkedValueList& arr_to_sort)
|
||||||
|
|
|
@ -188,4 +188,19 @@ describe("ability to work with generic non-array objects", () => {
|
||||||
);
|
);
|
||||||
expect(visited).toEqual(["baz", "bar", "foo"]);
|
expect(visited).toEqual(["baz", "bar", "foo"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("reverse", () => {
|
||||||
|
expect(Array.prototype.reverse.call(o)).toEqual({
|
||||||
|
length: 5,
|
||||||
|
4: "foo",
|
||||||
|
3: "bar",
|
||||||
|
1: "baz",
|
||||||
|
});
|
||||||
|
expect(Array.prototype.reverse.call({})).toEqual({});
|
||||||
|
expect(Array.prototype.reverse.call({ length: 10 })).toEqual({ length: 10 });
|
||||||
|
expect(Array.prototype.reverse.call({ length: 1, 0: "foo" })).toEqual({
|
||||||
|
length: 1,
|
||||||
|
0: "foo",
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue