LibJS+LibWeb: Prevent double invocation of [[GetOwnProperty]]

The `[[GetOwnProperty]]` internal method invocation in
`OrdinarySetWithOwnDescriptor` was being invocated again with the same
parameters in the `[[DefineOwnProperty]]` internal method that is also
later called in `OrdinarySetWithOwnDescriptor`.

The `PlatformObject.[[DefineOwnProperty]]` has similair logic.

This change adds an optional parameter to the `[[DefineOwnProperty]]`
internal method so the results of the previous `[[GetOwnProperty]]`
internal method invocation can be re-used.
This commit is contained in:
Jonne Ransijn 2024-11-01 21:03:18 +01:00 committed by Andreas Kling
parent 641c549463
commit 69f96122b6
Notes: github-actions[bot] 2024-11-02 11:27:54 +00:00
20 changed files with 47 additions and 36 deletions

View file

@ -3011,7 +3011,7 @@ public:
JS::Realm& realm() const { return m_realm; } JS::Realm& realm() const { return m_realm; }
private: private:
virtual JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> internal_get_own_property(JS::PropertyKey const&) const override; virtual JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> internal_get_own_property(JS::PropertyKey const&) const override;
virtual JS::ThrowCompletionOr<bool> internal_define_own_property(JS::PropertyKey const&, JS::PropertyDescriptor const&) override; virtual JS::ThrowCompletionOr<bool> internal_define_own_property(JS::PropertyKey const&, JS::PropertyDescriptor const&, Optional<JS::PropertyDescriptor>* precomputed_get_own_property = nullptr) override;
virtual JS::ThrowCompletionOr<bool> internal_delete(JS::PropertyKey const&) override; virtual JS::ThrowCompletionOr<bool> internal_delete(JS::PropertyKey const&) override;
virtual JS::ThrowCompletionOr<bool> internal_set_prototype_of(JS::Object* prototype) override; virtual JS::ThrowCompletionOr<bool> internal_set_prototype_of(JS::Object* prototype) override;
virtual JS::ThrowCompletionOr<bool> internal_prevent_extensions() override; virtual JS::ThrowCompletionOr<bool> internal_prevent_extensions() override;
@ -3129,7 +3129,7 @@ JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> @named_properties_class@
} }
// https://webidl.spec.whatwg.org/#named-properties-object-defineownproperty // https://webidl.spec.whatwg.org/#named-properties-object-defineownproperty
JS::ThrowCompletionOr<bool> @named_properties_class@::internal_define_own_property(JS::PropertyKey const&, JS::PropertyDescriptor const&) JS::ThrowCompletionOr<bool> @named_properties_class@::internal_define_own_property(JS::PropertyKey const&, JS::PropertyDescriptor const&, Optional<JS::PropertyDescriptor>*)
{ {
// 1. Return false. // 1. Return false.
return false; return false;

View file

@ -127,7 +127,7 @@ ThrowCompletionOr<Optional<PropertyDescriptor>> ArgumentsObject::internal_get_ow
} }
// 10.4.4.2 [[DefineOwnProperty]] ( P, Desc ), https://tc39.es/ecma262/#sec-arguments-exotic-objects-defineownproperty-p-desc // 10.4.4.2 [[DefineOwnProperty]] ( P, Desc ), https://tc39.es/ecma262/#sec-arguments-exotic-objects-defineownproperty-p-desc
ThrowCompletionOr<bool> ArgumentsObject::internal_define_own_property(PropertyKey const& property_key, PropertyDescriptor const& descriptor) ThrowCompletionOr<bool> ArgumentsObject::internal_define_own_property(PropertyKey const& property_key, PropertyDescriptor const& descriptor, Optional<PropertyDescriptor>* precomputed_get_own_property)
{ {
// 1. Let map be args.[[ParameterMap]]. // 1. Let map be args.[[ParameterMap]].
auto& map = parameter_map(); auto& map = parameter_map();
@ -150,7 +150,7 @@ ThrowCompletionOr<bool> ArgumentsObject::internal_define_own_property(PropertyKe
} }
// 5. Let allowed be ! OrdinaryDefineOwnProperty(args, P, newArgDesc). // 5. Let allowed be ! OrdinaryDefineOwnProperty(args, P, newArgDesc).
bool allowed = MUST(Object::internal_define_own_property(property_key, new_arg_desc)); bool allowed = MUST(Object::internal_define_own_property(property_key, new_arg_desc, precomputed_get_own_property));
// 6. If allowed is false, return false. // 6. If allowed is false, return false.
if (!allowed) if (!allowed)

View file

@ -23,7 +23,7 @@ public:
Environment& environment() { return m_environment; } Environment& environment() { return m_environment; }
virtual ThrowCompletionOr<Optional<PropertyDescriptor>> internal_get_own_property(PropertyKey const&) const override; virtual ThrowCompletionOr<Optional<PropertyDescriptor>> internal_get_own_property(PropertyKey const&) const override;
virtual ThrowCompletionOr<bool> internal_define_own_property(PropertyKey const&, PropertyDescriptor const&) override; virtual ThrowCompletionOr<bool> internal_define_own_property(PropertyKey const&, PropertyDescriptor const&, Optional<PropertyDescriptor>* precomputed_get_own_property = nullptr) override;
virtual ThrowCompletionOr<Value> internal_get(PropertyKey const&, Value receiver, CacheablePropertyMetadata*, PropertyLookupPhase) const override; virtual ThrowCompletionOr<Value> internal_get(PropertyKey const&, Value receiver, CacheablePropertyMetadata*, PropertyLookupPhase) const override;
virtual ThrowCompletionOr<bool> internal_set(PropertyKey const&, Value value, Value receiver, CacheablePropertyMetadata*) override; virtual ThrowCompletionOr<bool> internal_set(PropertyKey const&, Value value, Value receiver, CacheablePropertyMetadata*) override;
virtual ThrowCompletionOr<bool> internal_delete(PropertyKey const&) override; virtual ThrowCompletionOr<bool> internal_delete(PropertyKey const&) override;

View file

@ -277,7 +277,7 @@ ThrowCompletionOr<Optional<PropertyDescriptor>> Array::internal_get_own_property
} }
// 10.4.2.1 [[DefineOwnProperty]] ( P, Desc ), https://tc39.es/ecma262/#sec-array-exotic-objects-defineownproperty-p-desc // 10.4.2.1 [[DefineOwnProperty]] ( P, Desc ), https://tc39.es/ecma262/#sec-array-exotic-objects-defineownproperty-p-desc
ThrowCompletionOr<bool> Array::internal_define_own_property(PropertyKey const& property_key, PropertyDescriptor const& property_descriptor) ThrowCompletionOr<bool> Array::internal_define_own_property(PropertyKey const& property_key, PropertyDescriptor const& property_descriptor, Optional<PropertyDescriptor>* precomputed_get_own_property)
{ {
auto& vm = this->vm(); auto& vm = this->vm();
@ -303,7 +303,7 @@ ThrowCompletionOr<bool> Array::internal_define_own_property(PropertyKey const& p
return false; return false;
// h. Let succeeded be ! OrdinaryDefineOwnProperty(A, P, Desc). // h. Let succeeded be ! OrdinaryDefineOwnProperty(A, P, Desc).
auto succeeded = MUST(Object::internal_define_own_property(property_key, property_descriptor)); auto succeeded = MUST(Object::internal_define_own_property(property_key, property_descriptor, precomputed_get_own_property));
// i. If succeeded is false, return false. // i. If succeeded is false, return false.
if (!succeeded) if (!succeeded)
@ -319,7 +319,7 @@ ThrowCompletionOr<bool> Array::internal_define_own_property(PropertyKey const& p
} }
// 3. Return ? OrdinaryDefineOwnProperty(A, P, Desc). // 3. Return ? OrdinaryDefineOwnProperty(A, P, Desc).
return Object::internal_define_own_property(property_key, property_descriptor); return Object::internal_define_own_property(property_key, property_descriptor, precomputed_get_own_property);
} }
// NON-STANDARD: Used to reject deletes to ephemeral (non-configurable) length property // NON-STANDARD: Used to reject deletes to ephemeral (non-configurable) length property

