From 1cf5663e38f128b477871d44471163267bd89cb1 Mon Sep 17 00:00:00 2001 From: Idan Horowitz Date: Thu, 17 Jun 2021 14:15:14 +0300 Subject: [PATCH] LibJS: Add the Object.prototype.__lookup{Getter, Setter}__ methods These are a part of the Annex B extension of the specification. --- .../LibJS/Runtime/CommonPropertyNames.h | 2 + .../LibJS/Runtime/ObjectPrototype.cpp | 52 +++++++++++++++++++ .../Libraries/LibJS/Runtime/ObjectPrototype.h | 2 + 3 files changed, 56 insertions(+) diff --git a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h index 852d089f4b2..504175cd944 100644 --- a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h +++ b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h @@ -15,6 +15,8 @@ namespace JS { P(__proto__) \ P(__defineGetter__) \ P(__defineSetter__) \ + P(__lookupGetter__) \ + P(__lookupSetter__) \ P(BYTES_PER_ELEMENT) \ P(BigInt) \ P(Boolean) \ diff --git a/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp b/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp index 87c16d533c7..3f1cd5ad6a2 100644 --- a/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp @@ -40,6 +40,8 @@ void ObjectPrototype::initialize(GlobalObject& global_object) // Annex B 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.__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); } @@ -214,6 +216,56 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::define_setter) 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__ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::proto_getter) { diff --git a/Userland/Libraries/LibJS/Runtime/ObjectPrototype.h b/Userland/Libraries/LibJS/Runtime/ObjectPrototype.h index 83f41f8f0ff..36dd0617050 100644 --- a/Userland/Libraries/LibJS/Runtime/ObjectPrototype.h +++ b/Userland/Libraries/LibJS/Runtime/ObjectPrototype.h @@ -29,6 +29,8 @@ private: JS_DECLARE_NATIVE_FUNCTION(is_prototype_of); JS_DECLARE_NATIVE_FUNCTION(define_getter); 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_setter); };