Commit graph

2400 commits

Author SHA1 Message Date
Shannon Booth
0b946f39b2 Meta: Remove ENABLE_RUST build configuration option
This now is required to be set for the browser to function.
2026-04-02 22:59:42 +02:00
Shannon Booth
adabc5cedb LibJS: Handle empty UTF-16 strings in Rust FFI
Treat zero length UTF-16 slices from Rust as empty views at the FFI
boundary instead of assuming a non null backing pointer.

Add a regression test which crashed before these changes. Fixes
a crash loading github.com/ladybirdbrowser/ladybird.
2026-03-31 22:33:36 +02:00
Andreas Kling
6347827eb8 LibJS: Retry Unicode low-surrogate lastIndex positions
RegExpBuiltinExec used to snap any Unicode lastIndex that landed on a
low surrogate back to the start of the pair. That matched `/😀/u`,
but it skipped valid empty matches when the original low-surrogate
position was itself matchable, such as `/p{Script=Cyrillic}?(?<!\D)/v`
on `"A😘"` and the longer fuzzed global case.

Try the snapped position first, then retry the original lastIndex when
the snapped match fails. Only keep that second result when it is empty
at the original low-surrogate position, so consuming /u and /v matches
still cannot split a surrogate pair. In the Rust VM, treat backward
Unicode matches that start between surrogate halves as having no
complete code point to their left, which matches V8's lookbehind
behavior for those positions.

Add reduced coverage for both low-surrogate exec cases, the original
global match count regression, and the consuming-match retry regression.
2026-03-31 15:59:04 +02:00
Andreas Kling
50b137f527 LibJS: Reject mixed surrogate forms in RegExp names
Reject surrogate pairs in named group names unless both halves come
from the same raw form. A literal surrogate half was being
normalized into \uXXXX before LibRegex parsed the pattern, which let
mixed literal and escaped forms sneak through.

Validate surrogate handling on the UTF-16 pattern before
normalization, but only treat \k<...> as a named backreference when
the parser would do that too. Legacy regexes without named groups
still use \k as an identity escape, so their literal text must not be
rejected by the pre-scan.

Add runtime and syntax tests for the mixed forms, the valid literal,
fixed-width, and braced escape cases, and the legacy \k literals.
2026-03-31 15:59:04 +02:00
Andreas Kling
c167bfd50a Meta: Make Rust FFI headers reproducible
Teach import_rust_crate() to track RustFFI.h as a real build output,
and teach the relevant Rust build scripts to rerun when their FFI
inputs change.

Also keep a copy of RustFFI.h in Cargo's own OUT_DIR and restore the
configured FFI output from that cached copy after cargo rustc runs.
This fixes the case where Ninja knows the header is missing, reruns
the custom command, and Cargo exits without rerunning build.rs
because the crate itself is already up to date.

When Cargo leaves multiple hashed build-script outputs behind, pick
the newest root-output before restoring RustFFI.h so we do not copy a
stale header after Rust-side API changes.