View file

@ -48,7 +48,7 @@ public:
virtual ~Array() override = default; virtual ~Array() override = default;
virtual ThrowCompletionOr<Optional<PropertyDescriptor>> internal_get_own_property(PropertyKey const&) const override final; virtual ThrowCompletionOr<Optional<PropertyDescriptor>> internal_get_own_property(PropertyKey const&) const override final;
virtual ThrowCompletionOr<bool> internal_define_own_property(PropertyKey const&, PropertyDescriptor const&) override final; virtual ThrowCompletionOr<bool> internal_define_own_property(PropertyKey const&, PropertyDescriptor const&, Optional<PropertyDescriptor>* precomputed_get_own_property = nullptr) override final;
virtual ThrowCompletionOr<bool> internal_delete(PropertyKey const&) override; virtual ThrowCompletionOr<bool> internal_delete(PropertyKey const&) override;
virtual ThrowCompletionOr<MarkedVector<Value>> internal_own_property_keys() const override final; virtual ThrowCompletionOr<MarkedVector<Value>> internal_own_property_keys() const override final;

View file

@ -82,11 +82,11 @@ ThrowCompletionOr<Optional<PropertyDescriptor>> ModuleNamespaceObject::internal_
} }
// 10.4.6.6 [[DefineOwnProperty]] ( P, Desc ), https://tc39.es/ecma262/#sec-module-namespace-exotic-objects-defineownproperty-p-desc // 10.4.6.6 [[DefineOwnProperty]] ( P, Desc ), https://tc39.es/ecma262/#sec-module-namespace-exotic-objects-defineownproperty-p-desc
ThrowCompletionOr<bool> ModuleNamespaceObject::internal_define_own_property(PropertyKey const& property_key, PropertyDescriptor const& descriptor) ThrowCompletionOr<bool> ModuleNamespaceObject::internal_define_own_property(PropertyKey const& property_key, PropertyDescriptor const& descriptor, Optional<PropertyDescriptor>* precomputed_get_own_property)
{ {
// 1. If Type(P) is Symbol, return ! OrdinaryDefineOwnProperty(O, P, Desc). // 1. If Type(P) is Symbol, return ! OrdinaryDefineOwnProperty(O, P, Desc).
if (property_key.is_symbol()) if (property_key.is_symbol())
return MUST(Object::internal_define_own_property(property_key, descriptor)); return MUST(Object::internal_define_own_property(property_key, descriptor, precomputed_get_own_property));
// 2. Let current be ? O.[[GetOwnProperty]](P). // 2. Let current be ? O.[[GetOwnProperty]](P).
auto current = TRY(internal_get_own_property(property_key)); auto current = TRY(internal_get_own_property(property_key));

View file

@ -24,7 +24,7 @@ public:
virtual ThrowCompletionOr<bool> internal_is_extensible() const override; virtual ThrowCompletionOr<bool> internal_is_extensible() const override;
virtual ThrowCompletionOr<bool> internal_prevent_extensions() override; virtual ThrowCompletionOr<bool> internal_prevent_extensions() override;
virtual ThrowCompletionOr<Optional<PropertyDescriptor>> internal_get_own_property(PropertyKey const&) const override; virtual ThrowCompletionOr<Optional<PropertyDescriptor>> internal_get_own_property(PropertyKey const&) const override;
virtual ThrowCompletionOr<bool> internal_define_own_property(PropertyKey const&, PropertyDescriptor const&) override; virtual ThrowCompletionOr<bool> internal_define_own_property(PropertyKey const&, PropertyDescriptor const&, Optional<PropertyDescriptor>* precomputed_get_own_property = nullptr) override;
virtual ThrowCompletionOr<bool> internal_has_property(PropertyKey const&) const override; virtual ThrowCompletionOr<bool> internal_has_property(PropertyKey const&) const override;
virtual ThrowCompletionOr<Value> internal_get(PropertyKey const&, Value receiver, CacheablePropertyMetadata* = nullptr, PropertyLookupPhase = PropertyLookupPhase::OwnProperty) const override; virtual ThrowCompletionOr<Value> internal_get(PropertyKey const&, Value receiver, CacheablePropertyMetadata* = nullptr, PropertyLookupPhase = PropertyLookupPhase::OwnProperty) const override;
virtual ThrowCompletionOr<bool> internal_set(PropertyKey const&, Value value, Value receiver, CacheablePropertyMetadata*) override; virtual ThrowCompletionOr<bool> internal_set(PropertyKey const&, Value value, Value receiver, CacheablePropertyMetadata*) override;

View file

@ -848,12 +848,12 @@ ThrowCompletionOr<Optional<PropertyDescriptor>> Object::internal_get_own_propert
} }
// 10.1.6 [[DefineOwnProperty]] ( P, Desc ), https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-defineownproperty-p-desc // 10.1.6 [[DefineOwnProperty]] ( P, Desc ), https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-defineownproperty-p-desc
ThrowCompletionOr<bool> Object::internal_define_own_property(PropertyKey const& property_key, PropertyDescriptor const& property_descriptor) ThrowCompletionOr<bool> Object::internal_define_own_property(PropertyKey const& property_key, PropertyDescriptor const& property_descriptor, Optional<PropertyDescriptor>* precomputed_get_own_property)
{ {
VERIFY(property_key.is_valid()); VERIFY(property_key.is_valid());
// 1. Let current be ? O.[[GetOwnProperty]](P). // 1. Let current be ? O.[[GetOwnProperty]](P).
auto current = TRY(internal_get_own_property(property_key)); auto current = precomputed_get_own_property ? *precomputed_get_own_property : TRY(internal_get_own_property(property_key));
// 2. Let extensible be ? IsExtensible(O). // 2. Let extensible be ? IsExtensible(O).
auto extensible = TRY(is_extensible()); auto extensible = TRY(is_extensible());
@ -1009,8 +1009,10 @@ ThrowCompletionOr<bool> Object::ordinary_set_with_own_descriptor(PropertyKey con
if (!receiver.is_object()) if (!receiver.is_object())
return false; return false;
auto& receiver_object = receiver.as_object();
// c. Let existingDescriptor be ? Receiver.[[GetOwnProperty]](P). // c. Let existingDescriptor be ? Receiver.[[GetOwnProperty]](P).
auto existing_descriptor = TRY(receiver.as_object().internal_get_own_property(property_key)); auto existing_descriptor = TRY(receiver_object.internal_get_own_property(property_key));
// d. If existingDescriptor is not undefined, then // d. If existingDescriptor is not undefined, then
if (existing_descriptor.has_value()) { if (existing_descriptor.has_value()) {
@ -1034,15 +1036,15 @@ ThrowCompletionOr<bool> Object::ordinary_set_with_own_descriptor(PropertyKey con
} }
// iv. Return ? Receiver.[[DefineOwnProperty]](P, valueDesc). // iv. Return ? Receiver.[[DefineOwnProperty]](P, valueDesc).
return TRY(receiver.as_object().internal_define_own_property(property_key, value_descriptor)); return TRY(receiver_object.internal_define_own_property(property_key, value_descriptor, &existing_descriptor));
} }
// e. Else, // e. Else,
else { else {
// i. Assert: Receiver does not currently have a property P. // i. Assert: Receiver does not currently have a property P.
VERIFY(!receiver.as_object().storage_has(property_key)); VERIFY(!receiver_object.storage_has(property_key));
// ii. Return ? CreateDataProperty(Receiver, P, V). // ii. Return ? CreateDataProperty(Receiver, P, V).
return TRY(receiver.as_object().create_data_property(property_key, value)); return TRY(receiver_object.create_data_property(property_key, value));
} }
} }

