mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-29 19:10:26 +00:00
LibJS: Make Array.prototype.shift generic
This commit is contained in:
parent
690eb3bb8a
commit
7c1e2adf8a
Notes:
sideshowbarker
2024-07-18 12:16:45 +09:00
Author: https://github.com/davidot Commit: https://github.com/SerenityOS/serenity/commit/7c1e2adf8a1 Pull-request: https://github.com/SerenityOS/serenity/pull/8025 Reviewed-by: https://github.com/linusg
2 changed files with 51 additions and 6 deletions
|
@ -246,15 +246,50 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::pop)
|
|||
// 23.1.3.24 Array.prototype.shift ( ), https://tc39.es/ecma262/#sec-array.prototype.shift
|
||||
JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::shift)
|
||||
{
|
||||
auto* array = Array::typed_this(vm, global_object);
|
||||
if (!array)
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
if (array->indexed_properties().is_empty())
|
||||
return js_undefined();
|
||||
auto result = array->indexed_properties().take_first(array);
|
||||
auto length = length_of_array_like(global_object, *this_object);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
return result.value.value_or(js_undefined());
|
||||
if (length == 0) {
|
||||
this_object->put(vm.names.length, Value(0));
|
||||
if (vm.exception())
|
||||
return {};
|
||||
return js_undefined();
|
||||
}
|
||||
auto first = this_object->get(0).value_or(js_undefined());
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
for (size_t k = 1; k < length; ++k) {
|
||||
size_t from = k;
|
||||
size_t to = k - 1;
|
||||
bool from_present = this_object->has_property(from);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (from_present) {
|
||||
auto from_value = this_object->get(from).value_or(js_undefined());
|
||||
if (vm.exception())
|
||||
return {};
|
||||
this_object->put(to, from_value);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
} else {
|
||||
this_object->delete_property(to);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
this_object->delete_property(length - 1);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
|
||||
this_object->put(vm.names.length, Value(length - 1));
|
||||
if (vm.exception())
|
||||
return {};
|
||||
return first;
|
||||
}
|
||||
|
||||
// 23.1.3.30 Array.prototype.toString ( ), https://tc39.es/ecma262/#sec-array.prototype.tostring
|
||||
|
|
|
@ -100,6 +100,16 @@ describe("ability to work with generic non-array objects", () => {
|
|||
expect(Array.prototype.includes.call({ length: 5, 2: "foo" }, "foo")).toBeTrue();
|
||||
});
|
||||
|
||||
test("shift", () => {
|
||||
expect(Array.prototype.shift.call({})).toBeUndefined();
|
||||
expect(Array.prototype.shift.call({ length: 0 })).toBeUndefined();
|
||||
|
||||
const o = { length: 5, 0: "a", 1: "b", 3: "c" };
|
||||
const front = Array.prototype.shift.call(o);
|
||||
expect(front).toEqual("a");
|
||||
expect(o).toEqual({ length: 4, 0: "b", 2: "c" });
|
||||
});
|
||||
|
||||
const o = { length: 5, 0: "foo", 1: "bar", 3: "baz" };
|
||||
|
||||
test("every", () => {
|
||||
|
|
Loading…
Reference in a new issue