1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 22:37:35 +00:00

LibJS: Get rid of unnecessary work from canonical_numeric_index_string

The spec version of canonical_numeric_index_string is absurdly complex,
and ends up converting from a string to a number, and then back again
which is both slow and also requires a few allocations and a string
compare.

Instead lets use the logic we already have as that is much more
efficient.

This improves performance of all non-numeric property names.
This commit is contained in:
Anonymous 2022-02-12 12:51:06 -08:00 committed by Andreas Kling
parent 44a2ebea00
commit 3a184f7841
8 changed files with 57 additions and 98 deletions

View file

@ -17,39 +17,26 @@
namespace Web::Bindings::IDL {
// https://webidl.spec.whatwg.org/#is-an-array-index
bool is_an_array_index(JS::GlobalObject& global_object, JS::PropertyKey const& property_name)
bool is_an_array_index(JS::PropertyKey const& property_name)
{
// 1. If Type(P) is not String, then return false.
if (!property_name.is_number())
return false;
// 2. Let index be ! CanonicalNumericIndexString(P).
auto index = JS::canonical_numeric_index_string(global_object, property_name);
auto index = JS::canonical_numeric_index_string(property_name);
// 3. If index is undefined, then return false.
if (index.is_undefined())
if (!index.has_value()) {
// All of these are handled by canonical_numeric_index_string
// 3. If index is undefined, then return false.
// 4. If IsInteger(index) is false, then return false.
// 5. If index is 0, then return false.
// 6. If index < 0, then return false.
// 7. If index ≥ 2 ** 32 1, then return false.
// Note: 2 ** 32 1 is the maximum array length allowed by ECMAScript.
return false;
}
// 4. If IsInteger(index) is false, then return false.
// NOTE: IsInteger is the old name of IsIntegralNumber.
if (!index.is_integral_number())
return false;
// 5. If index is 0, then return false.
if (index.is_negative_zero())
return false;
// FIXME: I'm not sure if this is correct.
auto index_as_double = index.as_double();
// 6. If index < 0, then return false.
if (index_as_double < 0)
return false;
// 7. If index ≥ 2 ** 32 1, then return false.
// Note: 2 ** 32 1 is the maximum array length allowed by ECMAScript.
if (index_as_double >= NumericLimits<u32>::max())
return false;
// 8. Return true.
return true;