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.
Similar to 'Calendar Methods Record', this is part of a refactor to the
temporal spec which will need much work for all of the corresponding AOs
to be updated to use.
Put in a new header file to prevent circular include problems when using
this new record.
Additionally, use the second bit (instead of the first) to differentiate
between strings and symbols there. This will allow transparent
conversion of DFS to StringBase in the future.
This adapts our implementation to the editorial change in the temporal
proposal: 737baf2d
The changes to CalendarMethodsRecordLookup had already been implemented,
but we had followed the typo in the spec for CalendarMethodsRecordCall.
The issue in CalendarMethodsRecordCall hasn't surfaced yet, as the AOs
using Calendar Methods Record are currently not passing through a String
to represent a Calendar builtin.
No change to test-262.
This number is pure guesswork but it appears to fix GCC builds with
both ASAN and UBSAN hitting a native stack overflow before we have
a chance to catch it on our Azure CI.
This patch moves us away from the accumulator-based bytecode format to
one with explicit source and destination registers.
The new format has multiple benefits:
- ~25% faster on the Kraken and Octane benchmarks :^)
- Fewer instructions to accomplish the same thing
- Much easier for humans to read(!)
Because this change requires a fundamental shift in how bytecode is
generated, it is quite comprehensive.
Main implementation mechanism: generate_bytecode() virtual function now
takes an optional "preferred dst" operand, which allows callers to
communicate when they have an operand that would be optimal for the
result to go into. It also returns an optional "actual dst" operand,
which is where the completion value (if any) of the AST node is stored
after the node has "executed".
One thing of note that's new: because instructions can now take locals
as operands, this means we got rid of the GetLocal instruction.
A side-effect of that is we have to think about the temporal deadzone
(TDZ) a bit differently for locals (GetLocal would previously check
for empty values and interpret that as a TDZ access and throw).
We now insert special ThrowIfTDZ instructions in places where a local
access may be in the TDZ, to maintain the correct behavior.
There are a number of progressions and regressions from this test:
A number of async generator tests have been accidentally fixed while
converting the implementation to the new bytecode format. It didn't
seem useful to preserve bugs in the original code when converting it.
Some "does eval() return the correct completion value" tests have
regressed, in particular ones related to propagating the appropriate
completion after control flow statements like continue and break.
These are all fairly obscure issues, and I believe we can continue
working on them separately.
The net test262 result is a progression though. :^)
The JIT compiler was an interesting experiment, but ultimately the
security & complexity cost of doing arbitrary code generation at runtime
is far too high.
In subsequent commits, the bytecode format will change drastically, and
instead of rewriting the JIT to fit the new bytecode, this patch simply
removes the JIT instead.
Other engines, JavaScriptCore in particular, have already proven that
it's possible to handle the vast majority of contemporary web content
with an interpreter. They are currently ~5x faster than us on benchmarks
when running without a JIT. We need to catch up to them before
considering performance techniques with a heavy security cost.
This begins the process of aligning our implementation with the spec
with regard to using CalendarMethodsRecord. The main intent here is to
make it much easier to make normative changes to AOs which have been
updated to CalendarMethodsRecord.
While this does resolve various FIXMEs, many others above need to be
added in order to be able to pass through a CalendarMethodsRecord. The
use here aligns with what I can gather from the spec of what the
arguments to CreateCalendarMethodsRecord should be, but various AOs have
been updated so much with other changes it's not completely obvious.
Other AOs do not even exist in the latest version of the spec, but we
still rely on them.
As part of these updates, this commit coincidentally also fixes two
PlainDate roundingmode issues seen in test262 - a test of which is also
added in test-js. This issue boiled down to what appears to be an
observable optimization in the spec, where it can avoid calling
dateUntil in certain situations (roundingGranularityIsNoop).
However, the main goal here is to make it much easier to fix many more
issues in the future :^)
since/calendar-dateuntil-called-with-singular-largestunit.js ❌ -> ✅
until/calendar-dateuntil-called-with-singular-largestunit.js ❌ -> ✅
This is part of a large refactor made as part of the temporal spec.
Most AOs using the calendar now pass through this record. There will
need to be a long process of going through updating AOs to use this
record.
This makes it possible to use MakeIndexSequqnce in functions like:
template<typename T, size_t N>
constexpr auto foo(T (&a)[N])
This means AK/StdLibExtraDetails.h must now include AK/Types.h
for size_t, which means AK/Types.h can no longer include
AK/StdLibExtras.h (which arguably it shouldn't do anyways),
which requires rejiggering some things.
(IMHO Types.h shouldn't use AK::Details metaprogramming at all.
FlatPtr doesn't necessarily have to use Conditional<> and ssize_t could
maybe be in its own header or something. But since it's tangential to
this PR, going with the tried and true "lift things that cause the
cycle up to the top" approach.)
This is a bit tangled in that updating these functions involves a slew
of other spec changes.
However those spec updates fix a bunch of rounding issues, fixing 32
test cases.
Diff Tests:
+32 ✅ -32 ❌
This has the guts of the old temporal AO BalanceDuration with some
differences such as an extra precision of one unit. This appears to be
important for different rounding modes to act as a tiebreaker.
It also does not have any logic regarding a zoned date time 'relative
to' - the spec seems to have this factored in a way where callers are
expected to perform this logic if neccessary.
This is an editorial change in the ECMA-262 spec. See:
12d3687
This AO is meant to replace usages of IteratorNext followed by
IteratorValue with a single operation.
This allows, for example:
ThrowCompletionOr<Optional<Value>> foo()
{
return OptionalNone {};
}
The constructors and constraints here are lifted verbatim from
AK::Optional.