The following command was used to clang-format these files:
clang-format-18 -i $(find . \
-not \( -path "./\.*" -prune \) \
-not \( -path "./Base/*" -prune \) \
-not \( -path "./Build/*" -prune \) \
-not \( -path "./Toolchain/*" -prune \) \
-not \( -path "./Ports/*" -prune \) \
-type f -name "*.cpp" -o -name "*.mm" -o -name "*.h")
There are a couple of weird cases where clang-format now thinks that a
pointer access in an initializer list, e.g. `m_member(ptr->foo)`, is a
lambda return statement, and it puts spaces around the `->`.
There's no need to capture things as Handle when using HeapFunction.
In this case, it was even creating a strong reference cycle, which ended
up leaking.
currently crashes with an assertion failure in `String::repeated` if
malloc can't serve a `count * input_size` sized request, so add
`String::repeated_with_error` to propagate the error.
These changes are compatible with clang-format 16 and will be mandatory
when we eventually bump clang-format version. So, since there are no
real downsides, let's commit them now.
When running with --log-all-js-exceptions, we will print the message
and backtrace for every single JS exception that is thrown, not just
the ones nobody caught.
This can sometimes be very helpful in debugging sites that swallow
important exceptions.
This fixes the relevant warnings when running LibJSGCVerifier. Note that
the analysis is only performed over LibJS-adjacent code, but could be
performed over the entire codebase. That will have to wait for a future
commit.
This lets us avoid false positives when a GCPtr-wrapped member is only
a weak reference which is automatically updated by the GC when the
member's gc state is updated.
When a GetById / GetByValue bytecode operation results in accessing a
nullish object, we now include the name of the property and the object
being accessed in the exception message (if available). This should make
it easier to debug live websites.
For example, the following errors would all previously produce a generic
error message of "ToObject on null or undefined":
> foo = null
> foo.bar
Uncaught exception:
[TypeError] Cannot access property "bar" on null object "foo"
at <unknown>
> foo = { bar: undefined }
> foo.bar.baz
Uncaught exception:
[TypeError] Cannot access property "baz" on undefined object "foo.bar"
at <unknown>
Note we certainly don't capture all possible nullish property read
accesses here. This just covers cases I've seen most on live websites;
we can cover more cases as they arise.
ObservableArray inherits from JS::Array and overrides `internal_set`
and `internal_delete` to run an interceptor callback when an indexed
item is added or deleted.
As long as the inputs are Int32, we can convert them to UInt32 in a
spec-compliant way with a simple static_cast<u32>.
This allows calculations like `-3 >>> 2` to take the fast path as well,
which is extremely valuable for stuff like crypto code.
While we're doing this, also remove the fast paths from the generic
shift functions in Value.cpp, since we only end up there if we *didn't*
take the same fast path in the interpreter.
Update to the latest version of the spec which was refactored to use
time zone methods record. This requires updating a whole bunch of
callers to pass through a record too.
This also ends up improving exceptions on a missing
getOffsetNanosecondsFor method.
Comparing two Values has to call the generic same_value() helper,
and we can avoid this by simply using a stronger type for built-in
native function handlers.
This reverts commit 9c943f36ed.
This optimization is superseded by optimizing IsValidIntegerIndex for
TypedArrays with non-resizable ArrayBuffers. Reverting this commit has
no impact on test-js, test262, or live website performance.
This reverts commit 5fd53652b7.
This optimization is superseded by optimizing IsValidIntegerIndex for
TypedArrays with non-resizable ArrayBuffers. Reverting this commit has
no impact on test-js, test262, or live website performance.
This reverts commit 72cee4c88b.
This optimization is superseded by optimizing IsValidIntegerIndex for
TypedArrays with non-resizable ArrayBuffers. Reverting this commit has
no impact on test-js, test262, or live website performance.
If we know the TA does not have a resizable ArrayBuffer, we can avoid
most of the heavy lifting that IsValidIntegerIndex performs.
On https://cyxx.github.io/another_js, this reduces the runtime of
IsValidIntegerIndex from 7.1% to 3.7%.
This avoids a virtual dispatch upon invoking the element size getter.
The size is static, so we could make TypedArrayBase templated with a
NTTP for the size, but let's not undergo such a wide-spread refactor.
On https://cyxx.github.io/another_js, this reduces the runtime of
IsValidIntegerIndex from 8.9% to 7.1%.
This avoids visiting the underlying buffer twice from ArrayBuffer's
byte_length.
On https://cyxx.github.io/another_js, this reduces the runtime of
IsValidIntegerIndex from 9.9% to 8.9%.
In IsValidIntegerIndex, we check if the TA is detached before invoking
MakeTypedArrayWithBufferWitnessRecord. There's no need to check it
again.
On https://cyxx.github.io/another_js, this reduces the runtime of
IsValidIntegerIndex from 10.7% to 9.9%.
In IsValidIntegerIndex, we check if the TA is detached before invoking
IsTypedArrayOutOfBounds. There's no need to check it again.
On https://cyxx.github.io/another_js, this reduces the runtime of
IsValidIntegerIndex from 11.5% to 10.7%.
Note: When we better support SharedArrayBuffer, that part of this AO
might not be inlined, as it looks a bit expensive.
On https://cyxx.github.io/another_js, this reduces the runtime of
IsValidIntegerIndex from 12.5% to 11.5%.
In IsValidIntegerIndex, we check IsTypedArrayOutOfBounds before invoking
TypedArrayLength. There's no need to check it again.
On https://cyxx.github.io/another_js, this reduces the runtime of
IsValidIntegerIndex from 16% to 12.5%.
This follows a change in the spec which refactored this function and its
callers to make use of a record instead of stuffing all of the possible
return values into a single Value.
As always in temporal land, this AO remains out of date, as well of all
its callers. Update all of these callers to the new API where possible,
and use an ad-hoc function to convert this struct back to a JS::Value
for APIs that have not been updated yet.