Commit graph

1045 commits

Author SHA1 Message Date
Andreas Kling
4dc63ddf49 LibJS: Make Optional<Utf16String> use less space
Some checks are pending
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
By specializing the template, we can shrink it from 16 to 8 bytes.
This makes PrimitiveString a measly 32 bytes. :^)
2025-03-30 07:16:40 +01:00
Andreas Kling
152691f9eb LibWeb: Make RopeString subclass so PrimitiveString can be smaller
By moving the LHS and RHS pointers used by rope strings into a
RopeString subclass, we shrink PrimitiveString by 16 bytes. Most strings
are not rope strings, so this ends up saving quite a bit of memory.
2025-03-30 07:16:40 +01:00
Tim Ledbetter
568531f06a Everywhere: Mark GC::Cell derived classes as Weakable explicitly
Some checks are pending
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
Previously, all `GC::Cell` derived classes were Weakable. Marking only
those classes that require this functionality as Weakable allows us to
reduce the memory footprint of some frequently used classes.
2025-03-29 17:36:33 -05:00
Andreas Kling
2462a6b0fa LibJS: Use Value::to_byte_string() in fewer places 2025-03-28 12:31:40 -04:00
Andreas Kling
c71772126f LibJS: Remove ByteString internals from PrimitiveString
PrimitiveString is now internally either UTF-8, UTF-16, or both.
We no longer convert them to/from ByteString anywhere, nor does VM have
a ByteString cache.
2025-03-28 12:31:40 -04:00
Andreas Kling
f5dd776b11 LibJS: Remove some irrelevant hash lookups in ESFO constructor
If we don't have parameter expressions, we don't need to collect
metadata about whether instantiated var names collide with parameter
names or function names, as these flags are only used in the parameter
code path.
2025-03-27 23:12:04 +00:00
Andreas Kling
c037bda455 LibJS: Use a premade shape for normal function objects
This avoids going through all the shape transitions when setting up the
most common form of ESFO.

This is extremely hot on Uber Eats, and this provides some relief.
2025-03-27 23:12:04 +00:00
Andreas Kling
8af5f25dd0 LibJS: Use a premade shape for normal function object prototypes
Some checks are pending
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
This avoids one shape allocation per function instantiation.
2025-03-27 15:00:43 +00:00
Andreas Kling
dba1798de7 LibJS: Make StringOrSymbol::as_string() return a const reference
No need to copy the FlyString here, we can avoid the ref count churn.
2025-03-27 15:00:43 +00:00
Andreas Kling
7477002e46 LibJS: Keep parsed function parameters in a shared data structure
Instead of making a copy of the Vector<FunctionParameter> from the AST
every time we instantiate an ECMAScriptFunctionObject, we now keep the
parameters in a ref-counted FunctionParameters object.

This reduces memory usage, and also allows us to cache the bytecode
executables for default parameter expressions without recompiling them
for every instantiation. :^)
2025-03-27 15:00:43 +00:00
Andreas Kling
c12f8b80dc LibJS: Add fast_is<T> helpers for all the primitive wrapper objects
The JS runtime is full of checks for is<NumberObject> and friends.
They were showing up in a Speedometer profile as ~1% spent in
dynamic_cast, and this basically chops that down to nothing.
2025-03-25 23:57:00 +00:00
Andreas Kling
3cc5b1a6a5 LibJS: Do a bit less stuff in PropertyKey::try_coerce_into_number()
The many out-of-line function calls here stood out in a profile.
2025-03-25 23:57:00 +00:00
Jess
f3a937ee76 LibJS: Fix integer overflow in target_offset of TypedArray.set() 2025-03-25 07:45:42 +00:00
Andreas Kling
f1914893e9 LibJS+LibWeb: Remove more uses of DeprecatedFlyString 2025-03-24 22:27:17 +00:00
Andreas Kling
46a5710238 LibJS: Use FlyString in PropertyKey instead of DeprecatedFlyString
This required dealing with *substantial* fallout.
2025-03-24 22:27:17 +00:00
Andreas Kling
fc744e3f3f LibJS: Add fast path for strings in Value::to_property_key()
If the Value is already a primitive string, we can skip all the
conversion ceremony and return a PropertyKey right away.
2025-03-24 22:27:17 +00:00
Andreas Kling
53da8893ac LibJS: Replace PropertyKey(char[]) with PropertyKey(FlyString)
...and deal with the fallout.
2025-03-24 22:27:17 +00:00
Andreas Kling
d7908dbff5 LibJS: Change PropertyKey(ByteString) to PropertyKey(String)
...and deal with the fallout.
2025-03-24 22:27:17 +00:00
Andreas Kling
3b5032c4b1 LibJS: Remove unused StringOrSymbol constructors 2025-03-24 22:27:17 +00:00
Andreas Kling
e83a2c2369 LibJS: Prefer Value::to_string() over to_byte_string() in more places
We should always prefer working with String, and Value::to_string() may
even return a cached String if the Value refers to a primitive string,
but no caching occurs for ByteString.
2025-03-24 22:27:17 +00:00
Aliaksandr Kalenik
a8285f255b LibJS: Skip allocation of temp object for primitive types in Value::get
Previously, `String.prototype.split()` caused the construction of a
temporary StringObject when a string primitive was passed as an
argument, solely to perform a Symbol.split lookup. This change allows
skipping that allocation by looking directly into the prototype of
primitive values.

