mirror of
https://github.com/RGBCube/serenity
synced 2025-05-22 19:05:07 +00:00
LibJS: Make NativeProperty a plain Cell instead of an Object
This removes the need for NativeProperty objects to have a prototype, which just made things confusing.
This commit is contained in:
parent
ba641e97d9
commit
0166a1fa74
6 changed files with 33 additions and 25 deletions
|
@ -89,6 +89,7 @@ class HeapBlock;
|
||||||
class Interpreter;
|
class Interpreter;
|
||||||
class LexicalEnvironment;
|
class LexicalEnvironment;
|
||||||
class MarkedValueList;
|
class MarkedValueList;
|
||||||
|
class NativeProperty;
|
||||||
class PrimitiveString;
|
class PrimitiveString;
|
||||||
class Reference;
|
class Reference;
|
||||||
class ScopeNode;
|
class ScopeNode;
|
||||||
|
|
|
@ -29,9 +29,8 @@
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
NativeProperty::NativeProperty(GlobalObject& global_object, AK::Function<Value(Interpreter&, GlobalObject&)> getter, AK::Function<void(Interpreter&, GlobalObject&, Value)> setter)
|
NativeProperty::NativeProperty(AK::Function<Value(Interpreter&, GlobalObject&)> getter, AK::Function<void(Interpreter&, GlobalObject&, Value)> setter)
|
||||||
: Object(Object::ConstructWithoutPrototypeTag::Tag, global_object)
|
: m_getter(move(getter))
|
||||||
, m_getter(move(getter))
|
|
||||||
, m_setter(move(setter))
|
, m_setter(move(setter))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,18 +31,16 @@
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
class NativeProperty final : public Object {
|
class NativeProperty final : public Cell {
|
||||||
JS_OBJECT(NativeProperty, Object);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NativeProperty(GlobalObject&, AK::Function<Value(Interpreter&, GlobalObject&)> getter, AK::Function<void(Interpreter&, GlobalObject&, Value)> setter);
|
NativeProperty(AK::Function<Value(Interpreter&, GlobalObject&)> getter, AK::Function<void(Interpreter&, GlobalObject&, Value)> setter);
|
||||||
virtual ~NativeProperty() override;
|
virtual ~NativeProperty() override;
|
||||||
|
|
||||||
Value get(Interpreter&, GlobalObject&) const;
|
Value get(Interpreter&, GlobalObject&) const;
|
||||||
void set(Interpreter&, GlobalObject&, Value);
|
void set(Interpreter&, GlobalObject&, Value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual bool is_native_property() const override { return true; }
|
virtual const char* class_name() const override { return "NativeProperty"; }
|
||||||
|
|
||||||
AK::Function<Value(Interpreter&, GlobalObject&)> m_getter;
|
AK::Function<Value(Interpreter&, GlobalObject&)> m_getter;
|
||||||
AK::Function<void(Interpreter&, GlobalObject&, Value)> m_setter;
|
AK::Function<void(Interpreter&, GlobalObject&, Value)> m_setter;
|
||||||
|
|
|
@ -171,7 +171,7 @@ Value Object::get_own_property(const Object& this_object, PropertyName property_
|
||||||
if (value_here.is_accessor()) {
|
if (value_here.is_accessor()) {
|
||||||
return value_here.as_accessor().call_getter(Value(const_cast<Object*>(this)));
|
return value_here.as_accessor().call_getter(Value(const_cast<Object*>(this)));
|
||||||
}
|
}
|
||||||
if (value_here.is_object() && value_here.as_object().is_native_property())
|
if (value_here.is_native_property())
|
||||||
return call_native_property_getter(const_cast<Object*>(&this_object), value_here);
|
return call_native_property_getter(const_cast<Object*>(&this_object), value_here);
|
||||||
return value_here;
|
return value_here;
|
||||||
}
|
}
|
||||||
|
@ -282,7 +282,7 @@ Optional<PropertyDescriptor> Object::get_own_property_descriptor(PropertyName pr
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertyDescriptor descriptor { attributes, {}, nullptr, nullptr };
|
PropertyDescriptor descriptor { attributes, {}, nullptr, nullptr };
|
||||||
if (value.is_object() && value.as_object().is_native_property()) {
|
if (value.is_native_property()) {
|
||||||
auto result = call_native_property_getter(const_cast<Object*>(this), value);
|
auto result = call_native_property_getter(const_cast<Object*>(this), value);
|
||||||
descriptor.value = result.value_or(js_undefined());
|
descriptor.value = result.value_or(js_undefined());
|
||||||
} else if (value.is_accessor()) {
|
} else if (value.is_accessor()) {
|
||||||
|
@ -492,7 +492,7 @@ bool Object::put_own_property(Object& this_object, const FlyString& property_nam
|
||||||
if (value.is_empty())
|
if (value.is_empty())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (value_here.is_object() && value_here.as_object().is_native_property()) {
|
if (value_here.is_native_property()) {
|
||||||
call_native_property_setter(const_cast<Object*>(&this_object), value_here, value);
|
call_native_property_setter(const_cast<Object*>(&this_object), value_here, value);
|
||||||
} else {
|
} else {
|
||||||
m_storage[metadata.value().offset] = value;
|
m_storage[metadata.value().offset] = value;
|
||||||
|
@ -539,7 +539,7 @@ bool Object::put_own_property_by_index(Object& this_object, u32 property_index,
|
||||||
if (value.is_empty())
|
if (value.is_empty())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (value_here.is_object() && value_here.as_object().is_native_property()) {
|
if (value_here.is_native_property()) {
|
||||||
call_native_property_setter(const_cast<Object*>(&this_object), value_here, value);
|
call_native_property_setter(const_cast<Object*>(&this_object), value_here, value);
|
||||||
} else {
|
} else {
|
||||||
m_indexed_properties.put(&this_object, property_index, value, attributes, mode == PutOwnPropertyMode::Put);
|
m_indexed_properties.put(&this_object, property_index, value, attributes, mode == PutOwnPropertyMode::Put);
|
||||||
|
@ -643,7 +643,7 @@ bool Object::put_by_index(u32 property_index, Value value)
|
||||||
value_here.value.as_accessor().call_setter(object, value);
|
value_here.value.as_accessor().call_setter(object, value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (value_here.value.is_object() && value_here.value.as_object().is_native_property()) {
|
if (value_here.value.is_native_property()) {
|
||||||
call_native_property_setter(const_cast<Object*>(this), value_here.value, value);
|
call_native_property_setter(const_cast<Object*>(this), value_here.value, value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -678,7 +678,7 @@ bool Object::put(PropertyName property_name, Value value)
|
||||||
value_here.as_accessor().call_setter(Value(this), value);
|
value_here.as_accessor().call_setter(Value(this), value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (value_here.is_object() && value_here.as_object().is_native_property()) {
|
if (value_here.is_native_property()) {
|
||||||
call_native_property_setter(const_cast<Object*>(this), value_here, value);
|
call_native_property_setter(const_cast<Object*>(this), value_here, value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -704,7 +704,7 @@ bool Object::define_native_function(const FlyString& property_name, AK::Function
|
||||||
|
|
||||||
bool Object::define_native_property(const FlyString& property_name, AK::Function<Value(Interpreter&, GlobalObject&)> getter, AK::Function<void(Interpreter&, GlobalObject&, Value)> setter, PropertyAttributes attribute)
|
bool Object::define_native_property(const FlyString& property_name, AK::Function<Value(Interpreter&, GlobalObject&)> getter, AK::Function<void(Interpreter&, GlobalObject&, Value)> setter, PropertyAttributes attribute)
|
||||||
{
|
{
|
||||||
return define_property(property_name, heap().allocate<NativeProperty>(global_object(), global_object(), move(getter), move(setter)), attribute);
|
return define_property(property_name, heap().allocate<NativeProperty>(global_object(), move(getter), move(setter)), attribute);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Object::visit_children(Cell::Visitor& visitor)
|
void Object::visit_children(Cell::Visitor& visitor)
|
||||||
|
@ -809,24 +809,20 @@ Value Object::invoke(const FlyString& property_name, Optional<MarkedValueList> a
|
||||||
|
|
||||||
Value Object::call_native_property_getter(Object* this_object, Value property) const
|
Value Object::call_native_property_getter(Object* this_object, Value property) const
|
||||||
{
|
{
|
||||||
ASSERT(property.is_object());
|
ASSERT(property.is_native_property());
|
||||||
ASSERT(property.as_object().is_native_property());
|
|
||||||
auto& native_property = static_cast<NativeProperty&>(property.as_object());
|
|
||||||
auto& call_frame = interpreter().push_call_frame();
|
auto& call_frame = interpreter().push_call_frame();
|
||||||
call_frame.this_value = this_object;
|
call_frame.this_value = this_object;
|
||||||
auto result = native_property.get(interpreter(), global_object());
|
auto result = property.as_native_property().get(interpreter(), global_object());
|
||||||
interpreter().pop_call_frame();
|
interpreter().pop_call_frame();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Object::call_native_property_setter(Object* this_object, Value property, Value value) const
|
void Object::call_native_property_setter(Object* this_object, Value property, Value value) const
|
||||||
{
|
{
|
||||||
ASSERT(property.is_object());
|
ASSERT(property.is_native_property());
|
||||||
ASSERT(property.as_object().is_native_property());
|
|
||||||
auto& native_property = static_cast<NativeProperty&>(property.as_object());
|
|
||||||
auto& call_frame = interpreter().push_call_frame();
|
auto& call_frame = interpreter().push_call_frame();
|
||||||
call_frame.this_value = this_object;
|
call_frame.this_value = this_object;
|
||||||
native_property.set(interpreter(), global_object(), value);
|
property.as_native_property().set(interpreter(), global_object(), value);
|
||||||
interpreter().pop_call_frame();
|
interpreter().pop_call_frame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -110,7 +110,6 @@ public:
|
||||||
virtual bool is_function() const { return false; }
|
virtual bool is_function() const { return false; }
|
||||||
virtual bool is_native_function() const { return false; }
|
virtual bool is_native_function() const { return false; }
|
||||||
virtual bool is_bound_function() const { return false; }
|
virtual bool is_bound_function() const { return false; }
|
||||||
virtual bool is_native_property() const { return false; }
|
|
||||||
virtual bool is_proxy_object() const { return false; }
|
virtual bool is_proxy_object() const { return false; }
|
||||||
virtual bool is_regexp_object() const { return false; }
|
virtual bool is_regexp_object() const { return false; }
|
||||||
virtual bool is_boolean_object() const { return false; }
|
virtual bool is_boolean_object() const { return false; }
|
||||||
|
|
|
@ -51,6 +51,7 @@ public:
|
||||||
Symbol,
|
Symbol,
|
||||||
Accessor,
|
Accessor,
|
||||||
BigInt,
|
BigInt,
|
||||||
|
NativeProperty,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class PreferredType {
|
enum class PreferredType {
|
||||||
|
@ -69,7 +70,8 @@ public:
|
||||||
bool is_symbol() const { return m_type == Type::Symbol; }
|
bool is_symbol() const { return m_type == Type::Symbol; }
|
||||||
bool is_accessor() const { return m_type == Type::Accessor; };
|
bool is_accessor() const { return m_type == Type::Accessor; };
|
||||||
bool is_bigint() const { return m_type == Type::BigInt; };
|
bool is_bigint() const { return m_type == Type::BigInt; };
|
||||||
bool is_cell() const { return is_string() || is_accessor() || is_object() || is_bigint() || is_symbol(); }
|
bool is_native_property() const { return m_type == Type::NativeProperty; }
|
||||||
|
bool is_cell() const { return is_string() || is_accessor() || is_object() || is_bigint() || is_symbol() || is_native_property(); }
|
||||||
bool is_array() const;
|
bool is_array() const;
|
||||||
bool is_function() const;
|
bool is_function() const;
|
||||||
|
|
||||||
|
@ -147,6 +149,12 @@ public:
|
||||||
m_value.as_bigint = bigint;
|
m_value.as_bigint = bigint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value(NativeProperty* native_property)
|
||||||
|
: m_type(Type::NativeProperty)
|
||||||
|
{
|
||||||
|
m_value.as_native_property = native_property;
|
||||||
|
}
|
||||||
|
|
||||||
explicit Value(Type type)
|
explicit Value(Type type)
|
||||||
: m_type(type)
|
: m_type(type)
|
||||||
{
|
{
|
||||||
|
@ -220,6 +228,12 @@ public:
|
||||||
return *m_value.as_bigint;
|
return *m_value.as_bigint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NativeProperty& as_native_property()
|
||||||
|
{
|
||||||
|
ASSERT(is_native_property());
|
||||||
|
return *m_value.as_native_property;
|
||||||
|
}
|
||||||
|
|
||||||
Array& as_array();
|
Array& as_array();
|
||||||
Function& as_function();
|
Function& as_function();
|
||||||
|
|
||||||
|
@ -259,6 +273,7 @@ private:
|
||||||
Cell* as_cell;
|
Cell* as_cell;
|
||||||
Accessor* as_accessor;
|
Accessor* as_accessor;
|
||||||
BigInt* as_bigint;
|
BigInt* as_bigint;
|
||||||
|
NativeProperty* as_native_property;
|
||||||
} m_value;
|
} m_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue