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.
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.
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.
Remove the UTF-16 storage mode and make StringBuilder solely build
UTF-8 strings again. The remaining UTF-16 adoption path now goes
through Utf16StringBuilder, keeping the direct-adoption optimization
with the type that owns UTF-16 construction.
Move the remaining call sites that constructed StringBuilder in UTF-16
mode over to Utf16StringBuilder or explicit UTF-8 to UTF-16 conversion.
Teach FormatBuilder to target Utf16StringBuilder directly so formatted
Utf16String construction no longer needs StringBuilder's UTF-16 mode.
Update the Utf16String tests to cover Utf16StringBuilder adoption and
clear behavior directly.
Add vformat support for Utf16StringBuilder and expose appendff and
try_appendff helpers on the builder itself. This lets callers build a
Utf16String on the purpose-built UTF-16 path even when using formatting.
Use the new API for Utf16String::formatted and add AK coverage for
formatting directly into a Utf16StringBuilder.
Add a purpose-built builder for constructing Utf16String values.
It keeps ASCII storage while possible, widens to UTF-16 when needed,
and can hand outline storage to Utf16StringData for direct adoption.
Add AK coverage for ASCII strings, UTF-16 widening, code points,
trimming, and long string construction.
Remove the stale bytecode execution debug hook from Interpreter.cpp now
that bytecode dispatch always enters AsmInt directly. The remaining
bytecode dump flag is separate and still used by parser/codegen paths.
Remove the unused SANITIZE_PTRS destructor poisoning blocks from AK
pointer wrappers. Also drop the stale Qt Creator configuration define
that referenced this old mode.
Delete or unref directly from RefPtr, NonnullRefPtr, and NonnullOwnPtr
destructors instead of calling clear() or exchanging the member pointer.
This avoids storing null when the wrapper lifetime is ending.
Delete the owned object directly from OwnPtr destruction instead of
calling clear(). The object lifetime is ending, so there is no need to
store nullptr into m_ptr on this path.
OwnPtr now always deletes the owned object directly from clear(). Remove
the unused deleter template parameter and the DefaultDelete helper that
only supported that parameter. Drop the dedicated custom deleter test.
Add class-local allocation macros for operator new/delete through AK's
malloc helpers. The macros can optionally choose a HeapPartition.
Add Layout and Painting partitions, plus basic partition stats helpers.
Use the new partitions for LibWeb layout and painting object hierarchies
and layout-state side data.
Now that Badge can have multiple types, and a Badge of a derived class
can convert into a Badge of the superclass, we can simplify a few method
signatures and overloads.
Add a string heap partition and route long AK string backing
allocations through it.
Give StringBuilder partition-aware outlined storage so adopted String
and Utf16String buffers are allocated from the string heap. Keep the
string heap thread-local because mimalloc heaps may only allocate from
their creating thread, while cross-thread frees are handled by mimalloc.
Add a JSObjectStorage heap partition and route heap-backed property
storage (both named and indexed element buffers) through it.
These buffers are directly shaped by script-visible object and array
operations, so keeping them separate from the general heap makes a
corruption primitive less useful against unrelated allocations.
Move owned ArrayBuffer and SharedArrayBuffer data blocks into the
ArrayBuffer heap partition. Keep unowned and host storage explicit, so
Wasm memory and external LibWeb buffers stay outside this partition.
Introduce DataBlock::OwnedBackingStore as the LibJS-owned byte storage
representation. Expose byte spans instead of a ByteBuffer object, giving
ArrayBuffer one allocation boundary that can later grow toward guarded
or caged storage.
Let callers that need ByteBuffer data copy from backing-store bytes.
Keep TransferArrayBuffer zero-copy by moving the DataBlock directly
instead of materializing a ByteBuffer in between.
Update the Wasm typed-array test helper to compare viewed byte ranges
after ArrayBuffer stops exposing ByteBuffer identity.
Introduce HeapPartition and overload kmalloc and krealloc so allocation
sites can opt into a specific heap partition. Keep the default allocator
API unchanged. The only initial partition is General, which maps to the
regular allocator path.
Keep sanitizer builds on the system allocator so LeakSanitizer can still
trace AK container allocations. Remove the obsolete Serenity-specific
allocator branch while updating this file.
Problem: For several weeks now, CI Sanitizer runs have been logging
leaked RustCompiledRegex objects in the WebWorker process when a worker
is torn down while an off-thread script compile is still in flight.
Cause: compile_off_thread() (introduced in 4a7dc45b3f) parses and
compiles a fetched top-level script on a ThreadPool worker. The pool's a
process-lifetime singleton whose workers are never joined before exit —
and that leads to LSan reporting a false positive during teardown.
Fix: Suppress the false positive via __lsan_default_suppressions().
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.
Cppcheck 2.17 tool found issue with struct tm under Windows
Checking AK/Time.cpp ...
Checking AK/Time.cpp: AK_OS_WINDOWS...
AK/Time.cpp:488:15: error: Uninitialized variable: &tm [uninitvar]
(void)localtime_r(×tamp, &tm);
^
32/39 files checked 87% done
Also the gmtime_X` and localtime_X calls were not checked for failures,
so those are now checked too.
Problem: is_within_range<I>(F value) — where I is an integer and F is a
floating-point type — is unexpectedly too permissive in some cases:
a. Values that are 1 past the integer range unexpectedly pass; e.g.,
is_within_range<int>(2147483648.0f) returns true — even though
2147483648 is INT_MAX + 1.
b. Fractional values whose magnitude exceeds the destination max
unexpectedly pass; e.g., is_within_range<unsigned>(4294967295.5)
returns true — even though 4294967295.5 > UINT_MAX.
c. Fractional values within the destination’s numeric range unexpectedly
pass (e.g., is_within_range<int>(2.5) returns true) — even though
they aren’t exactly representable as the destination type.
Cause: TypeBoundsChecker integer-bounds specializations compare against
NumericLimits<Destination>::max() and ::min() directly. When a caller’s
value is a float, the integer max/min get implicitly converted to a
float for the comparison. For Destination/Source pairs with the integer
extreme not exactly representable in the float, that conversion rounds
up to the next power-of-two boundary — so “value <= F(max)” accepts
values that are actually out of range by one (case a). And the
comparison itself doesn’t reject fractional values (cases b and c).
Fix: When Source is a floating-point type:
1. First gate (case a) — Compare against 2^digits; exactly representable
in any IEEE float, and equals max + 1 for unsigned / -min for two’s-
complement signed integers.
2. Second gate (cases b and c) – Round-trip check: cast value to
Destination, then cast back — and require equality. Only integer-
valued floats whose truncation matches the original pass.
Fixes https://github.com/LadybirdBrowser/ladybird/issues/6212
This template is causing an "error: satisfaction of atomic constraint
‘IsConstructible<T, const U&> [with T = X; X]’ depends on itself"
through a self referential CSSScopeRule on GCC 16.1. Tighten the
template requirements to avoid it.
Make Variant::visit reject typed visitor overloads that cannot be
called for any variant alternative. This catches stale visitors after a
variant payload type changes instead of falling through to a generic
overload.
Update fetch body consumers that still expected ByteBuffer after the
body payload moved to Core::ImmutableBytes.
`as_if<T>()` previously had a fast path that used `fast_is<T>()` and a
static cast. Mixin types couldn't use this fast path, since a static
cast from a sibling base is not valid, so would fall back to using a
slow dynamic cast instead.
This change adds a `fast_as<T>()` mechanism for mixin types to opt in
to and teaches `as_if<T>()` to use it. This means `as<T>()` and
`as_if<T>()` can be used with mixin types without incurring the
overhead of a dynamic cast
Create Libraries/LibWeb/Compositor and make the existing rendering
thread the first owner in that subsystem. Rename RenderingThread to
CompositorThread so later commits can grow it into the presentation
owner without leaving that vocabulary in HTML.
Keep display-list rasterization and delivery behavior unchanged in this
commit. Add COMPOSITOR_DEBUG to AK/Debug.h.in in the same step so
compositor diagnostics live beside the rest of the project-wide debug
toggles from the start of the stack.
Add a helper for finding the first position in a sorted container where
needle can be inserted while preserving sort order. This gives callers a
lower-bound insertion point.
Cover empty inputs, duplicate values, custom comparators, and constexpr
use in TestBinarySearch.
Instead of sweeping all heap blocks in one go after marking, sweep
incrementally, one block at a time, interleaved with program execution.
This significantly reduces worst-case GC pause times by spreading
sweep work across multiple smaller time slices.
Sweep is driven by two complementary mechanisms:
1. Timer-based sweeping: A 16ms repeating timer drives background
sweep work, processing blocks for up to 5ms per timer fire.
2. Allocation-directed sweeping: Each allocator sweeps its own
pending blocks before creating new ones, ensuring forward
progress even without timer events.
Each allocator maintains its own list of blocks pending sweep,
and allocators with pending work are tracked in a separate list
for efficient timer-driven sweeping.
Key implementation details:
- Newly allocated cells during sweep are marked immediately to
prevent premature collection.
- Mark bits are cleared incrementally as each block is swept,
rather than in a separate pass over the entire heap.
- Finalization and weak reference processing remain stop-the-world
since they must complete atomically before any sweeping occurs.
StringBuilder::clear() did not reset m_utf16_builder_is_ascii. When a
UTF-16 mode builder processed a non-ASCII character then was cleared
and reused, subsequent ASCII content was stored as char16_t. The
to_utf16_string() path then corrupted the first code unit to null via
placement-new overlap in Utf16StringData::from_string_builder().
This caused the HTML parser's shared m_character_insertion_builder to
produce corrupted script text nodes when a non-ASCII character (e.g.
×) appeared in an earlier element, breaking inline script
execution with "Unexpected token Invalid" at line 1 column 1.
GCC 16 can clobber the first bytes of Utf16StringData payload when a
StringBuilder buffer is reused for string construction. The trailing
ASCII/UTF-16 storage previously started before sizeof(Utf16StringData),
inside tail padding, so placement-new of the header could zero the first
code unit.
This patch aligns the trailing storage union so payload begins after the
full header.
Display lists were the last user of SegmentedVector before the flat
command buffer replaced that storage. With no remaining includes, remove
the container and its unit test.
This is entirely unused but still could be useful in the AppKit port.
Originally this was meant for Swift interop which is why it had support
for other platforms, but now it's causing issues on systems like
FreeBSD, so lets just gate it behind the only platform it's useful for.
We also assume that Objective C blocks and Arc are supported for the
AppKit port to build so no need to check for that in CMake.