From 7df16925806a472712c75602161bcc2e93242cfc Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 5 Oct 2023 08:58:30 +0200 Subject: [PATCH] LibJS: Add Object::may_interfere_with_indexed_property_access() virtual This function must return true if the object may intercept and customize access to indexed properties (properties where the property name is a non-negative integer.) This will be used to implement fast path optimizations for array-like accesses in subsequent commits. --- .../LibWeb/BindingsGenerator/IDLGenerators.cpp | 2 ++ Userland/Libraries/LibJS/Runtime/ArgumentsObject.h | 2 ++ Userland/Libraries/LibJS/Runtime/ModuleNamespaceObject.h | 2 ++ Userland/Libraries/LibJS/Runtime/Object.h | 6 ++++++ Userland/Libraries/LibJS/Runtime/ProxyObject.h | 2 ++ Userland/Libraries/LibJS/Runtime/StringObject.h | 2 ++ Userland/Libraries/LibJS/Runtime/TypedArray.h | 2 ++ Userland/Libraries/LibWeb/Bindings/LegacyPlatformObject.h | 2 ++ Userland/Libraries/LibWeb/HTML/AudioTrackList.h | 2 ++ Userland/Libraries/LibWeb/HTML/Location.h | 2 ++ Userland/Libraries/LibWeb/HTML/VideoTrackList.h | 2 ++ Userland/Libraries/LibWeb/HTML/WindowProxy.h | 2 ++ 12 files changed, 28 insertions(+) diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp index b394d067fe..036922cbd3 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp @@ -2573,6 +2573,8 @@ private: virtual JS::ThrowCompletionOr internal_set_prototype_of(JS::Object* prototype) override; virtual JS::ThrowCompletionOr internal_prevent_extensions() override; + virtual bool may_interfere_with_indexed_property_access() const final { return true; } + JS::Realm& m_realm; // [[Realm]] }; )~~~"); diff --git a/Userland/Libraries/LibJS/Runtime/ArgumentsObject.h b/Userland/Libraries/LibJS/Runtime/ArgumentsObject.h index 166d2430ff..f2d41b4e14 100644 --- a/Userland/Libraries/LibJS/Runtime/ArgumentsObject.h +++ b/Userland/Libraries/LibJS/Runtime/ArgumentsObject.h @@ -27,6 +27,8 @@ public: virtual ThrowCompletionOr internal_set(PropertyKey const&, Value value, Value receiver) override; virtual ThrowCompletionOr internal_delete(PropertyKey const&) override; + virtual bool may_interfere_with_indexed_property_access() const final { return true; } + // [[ParameterMap]] Object& parameter_map() { return *m_parameter_map; } diff --git a/Userland/Libraries/LibJS/Runtime/ModuleNamespaceObject.h b/Userland/Libraries/LibJS/Runtime/ModuleNamespaceObject.h index 7f317ffe50..bddf8e40cd 100644 --- a/Userland/Libraries/LibJS/Runtime/ModuleNamespaceObject.h +++ b/Userland/Libraries/LibJS/Runtime/ModuleNamespaceObject.h @@ -31,6 +31,8 @@ public: virtual ThrowCompletionOr> internal_own_property_keys() const override; virtual void initialize(Realm&) override; + virtual bool may_interfere_with_indexed_property_access() const final { return true; } + private: ModuleNamespaceObject(Realm&, Module* module, Vector exports); diff --git a/Userland/Libraries/LibJS/Runtime/Object.h b/Userland/Libraries/LibJS/Runtime/Object.h index 11e6777665..2885ba6bfa 100644 --- a/Userland/Libraries/LibJS/Runtime/Object.h +++ b/Userland/Libraries/LibJS/Runtime/Object.h @@ -135,6 +135,12 @@ public: virtual ThrowCompletionOr internal_delete(PropertyKey const&); virtual ThrowCompletionOr> internal_own_property_keys() const; + // NOTE: Any subclass of Object that overrides property access slots ([[Get]], [[Set]] etc) + // to customize access to indexed properties (properties where the name is a positive integer) + // must return true for this, to opt out of optimizations that rely on assumptions that + // might not hold when property access behaves differently. + virtual bool may_interfere_with_indexed_property_access() const { return false; } + ThrowCompletionOr ordinary_set_with_own_descriptor(PropertyKey const&, Value, Value, Optional); // 10.4.7 Immutable Prototype Exotic Objects, https://tc39.es/ecma262/#sec-immutable-prototype-exotic-objects diff --git a/Userland/Libraries/LibJS/Runtime/ProxyObject.h b/Userland/Libraries/LibJS/Runtime/ProxyObject.h index 15fe721904..8492aaeb91 100644 --- a/Userland/Libraries/LibJS/Runtime/ProxyObject.h +++ b/Userland/Libraries/LibJS/Runtime/ProxyObject.h @@ -45,6 +45,8 @@ public: virtual ThrowCompletionOr internal_call(Value this_argument, MarkedVector arguments_list) override; virtual ThrowCompletionOr> internal_construct(MarkedVector arguments_list, FunctionObject& new_target) override; + virtual bool may_interfere_with_indexed_property_access() const final { return true; } + private: ProxyObject(Object& target, Object& handler, Object& prototype); diff --git a/Userland/Libraries/LibJS/Runtime/StringObject.h b/Userland/Libraries/LibJS/Runtime/StringObject.h index 9be24bcea0..3dab8b8f92 100644 --- a/Userland/Libraries/LibJS/Runtime/StringObject.h +++ b/Userland/Libraries/LibJS/Runtime/StringObject.h @@ -30,6 +30,8 @@ private: virtual ThrowCompletionOr internal_define_own_property(PropertyKey const&, PropertyDescriptor const&) override; virtual ThrowCompletionOr> internal_own_property_keys() const override; + virtual bool may_interfere_with_indexed_property_access() const final { return true; } + virtual bool is_string_object() const final { return true; } virtual void visit_edges(Visitor&) override; diff --git a/Userland/Libraries/LibJS/Runtime/TypedArray.h b/Userland/Libraries/LibJS/Runtime/TypedArray.h index a721ca8388..d984321eb5 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArray.h +++ b/Userland/Libraries/LibJS/Runtime/TypedArray.h @@ -414,6 +414,8 @@ public: return { move(keys) }; } + virtual bool may_interfere_with_indexed_property_access() const final { return true; } + ReadonlySpan data() const { return { reinterpret_cast(m_viewed_array_buffer->buffer().data() + m_byte_offset), m_array_length }; diff --git a/Userland/Libraries/LibWeb/Bindings/LegacyPlatformObject.h b/Userland/Libraries/LibWeb/Bindings/LegacyPlatformObject.h index 69e8e95eb8..700de6cd80 100644 --- a/Userland/Libraries/LibWeb/Bindings/LegacyPlatformObject.h +++ b/Userland/Libraries/LibWeb/Bindings/LegacyPlatformObject.h @@ -29,6 +29,8 @@ public: virtual JS::ThrowCompletionOr internal_prevent_extensions() override; virtual JS::ThrowCompletionOr> internal_own_property_keys() const override; + virtual bool may_interfere_with_indexed_property_access() const final { return true; } + enum class IgnoreNamedProps { No, Yes, diff --git a/Userland/Libraries/LibWeb/HTML/AudioTrackList.h b/Userland/Libraries/LibWeb/HTML/AudioTrackList.h index f52c8d53ff..14a69b5b0d 100644 --- a/Userland/Libraries/LibWeb/HTML/AudioTrackList.h +++ b/Userland/Libraries/LibWeb/HTML/AudioTrackList.h @@ -51,6 +51,8 @@ private: virtual void initialize(JS::Realm&) override; virtual JS::ThrowCompletionOr> internal_get_own_property(JS::PropertyKey const& property_name) const override; + virtual bool may_interfere_with_indexed_property_access() const final { return true; } + JS::MarkedVector> m_audio_tracks; }; diff --git a/Userland/Libraries/LibWeb/HTML/Location.h b/Userland/Libraries/LibWeb/HTML/Location.h index 1ed9b830c7..756a98014c 100644 --- a/Userland/Libraries/LibWeb/HTML/Location.h +++ b/Userland/Libraries/LibWeb/HTML/Location.h @@ -64,6 +64,8 @@ public: virtual JS::ThrowCompletionOr internal_delete(JS::PropertyKey const&) override; virtual JS::ThrowCompletionOr> internal_own_property_keys() const override; + virtual bool may_interfere_with_indexed_property_access() const final { return true; } + HTML::CrossOriginPropertyDescriptorMap const& cross_origin_property_descriptor_map() const { return m_cross_origin_property_descriptor_map; } HTML::CrossOriginPropertyDescriptorMap& cross_origin_property_descriptor_map() { return m_cross_origin_property_descriptor_map; } diff --git a/Userland/Libraries/LibWeb/HTML/VideoTrackList.h b/Userland/Libraries/LibWeb/HTML/VideoTrackList.h index f0d12ce755..964b5dbc4a 100644 --- a/Userland/Libraries/LibWeb/HTML/VideoTrackList.h +++ b/Userland/Libraries/LibWeb/HTML/VideoTrackList.h @@ -44,6 +44,8 @@ private: virtual void initialize(JS::Realm&) override; virtual JS::ThrowCompletionOr> internal_get_own_property(JS::PropertyKey const& property_name) const override; + virtual bool may_interfere_with_indexed_property_access() const final { return true; } + JS::MarkedVector> m_video_tracks; }; diff --git a/Userland/Libraries/LibWeb/HTML/WindowProxy.h b/Userland/Libraries/LibWeb/HTML/WindowProxy.h index 43dd46e0a1..6d203ce05c 100644 --- a/Userland/Libraries/LibWeb/HTML/WindowProxy.h +++ b/Userland/Libraries/LibWeb/HTML/WindowProxy.h @@ -31,6 +31,8 @@ public: virtual JS::ThrowCompletionOr internal_delete(JS::PropertyKey const&) override; virtual JS::ThrowCompletionOr> internal_own_property_keys() const override; + virtual bool may_interfere_with_indexed_property_access() const final { return true; } + JS::GCPtr window() const { return m_window; } void set_window(JS::NonnullGCPtr);