mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-22 17:24:48 -05:00
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:
parent
641c549463
commit
69f96122b6
Notes:
github-actions[bot]
2024-11-02 11:27:54 +00:00
Author: https://github.com/yyny Commit: https://github.com/LadybirdBrowser/ladybird/commit/69f96122b61 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2114
20 changed files with 47 additions and 36 deletions
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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 )
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue