diff --git a/Libraries/LibJS/Runtime/IndexedProperties.cpp b/Libraries/LibJS/Runtime/IndexedProperties.cpp index 91f2830c398..f630de2cf43 100644 --- a/Libraries/LibJS/Runtime/IndexedProperties.cpp +++ b/Libraries/LibJS/Runtime/IndexedProperties.cpp @@ -50,18 +50,29 @@ void SimpleIndexedPropertyStorage::put(u32 index, Value value, PropertyAttribute if (index >= m_array_size) { m_array_size = index + 1; grow_storage_if_needed(); + } else { + if (m_packed_elements[index].is_special_empty_value()) { + --m_number_of_empty_elements; + } } m_packed_elements[index] = value; + if (value.is_special_empty_value()) { + ++m_number_of_empty_elements; + } } void SimpleIndexedPropertyStorage::remove(u32 index) { VERIFY(index < m_array_size); + ++m_number_of_empty_elements; m_packed_elements[index] = js_special_empty_value(); } ValueAndAttributes SimpleIndexedPropertyStorage::take_first() { + if (m_packed_elements.first().is_special_empty_value()) { + --m_number_of_empty_elements; + } m_array_size--; return { m_packed_elements.take_first(), default_attributes }; } @@ -70,14 +81,32 @@ ValueAndAttributes SimpleIndexedPropertyStorage::take_last() { m_array_size--; auto last_element = m_packed_elements[m_array_size]; + if (last_element.is_special_empty_value()) { + --m_number_of_empty_elements; + } m_packed_elements[m_array_size] = js_special_empty_value(); return { last_element, default_attributes }; } bool SimpleIndexedPropertyStorage::set_array_like_size(size_t new_size) { + if (new_size == m_array_size) + return true; + + auto old_size = m_array_size; m_array_size = new_size; m_packed_elements.resize_with_default_value_and_keep_capacity(new_size, js_special_empty_value()); + + if (old_size <= m_array_size) { + m_number_of_empty_elements += m_array_size - old_size; + } else { + m_number_of_empty_elements = 0; + for (auto& value : m_packed_elements) { + if (value.is_special_empty_value()) + ++m_number_of_empty_elements; + } + } + return true; } diff --git a/Libraries/LibJS/Runtime/IndexedProperties.h b/Libraries/LibJS/Runtime/IndexedProperties.h index 03e599f3d6a..039e66a6e9b 100644 --- a/Libraries/LibJS/Runtime/IndexedProperties.h +++ b/Libraries/LibJS/Runtime/IndexedProperties.h @@ -90,12 +90,15 @@ public: return ValueAndAttributes { m_packed_elements.data()[index], default_attributes }; } + bool has_empty_elements() const { return m_number_of_empty_elements.value() > 0; } + private: friend GenericIndexedPropertyStorage; void grow_storage_if_needed(); size_t m_array_size { 0 }; + Checked m_number_of_empty_elements { 0 }; Vector m_packed_elements; };