View file

@ -138,7 +138,7 @@ public:
virtual ThrowCompletionOr<bool> internal_is_extensible() const; virtual ThrowCompletionOr<bool> internal_is_extensible() const;
virtual ThrowCompletionOr<bool> internal_prevent_extensions(); virtual ThrowCompletionOr<bool> internal_prevent_extensions();
virtual ThrowCompletionOr<Optional<PropertyDescriptor>> internal_get_own_property(PropertyKey const&) const; virtual ThrowCompletionOr<Optional<PropertyDescriptor>> internal_get_own_property(PropertyKey const&) const;
virtual ThrowCompletionOr<bool> internal_define_own_property(PropertyKey const&, PropertyDescriptor const&); virtual ThrowCompletionOr<bool> internal_define_own_property(PropertyKey const&, PropertyDescriptor const&, Optional<PropertyDescriptor>* precomputed_get_own_property = nullptr);
virtual ThrowCompletionOr<bool> internal_has_property(PropertyKey const&) const; virtual ThrowCompletionOr<bool> internal_has_property(PropertyKey const&) const;
enum class PropertyLookupPhase { enum class PropertyLookupPhase {
OwnProperty, OwnProperty,

View file

@ -336,7 +336,7 @@ ThrowCompletionOr<Optional<PropertyDescriptor>> ProxyObject::internal_get_own_pr
} }
// 10.5.6 [[DefineOwnProperty]] ( P, Desc ), https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc // 10.5.6 [[DefineOwnProperty]] ( P, Desc ), https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc
ThrowCompletionOr<bool> ProxyObject::internal_define_own_property(PropertyKey const& property_key, PropertyDescriptor const& property_descriptor) ThrowCompletionOr<bool> ProxyObject::internal_define_own_property(PropertyKey const& property_key, PropertyDescriptor const& property_descriptor, Optional<PropertyDescriptor>*)
{ {
LIMIT_PROXY_RECURSION_DEPTH(); LIMIT_PROXY_RECURSION_DEPTH();

View file

@ -37,7 +37,7 @@ public:
virtual ThrowCompletionOr<bool> internal_is_extensible() const override; virtual ThrowCompletionOr<bool> internal_is_extensible() const override;
virtual ThrowCompletionOr<bool> internal_prevent_extensions() override; virtual ThrowCompletionOr<bool> internal_prevent_extensions() override;
virtual ThrowCompletionOr<Optional<PropertyDescriptor>> internal_get_own_property(PropertyKey const&) const override; virtual ThrowCompletionOr<Optional<PropertyDescriptor>> internal_get_own_property(PropertyKey const&) const override;
virtual ThrowCompletionOr<bool> internal_define_own_property(PropertyKey const&, PropertyDescriptor const&) override; virtual ThrowCompletionOr<bool> internal_define_own_property(PropertyKey const&, PropertyDescriptor const&, Optional<PropertyDescriptor>* precomputed_get_own_property = nullptr) override;
virtual ThrowCompletionOr<bool> internal_has_property(PropertyKey const&) const override; virtual ThrowCompletionOr<bool> internal_has_property(PropertyKey const&) const override;
virtual ThrowCompletionOr<Value> internal_get(PropertyKey const&, Value receiver, CacheablePropertyMetadata*, PropertyLookupPhase) const override; virtual ThrowCompletionOr<Value> internal_get(PropertyKey const&, Value receiver, CacheablePropertyMetadata*, PropertyLookupPhase) const override;
virtual ThrowCompletionOr<bool> internal_set(PropertyKey const&, Value value, Value receiver, CacheablePropertyMetadata*) override; virtual ThrowCompletionOr<bool> internal_set(PropertyKey const&, Value value, Value receiver, CacheablePropertyMetadata*) override;

View file

@ -113,7 +113,7 @@ ThrowCompletionOr<Optional<PropertyDescriptor>> StringObject::internal_get_own_p
} }
// 10.4.3.2 [[DefineOwnProperty]] ( P, Desc ), https://tc39.es/ecma262/#sec-string-exotic-objects-defineownproperty-p-desc // 10.4.3.2 [[DefineOwnProperty]] ( P, Desc ), https://tc39.es/ecma262/#sec-string-exotic-objects-defineownproperty-p-desc
ThrowCompletionOr<bool> StringObject::internal_define_own_property(PropertyKey const& property_key, PropertyDescriptor const& property_descriptor) ThrowCompletionOr<bool> StringObject::internal_define_own_property(PropertyKey const& property_key, PropertyDescriptor const& property_descriptor, Optional<PropertyDescriptor>* precomputed_get_own_property)
{ {
VERIFY(property_key.is_valid()); VERIFY(property_key.is_valid());
@ -130,7 +130,7 @@ ThrowCompletionOr<bool> StringObject::internal_define_own_property(PropertyKey c
} }
// 3. Return ! OrdinaryDefineOwnProperty(S, P, Desc). // 3. Return ! OrdinaryDefineOwnProperty(S, P, Desc).
return Object::internal_define_own_property(property_key, property_descriptor); return Object::internal_define_own_property(property_key, property_descriptor, precomputed_get_own_property);
} }
// 10.4.3.3 [[OwnPropertyKeys]] ( ), https://tc39.es/ecma262/#sec-string-exotic-objects-ownpropertykeys // 10.4.3.3 [[OwnPropertyKeys]] ( ), https://tc39.es/ecma262/#sec-string-exotic-objects-ownpropertykeys

