Commit graph

126 commits

Author SHA1 Message Date
Andreas Kling
b81269e78b Libraries: Clean up UTF-16 source text paths
Store parser errors, source range filenames, source code filenames,
module source, and Rust parser errors as UTF-16 where they flow back
into JavaScript-visible strings. Keep byte-oriented source buffers
byte-backed.

Remove temporary PrimitiveString, ByteString, and UTF-8 detours from
JSON, RegExp, module debug logging, print formatting, and tests.
2026-06-22 19:51:25 +02:00
Andreas Kling
b6bef6b688 Libraries: Use UTF-16 for JS-visible runtime strings
Produce JS-visible string results as UTF-16 at their source, including
numeric formatting, BigInt and BigFraction formatting, URI encoding,
console formatting, parser errors, regular expression errors, Intl and
Temporal records, LibUnicode locale boundaries, and LibWeb bindings.

Handle fractional radix formatting through the UTF-16 builder view.
2026-06-22 19:51:25 +02:00
Andreas Kling
7025dd1fa7 Libraries: Parse JS strings from UTF-16
Thread UTF-16 string input through JSON, script parsing, Date parsing,
Intl option parsing, Temporal parsing, and the helper library boundaries
that feed those parsers. Preserve ASCII fast paths where the source data
is known to be ASCII.
2026-06-22 19:51:25 +02:00
Andreas Kling
ee37bb5a9c LibJS: Remove primitive string UTF-8 paths
Move the remaining LibJS primitive string users to UTF-16 views and
strings. Remove the primitive string UTF-8 accessors and byte-string
coercion paths so new callers cannot rely on the old storage model.
2026-06-22 19:51:25 +02:00
Ali Mohammad Pur
62cb073ada LibWasm: Validate the wasm-gc and function-references instructions
Actual implementations are still trap-on-exec.
2026-06-19 17:01:47 +02:00
Ali Mohammad Pur
3ca552b37b LibWasm: Parse wasm-gc types
No more unsupported heap refs.
2026-06-19 17:01:47 +02:00
Aliaksandr Kalenik
23885e7b4d LibWeb+WebContent+WebWorker: Drop display list player type selection
WebContent no longer chooses between CPU and GPU display list players,
and the remaining callers always use Skia raster playback. Remove the
PageClient virtual and now-single-value enum, then play SVG image and
cursor display lists directly.
2026-06-18 10:25:44 +02:00
Andreas Kling
37e7526367 LibGfx: Split image decoders into a separate library
Move the image loader sources and decoder-only dependencies from LibGfx
into a new LibImageDecoders library. This keeps the APNG-enabled PNG
loader out of processes that only need core graphics and image writers.

Link the ImageDecoder service, direct decoder tests, fuzzers, test-web,
and the image utility against LibImageDecoders where they still decode
images in-process.
2026-06-10 11:55:48 +02:00
Andreas Kling
3f4f0f0c02 Utilities: Keep wasm event loop alive
Create the wasm utility event loop with
Core::EventLoop::initialize_for_current_thread() so it follows the same
process-lifetime model as other program main loops.
2026-06-05 09:18:39 +02:00
Andreas Kling
83b293e4f2 LibCore: Keep main event loops alive
Add an explicit initializer for process-lifetime event loops and use it
for browser, helper service, and utility main loops. This preserves weak
event loop references for cross-thread users while making main thread
loop lifetime independent of normal program teardown.
2026-06-05 09:18:39 +02:00
Andreas Kling
dfb2656d9c Utilities: Replace LibLine with libedit
Use libedit's readline-compatible interface for the JavaScript REPL so
line editing, history, and tab completion no longer depend on LibLine.
The REPL keeps its existing multiline input and completion behavior,
but no longer provides LibLine's live syntax highlighting.

