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:
Linus Groh 2021-07-04 23:48:47 +01:00
parent fac8f9a94d
commit cb20baebae
Notes: sideshowbarker 2024-07-18 10:25:20 +09:00
5 changed files with 41 additions and 0 deletions

View file

@ -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());

View file

@ -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);

View file

@ -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)
{

View file

@ -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);

View file

@ -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");
});