View file

@ -28,7 +28,7 @@ protected:
private: private:
virtual ThrowCompletionOr<Optional<PropertyDescriptor>> internal_get_own_property(PropertyKey const&) const override; virtual ThrowCompletionOr<Optional<PropertyDescriptor>> internal_get_own_property(PropertyKey const&) const override;
virtual ThrowCompletionOr<bool> internal_define_own_property(PropertyKey const&, PropertyDescriptor const&) override; virtual ThrowCompletionOr<bool> internal_define_own_property(PropertyKey const&, PropertyDescriptor const&, Optional<PropertyDescriptor>* precomputed_get_own_property = nullptr) override;
virtual ThrowCompletionOr<MarkedVector<Value>> internal_own_property_keys() const override; virtual ThrowCompletionOr<MarkedVector<Value>> internal_own_property_keys() const override;
virtual bool is_string_object() const final { return true; } virtual bool is_string_object() const final { return true; }

View file

@ -268,7 +268,7 @@ public:
} }
// 10.4.5.3 [[DefineOwnProperty]] ( P, Desc ), https://tc39.es/ecma262/#sec-integer-indexed-exotic-objects-defineownproperty-p-desc // 10.4.5.3 [[DefineOwnProperty]] ( P, Desc ), https://tc39.es/ecma262/#sec-integer-indexed-exotic-objects-defineownproperty-p-desc
virtual ThrowCompletionOr<bool> internal_define_own_property(PropertyKey const& property_key, PropertyDescriptor const& property_descriptor) override virtual ThrowCompletionOr<bool> internal_define_own_property(PropertyKey const& property_key, PropertyDescriptor const& property_descriptor, Optional<PropertyDescriptor>* precomputed_get_own_property = nullptr) override
{ {
VERIFY(property_key.is_valid()); VERIFY(property_key.is_valid());
@ -313,7 +313,7 @@ public:
} }
// 2. Return ! OrdinaryDefineOwnProperty(O, P, Desc). // 2. Return ! OrdinaryDefineOwnProperty(O, P, Desc).
return Object::internal_define_own_property(property_key, property_descriptor); return Object::internal_define_own_property(property_key, property_descriptor, precomputed_get_own_property);
} }
// 10.4.5.4 [[Get]] ( P, Receiver ), 10.4.5.4 [[Get]] ( P, Receiver ) // 10.4.5.4 [[Get]] ( P, Receiver ), 10.4.5.4 [[Get]] ( P, Receiver )

