Commit Graph

243 Commits

Author SHA1 Message Date
Luke Wilde
0eceee0a05 LibJS: Replace Array.fromAsync with a native JavaScript implementation
This allows us to use the bytecode implementation of await, which
correctly suspends execution contexts and handles completion
injections.

This gains us 4 test262 tests around mutating Array.fromAsync's
iterable whilst it's suspended as well.

This is also one step towards removing spin_until, which the
non-bytecode implementation of await uses.

```
Duration:
     -5.98s

Summary:
    Diff Tests:
        +4     -4 

Diff Tests:
    [...]/Array/fromAsync/asyncitems-array-add-to-singleton.js  -> 
    [...]/Array/fromAsync/asyncitems-array-add.js               -> 
    [...]/Array/fromAsync/asyncitems-array-mutate.js            -> 
    [...]/Array/fromAsync/asyncitems-array-remove.js            -> 
```
2025-11-30 11:54:54 +01:00
Tim Ledbetter
166c8b116f LibJS: Avoid cast to out-of-range value in MathObject::abs() fast path 2025-11-30 11:54:02 +01:00
aplefull
eed4dd3745 LibRegex: Add support for string literals in character classes 2025-11-26 11:34:38 +01:00
aplefull
a49c39de32 LibRegex: Support matching unicode multi-character sequences 2025-11-26 11:34:38 +01:00
Timothy Flynn
54b9ddcc80 LibJS: Use relative date in NudgeToCalendarUnit when comparing durations
This is a normative change in the Temporal proposal. See:
https://github.com/tc39/proposal-temporal/commit/17e12be

The test added here would previously crash.
2025-11-20 08:28:51 -05:00
Timothy Flynn
15e4deb831 LibJS: Remove "era" from Temporal's DateTimeFormat formatting options
This is an editorial change in the Temporal proposal. See:
https://github.com/tc39/proposal-temporal/commit/0ecf157

The test added here would previously throw:

    TypeError: Unable to determine format for Temporal.PlainDate
2025-11-16 07:59:59 -05:00
Timothy Flynn
c7e4a99219 LibJS: Handle negativity in Temporal's ApplyUnsignedRoundingMode
I don't fully understand the BigInt math here, as the computation for
d1 and d2 don't align with the spec due to BigInt logic. This was
discussed a bit in SerenityOS's Discord some years ago:

https://discord.com/channels/830522505605283862/851522357734408232/978786665306918932