Remove the unused LibLine dependency from the wasm utility and delete
the LibLine library from the build now that it has no remaining
consumers.
2026-06-05 00:09:37 +02:00
Ali Mohammad Pur
248b7e4515 Utilities/wasm: Stub non-function imports under --export-all-imports
The flag used to stub only function imports and silently drop everything
else, which made --export-all-imports unusable for modules that import
memories, tables, globals, or tags. Stub each kind by allocating a
matching empty instance.
2026-05-27 09:52:34 +02:00
Andreas Kling
a7ece4b062 LibWeb: Make the Rust HTML parser unconditional
Remove the runtime selector between the old C++ tree builder and the new
Rust implementation. Always construct HTML documents and fragments with
the Rust parser now that it matches the existing tests.

Simplify dump-html-tree by dropping the backend option that only made
sense while both parser implementations were available.
2026-05-17 15:35:56 +02:00
Andreas Kling
09296315c2 LibWeb: Add Rust HTML parser host plumbing
Add the C++ and Rust scaffolding that lets the tree builder live in
Rust while the DOM remains owned by LibWeb. Keep the exported surface
small: Rust stores parser state, and C++ provides node creation,
insertion, script, template, and GC hooks.

Route dump-html-tree through the selectable parser backend so the new
implementation can be exercised beside the existing parser while it is
being brought up.
2026-05-17 15:35:56 +02:00
Andreas Kling
edf909f83d Utilities: Add dump-html-tree
Add a small parser utility for inspecting tree-construction output in
the same spirit as dump-html-tokens. Print an annotated DOM tree so
parser changes can be compared without launching the browser.

Keep a silent iteration mode for external benchmark tools, where the
parser still builds the DOM but the utility avoids serialization and
stdout work.
2026-05-17 15:35:56 +02:00
Andreas Kling
54a172f3b5 LibWeb: Add HTML tokenizer dump tests
Add a dump-html-tokens utility that prints HTML tokenizer output in a
stable text format, along with focused tokenizer input and expectation
files.

Include silent and repeated-iteration modes so the utility can also be
used for local tokenizer throughput checks without changing the dumped
token format.
2026-05-15 21:01:40 +02:00
Andreas Kling
e3841a7392 LibJS: Compact Shape property table to a sorted flat array
Replace the lazy per-shape OrderedHashMap cache for non-dictionary
shapes with a GC-allocated descriptor array. Store descriptors in hash
order for lookup while keeping an enum index so callers can still walk
properties in insertion order.

Keep dictionary shapes on the mutable OrderedHashMap path, and migrate
callers that enumerated Shape::property_table() to the new insertion
order iterator. Cap descriptor arrays to their compact u16 index range
and keep larger dictionary shapes on the mutable table path across
prototype transitions and prototype clones.

Add coverage for setting the prototype of a dictionary object with more
than 65536 named properties.
2026-05-14 19:59:40 +02:00
Ali Mohammad Pur
a36f6abedb LibWasm+LibWeb: Properly track module lifetime with function refs 2026-05-10 16:41:42 +02:00
Ali Mohammad Pur
a33e148339 LibWasm+Meta: Add Cranelift AOT compilation backend
Add an optional Cranelift-based AOT compiler for WebAssembly functions,
enabled via -DENABLE_CRANELIFT_JIT=ON.
2026-05-10 16:41:42 +02:00
Andreas Kling
b265694f0d LibJS: Match bytecode cache blobs to their source
Store a SHA-256 fingerprint of the decoded source text in each bytecode
cache blob, and require callers to provide the expected fingerprint when
validating or decoding a blob.