View file

@ -253,10 +253,12 @@ JS::ThrowCompletionOr<bool> PlatformObject::internal_set(JS::PropertyKey const&
} }
// https://webidl.spec.whatwg.org/#legacy-platform-object-defineownproperty // https://webidl.spec.whatwg.org/#legacy-platform-object-defineownproperty
JS::ThrowCompletionOr<bool> PlatformObject::internal_define_own_property(JS::PropertyKey const& property_name, JS::PropertyDescriptor const& property_descriptor) JS::ThrowCompletionOr<bool> PlatformObject::internal_define_own_property(JS::PropertyKey const& property_name, JS::PropertyDescriptor const& property_descriptor, Optional<JS::PropertyDescriptor>* precomputed_get_own_property)
{ {
Optional<JS::PropertyDescriptor> get_own_property_result = {};
if (!m_legacy_platform_object_flags.has_value() || m_legacy_platform_object_flags->has_global_interface_extended_attribute) if (!m_legacy_platform_object_flags.has_value() || m_legacy_platform_object_flags->has_global_interface_extended_attribute)
return Base::internal_define_own_property(property_name, property_descriptor); return Base::internal_define_own_property(property_name, property_descriptor, precomputed_get_own_property);
auto& vm = this->vm(); auto& vm = this->vm();
@ -287,7 +289,14 @@ JS::ThrowCompletionOr<bool> PlatformObject::internal_define_own_property(JS::Pro
// 2. If O implements an interface with the [LegacyOverrideBuiltIns] extended attribute or O does not have an own property named P, then: // 2. If O implements an interface with the [LegacyOverrideBuiltIns] extended attribute or O does not have an own property named P, then:
// NOTE: Own property lookup has to be done manually instead of using Object::has_own_property, as that would use the overridden internal_get_own_property. // NOTE: Own property lookup has to be done manually instead of using Object::has_own_property, as that would use the overridden internal_get_own_property.
if (m_legacy_platform_object_flags->has_legacy_override_built_ins_interface_extended_attribute || !TRY(Object::internal_get_own_property(property_name)).has_value()) { if (!m_legacy_platform_object_flags->has_legacy_override_built_ins_interface_extended_attribute) {
// AD-HOC: Avoid computing the [[GetOwnProperty]] multiple times.
if (!precomputed_get_own_property) {
get_own_property_result = TRY(Object::internal_get_own_property(property_name));
precomputed_get_own_property = &get_own_property_result;
}
}
if (m_legacy_platform_object_flags->has_legacy_override_built_ins_interface_extended_attribute || precomputed_get_own_property->has_value()) {
// 1. If creating is false and O does not implement an interface with a named property setter, then return false. // 1. If creating is false and O does not implement an interface with a named property setter, then return false.
if (!creating && !m_legacy_platform_object_flags->has_named_property_setter) if (!creating && !m_legacy_platform_object_flags->has_named_property_setter)
return false; return false;
@ -308,7 +317,7 @@ JS::ThrowCompletionOr<bool> PlatformObject::internal_define_own_property(JS::Pro
} }
// 3. Return ! OrdinaryDefineOwnProperty(O, P, Desc). // 3. Return ! OrdinaryDefineOwnProperty(O, P, Desc).
return Object::internal_define_own_property(property_name, property_descriptor); return Object::internal_define_own_property(property_name, property_descriptor, precomputed_get_own_property);
} }
// https://webidl.spec.whatwg.org/#legacy-platform-object-delete // https://webidl.spec.whatwg.org/#legacy-platform-object-delete

View file

@ -37,7 +37,7 @@ public:
// ^JS::Object // ^JS::Object
virtual JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> internal_get_own_property(JS::PropertyKey const&) const override; virtual JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> internal_get_own_property(JS::PropertyKey const&) const override;
virtual JS::ThrowCompletionOr<bool> internal_set(JS::PropertyKey const&, JS::Value, JS::Value, JS::CacheablePropertyMetadata* = nullptr) override; virtual JS::ThrowCompletionOr<bool> internal_set(JS::PropertyKey const&, JS::Value, JS::Value, JS::CacheablePropertyMetadata* = nullptr) override;
virtual JS::ThrowCompletionOr<bool> internal_define_own_property(JS::PropertyKey const&, JS::PropertyDescriptor const&) override; virtual JS::ThrowCompletionOr<bool> internal_define_own_property(JS::PropertyKey const&, JS::PropertyDescriptor const&, Optional<JS::PropertyDescriptor>* precomputed_get_own_property = nullptr) override;
virtual JS::ThrowCompletionOr<bool> internal_delete(JS::PropertyKey const&) override; virtual JS::ThrowCompletionOr<bool> internal_delete(JS::PropertyKey const&) override;
virtual JS::ThrowCompletionOr<bool> internal_prevent_extensions() override; virtual JS::ThrowCompletionOr<bool> internal_prevent_extensions() override;
virtual JS::ThrowCompletionOr<JS::MarkedVector<JS::Value>> internal_own_property_keys() const override; virtual JS::ThrowCompletionOr<JS::MarkedVector<JS::Value>> internal_own_property_keys() const override;

View file

@ -528,13 +528,13 @@ JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> Location::internal_get_o
} }
// 7.10.5.6 [[DefineOwnProperty]] ( P, Desc ), https://html.spec.whatwg.org/multipage/history.html#location-defineownproperty // 7.10.5.6 [[DefineOwnProperty]] ( P, Desc ), https://html.spec.whatwg.org/multipage/history.html#location-defineownproperty
JS::ThrowCompletionOr<bool> Location::internal_define_own_property(JS::PropertyKey const& property_key, JS::PropertyDescriptor const& descriptor) JS::ThrowCompletionOr<bool> Location::internal_define_own_property(JS::PropertyKey const& property_key, JS::PropertyDescriptor const& descriptor, Optional<JS::PropertyDescriptor>* precomputed_get_own_property)
{ {
// 1. If IsPlatformObjectSameOrigin(this) is true, then: // 1. If IsPlatformObjectSameOrigin(this) is true, then:
if (HTML::is_platform_object_same_origin(*this)) { if (HTML::is_platform_object_same_origin(*this)) {
// 1. If the value of the [[DefaultProperties]] internal slot of this contains P, then return false. // 1. If the value of the [[DefaultProperties]] internal slot of this contains P, then return false.
// 2. Return ? OrdinaryDefineOwnProperty(this, P, Desc). // 2. Return ? OrdinaryDefineOwnProperty(this, P, Desc).
return JS::Object::internal_define_own_property(property_key, descriptor); return JS::Object::internal_define_own_property(property_key, descriptor, precomputed_get_own_property);
} }
// 2. Throw a "SecurityError" DOMException. // 2. Throw a "SecurityError" DOMException.

View file

@ -59,7 +59,7 @@ public:
virtual JS::ThrowCompletionOr<bool> internal_is_extensible() const override; virtual JS::ThrowCompletionOr<bool> internal_is_extensible() const override;
virtual JS::ThrowCompletionOr<bool> internal_prevent_extensions() override; virtual JS::ThrowCompletionOr<bool> internal_prevent_extensions() override;
virtual JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> internal_get_own_property(JS::PropertyKey const&) const override; virtual JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> internal_get_own_property(JS::PropertyKey const&) const override;
virtual JS::ThrowCompletionOr<bool> internal_define_own_property(JS::PropertyKey const&, JS::PropertyDescriptor const&) override; virtual JS::ThrowCompletionOr<bool> internal_define_own_property(JS::PropertyKey const&, JS::PropertyDescriptor const&, Optional<JS::PropertyDescriptor>* precomputed_get_own_property = nullptr) override;
virtual JS::ThrowCompletionOr<JS::Value> internal_get(JS::PropertyKey const&, JS::Value receiver, JS::CacheablePropertyMetadata*, PropertyLookupPhase) const override; virtual JS::ThrowCompletionOr<JS::Value> internal_get(JS::PropertyKey const&, JS::Value receiver, JS::CacheablePropertyMetadata*, PropertyLookupPhase) const override;
virtual JS::ThrowCompletionOr<bool> internal_set(JS::PropertyKey const&, JS::Value value, JS::Value receiver, JS::CacheablePropertyMetadata*) override; virtual JS::ThrowCompletionOr<bool> internal_set(JS::PropertyKey const&, JS::Value value, JS::Value receiver, JS::CacheablePropertyMetadata*) override;
virtual JS::ThrowCompletionOr<bool> internal_delete(JS::PropertyKey const&) override; virtual JS::ThrowCompletionOr<bool> internal_delete(JS::PropertyKey const&) override;

View file

@ -133,7 +133,7 @@ JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> WindowProxy::internal_ge
} }
// 7.4.6 [[DefineOwnProperty]] ( P, Desc ), https://html.spec.whatwg.org/multipage/window-object.html#windowproxy-defineownproperty // 7.4.6 [[DefineOwnProperty]] ( P, Desc ), https://html.spec.whatwg.org/multipage/window-object.html#windowproxy-defineownproperty
JS::ThrowCompletionOr<bool> WindowProxy::internal_define_own_property(JS::PropertyKey const& property_key, JS::PropertyDescriptor const& descriptor) JS::ThrowCompletionOr<bool> WindowProxy::internal_define_own_property(JS::PropertyKey const& property_key, JS::PropertyDescriptor const& descriptor, Optional<JS::PropertyDescriptor>*)
{ {
// 1. Let W be the value of the [[Window]] internal slot of this. // 1. Let W be the value of the [[Window]] internal slot of this.

View file

@ -26,7 +26,7 @@ public:
virtual JS::ThrowCompletionOr<bool> internal_is_extensible() const override; virtual JS::ThrowCompletionOr<bool> internal_is_extensible() const override;
virtual JS::ThrowCompletionOr<bool> internal_prevent_extensions() override; virtual JS::ThrowCompletionOr<bool> internal_prevent_extensions() override;
virtual JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> internal_get_own_property(JS::PropertyKey const&) const override; virtual JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> internal_get_own_property(JS::PropertyKey const&) const override;
virtual JS::ThrowCompletionOr<bool> internal_define_own_property(JS::PropertyKey const&, JS::PropertyDescriptor const&) override; virtual JS::ThrowCompletionOr<bool> internal_define_own_property(JS::PropertyKey const&, JS::PropertyDescriptor const&, Optional<JS::PropertyDescriptor>* precomputed_get_own_property = nullptr) override;
virtual JS::ThrowCompletionOr<JS::Value> internal_get(JS::PropertyKey const&, JS::Value receiver, JS::CacheablePropertyMetadata*, PropertyLookupPhase) const override; virtual JS::ThrowCompletionOr<JS::Value> internal_get(JS::PropertyKey const&, JS::Value receiver, JS::CacheablePropertyMetadata*, PropertyLookupPhase) const override;
virtual JS::ThrowCompletionOr<bool> internal_set(JS::PropertyKey const&, JS::Value value, JS::Value receiver, JS::CacheablePropertyMetadata*) override; virtual JS::ThrowCompletionOr<bool> internal_set(JS::PropertyKey const&, JS::Value value, JS::Value receiver, JS::CacheablePropertyMetadata*) override;
virtual JS::ThrowCompletionOr<bool> internal_delete(JS::PropertyKey const&) override; virtual JS::ThrowCompletionOr<bool> internal_delete(JS::PropertyKey const&) override;