But some new tests in test262 indicate that we need to handle negative
values here, instead of just throwing away the sign.
2025-11-14 06:32:49 -05:00
Timothy Flynn
019c529c07 Meta: Increase the line length enforced by prettier to 120
This matches our coding style recommendation in CodingStyle.md, and
matches our python formatting.
2025-10-31 19:55:50 -04:00
Andreas Kling
fdb85a330e LibJS: Stop tracking whether execution context is strict mode or not
This was only used for basic testing, and forced us to plumb this flag
flag in a bunch of places.
2025-10-29 21:20:10 +01:00
aplefull
5632a52531 LibRegex: Properly track code units in u-v modes
Previously, both string_position and view_index used code unit offsets
regardless of mode. Now in unicode mode, these variables track code
point positions while string_position_in_code_units is properly
updated to reflect code unit offsets.
2025-10-24 21:23:06 +02:00
aplefull
cd4ac4f30f LibJS: Escape line terminators in regex source 2025-10-24 13:24:55 -04:00
aplefull
7ce4abe330 LibRegex+LibUnicode: Add unicode string properties 2025-10-24 13:24:55 -04:00
aplefull
4b989b8efd LibRegex: Add support for forward references to named capture groups
This commit implements support for forward references to named capture
groups. We now allow patterns like \k<name>(?<name>x) and
self-references like (?<name>\k<name>x).
2025-10-16 16:37:54 +02:00
aplefull
25a47ceb1b LibRegex+LibJS: Include all named capture groups in source order
Previously, named capture groups in RegExp results did not always follow
their source order, and unmatched groups were omitted. According to the
spec, all named capture groups must appear in the result object in the
order they are defined, even if they did not participate in the match.
This commit makes sure we follow this requirement.
2025-10-16 16:37:54 +02:00
Timothy Flynn
400300945f LibJS: Fill all available space when TA.copyWithin shrinks the array
This is a normative change in the ECMA-262 spec. See:
https://github.com/tc39/ecma262/commit/d228070p
2025-10-03 09:03:40 +02:00
Timothy Flynn
979761ad82 LibJS: Implement WeakMap.prototype.getOrInsert[Computed]
This is part of the Upsert proposal:
https://github.com/tc39/proposal-upsert
2025-10-03 08:58:40 +02:00
Timothy Flynn
b6924309a0 LibJS: Implement Map.prototype.getOrInsert[Computed]
This is part of the Upsert proposal:
https://github.com/tc39/proposal-upsert
2025-10-03 08:58:40 +02:00
Timothy Flynn
853e3ecf23 LibJS: Include the WeakMap key (not value) in non-weakable key errors
It is the key that cannot be held weakly, and thus the key that should
be include in the error message.
2025-10-03 08:58:40 +02:00
vedant-pandey
d082e7ec58 LibJS: Move Typed Array copyWithin optimization before index update
The optimization for non-shared ArrayBuffers operates on incorrect
values of from_byte_index and to_byte_index because they will have been
modified in the preceding steps. This causes the incorrect range to be
copied within the buffer.
2025-10-02 19:41:31 +02:00
Timothy Flynn
cb6ca85564 LibJS: Handle relativeTo ZDTs that fall within second DST wallclock time
This is a normative change in the Temporal proposal. See:
https://github.com/tc39/proposal-temporal/commit/1a089eb
2025-09-28 11:33:43 -04:00
Aliaksandr Kalenik
451c947c3f LibJS: Fast-path own-property enumeration and reduce descriptor lookups
Before this change, PropertyNameIterator (used by for..in) and
`Object::enumerable_own_property_names()` (used by `Object.keys()`,
`Object.values()`, and `Object.entries()`) enumerated an object's own
enumerable properties exactly as the spec prescribes:
- Call `internal_own_property_keys()`, allocating a list of JS::Value
  keys.
- For each key, call internal_get_own_property() to obtain a
  descriptor and check `[[Enumerable]]`.

While that is required in the general case (e.g. for Proxy objects or
platform/exotic objects that override `[[OwnPropertyKeys]]`), it's
overkill for ordinary JS objects that store their own properties in the
shape table and indexed-properties storage.

This change introduces `for_each_own_property_with_enumerability()`,
which, for objects where
`eligible_for_own_property_enumeration_fast_path()` is `true`, lets us
read the enumerability directly from shape metadata (and from
indexed-properties storage) without a per-property descriptor lookup.
When we cannot avoid `internal_get_own_property()`, we still
benefit by skipping the temporary `Vector<Value>` of keys and avoiding
the unnecessary round-trip between PropertyKey and Value.
2025-09-21 15:06:32 +02:00
Aliaksandr Kalenik
e81833423b LibJS: Add PutByNumericId and change PutById to be string key only
Previously, PutById constructed a PropertyKey from the identifier,
which coerced numeric-like strings to numbers. This moves that decision
to bytecode generation: the bytecode generator now emits PutByNumericId
for numeric keys and PutById for string keys. This removes per-execution
parsing from the interpreter.

1.4x speedup on the following microbenchmark:
```js
const o = {};
for (let i = 0; i < 10_000_000; i++) {
    o.a = 1;
    o.b = 2;
    o.c = 3;
}
```
2025-09-13 20:02:28 +02:00
Timothy Flynn
2fa6655dcb LibJS: Ensure NudgeToCalendarUnit is given a non-zero duration sign
Otherwise, we trip internal Temporal spec assertions.

