Commit Graph

644 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
583164e412 Meta: Upgrade prettier to version 3.6.2
This version is installed by default nowadays and has slight differences
from 3.3.3.
2025-10-31 19:55:50 -04: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
Adam Patterson
120bba597d LibJS: Remove using-declaration.js from .prettierignore
This is the second and final commit to remove using-declaration from
.prettierignore. While there is standard formatting changes here, there
is also scoping changes for the 'using' declarations due to the
following error:

Libraries/LibJS/Tests/using-declaration.js: SyntaxError:
Using declaration cannot appear in the top level when source
type is `script` or in the bare case statement.
2025-10-09 15:49:49 -04:00
Adam Patterson
052013f8e6 LibJS: Partially format using-declaration.js with prettier
This contains prettier formatting fixes for using-declaration.js. The
file isn't fully formatted at this state. There is a minor scoping code
change that must happen in the next commit to be able to remove this
file from .prettierignore, but I wanted to separate the code change from
the formatting change to improve the review process.

This contains formatting and changing single quotes to double quotes.
2025-10-09 15:49:49 -04:00
Adam Patterson
0eac4cc6ad LibJS: Remove files from .prettierignore
.prettierignore had files listed for an issue with 'using' declarations,
this is no longer an issue for prettier (tested on 3.6.2).
2025-10-09 15:49:49 -04: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
2a288f6d53 LibJS: Invalidate PrototypeChainValidity when prototype shape is a dict
Adds missing PrototypeChainValidity invalidation for add/set/delete
operations on dictionary-mode prototype shapes.
2025-09-22 18:41:23 +02: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
c3b0eabf18 LibJS: Capture PrototypeChainValidity before executing internal_get()
- Capture PrototypeChainValidity before invoking `internal_get()`. A
  getter may mutate the prototype chain (e.g., delete itself). Capturing
  earlier ensures such mutations invalidate the cached entry and prevent
  stale GetById hits.
- When caching, take PrototypeChainValidity from the base object
  (receiver), not from the prototype where the property was found.
  Otherwise, changes to an intermediate prototype between the base
  object and the cached prototype object go unnoticed, leading to
  incorrect cache hits.
2025-09-18 15:56:20 +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
Pavel Shliak
4f0e8236a0 LibJS: Make class accessors non-enumerable
According to ECMA-262 §15.4.5 (MethodDefinitionEvaluation),
getters and setters defined in class bodies
must create property descriptors with
[[Enumerable]]: false. Previously we incorrectly marked them enumerable.

This patch updates `ClassMethod::class_element_evaluation` so that both
getter and setter descriptors use `.enumerable = false`.
2025-09-07 08:35:10 -04:00
Luke Wilde
18c0739bbb LibJS: Copy base object of LHS of assignment to preserve eval order
Previously, the given test would create an object with the test
property that pointed to itself.

This is because `temp = temp.test || {}` overwrote the `temp` local
register, and `temp.test = temp` used the new object instead of the
original one it fetched.

Allows https://www.yorkshiretea.co.uk/ to load, which was failing in
Gsap library initialization.
2025-09-02 12:59:52 +01: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
e2b245add1 LibJS: Handle out-of-range prefixed numbers in Token::double_value
This regressed in cd15b1a2c9.

If a prefixed number is out-of-range of a u64, stroul would previously
fall back to ULONG_MAX. This patch restores that behavior.
2025-08-10 13:35:37 +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
Luke Wilde
f12b6b258f LibJS: Don't use presence of function params to identify function scope
Instead, we can just use the scope type to determine if a scope is a
function scope.

This fixes using `this` for parameter default values in arrow functions
crashing. This happened by `uses_this_from_environment` was not set in
`set_uses_this`, as it didn't think it was in a function scope whilst
parsing parameters.

Fixes closing modal dialogs causing a crash on https://www.ikea.com/

No test262 diff.

Reverts the functional part of 08cfd5f, because it was a workaround for
this issue.
2025-06-17 20:48:45 +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
Aliaksandr Kalenik
285bc005cb LibJS: Do more comprehensive check if next() fast path is possible
Before this change each built-in iterator object has a boolean
`m_next_method_was_redefined`. If user code later changed the iterator’s
prototype (e.g. `Object.setPrototypeOf()`), we still believed the
built-in fast-path was safe and skipped the user supplied override,
producing wrong results.

With this change
`BuiltinIterator::as_builtin_iterator_if_next_is_not_redefined()` looks
up the current `next` property and verifies that it is still the
built-in native function.
2025-06-02 00:15:36 +02: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