This rejects sidecars for stale HTTP cache entries whose URL and request
headers still match but whose source body has been replaced. Bytecode
cache tests cover the mismatched-source rejection path.
2026-05-06 08:20:06 +02:00
Undefine
b9fec5edbf Meta: Rename and merge some lagom_* and ladybird_*
We had both {lagom,ladybird}_test and {lagom,ladybird}_lib, now both
are just one helper. Also rename all other lagom_* helpers to be
ladybird_*.
2026-05-05 22:08:24 +02:00
Andreas Kling
7ecc89bd60 js: Expose a synchronous gc() function in the REPL and script global
The global gc() helper used to live in LibJS itself, but was recently
removed. Several JS benchmarks still call gc() to force a collection,
so reintroduce it on the js binary's global object (both the REPL
and the bare script global) where it belongs as a testing affordance.
2026-04-26 01:26:44 +02:00
R-Goc
1ea9c00f7c Utilities: Mark unused variable with maybe_unused
This marks s_keep_running_repl as maybe_unused as it is set but unused
when running on Windows where we don't provide REPL functionality.
2026-04-20 15:45:58 -06:00
Andreas Kling
2ca7dfa649 LibJS: Move bytecode interpreter state to VM
The bytecode interpreter only needed the running execution context,
but still threaded a separate Interpreter object through both the C++
and asm entry points. Move that state and the bytecode execution
helpers onto VM instead, and teach the asm generator and slow paths to
use VM directly.
2026-04-13 18:29:43 +02:00
Ivan Krasilnikov
b2db3574c5 test262-runner: Support multi-line YAML flags
The metadata parser only handled inline flags (e.g. `flags: [noStrict]`)
but not the YAML block list format:

  flags:
    - noStrict

This caused ~130 test/staging/sm test262 tests failures from running
them in both strict and sloppy modes by test262-runner.
2026-03-29 13:21:17 +02:00
Andreas Kling
71713017c5 test262-runner: Remove parse-only fast path for negative tests
The Rust parse_program() does not validate regex patterns or catch
all early errors during the parse phase alone -- those are caught
during compilation. The old C++ Parser did catch them during parsing.

Remove the fast parse-only path for negative tests so they go through
the full VM + compilation path, which correctly surfaces all errors.

The parse-only mode (--parse-only flag) is kept for explicit use.
2026-03-19 21:55:10 -05:00
Andreas Kling
30f108ba36 LibJS: Remove C++ lexer, use Rust tokenizer for syntax highlighting
Delete Lexer.cpp/h and Token.cpp, replacing all tokenization with a
new rust_tokenize() FFI function that calls back for each token.

Rewrite SyntaxHighlighter.cpp and js.cpp REPL to use the Rust
tokenizer. The token type and category enums in Token.h now mirror
the Rust definitions in token.rs.

Move is_syntax_character/is_whitespace/is_line_terminator helpers
into RegExpConstructor.cpp as static functions, since they were only
used there.
2026-03-19 21:55:10 -05:00
Andreas Kling
169452f41b LibJS: Remove C++ parser
Delete Parser.cpp/h and ScopeCollector.cpp/h, now that all parsing
goes through the Rust pipeline.

Port test262-runner to use RustIntegration::parse_program() for its
fast parse-only check instead of the C++ Parser.

Add parsed_program_has_errors() and free_parsed_program() to the
RustIntegration public API for parse-only use cases.
2026-03-19 21:55:10 -05:00
Andreas Kling
272562ddc5 LibJS: Remove dead C++ bytecode compilation functions
Remove Bytecode::compile() and the old create() overloads on
ECMAScriptFunctionObject that accepted C++ AST nodes. These
have no remaining callers now that all compilation goes through
the Rust pipeline.

Also remove the if-constexpr Parse Node branch from
async_block_start, since the Statement template instantiation
was already removed.

Fix transitive include dependencies on Generator.h by adding
explicit includes for headers that were previously pulled in
transitively.
2026-03-19 21:55:10 -05:00
Andreas Kling
77cd434710 LibJS: Remove C++ compiler pipeline fallback paths
Now that the Rust pipeline is the sole compilation path, remove all
C++ parser/codegen fallback paths from the callers:

- Script::parse() no longer falls back to C++ Parser
- SourceTextModule::parse() no longer falls back to C++ Parser
- perform_eval() no longer falls back to C++ Parser + Generator
- create_dynamic_function() no longer falls back to C++ Parser
- ShadowRealm eval no longer falls back to C++ Parser + Generator
- Interpreter::run(Script&) no longer falls back to Generator

Also remove the now-dead old constructors that took C++ AST nodes,
the module_requests() helper, and AST dump code from js.cpp.
2026-03-19 21:55:10 -05:00
Timothy Flynn
7e4cfcfc71 test262-runner: Log the amount of time taken per-test
Finding this useful for finding long-running individual tests. This will
be shown automatically when libjs-test262/main.py is run with the -v.
2026-03-06 14:34:58 +01:00
Timothy Flynn
ac54cbbecf test262-runner: Extract run_test invocation to a lambda
This block of code is nearly identical between the two invocations. This
extracts them to a lambda so a subsequent update can be made just once.
2026-03-06 14:34:58 +01:00
Shannon Booth
1811679ceb test262-runner: Make more use of Value::as_if 2026-02-28 10:24:37 -05:00
Shannon Booth
0334a6b341 js: Make more use of Value::as_if 2026-02-28 10:24:37 -05:00
Andreas Kling
6cdfbd01a6 LibJS: Add alternative source-to-bytecode pipeline in Rust
Implement a complete Rust reimplementation of the LibJS frontend:
lexer, parser, AST, scope collector, and bytecode code generator.

The Rust pipeline is built via Corrosion (CMake-Cargo bridge) and
linked into LibJS as a static library. It is gated behind a build
flag (ENABLE_RUST, on by default except on Windows) and two runtime
environment variables:

- LIBJS_CPP: Use the C++ pipeline instead of Rust
- LIBJS_COMPARE_PIPELINES=1: Run both pipelines in lockstep,
  aborting on any difference in AST or bytecode generated.

The C++ side communicates with Rust through a C FFI layer
(RustIntegration.cpp/h) that passes source text to Rust and receives
a populated Executable back via a BytecodeFactory interface.
2026-02-24 09:39:42 +01:00
Andreas Kling
09a11a1a5c LibJS: Drop AST after first compilation on SourceTextModule
Now that initialize_environment() uses pre-computed data and
execute_module() caches its executable / uses TLA shared data,
we can drop the AST reference after it's no longer needed.

For TLA modules, the AST is dropped immediately after constructing
the SharedFunctionInstanceData (which takes its own ref). For non-TLA
modules, the AST is dropped after the first bytecode compilation.

Also remove the m_default_export field (replaced by the pre-computed
m_default_export_binding_name) and extract default export info in
parse() instead of the constructor.
2026-02-11 23:57:41 +01:00
Andreas Kling
6d0b54dd0b LibJS: Drop AST after first compilation on Script
After compiling the bytecode executable on first run, null out the
AST (m_parse_node) and clear AnnexB candidates since they are no
longer needed. This frees the memory held by the entire AST for the
script's lifetime.

The parse_node() accessor now returns a nullable pointer. Callers
(js.cpp for AST dumping, Interpreter for first compilation) access
the AST before it is dropped.
2026-02-11 23:57:41 +01:00
Marcus Nilsson
5fa9747105 LibWasm: Parse and validate typeuse references
This adds parsing of `(ref typeidx)` and validates that `typeidx` is a
valid index. Currently, nullability of the reference is lost.

A bug causing the code below to fail parsing has been fixed.
```wat
(module
  (type $T (struct (field i32) (field f32)))
  (type $T1 (struct (field i32) (field f32)))
  (; many more types... ;)
  (type $T64 (struct (field i32) (field f32)))
  (type $f (func (result (ref null $T64))))
)
```

The spec tests type-equivalence.{0,1,3,13} have been disabled as they
were previously false positives.
2026-02-10 13:00:16 +01:00
Andreas Kling
6f93832058 Tests/LibJS: Register test-js-bytecode and test-js-ast with CTest 2026-02-10 02:05:20 +01:00
Andreas Kling
52ddc15fb3 LibJS: Redesign AST dump with unicode tree drawing
Replace the old indentation-based AST dump with a new tree-drawing
approach using unicode box characters. Each node now also shows its
source position as @line:column, and additional internal state:

- Identifier: [argument:N] vs [variable:N], declaration kind
  (var/let/const), [global], [in-eval-scope]
