Prechádzať zdrojové kódy

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.
davidot 4 rokov pred
rodič
commit
7310713d11

+ 0 - 16
Userland/Libraries/LibJS/Runtime/ArrayPrototype.cpp

@@ -348,14 +348,6 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::push)
     auto* this_object = vm.this_value(global_object).to_object(global_object);
     auto* this_object = vm.this_value(global_object).to_object(global_object);
     if (!this_object)
     if (!this_object)
         return {};
         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);
     auto length = length_of_array_like(global_object, *this_object);
     if (vm.exception())
     if (vm.exception())
         return {};
         return {};
@@ -434,14 +426,6 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::pop)
     auto* this_object = vm.this_value(global_object).to_object(global_object);
     auto* this_object = vm.this_value(global_object).to_object(global_object);
     if (!this_object)
     if (!this_object)
         return {};
         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);
     auto length = length_of_array_like(global_object, *this_object);
     if (vm.exception())
     if (vm.exception())
         return {};
         return {};

+ 15 - 0
Userland/Libraries/LibJS/Tests/builtins/Array/Array.prototype.pop.js

@@ -26,4 +26,19 @@ describe("normal behavior", () => {
         expect(a.pop()).toBeUndefined();
         expect(a.pop()).toBeUndefined();
         expect(a).toEqual([]);
         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];
+    });
 });
 });