diff options
author | Idan Horowitz <idan.horowitz@gmail.com> | 2021-06-17 14:12:38 +0300 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2021-06-17 13:20:18 +0100 |
commit | 37340aa599e177597f81748a14951c0d3d38efaf (patch) | |
tree | 311f2ec4450442539728005d1f09dcebca4a6381 | |
parent | d1c109be964b0990deb2e460a73f841a70b7c70e (diff) | |
download | serenity-37340aa599e177597f81748a14951c0d3d38efaf.zip |
LibJS: Add the Object.prototype.__proto__ native accessor property
This is part of the Annex B extension of the specification.
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp | 39 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/ObjectPrototype.h | 2 |
3 files changed, 42 insertions, 0 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h index 445f3e120d..a2bbf9e2b1 100644 --- a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h +++ b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h @@ -12,6 +12,7 @@ namespace JS { #define ENUMERATE_STANDARD_PROPERTY_NAMES(P) \ + P(__proto__) \ 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 cbb0730149..97e2049c36 100644 --- a/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp @@ -35,6 +35,9 @@ void ObjectPrototype::initialize(GlobalObject& global_object) define_native_function(vm.names.valueOf, value_of, 0, attr); define_native_function(vm.names.propertyIsEnumerable, property_is_enumerable, 1, attr); define_native_function(vm.names.isPrototypeOf, is_prototype_of, 1, attr); + + // Annex B + define_native_accessor(vm.names.__proto__, proto_getter, proto_setter, Attribute::Configurable); } ObjectPrototype::~ObjectPrototype() @@ -144,4 +147,40 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::is_prototype_of) } } +// 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) +{ + auto object = vm.this_value(global_object).to_object(global_object); + if (vm.exception()) + return {}; + auto proto = object->prototype(); + if (vm.exception()) + return {}; + return proto; +} + +// B.2.2.1.2 set Object.prototype.__proto__, https://tc39.es/ecma262/#sec-set-object.prototype.__proto__ +JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::proto_setter) +{ + auto object = require_object_coercible(global_object, vm.this_value(global_object)); + if (vm.exception()) + return {}; + + auto proto = vm.argument(0); + if (!proto.is_object() && !proto.is_null()) + return js_undefined(); + + if (!object.is_object()) + return js_undefined(); + + auto status = object.as_object().set_prototype(proto.is_object() ? &proto.as_object() : nullptr); + if (vm.exception()) + return {}; + if (!status) { + vm.throw_exception<TypeError>(global_object, ErrorType::ObjectSetPrototypeOfReturnedFalse); + return {}; + } + return js_undefined(); +} + } diff --git a/Userland/Libraries/LibJS/Runtime/ObjectPrototype.h b/Userland/Libraries/LibJS/Runtime/ObjectPrototype.h index e303c03718..b01208a93b 100644 --- a/Userland/Libraries/LibJS/Runtime/ObjectPrototype.h +++ b/Userland/Libraries/LibJS/Runtime/ObjectPrototype.h @@ -27,6 +27,8 @@ private: JS_DECLARE_NATIVE_FUNCTION(value_of); JS_DECLARE_NATIVE_FUNCTION(property_is_enumerable); JS_DECLARE_NATIVE_FUNCTION(is_prototype_of); + JS_DECLARE_NATIVE_FUNCTION(proto_getter); + JS_DECLARE_NATIVE_FUNCTION(proto_setter); }; } |