summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIdan Horowitz <idan.horowitz@gmail.com>2021-06-17 14:12:38 +0300
committerLinus Groh <mail@linusgroh.de>2021-06-17 13:20:18 +0100
commit37340aa599e177597f81748a14951c0d3d38efaf (patch)
tree311f2ec4450442539728005d1f09dcebca4a6381
parentd1c109be964b0990deb2e460a73f841a70b7c70e (diff)
downloadserenity-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.h1
-rw-r--r--Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp39
-rw-r--r--Userland/Libraries/LibJS/Runtime/ObjectPrototype.h2
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);
};
}