We can reduce the amount of padding the compiler adds in order to
ensure data alignment of member variables by ordering the types in
a struct by size in decending order.
Found By PVS-Studio: https://pvs-studio.com/en/docs/warnings/v802/
This is often needed in ArrayPrototype when getting items with indices
above 2**32-1 is possible since length is at most 2**53-1.
This also fixes a number of these cases in ArrayPrototype where the type
was not big enough to hold the potential values.
10.4.2 Array Exotic Objects
https://tc39.es/ecma262/#sec-array-exotic-objects
A String property name P is an array index if and only if
ToString(ToUint32(P)) equals P and ToUint32(P) is not the same value
as 𝔽(2^32 - 1).
This would previously crash as we used to_string() without checking the
type first. Circumvent that by handling invalid and numeric ones
separately and then using to_string_or_symbol().
Negative numeric properties are not a thing (and we even VERIFY()'d this
in the constructor). It still allows using types with a negative range
for now as we have various places using int for example (without
actually needing the negative range, but that's a different story).
u32 is the internal type of `m_number` already, so this now allows us to
leverage the full u32 range for numeric properties.
Requires a bunch of find-and-replace updates across LibJS, but
constructing a PropertyName from a nullptr Symbol* should not be
possible - let's enforce this at the compiler level instead of using
VERIFY() (and already dereference Symbol pointers at the call site).
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.
We were doing a *lot* of string-to-int conversion while creating a new
global object. This happened because Object::put() would try to convert
the property name (string) to an integer to see if it refers to an
indexed property.
Sidestep this issue by using PropertyName for the CommonPropertyNames
struct on VM (vm.names.foo), and giving PropertyName a flag that tells
us whether it's a string that *may be* a number.
All CommonPropertyNames are set up so they are known to not be numbers.
This is how it's stored internally - even though we still only construct
from i32. I had the compiler yell at me while trying something with this
and didn't want to add yet another cast, so let's quickly fix this.
SPDX License Identifiers are a more compact / standardized
way of representing file license information.
See: https://spdx.dev/resources/use/#identifiers
This was done with the `ambr` search and replace tool.
ambr --no-parent-ignore --key-from-file --rep-from-file key.txt rep.txt *
(...and ASSERT_NOT_REACHED => VERIFY_NOT_REACHED)
Since all of these checks are done in release builds as well,
let's rename them to VERIFY to prevent confusion, as everyone is
used to assertions being compiled out in release.
We can introduce a new ASSERT macro that is specifically for debug
checks, but I'm doing this wholesale conversion first since we've
accumulated thousands of these already, and it's not immediately
obvious which ones are suitable for ASSERT.