1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-23 18:25:08 +00:00

LibJS: Add property configuration transitions

Object.defineProperty() can now change the attributes of a property
already on the object. Internally this becomes a shape transition with
the TransitionType::Configure. Such transitions don't expand the
property storage capacity, but rather simply keep attributes up to date
when generating a property table.
This commit is contained in:
Andreas Kling 2020-04-09 22:55:17 +02:00
parent e6d920d87d
commit 8286f8b996
5 changed files with 57 additions and 8 deletions

View file

@ -106,16 +106,30 @@ void Object::put_own_property(Object& this_object, const FlyString& property_nam
set_shape(*new_shape);
metadata = shape().lookup(property_name);
ASSERT(metadata.has_value());
} else if (!(metadata.value().attributes & Attribute::Writable)) {
dbg() << "Disallow write to non-writable property";
return;
}
if (mode == PutOwnPropertyMode::DefineProperty && !(metadata.value().attributes & Attribute::Configurable) && attributes != metadata.value().attributes) {
dbg() << "Disallow reconfig of non-configurable property";
interpreter().throw_exception<Error>("TypeError", String::format("Cannot redefine property '%s'", property_name.characters()));
return;
}
if (mode == PutOwnPropertyMode::DefineProperty && attributes != metadata.value().attributes) {
auto* new_shape = m_shape->create_configure_transition(property_name, attributes);
set_shape(*new_shape);
metadata = shape().lookup(property_name);
dbg() << "Reconfigured property " << property_name << ", new shape says offset is " << metadata.value().offset << " and my storage capacity is " << m_storage.size();
}
if (mode == PutOwnPropertyMode::Put && !(metadata.value().attributes & Attribute::Writable)) {
dbg() << "Disallow write to non-writable property";
return;
}
if (value.is_empty())
return;
auto value_here = m_storage[metadata.value().offset];
if (value_here.is_object() && value_here.as_object().is_native_property()) {
auto& native_property = static_cast<NativeProperty&>(value_here.as_object());