mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 02:07:35 +00:00
LibJS: Make ObjectPrototype an immutable prototype exotic object
To make this happen, this patch implements the SetImmutablePrototype abstract operation (as a method on Object) and then overrides [[SetPrototypeOf]] on ObjectPrototype.
This commit is contained in:
parent
fac8f9a94d
commit
cb20baebae
5 changed files with 41 additions and 0 deletions
|
@ -870,6 +870,26 @@ MarkedValueList Object::internal_own_property_keys() const
|
||||||
return keys;
|
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
|
Optional<ValueAndAttributes> Object::storage_get(PropertyName const& property_name, CallNativeProperty call_native_property) const
|
||||||
{
|
{
|
||||||
VERIFY(property_name.is_valid());
|
VERIFY(property_name.is_valid());
|
||||||
|
|
|
@ -100,6 +100,10 @@ public:
|
||||||
virtual bool internal_delete(PropertyName const&);
|
virtual bool internal_delete(PropertyName const&);
|
||||||
virtual MarkedValueList internal_own_property_keys() 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
|
// 20.1 Object Objects, https://tc39.es/ecma262/#sec-object-objects
|
||||||
|
|
||||||
Object* define_properties(Value properties);
|
Object* define_properties(Value properties);
|
||||||
|
|
|
@ -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
|
// 20.1.3.2 Object.prototype.hasOwnProperty ( V ), https://tc39.es/ecma262/#sec-object.prototype.hasownproperty
|
||||||
JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::has_own_property)
|
JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::has_own_property)
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,6 +18,10 @@ public:
|
||||||
virtual void initialize(GlobalObject&) override;
|
virtual void initialize(GlobalObject&) override;
|
||||||
virtual ~ObjectPrototype() 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%
|
// public to serve as intrinsic function %Object.prototype.toString%
|
||||||
JS_DECLARE_NATIVE_FUNCTION(to_string);
|
JS_DECLARE_NATIVE_FUNCTION(to_string);
|
||||||
|
|
||||||
|
|
|
@ -3,3 +3,10 @@ test("basic functionality", () => {
|
||||||
Object.prototype.foo = 123;
|
Object.prototype.foo = 123;
|
||||||
expect(o.foo).toBe(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");
|
||||||
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue