Commit graph

78 commits

Author SHA1 Message Date
Ali Mohammad Pur
8a74f52571 LibWasm: Partially implement the (new) exception handling proposal
This implements try_table and throw_ref execution in the interpreter.
2026-06-19 17:01:47 +02:00
Ali Mohammad Pur
16d1486cc9 LibWasm: Implement the wasm-gc instruction set in the BC interpreter 2026-06-19 17:01:47 +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
42c0a430f5 LibWasm: Implement the spec's type matching relations 2026-06-19 17:01:47 +02:00
Ali Mohammad Pur
340d87efd6 LibWasm: Catch SIGFPE on jitted code too
SIGFPE can happen if we emit a bare idiv.
2026-06-15 16:09:51 +02:00
Ali Mohammad Pur
c414f31ecf LibWasm: Correctly handle memory64's addr types in the interpreter 2026-06-10 14:10:57 +02:00
Ali Mohammad Pur
08221aebab LibWasm: Start execution immediately after validation
This adds a tier-up mechanism at loop edges, making it so we can
seamlessly (ish) transition between interpreted and native code so we
can start running wasm code immediately after validation while
compilation happens in the background, and switching to native code
eventually once we hit a big enough function that would benefit from
being compiled to begin with.
2026-06-05 00:08:11 +02:00
Andreas Kling
164ed80244 Meta: Enable exit-time destructor warnings for libraries
Enable -Wexit-time-destructors for all in-tree library targets and
update process-lifetime library statics so they no longer register
exit-time destructors. Long-lived caches, lookup tables, singleton
registries, and generated constants now use NeverDestroyed or leaked
references where the data is intended to live until process exit.

Update LibWeb, LibLine, and the binding generators so regenerated
sources follow the same rule instead of reintroducing destructed
statics.
2026-06-04 19:20:49 +02:00
Ali Mohammad Pur
5c1d2004b7 LibWasm: Handle traps emitted from cranelift 2026-06-03 11:51:43 +02:00
Ali Mohammad Pur
68f6c03a67 LibWasm: Correctly handle failed validation 2026-06-03 11:51:43 +02:00
Ali Mohammad Pur
01db906039 LibWasm: Disable direct threading on ASAN builds
ASAN changes tailcall semantics that break the code.
2026-05-31 20:26:22 +02:00
Ali Mohammad Pur
402e151b62 LibWasm: Move the "rest" of br_if.nostack into a separate function
...instead of a lambda, so gcc doesn't have to deal with annotations on
lambdas.
2026-05-28 10:34:26 +02:00
Ali Mohammad Pur
f31519c393 LibWasm: Add runtime checks to nostack br/br_if
synthetic_br_nostack and synthetic_br_if_nostack assumed the runtime
value stack already matches the target label's expected size. The
register allocator can leave more values on the stack than the
validator's abstract count predicted, so the bare nostack variants get
us out of sync and we crash later. This makes it so they drop to regular
br/br_if behaviour if they notice that the size is not as expected.
2026-05-27 09:52:34 +02:00
sideshowbarker
59eb221d7c LibWasm: Fix “return” leaking intermediate value-stack entries to caller
Problem: Loading WebAssembly modules that use “return” mid-function can
corrupt the heap and crash the browser.

Cause: HANDLE_INSTRUCTION(return_) shrank the label stack but left any
working values pushed before the “return” instruction on the shared
value stack. Those residuals leaked into the caller’s frame and
accumulated across calls — until they overflowed the value stack’s
inline storage and corrupted adjacent allocator metadata.

Fix: After shrinking the label stack down to the function-level label,
also remove value-stack entries between that label’s recorded
stack_height and the top .arity() result values — mirroring the cleanup
that branch_to_label<true> already performs for br/br_if.

Fixes https://github.com/LadybirdBrowser/ladybird/issues/9614
2026-05-25 09:00:44 +02:00
Andreas Kling
f374e72c54 LibWasm: Store try_table catches out of line
TryTableArgs only needs catches for try_table instructions. Reuse the
structured-instruction layout with catch storage in place of the else
target, and keep the catch elements in a FixedArray.