This is an editorial change in the Temporal spec. See:
https://github.com/tc39/proposal-temporal/commit/30f8575
2025-08-29 01:14:20 +02:00
Timothy Flynn
3f75cf270a LibJS: Move ambiguous Temporal time string handling to a separate parser
This is an editorial change in the Temporal proposal. See:
https://github.com/tc39/proposal-temporal/commit/fa3d0b9
2025-07-23 22:05:15 +02:00
Timothy Flynn
3b3ff6f057 LibJS: Split up the GetTemporalUnitValuedOption AO
This is an editorial change in the Temporal proposal. See:
https://github.com/tc39/proposal-temporal/commit/fcdb47e
https://github.com/tc39/proposal-temporal/commit/ef04774
https://github.com/tc39/proposal-temporal/commit/2070032
https://github.com/tc39/proposal-temporal/commit/adf50d4
https://github.com/tc39/proposal-temporal/commit/40eaeb7
https://github.com/tc39/proposal-temporal/commit/aab7bee
https://github.com/tc39/proposal-temporal/commit/a10d38d
https://github.com/tc39/proposal-temporal/commit/06ce375
2025-07-23 22:05:15 +02:00
Timothy Flynn
04fe0c6aec LibJS: Create match indices based on code unit length
In Unicode mode, we were mixing code units (start_index) with code point
length (end_index).
2025-07-22 23:11:19 +02:00
Jelle Raaijmakers
5d19aacce7 LibJS: Do not directly append RegExp pattern code points during parse
There apparently is a bit of a disconnect between the spec asking us to
construct the pattern using code points and LibRegex not being able to
swallow those. Whenever we had multi-byte code points in the pattern and
tried to match that in unicode mode, we would fail.

Change the parser to encode all non-ASCII code units. Fixes 2 test262
cases in `language/literals/regexp`.
2025-07-22 01:23:52 +02:00
Timothy Flynn
0e6ee925f0 Meta+LibJS: Update simdutf to version 7.3.3
This contains a fix for handling invalid trailing padding characters.
2025-07-16 17:03:15 +02:00
Timothy Flynn
efa9737cf7 AK+LibJS: Do not set UTF-16 code point length to its code unit length 2025-06-25 22:20:47 +02:00
Viktor Szépe
19f88f96dc Everywhere: Fix typos - act III 2025-06-16 14:20:48 +01:00
R-Goc
9ec26058d1 LibTest/Tests: Build and run test-js on windows
This commit allows test-js to build and run, also in CI.

Co-authored-by: Andrew Kaster <andrew@ladybird.org>
2025-06-05 22:00:55 -06:00
Timothy Flynn
128675770c LibJS: Implement Intl.Locale.prototype.variants
This is a normative change in the ECMA-402 spec. See:
https://github.com/tc39/ecma402/commit/e8c995a
2025-06-04 17:11:35 -04:00
Aliaksandr Kalenik
1274f4e2f7 LibJS: Optimize Function.prototype.apply()
...by avoiding `CreateListFromArrayLike` in cases when we could directly
use elements of underlying object's indexed properties storage.

