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

LibJS: Automatically & lazily coerce PropertyNames into numbers

This commit expands on 5eef07d232 by
automatically trying to coerce Type::String PropertyNames into numbers
when a caller checks if the PropertyName is_number/is_string.
This has several benefits:
 - We no longer have to duplicate the number coercion code to every
   function that accepts a PropertyNumber. (Or more likely, forget to.)
 - This keeps the lazy nature of only doing the coercion when and if
   there is a semantic difference to the different PropertyName types,
   which means this shouldnt cause any performance drop.
 - Since this coercion changes the state of the PropertyName itself the
   result is essentially cached and can speed up any repeat uses of the
   same PropertyName instance.
This commit is contained in:
Idan Horowitz 2021-06-16 20:51:07 +03:00 committed by Linus Groh
parent 623eadb44e
commit b9d9187feb
2 changed files with 31 additions and 49 deletions

View file

@ -196,11 +196,6 @@ bool Object::set_integrity_level(IntegrityLevel level)
case IntegrityLevel::Sealed:
for (auto& key : keys) {
auto property_name = PropertyName::from_value(global_object(), key);
if (property_name.is_string() && property_name.string_may_be_number()) {
i32 property_index = property_name.as_string().to_int().value_or(-1);
if (property_index >= 0)
property_name = property_index;
}
update_property(property_name, ~Attribute::Configurable);
if (vm.exception())
return {};
@ -209,11 +204,6 @@ bool Object::set_integrity_level(IntegrityLevel level)
case IntegrityLevel::Frozen:
for (auto& key : keys) {
auto property_name = PropertyName::from_value(global_object(), key);
if (property_name.is_string() && property_name.string_may_be_number()) {
i32 property_index = property_name.as_string().to_int().value_or(-1);
if (property_index >= 0)
property_name = property_index;
}
auto property_descriptor = get_own_property_descriptor(property_name);
if (!property_descriptor.has_value())
continue;
@ -395,11 +385,6 @@ Optional<PropertyDescriptor> Object::get_own_property_descriptor(const PropertyN
value = existing_value.value().value;
attributes = existing_value.value().attributes;
} else {
if (property_name.is_string() && property_name.string_may_be_number()) {
i32 property_index = property_name.as_string().to_int().value_or(-1);
if (property_index >= 0)
return get_own_property_descriptor(property_index);
}
auto metadata = shape().lookup(property_name.to_string_or_symbol());
if (!metadata.has_value())
return {};
@ -545,11 +530,6 @@ bool Object::define_property(const PropertyName& property_name, Value value, Pro
if (property_name.is_number())
return put_own_property_by_index(property_name.as_number(), value, attributes, PutOwnPropertyMode::DefineProperty, throw_exceptions);
if (property_name.is_string() && property_name.string_may_be_number()) {
i32 property_index = property_name.as_string().to_int().value_or(-1);
if (property_index >= 0)
return put_own_property_by_index(property_index, value, attributes, PutOwnPropertyMode::DefineProperty, throw_exceptions);
}
return put_own_property(property_name.to_string_or_symbol(), value, attributes, PutOwnPropertyMode::DefineProperty, throw_exceptions);
}
@ -775,12 +755,6 @@ bool Object::delete_property(const PropertyName& property_name)
if (property_name.is_number())
return m_indexed_properties.remove(property_name.as_number());
if (property_name.is_string() && property_name.string_may_be_number()) {
i32 property_index = property_name.as_string().to_int().value_or(-1);
if (property_index >= 0)
return m_indexed_properties.remove(property_index);
}
auto metadata = shape().lookup(property_name.to_string_or_symbol());
if (!metadata.has_value())
return true;
@ -836,13 +810,6 @@ Value Object::get(const PropertyName& property_name, Value receiver, bool withou
if (property_name.is_number())
return get_by_index(property_name.as_number(), without_side_effects);
if (property_name.is_string() && property_name.string_may_be_number()) {
auto& property_string = property_name.as_string();
i32 property_index = property_string.to_int().value_or(-1);
if (property_index >= 0)
return get_by_index(property_index, without_side_effects);
}
if (receiver.is_empty())
receiver = Value(this);
@ -904,13 +871,6 @@ bool Object::put(const PropertyName& property_name, Value value, Value receiver)
VERIFY(!value.is_empty());
if (property_name.is_string() && property_name.string_may_be_number()) {
auto& property_string = property_name.as_string();
i32 property_index = property_string.to_int().value_or(-1);
if (property_index >= 0)
return put_by_index(property_index, value);
}
auto string_or_symbol = property_name.to_string_or_symbol();
if (receiver.is_empty())
@ -1045,12 +1005,6 @@ bool Object::has_own_property(const PropertyName& property_name) const
if (property_name.is_number())
return has_indexed_property(property_name.as_number());
if (property_name.is_string() && property_name.string_may_be_number()) {
i32 property_index = property_name.as_string().to_int().value_or(-1);
if (property_index >= 0)
return has_indexed_property(property_index);
}
return shape().lookup(property_name.to_string_or_symbol()).has_value();
}