mirror of
https://github.com/SerenityOS/serenity
synced 2024-10-15 12:23:15 +00:00
LibJS: Add PropertyLookupPhase enum to distinguish Object [[Get]] calls
We can now tell the difference between an own property access and a subsequent (automatic) prototype chain access. This will be used to implement caching of prototype chain accesses.
This commit is contained in:
parent
3945e1a82a
commit
493a04d5fe
|
@ -113,7 +113,7 @@ JS::ThrowCompletionOr<bool> SheetGlobalObject::internal_has_property(JS::Propert
|
|||
return Object::internal_has_property(name);
|
||||
}
|
||||
|
||||
JS::ThrowCompletionOr<JS::Value> SheetGlobalObject::internal_get(const JS::PropertyKey& property_name, JS::Value receiver, JS::CacheablePropertyMetadata*) const
|
||||
JS::ThrowCompletionOr<JS::Value> SheetGlobalObject::internal_get(const JS::PropertyKey& property_name, JS::Value receiver, JS::CacheablePropertyMetadata*, PropertyLookupPhase) const
|
||||
{
|
||||
if (property_name.is_string()) {
|
||||
if (property_name.as_string() == "value") {
|
||||
|
|
|
@ -29,7 +29,7 @@ public:
|
|||
virtual ~SheetGlobalObject() override = default;
|
||||
|
||||
virtual JS::ThrowCompletionOr<bool> internal_has_property(JS::PropertyKey const& name) const override;
|
||||
virtual JS::ThrowCompletionOr<JS::Value> internal_get(JS::PropertyKey const&, JS::Value receiver, JS::CacheablePropertyMetadata*) 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;
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(get_real_cell_contents);
|
||||
|
|
|
@ -33,7 +33,7 @@ void ArgumentsObject::visit_edges(Cell::Visitor& visitor)
|
|||
}
|
||||
|
||||
// 10.4.4.3 [[Get]] ( P, Receiver ), https://tc39.es/ecma262/#sec-arguments-exotic-objects-get-p-receiver
|
||||
ThrowCompletionOr<Value> ArgumentsObject::internal_get(PropertyKey const& property_key, Value receiver, CacheablePropertyMetadata* cacheable_metadata) const
|
||||
ThrowCompletionOr<Value> ArgumentsObject::internal_get(PropertyKey const& property_key, Value receiver, CacheablePropertyMetadata* cacheable_metadata, PropertyLookupPhase phase) const
|
||||
{
|
||||
// 1. Let map be args.[[ParameterMap]].
|
||||
auto& map = *m_parameter_map;
|
||||
|
@ -44,7 +44,7 @@ ThrowCompletionOr<Value> ArgumentsObject::internal_get(PropertyKey const& proper
|
|||
// 3. If isMapped is false, then
|
||||
if (!is_mapped) {
|
||||
// a. Return ? OrdinaryGet(args, P, Receiver).
|
||||
return Object::internal_get(property_key, receiver, cacheable_metadata);
|
||||
return Object::internal_get(property_key, receiver, cacheable_metadata, phase);
|
||||
}
|
||||
|
||||
// FIXME: a. Assert: map contains a formal parameter mapping for P.
|
||||
|
|
|
@ -24,7 +24,7 @@ public:
|
|||
|
||||
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<Value> internal_get(PropertyKey const&, Value receiver, CacheablePropertyMetadata*) 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_delete(PropertyKey const&) override;
|
||||
|
||||
|
|
|
@ -137,14 +137,14 @@ ThrowCompletionOr<bool> ModuleNamespaceObject::internal_has_property(PropertyKey
|
|||
}
|
||||
|
||||
// 10.4.6.8 [[Get]] ( P, Receiver ), https://tc39.es/ecma262/#sec-module-namespace-exotic-objects-get-p-receiver
|
||||
ThrowCompletionOr<Value> ModuleNamespaceObject::internal_get(PropertyKey const& property_key, Value receiver, CacheablePropertyMetadata* cacheable_metadata) const
|
||||
ThrowCompletionOr<Value> ModuleNamespaceObject::internal_get(PropertyKey const& property_key, Value receiver, CacheablePropertyMetadata* cacheable_metadata, PropertyLookupPhase phase) const
|
||||
{
|
||||
auto& vm = this->vm();
|
||||
|
||||
// 1. If Type(P) is Symbol, then
|
||||
if (property_key.is_symbol()) {
|
||||
// a. Return ! OrdinaryGet(O, P, Receiver).
|
||||
return MUST(Object::internal_get(property_key, receiver, cacheable_metadata));
|
||||
return MUST(Object::internal_get(property_key, receiver, cacheable_metadata, phase));
|
||||
}
|
||||
|
||||
// 2. Let exports be O.[[Exports]].
|
||||
|
|
|
@ -26,7 +26,7 @@ public:
|
|||
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_has_property(PropertyKey const&) const override;
|
||||
virtual ThrowCompletionOr<Value> internal_get(PropertyKey const&, Value receiver, CacheablePropertyMetadata* = nullptr) 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_delete(PropertyKey const&) override;
|
||||
virtual ThrowCompletionOr<MarkedVector<Value>> internal_own_property_keys() const override;
|
||||
|
|
|
@ -873,7 +873,7 @@ ThrowCompletionOr<bool> Object::internal_has_property(PropertyKey const& propert
|
|||
}
|
||||
|
||||
// 10.1.8 [[Get]] ( P, Receiver ), https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-get-p-receiver
|
||||
ThrowCompletionOr<Value> Object::internal_get(PropertyKey const& property_key, Value receiver, CacheablePropertyMetadata* cacheable_metadata) const
|
||||
ThrowCompletionOr<Value> Object::internal_get(PropertyKey const& property_key, Value receiver, CacheablePropertyMetadata* cacheable_metadata, PropertyLookupPhase phase) const
|
||||
{
|
||||
VERIFY(!receiver.is_empty());
|
||||
VERIFY(property_key.is_valid());
|
||||
|
@ -893,17 +893,19 @@ ThrowCompletionOr<Value> Object::internal_get(PropertyKey const& property_key, V
|
|||
return js_undefined();
|
||||
|
||||
// c. Return ? parent.[[Get]](P, Receiver).
|
||||
return parent->internal_get(property_key, receiver);
|
||||
return parent->internal_get(property_key, receiver, nullptr, PropertyLookupPhase::PrototypeChain);
|
||||
}
|
||||
|
||||
// 3. If IsDataDescriptor(desc) is true, return desc.[[Value]].
|
||||
if (descriptor->is_data_descriptor()) {
|
||||
// Non-standard: If the caller has requested cacheable metadata and the property is an own property, fill it in.
|
||||
if (cacheable_metadata && descriptor->property_offset.has_value() && shape().is_cacheable()) {
|
||||
*cacheable_metadata = CacheablePropertyMetadata {
|
||||
.type = CacheablePropertyMetadata::Type::OwnProperty,
|
||||
.property_offset = descriptor->property_offset.value(),
|
||||
};
|
||||
if (phase == PropertyLookupPhase::OwnProperty) {
|
||||
*cacheable_metadata = CacheablePropertyMetadata {
|
||||
.type = CacheablePropertyMetadata::Type::OwnProperty,
|
||||
.property_offset = descriptor->property_offset.value(),
|
||||
};
|
||||
}
|
||||
}
|
||||
return *descriptor->value;
|
||||
}
|
||||
|
|
|
@ -138,7 +138,11 @@ public:
|
|||
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_has_property(PropertyKey const&) const;
|
||||
virtual ThrowCompletionOr<Value> internal_get(PropertyKey const&, Value receiver, CacheablePropertyMetadata* = nullptr) const;
|
||||
enum class PropertyLookupPhase {
|
||||
OwnProperty,
|
||||
PrototypeChain,
|
||||
};
|
||||
virtual ThrowCompletionOr<Value> internal_get(PropertyKey const&, Value receiver, CacheablePropertyMetadata* = nullptr, PropertyLookupPhase = PropertyLookupPhase::OwnProperty) const;
|
||||
virtual ThrowCompletionOr<bool> internal_set(PropertyKey const&, Value value, Value receiver, CacheablePropertyMetadata* = nullptr);
|
||||
virtual ThrowCompletionOr<bool> internal_delete(PropertyKey const&);
|
||||
virtual ThrowCompletionOr<MarkedVector<Value>> internal_own_property_keys() const;
|
||||
|
|
|
@ -455,7 +455,7 @@ ThrowCompletionOr<bool> ProxyObject::internal_has_property(PropertyKey const& pr
|
|||
}
|
||||
|
||||
// 10.5.8 [[Get]] ( P, Receiver ), https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-get-p-receiver
|
||||
ThrowCompletionOr<Value> ProxyObject::internal_get(PropertyKey const& property_key, Value receiver, CacheablePropertyMetadata*) const
|
||||
ThrowCompletionOr<Value> ProxyObject::internal_get(PropertyKey const& property_key, Value receiver, CacheablePropertyMetadata*, PropertyLookupPhase) const
|
||||
{
|
||||
// NOTE: We don't return any cacheable metadata for proxy lookups.
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ public:
|
|||
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_has_property(PropertyKey const&) const override;
|
||||
virtual ThrowCompletionOr<Value> internal_get(PropertyKey const&, Value receiver, CacheablePropertyMetadata*) 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_delete(PropertyKey const&) override;
|
||||
virtual ThrowCompletionOr<MarkedVector<Value>> internal_own_property_keys() const override;
|
||||
|
|
|
@ -317,7 +317,7 @@ public:
|
|||
}
|
||||
|
||||
// 10.4.5.4 [[Get]] ( P, Receiver ), 10.4.5.4 [[Get]] ( P, Receiver )
|
||||
virtual ThrowCompletionOr<Value> internal_get(PropertyKey const& property_key, Value receiver, CacheablePropertyMetadata* cacheable_metadata) const override
|
||||
virtual ThrowCompletionOr<Value> internal_get(PropertyKey const& property_key, Value receiver, CacheablePropertyMetadata* cacheable_metadata, PropertyLookupPhase phase) const override
|
||||
{
|
||||
VERIFY(!receiver.is_empty());
|
||||
|
||||
|
@ -339,7 +339,7 @@ public:
|
|||
}
|
||||
|
||||
// 2. Return ? OrdinaryGet(O, P, Receiver).
|
||||
return Object::internal_get(property_key, receiver, cacheable_metadata);
|
||||
return Object::internal_get(property_key, receiver, cacheable_metadata, phase);
|
||||
}
|
||||
|
||||
// 10.4.5.5 [[Set]] ( P, V, Receiver ), https://tc39.es/ecma262/#sec-integer-indexed-exotic-objects-set-p-v-receiver
|
||||
|
|
|
@ -409,15 +409,15 @@ JS::ThrowCompletionOr<bool> CSSStyleDeclaration::internal_has_property(JS::Prope
|
|||
return property_id_from_name(name.to_string()) != CSS::PropertyID::Invalid;
|
||||
}
|
||||
|
||||
JS::ThrowCompletionOr<JS::Value> CSSStyleDeclaration::internal_get(JS::PropertyKey const& name, JS::Value receiver, JS::CacheablePropertyMetadata* cacheable_metadata) const
|
||||
JS::ThrowCompletionOr<JS::Value> CSSStyleDeclaration::internal_get(JS::PropertyKey const& name, JS::Value receiver, JS::CacheablePropertyMetadata* cacheable_metadata, PropertyLookupPhase phase) const
|
||||
{
|
||||
if (name.is_number())
|
||||
return { JS::PrimitiveString::create(vm(), item(name.as_number())) };
|
||||
if (!name.is_string())
|
||||
return Base::internal_get(name, receiver, cacheable_metadata);
|
||||
return Base::internal_get(name, receiver, cacheable_metadata, phase);
|
||||
auto property_id = property_id_from_name(name.to_string());
|
||||
if (property_id == CSS::PropertyID::Invalid)
|
||||
return Base::internal_get(name, receiver, cacheable_metadata);
|
||||
return Base::internal_get(name, receiver, cacheable_metadata, phase);
|
||||
if (auto maybe_property = property(property_id); maybe_property.has_value())
|
||||
return { JS::PrimitiveString::create(vm(), maybe_property->value->to_string()) };
|
||||
return { JS::PrimitiveString::create(vm(), String {}) };
|
||||
|
|
|
@ -42,7 +42,7 @@ public:
|
|||
virtual String serialized() const = 0;
|
||||
|
||||
virtual JS::ThrowCompletionOr<bool> internal_has_property(JS::PropertyKey const& name) const override;
|
||||
virtual JS::ThrowCompletionOr<JS::Value> internal_get(JS::PropertyKey const&, JS::Value receiver, JS::CacheablePropertyMetadata*) 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;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -483,13 +483,13 @@ JS::ThrowCompletionOr<bool> Location::internal_define_own_property(JS::PropertyK
|
|||
}
|
||||
|
||||
// 7.10.5.7 [[Get]] ( P, Receiver ), https://html.spec.whatwg.org/multipage/history.html#location-get
|
||||
JS::ThrowCompletionOr<JS::Value> Location::internal_get(JS::PropertyKey const& property_key, JS::Value receiver, JS::CacheablePropertyMetadata* cacheable_metadata) const
|
||||
JS::ThrowCompletionOr<JS::Value> Location::internal_get(JS::PropertyKey const& property_key, JS::Value receiver, JS::CacheablePropertyMetadata* cacheable_metadata, PropertyLookupPhase phase) const
|
||||
{
|
||||
auto& vm = this->vm();
|
||||
|
||||
// 1. If IsPlatformObjectSameOrigin(this) is true, then return ? OrdinaryGet(this, P, Receiver).
|
||||
if (HTML::is_platform_object_same_origin(*this))
|
||||
return JS::Object::internal_get(property_key, receiver, cacheable_metadata);
|
||||
return JS::Object::internal_get(property_key, receiver, cacheable_metadata, phase);
|
||||
|
||||
// 2. Return ? CrossOriginGet(this, P, Receiver).
|
||||
return HTML::cross_origin_get(vm, static_cast<JS::Object const&>(*this), property_key, receiver);
|
||||
|
|
|
@ -60,7 +60,7 @@ public:
|
|||
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<bool> internal_define_own_property(JS::PropertyKey const&, JS::PropertyDescriptor const&) override;
|
||||
virtual JS::ThrowCompletionOr<JS::Value> internal_get(JS::PropertyKey const&, JS::Value receiver, JS::CacheablePropertyMetadata*) 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_delete(JS::PropertyKey const&) override;
|
||||
virtual JS::ThrowCompletionOr<JS::MarkedVector<JS::Value>> internal_own_property_keys() const override;
|
||||
|
|
|
@ -153,7 +153,7 @@ JS::ThrowCompletionOr<bool> WindowProxy::internal_define_own_property(JS::Proper
|
|||
}
|
||||
|
||||
// 7.4.7 [[Get]] ( P, Receiver ), https://html.spec.whatwg.org/multipage/window-object.html#windowproxy-get
|
||||
JS::ThrowCompletionOr<JS::Value> WindowProxy::internal_get(JS::PropertyKey const& property_key, JS::Value receiver, JS::CacheablePropertyMetadata*) const
|
||||
JS::ThrowCompletionOr<JS::Value> WindowProxy::internal_get(JS::PropertyKey const& property_key, JS::Value receiver, JS::CacheablePropertyMetadata*, PropertyLookupPhase) const
|
||||
{
|
||||
auto& vm = this->vm();
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ public:
|
|||
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<bool> internal_define_own_property(JS::PropertyKey const&, JS::PropertyDescriptor const&) override;
|
||||
virtual JS::ThrowCompletionOr<JS::Value> internal_get(JS::PropertyKey const&, JS::Value receiver, JS::CacheablePropertyMetadata*) 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_delete(JS::PropertyKey const&) override;
|
||||
virtual JS::ThrowCompletionOr<JS::MarkedVector<JS::Value>> internal_own_property_keys() const override;
|
||||
|
|
Loading…
Reference in a new issue