Finally, track the remaining Rust-side inputs that could leave build
artifacts stale: LibUnicode and LibJS now rerun build.rs when src/
changes, and the asmintgen rule now depends on Cargo.lock, the
BytecodeDef path dependency, and newly added Rust source files.
2026-03-31 15:59:04 +02:00
Shannon Booth
685c875431 LibJS: Avoid constructing Utf16View with a null pointer for empty string
When decoding a zero length string, we would pass through the (null)
data() of an empty Vector to the Utf16View constructor. Return an empty
PrimitiveString early instead.
2026-03-31 13:48:50 +01:00
Undefine
b85f2c8b89 LibJS+Meta: Fix a x86_64 CMake check for some platforms
On platforms like FreeBSD x86_64 has the value of lowercase `amd64` in
`CMAKE_SYSTEM_PROCESSOR` which caused this check to fail and then
caused linking errors.
2026-03-29 13:59:11 -06:00
Tim Ledbetter
275e141823 LibJS: Rename Value::as_array() to Value::as_array_exotic_object()`
This better describes what the method returns and avoids the possible
confusion caused by the mismatch in behavior between
`Value::is_array()` and `Value::as_array()`.
2026-03-29 13:45:38 +02:00
Tim Ledbetter
17ea7b5f86 LibJS: Handle proxy-wrapped arrays in console.table()
Previously, we would crash if `console.table()` was called with a
proxy-wrapped array. This is because `Value::is_array()` returns true
for proxy-wrapped arrays but `as_array()` simply casts to an Array
object. We now treat these objects as array-like and access elements
generically through the Object interface, which correctly dispatches
through Proxy traps.
2026-03-29 13:45:38 +02:00
Tim Ledbetter
ed76bcf653 LibJS: Add assertions to Value::as_array() and Value::as_function()
These were previously removed in 4287da7d.
2026-03-29 13:45:38 +02:00
InvalidUsernameException
cf6c9d69f4 LibJS: Initialize constants in execution context right away
In b2d9fd3352, the root cause of the crash
was somewhat misdiagnosed, particularly around what place in code an
allocation could occur while constants data was uninitialized.

But more importantly, we can do better than the solution in that commit.
Instead of initializing constants with default values and then
overwriting them afterwards, simply initialize them with their actual
values directly when constructing the execution context.

This effectivly reverts commit b2d9fd3352.
2026-03-29 13:44:06 +02:00
InvalidUsernameException
7002c47ce1 LibJS+LibWeb: Pass constants into execution context constructor
The additional data being passed will be used in an upcoming commit.
Allows splitting the churn of modified function signatures from the
logically meaningful code change.

No behavior change.
2026-03-29 13:44:06 +02:00
Johan Dahlin
b542617e09 LibJS: Box StatementKind::ClassFieldInitializer variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
057725c731 LibJS: Box StatementKind::FunctionDeclaration variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
247b9a0a87 LibJS: Box StatementKind::UsingDeclaration variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
0167c83b35 LibJS: Box StatementKind::VariableDeclaration variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
938ec6ca18 LibJS: Box StatementKind::Labelled variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
345dbab49a LibJS: Box StatementKind::With variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
a36d7e5d88 LibJS: Box StatementKind::ForInOf variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
64ea365379 LibJS: Box StatementKind::For variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
31ae13eec6 LibJS: Box StatementKind::DoWhile variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
f29b7ab579 LibJS: Box StatementKind::While variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
3496379d09 LibJS: Box StatementKind::If variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
5ab51b173d LibJS: Box ExpressionKind::Yield variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
c62b7f2f87 LibJS: Box ExpressionKind::ImportCall variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
15097fa8e0 LibJS: Box ExpressionKind::TaggedTemplateLiteral variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
9d0d8129f4 LibJS: Box ExpressionKind::OptionalChain variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
7262ab5880 LibJS: Box ExpressionKind::Member variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
07e187ae6d LibJS: Box ExpressionKind::Conditional variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
333ae7cc6d LibJS: Box ExpressionKind::Assignment variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
0cae77b94a LibJS: Box ExpressionKind::Update variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
4d5df1f10b LibJS: Box ExpressionKind::Logical variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
5a02479704 LibJS: Box ExpressionKind::Binary variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
2c210df618 LibJS: Box ExpressionKind::Object variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
badad22006 LibJS: Box ExpressionKind::Array variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
f3c68d516b LibJS: Box ExpressionKind::Sequence variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
9981b2eaf5 LibJS: Box ExpressionKind::PrivateIdentifier variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
9f0265f953 LibJS: Box ExpressionKind::BigIntLiteral variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
5da800bff2 LibJS: Box ExpressionKind::StringLiteral variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
8dda68e642 LibJS: Box StatementKind::Program variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
3d0aaf41a9 LibJS: Box ExpressionKind::RegExpLiteral variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
780605f986 LibJS: Box ExpressionKind::TemplateLiteral variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
bb44d3bb38 LibJS: Box StatementKind::Export variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
9d29703962 LibJS: Box StatementKind::Import variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
b922b4a31b LibJS: Box StatementKind::Try variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
ff047383e4 LibJS: Box StatementKind::Switch variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
102c73a072 LibJS: Box ExpressionKind::SuperCall variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
0a1bf8079c LibJS: Box ExpressionKind::New variant 2026-03-28 11:55:41 +01:00
Johan Dahlin
d2a5c1260d LibJS: Box ExpressionKind::Call variant 2026-03-28 11:55:41 +01:00
InvalidUsernameException
b2d9fd3352 LibJS: Also initialize constants and arguments of ExecutionContext
When allocating ExecutionContext, we were skipping allocating constants,
because they are filled in shortly after. However, there is still some
code executing between allocating the ExecutionContext and assigning
constants. This code may allocate GC-aware objects before the
assignment.  Allocating any GC object may cause a garbage collection to
be triggered.  And running garbage collection on uninitialized objects
might have all kinds of unintended effects.

To avoid that, simply initialize constants right away. To be safe, also
initialize arguments, but I haven't checked more closely if it is needed
for them or not.

The specific case where this bug manifested was JetStream3's
raytrace-private-class-fields.js, which was triggering a segmentation
fault when trying to visit a functions constant during GC marking phase.
The offending allocation triggering the garbage collection is the
corresponding FunctionEnvironment being created.

This crash was exposed as a combination of multiple things coming
together. In particular, both of 1179e40d3f and 61e6dbe4e7 combined
were exposing the problem, but is seems neither commit is at fault. Most
likely the crash happening or not is sensitive to the exact amount of GC
pressure being present or size of individual execution contexts. And so
any change that affects those might make it appear or go away.

To put in an additional wrinkle, this could only be observed using the
ASM JS interpreter. The CPP interpreter was using a fast path for
function calls that has a different allocation pattern and did not run
into the crash.

No explicit regression test for this change because:
* The problem is very sensitive to implementation details and a
  reproduction that stays valid with code changes in the interpreter is
  probably impossible to come by.
* The bug was exposed by the JS benchmarks, which already are as good as
  a regression test as we are going to get here realistically.
2026-03-27 19:31:17 +01:00