This avoids storing a full Vector inline in every Instruction variant
alternative and keeps the catch storage copyable for the variant.
2026-05-14 12:19:38 +02:00
Andreas Kling
571bbba042 LibWasm: Use chunked synthetic instruction storage
Keep synthetic instruction pointers stable by storing them in fixed
chunks instead of one large Vector. This removes the old oversized
reserve. Expressions without synthetic instructions now avoid extra
instruction storage entirely.
2026-05-14 12:19:38 +02:00
Andreas Kling
8775f48436 LibWasm: Store structured metadata directly
Validation always fills structured instruction metadata before compiled
expressions are executed. Store the metadata directly instead of using
Optional, and update execution and printing paths accordingly.
2026-05-14 12:19:38 +02:00
Andreas Kling
f22dec54ef LibWasm: Store opcodes in 32 bits
Wasm opcodes only need one byte plus a 24-bit selector for
prefixed instructions. Store them in u32 instead of u64 and reject
selectors that would not fit. Update the Rust opcode generator to
accept the new integer suffixes used by Opcode.h.
2026-05-14 12:19:38 +02:00
Ali Mohammad Pur
9bda97a11b LibWasm: Avoid huge switches in all handlers' log functions
This explodes the debug info size, making the CI runner OOM when
building this file :)
2026-05-10 16:41:42 +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
Ali Mohammad Pur
5ab2eaed8c LibWasm: Fix some signedness bugs
- memory.grow page count
- memory.copy offsets and underflow in copy op
- table_{set,get} index exec
2026-05-10 16:41:42 +02:00
Andreas Kling
eb789e790e Everywhere: Use AK::SaturatingMath and remove Checked saturating APIs
Port all callers of Checked<T>::saturating_add/sub/mul to the new
standalone functions in AK/SaturatingMath.h, and remove the old
APIs from Checked.
2026-03-21 18:20:09 -05:00
Jelle Raaijmakers
bd9bc10eb2 LibWasm: Remove Vector size checks in (return_)call_indirect
These are followed by `Vector::operator==` which immediately compares
sizes as well.
2026-03-07 16:05:20 +01:00
Jelle Raaijmakers
fa1417114e LibWasm: Implement call_ref and return_call_ref instructions
These are part of the typed function references proposal, which is now
widely used by toolchains like wasm-bindgen. This makes sites like
wordsalad.online load in Ladybird.
2026-03-07 16:05:20 +01:00
Ali Mohammad Pur
0e7fb1386e LibWasm: Use the right indices for i64 constlocal fused ops
Also aligns the i32 ones to use the same detection logic as the i64
cases.
2026-02-23 00:22:47 +01:00
Rocco Corsi
d2ddf5d91d LibWasm: Disable direct threading on debug+gcc15
In preperation for Ubuntu 26.04 LTS, which will most likely come default
with GNU GCC 15.2.0 (but should have versions 14 and 16 available),
found that musttail/tail-call optimization fails for non-release builds.

Testing done on Ubuntu 25.10 which has GNU GCC 15.2.0 as default,
checking: Release, Debug, All_Debug, Sanitizer, and Distribution.

Fixes: #6745
2026-02-10 01:58:40 +01: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
0dc39e9bfd LibWasm: Use the source_value() mechanism in binary_numeric_operation
This avoids a bunch of extra stack ops and some unnecessary loads for
registers.
2026-02-02 14:11:49 +01:00
Ali Mohammad Pur
9964c64446 LibWasm: Implement the i32 const/local fusions for i64 too 2026-02-02 14:11:49 +01:00
Ali Mohammad Pur
a0ce33e616 LibWasm: Preserve the right number of values on loop entry 2026-02-02 14:11:49 +01:00
Ali Mohammad Pur
a5db31943e LibWasm: Fix return_call label stack shrink
The label stack should be shrunk to the frame's label_index (exclusive),
not label_index + 1. Also add the missing shrink call for
return_call_indirect.
2026-02-02 14:11:49 +01:00
Ali Mohammad Pur
9d7c56d7ab LibWasm: Defer the load of addresses until after dispatch
This unlocks a significant (+50%) performance improvement that previous
commits have been building up towards.
2026-02-02 14:11:49 +01:00
Ali Mohammad Pur
7f5ca14f58 LibWasm: Specialize instruction dispatch for all-stack cases too 2026-02-02 14:11:49 +01:00
Ali Mohammad Pur
2d15ef7372 LibWasm: Remove all runtime VERIFYs from the 'block' handler
All of these are already checked at the verification stage, so downgrade
them to ASSERTs.
2026-02-02 14:11:49 +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
ae9ced65b7 LibWasm: Add a bunch more fused ops
- synthetic_argument_set, synthetic_argument_tee
- synthetic_local_get_0..7, synthetic_local_set_0..7
- synthetic_br_nostack, synthetic_br_if_nostack
- synthetic_local_copy for local-to-local copies
- synthetic_i32_{sub,mul,and,or,xor,shl,shru,shrs}2local
2026-02-02 14:11:49 +01:00
Ali Mohammad Pur
9a74bf87d8 LibWasm: Minimize runtime overhead for block/branch ops
Preevaluate arity and params to avoid pointer chasing at exec time.
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
f180d90c20 LibWasm: Re-add trace logging to handlers 2026-02-02 14:11:49 +01:00
Ali Mohammad Pur
0d5363caff LibWasm: Compress current_ip + addresses into one u64 field
This saves a register, which then consequently saves us from spilling on
the stack (in most places that matter).
2026-02-02 14:11:49 +01:00
Ali Mohammad Pur
446240da63 LibWasm: Specialise source/dest accesses based on stack access 2026-02-02 14:11:49 +01:00
Ali Mohammad Pur
6ede78aa0a LibWasm: Validate compiled instruction stream
This helps catch a bunch of miscompilations early.
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
70f839ccb2 LibWasm: Take call arguments as references and recycle the allocations
This opens the way for a allocated-at-start call frame optimisation
(that will come in a future commit).
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
Ali Mohammad Pur
ac979648bd AK+LibJS: Zero out new Vector allocs instead of calling trivial ctor
As JS::Value is marked "trivial" without actually being trivial, make
the one user that would lead to garbage JS::Value entries provide a
default value instead.
2026-02-02 14:11:49 +01:00
Ali Mohammad Pur
b93c17e5e7 LibWasm: Implement (n)madd/vetor dot arguments the right way
Previously we were reading the arguments in an incorrect order, and
placing the result in the wrong slot.
This also removes the hacky implementation of accumulative relaxed dot,
and just implements it directly as a new operator.
2025-12-12 19:12:53 +01:00
Rocco Corsi
c9e9208dca LibWasm: Make debug messages have unique wording 2025-12-12 19:12:19 +01:00