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:
parent
e6d920d87d
commit
8286f8b996
5 changed files with 57 additions and 8 deletions
|
@ -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());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue