1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 15:47:44 +00:00

LibJS: Implement basic support for the "delete" operator

It turns out "delete" is actually a unary op :)
This patch implements deletion of object properties, it doesn't yet
work for casually deleting properties from the global object.

When deleting a property from an object, we switch that object to
having a unique shape, no longer sharing shapes with others.
Once an object has a unique shape, it no longer needs to care about
shape transitions.
This commit is contained in:
Andreas Kling 2020-04-26 13:53:40 +02:00
parent 1617be1e6f
commit f897c41092
9 changed files with 190 additions and 8 deletions

View file

@ -29,6 +29,17 @@
namespace JS {
Shape* Shape::create_unique_clone() const
{
auto* new_shape = heap().allocate<Shape>();
new_shape->m_unique = true;
new_shape->m_prototype = m_prototype;
ensure_property_table();
new_shape->ensure_property_table();
(*new_shape->m_property_table) = *m_property_table;
return new_shape;
}
Shape* Shape::create_put_transition(const FlyString& property_name, u8 attributes)
{
TransitionKey key { property_name, attributes };
@ -89,7 +100,10 @@ void Shape::visit_children(Cell::Visitor& visitor)
Optional<PropertyMetadata> Shape::lookup(const FlyString& property_name) const
{
return property_table().get(property_name);
auto property = property_table().get(property_name);
if (!property.has_value())
return {};
return property;
}
const HashMap<FlyString, PropertyMetadata>& Shape::property_table() const
@ -134,4 +148,32 @@ void Shape::ensure_property_table() const
}
}
void Shape::add_property_to_unique_shape(const FlyString& property_name, u8 attributes)
{
ASSERT(is_unique());
ASSERT(m_property_table);
ASSERT(!m_property_table->contains(property_name));
m_property_table->set(property_name, { m_property_table->size(), attributes });
}
void Shape::reconfigure_property_in_unique_shape(const FlyString& property_name, u8 attributes)
{
ASSERT(is_unique());
ASSERT(m_property_table);
ASSERT(m_property_table->contains(property_name));
m_property_table->set(property_name, { m_property_table->size(), attributes });
}
void Shape::remove_property_from_unique_shape(const FlyString& property_name, size_t offset)
{
ASSERT(is_unique());
ASSERT(m_property_table);
m_property_table->remove(property_name);
for (auto& it : *m_property_table) {
ASSERT(it.value.offset != offset);
if (it.value.offset > offset)
--it.value.offset;
}
}
}