summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibJS/Runtime/Object.cpp20
-rw-r--r--Userland/Libraries/LibJS/Runtime/Object.h4
-rw-r--r--Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp6
-rw-r--r--Userland/Libraries/LibJS/Runtime/ObjectPrototype.h4
-rw-r--r--Userland/Libraries/LibJS/Tests/builtins/Object/Object.prototype.js7
5 files changed, 41 insertions, 0 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/Object.cpp b/Userland/Libraries/LibJS/Runtime/Object.cpp
index fcd6c9c35b..6850e7198a 100644
--- a/Userland/Libraries/LibJS/Runtime/Object.cpp
+++ b/Userland/Libraries/LibJS/Runtime/Object.cpp
@@ -870,6 +870,26 @@ MarkedValueList Object::internal_own_property_keys() const
return keys;
}
+// 10.4.7.2 SetImmutablePrototype ( O, V ), https://tc39.es/ecma262/#sec-set-immutable-prototype
+bool Object::set_immutable_prototype(Object* prototype)
+{
+ auto& vm = this->vm();
+
+ // 1. Assert: Either Type(V) is Object or Type(V) is Null.
+
+ // 2. Let current be ? O.[[GetPrototypeOf]]().
+ auto* current = internal_get_prototype_of();
+ if (vm.exception())
+ return {};
+
+ // 3. If SameValue(V, current) is true, return true.
+ if (prototype == current)
+ return true;
+
+ // 4. Return false.
+ return false;
+}
+
Optional<ValueAndAttributes> Object::storage_get(PropertyName const& property_name, CallNativeProperty call_native_property) const
{
VERIFY(property_name.is_valid());
diff --git a/Userland/Libraries/LibJS/Runtime/Object.h b/Userland/Libraries/LibJS/Runtime/Object.h
index 6659a886f1..29bfdc7800 100644
--- a/Userland/Libraries/LibJS/Runtime/Object.h
+++ b/Userland/Libraries/LibJS/Runtime/Object.h
@@ -100,6 +100,10 @@ public:
virtual bool internal_delete(PropertyName const&);
virtual MarkedValueList internal_own_property_keys() const;
+ // 10.4.7 Immutable Prototype Exotic Objects, https://tc39.es/ecma262/#sec-immutable-prototype-exotic-objects
+
+ bool set_immutable_prototype(Object* prototype);
+
// 20.1 Object Objects, https://tc39.es/ecma262/#sec-object-objects
Object* define_properties(Value properties);
diff --git a/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp b/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp
index 367ed5d815..21b1a2747f 100644
--- a/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp
+++ b/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp
@@ -50,6 +50,12 @@ ObjectPrototype::~ObjectPrototype()
{
}
+// 10.4.7.1 [[SetPrototypeOf]] ( V ), https://tc39.es/ecma262/#sec-immutable-prototype-exotic-objects-setprototypeof-v
+bool ObjectPrototype::internal_set_prototype_of(Object* prototype)
+{
+ return set_immutable_prototype(prototype);
+}
+
// 20.1.3.2 Object.prototype.hasOwnProperty ( V ), https://tc39.es/ecma262/#sec-object.prototype.hasownproperty
JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::has_own_property)
{
diff --git a/Userland/Libraries/LibJS/Runtime/ObjectPrototype.h b/Userland/Libraries/LibJS/Runtime/ObjectPrototype.h
index 36dd061705..969ea442dd 100644
--- a/Userland/Libraries/LibJS/Runtime/ObjectPrototype.h
+++ b/Userland/Libraries/LibJS/Runtime/ObjectPrototype.h
@@ -18,6 +18,10 @@ public:
virtual void initialize(GlobalObject&) override;
virtual ~ObjectPrototype() override;
+ // 10.4.7 Immutable Prototype Exotic Objects, https://tc39.es/ecma262/#sec-immutable-prototype-exotic-objects
+
+ virtual bool internal_set_prototype_of(Object* prototype) override;
+
// public to serve as intrinsic function %Object.prototype.toString%
JS_DECLARE_NATIVE_FUNCTION(to_string);
diff --git a/Userland/Libraries/LibJS/Tests/builtins/Object/Object.prototype.js b/Userland/Libraries/LibJS/Tests/builtins/Object/Object.prototype.js
index eab7093b3b..7f06f7eb13 100644
--- a/Userland/Libraries/LibJS/Tests/builtins/Object/Object.prototype.js
+++ b/Userland/Libraries/LibJS/Tests/builtins/Object/Object.prototype.js
@@ -3,3 +3,10 @@ test("basic functionality", () => {
Object.prototype.foo = 123;
expect(o.foo).toBe(123);
});
+
+test("is an immutable prototype exotic object", () => {
+ const p = Object.create(null);
+ expect(() => {
+ Object.setPrototypeOf(Object.prototype, p);
+ }).toThrowWithMessage(TypeError, "Object's [[SetPrototypeOf]] method returned false");
+});