Ver código fonte

LibJS: Add the Object.prototype.__lookup{Getter, Setter}__ methods

These are a part of the Annex B extension of the specification.
Idan Horowitz 4 anos atrás
pai
commit
1cf5663e38

+ 2 - 0
Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h

@@ -15,6 +15,8 @@ namespace JS {
     P(__proto__)                             \
     P(__proto__)                             \
     P(__defineGetter__)                      \
     P(__defineGetter__)                      \
     P(__defineSetter__)                      \
     P(__defineSetter__)                      \
+    P(__lookupGetter__)                      \
+    P(__lookupSetter__)                      \
     P(BYTES_PER_ELEMENT)                     \
     P(BYTES_PER_ELEMENT)                     \
     P(BigInt)                                \
     P(BigInt)                                \
     P(Boolean)                               \
     P(Boolean)                               \

+ 52 - 0
Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp

@@ -40,6 +40,8 @@ void ObjectPrototype::initialize(GlobalObject& global_object)
     // Annex B
     // Annex B
     define_native_function(vm.names.__defineGetter__, define_getter, 2, attr);
     define_native_function(vm.names.__defineGetter__, define_getter, 2, attr);
     define_native_function(vm.names.__defineSetter__, define_setter, 2, attr);
     define_native_function(vm.names.__defineSetter__, define_setter, 2, attr);
+    define_native_function(vm.names.__lookupGetter__, lookup_getter, 1, attr);
+    define_native_function(vm.names.__lookupSetter__, lookup_setter, 1, attr);
     define_native_accessor(vm.names.__proto__, proto_getter, proto_setter, Attribute::Configurable);
     define_native_accessor(vm.names.__proto__, proto_getter, proto_setter, Attribute::Configurable);
 }
 }
 
 
@@ -214,6 +216,56 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::define_setter)
     return js_undefined();
     return js_undefined();
 }
 }
 
 
+// B.2.2.4 Object.prototype.__lookupGetter__ ( P ), https://tc39.es/ecma262/#sec-object.prototype.__lookupGetter__
+JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::lookup_getter)
+{
+    auto object = vm.this_value(global_object).to_object(global_object);
+    if (vm.exception())
+        return {};
+
+    auto key = vm.argument(0).to_property_key(global_object);
+    if (vm.exception())
+        return {};
+
+    while (object) {
+        auto desc = object->get_own_property_descriptor(key);
+        if (vm.exception())
+            return {};
+        if (desc.has_value())
+            return desc->getter ?: js_undefined();
+        object = object->prototype();
+        if (vm.exception())
+            return {};
+    }
+
+    return js_undefined();
+}
+
+// B.2.2.5 Object.prototype.__lookupSetter__ ( P ), https://tc39.es/ecma262/#sec-object.prototype.__lookupSetter__
+JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::lookup_setter)
+{
+    auto* object = vm.this_value(global_object).to_object(global_object);
+    if (vm.exception())
+        return {};
+
+    auto key = vm.argument(0).to_property_key(global_object);
+    if (vm.exception())
+        return {};
+
+    while (object) {
+        auto desc = object->get_own_property_descriptor(key);
+        if (vm.exception())
+            return {};
+        if (desc.has_value())
+            return desc->setter ?: js_undefined();
+        object = object->prototype();
+        if (vm.exception())
+            return {};
+    }
+
+    return js_undefined();
+}
+
 // B.2.2.1.1 get Object.prototype.__proto__, https://tc39.es/ecma262/#sec-get-object.prototype.__proto__
 // B.2.2.1.1 get Object.prototype.__proto__, https://tc39.es/ecma262/#sec-get-object.prototype.__proto__
 JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::proto_getter)
 JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::proto_getter)
 {
 {

+ 2 - 0
Userland/Libraries/LibJS/Runtime/ObjectPrototype.h

@@ -29,6 +29,8 @@ private:
     JS_DECLARE_NATIVE_FUNCTION(is_prototype_of);
     JS_DECLARE_NATIVE_FUNCTION(is_prototype_of);
     JS_DECLARE_NATIVE_FUNCTION(define_getter);
     JS_DECLARE_NATIVE_FUNCTION(define_getter);
     JS_DECLARE_NATIVE_FUNCTION(define_setter);
     JS_DECLARE_NATIVE_FUNCTION(define_setter);
+    JS_DECLARE_NATIVE_FUNCTION(lookup_getter);
+    JS_DECLARE_NATIVE_FUNCTION(lookup_setter);
     JS_DECLARE_NATIVE_FUNCTION(proto_getter);
     JS_DECLARE_NATIVE_FUNCTION(proto_getter);
     JS_DECLARE_NATIVE_FUNCTION(proto_setter);
     JS_DECLARE_NATIVE_FUNCTION(proto_setter);
 };
 };