Makes this program go 2.1x faster:
```js
function target(a, b, c) {
    return a + b + c;
}

const args = [1, 2, 3];
let result = 0;

(function() {
    for (let i = 0; i < 10_000_000; i++) {
        result += target.apply(null, args);
    }
})();
```
2025-06-03 17:16:01 +02:00
Timothy Flynn
8145572180 LibJS+LibUnicode: Support ambiguous time zone transitions
For example, time zone transitions can result in repeated or skipped
wall times. Temporal wants us to handle these transitions.
2025-06-03 09:09:21 +12:00
Timothy Flynn
c8b4dc4847 LibJS: Require strict matching with a precise ZonedDateTime offset
This is a normative change in the Temporal proposal. See:
https://github.com/tc39/proposal-temporal/commit/1117eaf
2025-06-03 09:09:21 +12:00
Timothy Flynn
f091047159 LibJS+LibUnicode: Implement retrieval of collator keyword values
Completely missed this when implementing Intl.Collator!
2025-06-03 09:03:33 +12:00
Timothy Flynn
5e40db5a17 AK: Remove some now-unnecessary workarounds for simdutf base64 usage 2025-06-01 08:03:00 -04:00
Timothy Flynn
8e5cc74eb1 LibJS: Add notation to Intl.PluralRules
This is a normative change in the ECMA-402 spec. See:
https://github.com/tc39/ecma402/commit/a7ff535
2025-05-27 10:39:25 -04:00
Manuel Zahariev
addff9e35d LibJS: Unit tests for non-standard date formats 2025-05-26 18:48:09 +02:00
Manuel Zahariev
973110c046 LibJS: Convert date_parse_string to use DateParser 2025-05-26 18:48:09 +02:00
Aliaksandr Kalenik
bd6750aaa5 LibJS: Skip prototype chain lookup in internal_set() for arrays
...when Array.prototype and Object.prototype are intact.

If `internal_set()` is called on an array exotic object with a numeric
PropertyKey, and:
- the prototype chain has not been modified (i.e., there are no getters
  or setters for indexed properties), and
- the array is not the target of a Proxy object,

then we can directly store the value in the receiver's indexed
properties, without checking whether it already exists somewhere in the
prototype chain.

1.7x improvement on the following program:
```js
function f() {
    let a = [];
    let i = 0;
    while (i < 10_000_000) {
        a.push(i);
        i++;
    }
}

f();
```
2025-05-23 14:51:32 +02:00
Shannon Booth
5495531118 LibJS: Implement 'less than' for a String over code units
...Instead of code points.
2025-05-17 08:00:59 -04:00
Timothy Flynn
8a80ff7b3b AK+LibJS: Use simdutf for all base64 operations
We were previously unable to use simdutf for base64 decoding operations
other than "loose". Upstream has added support for the "strict" and
"stop-before-partial" operations, so let's make use of them!
2025-05-03 11:21:10 -04:00
Timothy Flynn
4d70f6ce1c LibJS: Ensure iterator parameter validation closes underlying iterator
This is a normative change in the ECMA-262 spec. See:
https://github.com/tc39/ecma262/commit/9552f29
https://github.com/tc39/ecma262/commit/f2bad00
2025-04-29 07:33:08 -04:00
Timothy Flynn
568524f8ba LibJS: Close sync iterator when async wrapper yields rejection
This is a normative change in the ECMA-262 spec. See:
https://github.com/tc39/ecma262/commit/ff129b1
2025-04-29 07:33:08 -04:00
aplefull
223c9c91e6 LibJS: Implement rawJSON and isRawJSON functions 2025-04-24 09:33:49 -04:00
Jess
83e46b3728 LibRegex: Fix crash when parse result exceeds max cache size
Before, If the cache was empty we would try and evict non-existant
entries and crash. So the fix is to make sure that we don't saturate
the cache with a single parse result.
2025-04-04 16:10:25 +02:00
Jess
f3a937ee76 LibJS: Fix integer overflow in target_offset of TypedArray.set() 2025-03-25 07:45:42 +00:00
Tim Ledbetter
ed62aa6224 Revert "LibJS: Reduce number of proxy traps called during for..in…
…iteration"

This reverts commit 357eeba49c.
2025-03-21 11:44:21 -05:00
Andreas Kling
357eeba49c LibJS: Reduce number of proxy traps called during for..in iteration
Before this change, we would enumerate all the keys with
[[OwnPropertyKeys]], and then do [[GetOwnPropertyDescriptor]] twice for
each key as we went through them.

We now only do one [[GetOwnPropertyDescriptor]] per key, which
drastically reduces the number of proxy traps when those are involved.
The new trap sequence matches what you get with V8, so I don't think
anyone will be unpleasantly surprised here.
2025-03-20 17:50:02 -05:00