1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 22:37:35 +00:00

LibJS: Remove fast array paths in ArrayPrototype::{pop, push}

Unfortunately this fast path leads to problems if Array.prototype is
changed. We probably need to find out some way to optimize these methods
by detecting changes to the prototype or other mechanisms.
This commit is contained in:
davidot 2021-07-07 14:07:56 +02:00 committed by Linus Groh
parent 2900c8cf09
commit 7310713d11
2 changed files with 15 additions and 16 deletions

View file

@ -348,14 +348,6 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::push)
auto* this_object = vm.this_value(global_object).to_object(global_object);
if (!this_object)
return {};
if (is<Array>(this_object)) {
auto* array = static_cast<Array*>(this_object);
if (array->length_is_writable()) {
for (size_t i = 0; i < vm.argument_count(); ++i)
array->indexed_properties().append(vm.argument(i));
return Value(static_cast<i32>(array->indexed_properties().array_like_size()));
}
}
auto length = length_of_array_like(global_object, *this_object);
if (vm.exception())
return {};
@ -434,14 +426,6 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::pop)
auto* this_object = vm.this_value(global_object).to_object(global_object);
if (!this_object)
return {};
if (is<Array>(this_object)) {
auto* array = static_cast<Array*>(this_object);
if (array->length_is_writable()) {
if (array->indexed_properties().is_empty())
return js_undefined();
return array->indexed_properties().take_last(array).value.value_or(js_undefined());
}
}
auto length = length_of_array_like(global_object, *this_object);
if (vm.exception())
return {};

View file

@ -26,4 +26,19 @@ describe("normal behavior", () => {
expect(a.pop()).toBeUndefined();
expect(a).toEqual([]);
});
test("array with prototype indexed value", () => {
Array.prototype[1] = 1;
var a = [0];
a.length = 2;
expect(a[1]).toEqual(1);
expect(a.pop()).toEqual(1);
expect(a.length).toEqual(1);
expect(a).toEqual([0]);
expect(a[1]).toEqual(1);
delete Array.prototype[1];
});
});