As a result, we can avoid ~200000 StringObject allocations in a single
test from the Speedometer 2 benchmark.

Co-Authored-By: Andreas Kling <andreas@ladybird.org>
2025-03-24 20:38:11 +01:00
Andreas Kling
5f12b2a05d LibJS: Make IteratorRecord inherit from Cell, not Object
Some checks are pending
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
This shaves its size down from 104 bytes to 48 bytes, cutting GC
pressure caused by this type in more than half.
2025-03-22 16:59:44 -05:00
Andreas Kling
1d88c4529c LibJS: Allow JS::Value to store a non-object Cell
This will allow us to refer to non-object Cells more readily in bytecode
and opens up for some nice optimizations.
2025-03-22 16:59:44 -05:00
Andreas Kling
8fcff2fa18 LibJS: Store Module::environment() as ModuleEnvironment
Let's use a more specific type here to allow for devirtualization.
2025-03-20 12:51:21 -05:00
Jess
12cbefbee7 LibJS+LibCrypto: Use a bitwise approach for BigInt's as*IntN methods
This speeds up expressions such as `BigInt.asIntN(0x4000000000000, 1n)`
(#3615). And those involving very large bigints.
2025-03-20 09:44:12 +01:00
Jess
92d0cd3c7c LibJS: Make InvalidIndex detail the full range of allowed values 2025-03-20 09:44:12 +01:00
Jess
f5a6704219 LibJS: Fix UAF in ECMAScriptFunctionObject::internal_construct
Currently, we create `this_argument` with
`ordinary_create_from_constructor`, then we use `arguments_list` to
build the callee_context.

The issue is we don't properly model the side-effects of
`ordinary_create_from_constructor`, if `new_target` is a proxy object
then when we `get` the prototype, arbitrary javascript can run.

This javascript could perform a function call with enough arguments to
reallocate the interpreters m_argument_values_buffer vector. This is
dangerous and leads to a use-after-free, as our stack frame maintains a
pointer to m_argument_values_buffer (`arguments_list`).
2025-03-19 10:31:00 +01:00
Timothy Flynn
780de1395b LibJS: Merge Intl.DurationFormat style and display fields into a struct
This is an editorial change in the ECMA-402 spec. See:
d56d624
2025-03-18 11:47:23 -04:00
Timothy Flynn
00d00b84d3 LibJS: Ensure relevant extension keys are included in ICU locale data
This is a normative change in the ECMA-402 spec. See:
7508197

In our implementation, we don't have the affected AOs directly, as we
delegate to ICU. So instead, we must ensure we provide ICU a locale with
the relevant extension keys present.
2025-03-18 11:47:23 -04:00
Timothy Flynn
37b8ba96f1 LibJS: Use currency digits for NumberFormat only for standard notation
This is a normative change in the ECMA-402 spec. See:
9140da2
2025-03-18 11:47:23 -04:00
Timothy Flynn
96c059bf67 LibJS: Use correct enum casing in some Intl constructors 2025-03-18 11:47:23 -04:00
Timothy Flynn
532f156f4a LibJS: Remove some single-use Intl.DurationFormat variables
This is an editorial change in the ECMA-402 spec. See:
4c139f1
da498c2
ed5c716
2025-03-04 07:36:10 -05:00
Timothy Flynn
1e462daa9b LibJS: Simplify the Intl.DurationFormat GetDurationUnitOptions AO
This is an editorial change in the ECMA-402 spec. See:
d097048
2025-03-04 07:36:10 -05:00
Timothy Flynn
2f023c2d9c LibJS: Simplify Intl.DurationFormat.prototype.resolvedOptions
This is an editorial change in the ECMA-402 spec. See:
e3d3406
2025-03-04 07:36:10 -05:00
Timothy Flynn
56a6daee4d LibJS: Standardize the spec-order of Intl.DurationFormat definitions
This is an editorial change in the ECMA-402 spec. See:
54ca35d
6cdcab3
e4cbfba
2025-03-04 07:36:10 -05:00
Timothy Flynn
aa61307392 LibJS: Re-arrange and rename a few Intl properties
This is an editorial change in the ECMA-402 spec. See:
a46e37d
e102741
67a8417
ecb086c
2025-03-04 07:36:10 -05:00
aplefull
80b2c11c81 LibJS: Implement Math.sumPrecise 2025-03-03 21:46:22 +01:00
aplefull
53cdb04ee8 LibJS: Fix parseFloat(-0) returning -0 instead of +0
The optimization that skips the string conversion for number values was
causing -0 to be returned as-is. This patch adds a check for this case.
2025-03-02 11:30:34 -05:00
Timothy Flynn
29c8e7c203 LibJS: Disallow large dates in ToTemporalMonthDay
This is a normative change in the Temporal proposal. See:
bd5ac12

Note: No test added here because this only affects non-ISO-8601
calendars, which we do not yet support.
2025-03-01 14:49:20 +01:00
Timothy Flynn
080d32c7d0 LibJS: Use Intl.DurationFormat for Temporal.Duration.p.toLocaleString
This is an normative change in the Temporal proposal. See:
ffb4fb5
2025-03-01 14:49:20 +01:00
Timothy Flynn
8f51d1dd04 LibJS: Integrate Temporal.Duration into Intl.DurationFormat
This is a normative change in the Temporal proposal. See:
2d97205
2025-03-01 14:49:20 +01:00
Timothy Flynn
f16fe66def LibJS: Migrate IsValidDuration to ECMA-262
This is an editorial change in the Temporal proposal. See:
03770bb

Note: We were actually already using the Temporal definition of this AO
in Intl.DurationFormat, so there's no change needed there.
2025-03-01 14:49:20 +01:00
Timothy Flynn
aa737bb654 LibJS: Migrate ToIntegerIfIntegral to ECMA-262
This is an editorial change in the Temporal proposal. See:
5f76109
2025-03-01 14:49:20 +01:00
Timothy Flynn
a8d6e5c3db LibJS: Migrate Temporal updates to ECMA-262 AOs to the main AO file
These are going to be included in the ECMA-262 AOs once Temporal reaches
stage 4. There's no need to keep them in the Temporal namespace. Some
upcoming Temporal editorial changes will get awkward without this patch.
2025-03-01 14:49:20 +01:00
Timothy Flynn
ea52952774 LibJS: Update Date AOs to use Temporal
Neglected to do this after the Temporal rewrite. This lets us eliminate
the duplicated GetUTCEpochNanoseconds definition in Temporal.
2025-03-01 14:49:20 +01:00
Timothy Flynn
5764eeab05 LibJS: Update spec numbers for the Intl.DurationFormat proposal
This proposal has reached stage 4 and was merged into the ECMA-402 spec.
See: 3ff3cc7
2025-03-01 14:49:20 +01:00
Timothy Flynn
e591636419 AK+Everywhere: Store JSON object keys as String 2025-02-20 19:27:51 -05:00
Jess
8ed7dee0f0 LibJS: Propogate allocation errors in BigInt constructor functions 2025-02-19 09:00:59 -05:00
Luke Wilde
105096e75a LibJS: Stop executing successful regex if it's past the end of the input
If the regex always matches the input, even if it's past the end, then
we need to stop execution of the regex when it's past the end. This
corresponds to step 13.a and prevents it from infinitely looping.

Reduced from: d98672060f/packages/react-i18n/src/utilities/money.ts (L10-L14)
2025-02-16 09:22:37 +01:00
Psychpsyo
f92d037752 LibJS: Parse dates like "Jan 15, 2025" 2025-02-14 06:27:37 -05:00