- FunctionNode: [strict], [arrow], [direct-eval], [uses-this],
  [uses-this-from-environment], [might-need-arguments]
- Program: (script)/(module), [strict], [top-level-await]
- YieldExpression: [yield*] for delegation

Dump code is moved from AST.cpp into a new ASTDump.cpp file.
2026-02-10 02:05:20 +01:00
Adam Colvin
2df5a7bb31 LibJS: Add source locations to console.trace()
LibJS+DevTools: Implement console.trace() with source locations

- Add Console::TraceFrame struct with source location data
- Implement Console::trace() to gather stack information
- Add WebView::StackFrame and ConsoleTrace for IPC
- Implement DevToolsConsoleClient::printer() for traces
- Update FrameActor to format traces for DevTools
- Update WorkerDebugConsoleClient trace handling
- Update ReplConsoleClient to format trace output
2026-02-06 11:58:07 +00:00
Marcus Nilsson
bfa51c2555 LibWasm: Parse struct types and support multiple types in type section
This patch adds support for parsing structs in the type section.

It also removes the assumption that all types in the type section are
function types, adding appropriate validation.

Spec tests struct.3 and struct.4 have been disable as this would
require expanding `ValueType` to include more heap-types.
2026-02-04 14:29:22 +01:00
Ali Mohammad Pur
0e6943b17d LibWasm: Avoid unnecessary bounds checks in memory ops 2026-02-02 14:11:49 +01:00
Ali Mohammad Pur
921373a045 LibWasm: Implement call argument forwarding using call records 2026-02-02 14:11:49 +01:00
Ali Mohammad Pur
a72127c39d LibWasm: Move out addresses into their own allocation
Instead of trying to indirectly load 2x64 bits from *cc, load addresses
directly from their own contiguous allocation.

This allows a future optimisation where we defer loading addresses to
reduce memory port pressure.
2026-02-02 14:11:49 +01:00
Ali Mohammad Pur
be9d8288ef LibWasm: Take call arguments and results on registers if possible 2026-02-02 14:11:49 +01:00
Ali Mohammad Pur
b89ecfc6bc LibWasm: Split parameters from locals 2026-02-02 14:11:49 +01:00
Luke Wilde
babfd70ca7 LibGC: Enforce that a Cell type must declare the allocator to use
This ensures that we are explicitly declaring the allocator to use when
allocating a cell(-inheriting) type, instead of silently falling back
to size-based allocation.

Since this is done in allocate_cell, this will only be detected for
types that are actively being allocated. However, since that means
they're _not_ being allocated, that means it's safe to not declare
an allocator to use for those. For example, the base TypedArray<T>,
which is never directly allocated and only the defined specializations
are ever allocated.
2026-01-20 12:00:11 +01:00
ayeteadoe
5279e0ce73 CMake: Remove ENABLE_WINDOWS_CI option and adjust presets to match Unix
ENABLE_WINDOWS_CI and the *_CI presets were initially added back when
the AK library and all the AK Test* executables were the only targets
that supported building and running in CI. Since then, almost all the
targets in the codebase are built on Windows besides the following:
    - LibLine
    - test-262-runner

Since these targets above are not required to actually run or test the
browser on Windows in its current experimental state, fully disabling
them should be fine for now.

ENABLE_WINDOWS_CI was also used to exclude test-web from ctest. This
can be fully disabled on Windows for now until proper runtime support
is added.

The remaining locations were all using ENABLE_WINDOWS_CI as a proxy for
ENABLE_ADDRESS_SANITIZER, so we can just be explicit instead.

The new presets map much more directly to the unix Release, Debug, and
Sanitizer presets which should make setting up ladybird on Windows less
confusing.

We also make the new Windows_Experimental_Release preset the default in
ladybird.py to match Unix.
2026-01-16 11:15:16 -07:00
Undefine
3c8546fbf2 test262-runner: Use the correct assertion failed signature on FreeBSD 2026-01-12 20:58:21 +01:00