summaryrefslogtreecommitdiff
path: root/Libraries/LibJS/Runtime
diff options
context:
space:
mode:
authorJack Karamanian <karamanian.jack@gmail.com>2020-06-13 21:23:33 -0500
committerAndreas Kling <kling@serenityos.org>2020-06-29 17:54:54 +0200
commita535d58cac6cfef7c85cd9ee8419189d58560afb (patch)
tree05d2391f38957189ab9e2ad6a19a4fc625c7bab3 /Libraries/LibJS/Runtime
parent949bffdc933a5e992c7ae09fa7d2031abd343276 (diff)
downloadserenity-a535d58cac6cfef7c85cd9ee8419189d58560afb.zip
LibJS: Add Object::define_accessor()
This is a helper function based on the getter/setter definition logic from ObjectExpression::execute() to look up an Accessor property if it already exists, define a new Accessor property if it doesn't exist, and set the getter or setter function on the Accessor.
Diffstat (limited to 'Libraries/LibJS/Runtime')
-rw-r--r--Libraries/LibJS/Runtime/Object.cpp25
-rw-r--r--Libraries/LibJS/Runtime/Object.h1
2 files changed, 26 insertions, 0 deletions
diff --git a/Libraries/LibJS/Runtime/Object.cpp b/Libraries/LibJS/Runtime/Object.cpp
index 0b87bc57fd..2d1feb8ebd 100644
--- a/Libraries/LibJS/Runtime/Object.cpp
+++ b/Libraries/LibJS/Runtime/Object.cpp
@@ -427,6 +427,31 @@ bool Object::define_property(PropertyName property_name, Value value, PropertyAt
return put_own_property(*this, property_name.as_string(), value, attributes, PutOwnPropertyMode::DefineProperty, throw_exceptions);
}
+bool Object::define_accessor(PropertyName property_name, Function& getter_or_setter, bool is_getter, PropertyAttributes attributes, bool throw_exceptions)
+{
+ Accessor* accessor { nullptr };
+ auto property_metadata = shape().lookup(property_name.as_string());
+ if (property_metadata.has_value()) {
+ auto existing_property = get_direct(property_metadata.value().offset);
+ if (existing_property.is_accessor())
+ accessor = &existing_property.as_accessor();
+ }
+ if (!accessor) {
+ accessor = Accessor::create(interpreter(), nullptr, nullptr);
+ bool definition_success = define_property(property_name, accessor, attributes, throw_exceptions);
+ if (interpreter().exception())
+ return {};
+ if (!definition_success)
+ return false;
+ }
+ if (is_getter)
+ accessor->set_getter(&getter_or_setter);
+ else
+ accessor->set_setter(&getter_or_setter);
+
+ return true;
+}
+
bool Object::put_own_property(Object& this_object, const FlyString& property_name, Value value, PropertyAttributes attributes, PutOwnPropertyMode mode, bool throw_exceptions)
{
ASSERT(!(mode == PutOwnPropertyMode::Put && value.is_accessor()));
diff --git a/Libraries/LibJS/Runtime/Object.h b/Libraries/LibJS/Runtime/Object.h
index 4cf78f822d..3723560e27 100644
--- a/Libraries/LibJS/Runtime/Object.h
+++ b/Libraries/LibJS/Runtime/Object.h
@@ -98,6 +98,7 @@ public:
virtual bool define_property(const FlyString& property_name, const Object& descriptor, bool throw_exceptions = true);
bool define_property(PropertyName, Value value, PropertyAttributes attributes = default_attributes, bool throw_exceptions = true);
+ bool define_accessor(PropertyName, Function& getter_or_setter, bool is_getter, PropertyAttributes attributes = default_attributes, bool throw_exceptions = true);
bool define_native_function(const FlyString& property_name, AK::Function<Value(Interpreter&, GlobalObject&)>, i32 length = 0, PropertyAttributes attributes = default_attributes);
bool define_native_property(const FlyString& property_name, AK::Function<Value(Interpreter&, GlobalObject&)> getter, AK::Function<void(Interpreter&, GlobalObject&, Value)> setter, PropertyAttributes attributes = default_attributes);