Commit graph

104 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
13969b6bd4 LibJS: Store primitive strings as UTF-16
Keep primitive string storage in Utf16String and remove the UTF-8
storage path from PrimitiveString. ASCII strings still use compact
Utf16String ASCII storage, while UTF-16 becomes the only owned
representation.
2026-06-22 19:51:25 +02:00
Andreas Kling
45c499d185 LibJS: Isolate ArrayBuffer backing stores
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.
2026-06-10 14:50:10 +02:00
sideshowbarker
532636d6e7 LibWeb: Remove ChunkSteps & ReadAllOn* dead code from Streams reader
Drop no-longer-reachable ChunkSteps & ReadAllOn* callbacks from Streams.
(Seems they got orphaned by the changes in c14d5f27f9 and eb0a51faf09.)
2026-06-09 16:45:19 +12:00
sideshowbarker
8e74650416 LibWeb: Fix crash when reading a detached or out-of-bounds stream chunk
Problem: Crash when reading a ReadableStream whose chunk is a Uint8Array
backed by a detached ArrayBuffer.

Cause: The ReadLoopReadRequest::on_chunk code skipped existing guards
when extracting the chunk bytes — leading to bytes() getting called on
the detached buffer, which tripped an assert.

Fix: Read the chunk through Uint8Array::data() — which guards for the
case where the view is detached (or out-of-bounds). That aligns things
with what the sibling IncrementalReadLoopReadRequest was already doing.

Fixes https://github.com/LadybirdBrowser/ladybird/issues/9965
2026-06-08 13:45:00 +02:00
Shannon Booth
97abc707c7 LibWeb/Bindings: Generate buffer typedefs as variants
Represent BufferSource and ArrayBufferView as ordinary IDL typedefs over
their underlying union types, instead of special casing in the IDL
generator. This allows the union conversion/return machinery handle
these types consistently with other typedefs, which removes buffer
specific paths from the IDL generator.

This necessitates changing the WebIDL::BufferSource and
WebIDL::ArrayBufferView classes as views over these variants. This
replaces the old GC backed BufferableObject wrapper structure and
provide convenience helpers to determine things such as the byte length,
byte offset, backing buffer, and typed-array APIs.
2026-05-30 11:22:08 +02:00
Shannon Booth
637fd51595 LibWeb: Unify WebIDL C++ type generation
Represent WebIDL C++ types with a single CppType model that tracks
nullability, optional presence, and contained storage.

GC-like values now use GC::Ref/GC::Ptr directly, while containers choose
"plain", "Root", or "Conservative" container types depending on what
they contain. For example, sequence<Element> becomes a RootVector of
GC::Ref values, while sequence<SomeDictionary> becomes a
ConservativeVector only when the dictionary contains GC-like values.
This moves the generated bindings away from wrapping GC values in
GC::Root by default.

This has broad fallout as the types passed to interfaces for GC
objects changes almost fully across the board.
2026-05-23 18:26:12 +02:00
Shannon Booth
387cd6e2e2 LibGC: Default-construct RootVector from the global heap
Similar to GC::Root<T>, make GC::RootVector<T> constructible without
explicitly passing a Heap.

This is implemented by having RootVectorBase use GC::Heap::the() for
heap-free construction.
2026-05-20 20:37:55 +02:00
Andreas Kling
25b817db71 LibWeb: Avoid temporary stream chunks for fetch bytes
Teach readable byte stream enqueueing about native byte producers by
sharing the post-transfer part of the spec algorithm. This lets fetch
hand owned network bytes directly to the byte stream controller instead
of first wrapping them in an unobservable Uint8Array and then
transferring its buffer back into another ArrayBuffer.

Keep the public enqueue(chunk) path spec-shaped and make the native
path rejoin after the TransferArrayBuffer step, so observable chunks are
still created by the shared reader and queue handling code.

This reduces GC churn while playing YouTube videos.
2026-05-15 15:20:33 +02:00
Luke Wilde
de35994fc2 LibJS+LibWeb: Use the unified Visitor for Variant-holding members 2026-05-15 08:51:17 +02:00
Ali Mohammad Pur
0bb987e809 LibJS+LibWeb: Allow instantiating DataBlock with an external buffer
This requires the minimal API exposed by ByteBuffer, allowing external
users to implement them as needed instead of being forced to use a
ByteBuffer.
2026-05-10 16:41:42 +02:00
Shannon Booth
040d7c38cf LibWeb/Streams: Convert Transformer to IDL bindings conversion 2026-05-09 10:49:49 +02:00
Shannon Booth
fedbc1ec94 LibWeb/Streams: Convert UnderlyingSource to IDL bindings conversion 2026-05-09 10:49:49 +02:00
Shannon Booth
23a910fcf2 LibWeb/Streams: Convert UnderlyingSink to IDL bindings conversion 2026-05-09 10:49:49 +02:00
Shannon Booth
5adfd1c43a LibWeb/Bindings: Generate struct definitions from IDL dictionaries
Previously we were inconsistent by generating code for enum definitions
but not generating code for dictionaries. With future changes to the
IDL generator to expose helpers to convert to and from IDL values
this produced circular depdendencies. To solve this problem, also
generate the dictionary definitions in bindings headers.
2026-05-09 10:49:49 +02:00
Andreas Kling
b629914428 LibWeb: Make TransferArrayBuffer zero-copy
Move owned ArrayBuffer storage directly when transferring stream
buffers instead of copying the bytes before detaching the source.
WebAssembly memory continues to copy because its ArrayBuffer wraps
externally-owned storage.

Preserve the abrupt completion from DetachArrayBuffer before moving
storage so non-transferable buffers, such as WebAssembly.Memory-backed
views, still surface TypeError through stream operations instead of
aborting.

This saves ~130ms of main thread time when loading a YouTube video
on my Linux computer. :^)
2026-04-25 10:53:51 +02:00
Shannon Booth
cc6e048bd6 LibWeb+LibIDL: Remove support for #import directives during parsing
These no longer serve any purpose now that we run the IDLGenerator
on all of these files at once.
2026-04-24 20:08:29 +02:00
Shannon Booth
fd44da6829 LibWeb/Bindings: Emit one bindings header and cpp per IDL
Previously, the LibWeb bindings generator would output multiple per
interface files like Prototype/Constructor/Namespace/GlobalMixin
depending on the contents of that IDL file.

This complicates the build system as it means that it does not know
what files will be generated without knowledge of the contents of that
IDL file.

Instead, for each IDL file only generate a single Bindings/<IDLFile>.h
and Bindings/<IDLFile>.cpp.
2026-04-21 07:36:13 +02:00
Shannon Booth
46cd47753f LibWeb: Make more use of Value::{as,as_if,is} in LibWeb 2026-02-28 10:24:37 -05:00
Timothy Flynn
ea32502947 Everywhere: Run clang-format
The following command was used to clang-format these files:

    clang-format-21 -i $(find . \
        -not \( -path "./\.*" -prune \) \
        -not \( -path "./Build/*" -prune \) \
        -not \( -path "./Toolchain/*" -prune \) \
        -type f -name "*.cpp" -o -name "*.mm" -o -name "*.h")
2026-02-18 08:02:45 -05:00
Shannon Booth
4d64f21fa5 LibWeb: Give IDL exposed PlatformObjects an InterfaceName
By making use of the WEB_PLATFORM_OBJECT macro we can remove
the boilerplate of needing to add this override for every
serializable platform object so that we can check whether they
are exposed or not.
2026-02-14 20:22:40 +01:00
Andreas Kling
d1e8189f3f LibWeb: Make WebIDL::property_to_callback() return GC::Ptr
...instead of GC::Root. The roots were causing reference cycles
somewhere, and there was no need for them to be roots.
2025-12-25 20:21:37 +01:00
Timothy Flynn
8bcbe10afa LibWeb: Avoid unused ByteBuffer copy in ReadableStream 2025-12-21 09:24:51 -06:00
Aliaksandr Kalenik
2e9c8ab669 LibWeb: Register shutdown-on-close handler once in ReadableStreamPipeTo
Previously, we added a `reader.closed()` promise reaction during every
`ReadableStreamPipeTo::process()` call, which meant allocating a new
reaction objects for every processed chunk and retaining all of them
until the stream closed. The same issue existed for `writer.closed()`
inside `ReadableStreamPipeTo::read_chunk()`.

This change registers a single shutdown handler for both the reader and
the writer in the ReadableStreamPipeTo constructor.
2025-12-08 13:57:14 -05:00
Aliaksandr Kalenik
18089937a5 LibWeb: Use last promise to wait for pending writes ReadableStreamPipeTo
ReadableStreamPipeTo is used in fetching, and previously requests with
large bodies could lead to tens of thousands of pending write promises
being accumulated in `m_pending_writes`.

With this change, instead of accumulating all pending write promises up
until pipe shutdown, we only keep track of the last one and use it to
determine whether there are pending writes when we need to shut down the
pipe.
2025-12-08 11:45:02 -05:00
Shivendra Kumar
4221a18974 LibWeb: Fix typo "folowing" → "following" 2025-09-24 11:54:42 +01:00
ayeteadoe
3df8e00d91 LibWeb: Enable EXPLICIT_SYMBOL_EXPORT 2025-08-23 16:04:36 -06:00
Tim Ledbetter
aadd563592 LibWeb: Replace usages of dynamic_cast with as and as_if 2025-08-22 20:26:09 +02:00
Timothy Flynn
70db474cf0 LibJS+LibWeb: Port interned bytecode strings to UTF-16
This was almost a no-op, except we intern JS exception messages. So the
bulk of this patch is porting exception messages to UTF-16.
2025-08-14 10:27:08 +02:00
Timothy Flynn
0efa98a57a LibJS+LibWeb+WebContent: Port JS::PropertyKey to UTF-16
This has quite a lot of fall out. But the majority of it is just type or
UDL substitution, where the changes just fall through to other function
calls.

By changing property key storage to UTF-16, the main affected areas are:
* NativeFunction names must now be UTF-16
* Bytecode identifiers must now be UTF-16
* Module/binding names must now be UTF-16
2025-08-05 07:07:15 -04:00
Kenneth Myhra
2394845d58 LibWeb: Align specification step text with current specification 2025-07-20 12:30:43 +12:00
Timothy Flynn
64abc6101d LibWeb+WebWorker: Use IPC mechanics for structured serialization
Our structured serialization implementation had its own bespoke encoder
and decoder to serialize JS values. It also used a u32 buffer under the
hood, which made using its structures a bit awkward. We had previously
worked around its data structures in transferable streams, which nested
transfers of MessagePort instances. We basically had to add hooks into
the MessagePort to route to the correct transfer receiving steps, and
we could not invoke the correct AOs directly as the spec dictates.

We now use IPC mechanics to encode and decode data. This works because,
although we are encoding JS values, we are only ultimately encoding
primitive and basic AK types. The resulting data structures actually
enforce that we implement transferable streams exactly as the spec is
worded (I had planned to do that in a separate commit, but the fallout
of this patch actually required that change).
2025-07-18 10:09:02 -04:00
Timothy Flynn
7fad8c333d LibWeb: Use forward-declarations of structured serialized types
This reduces the rebuilt targets when touching StructuredSerialize.h
from ~1200 to ~400. The remaining are due to generated IPC headers.
2025-07-18 10:09:02 -04:00
Aliaksandr Kalenik
346c083d58 LibWeb: Don't drop messages received before MessagePort is enabled
This change implements following behavior defined in the spec:
https://html.spec.whatwg.org/multipage/web-messaging.html#examples-5
> The start() method, whether called explicitly or implicitly (by
setting onmessage), starts the flow of messages: messages posted on
message ports are initially paused, so that they don't get dropped on
the floor before the script has had a chance to set up its handlers.

Now we don't read bytes from the underlying transport socket until the
message port transitions to the enabled state. This required the
following places to explicitly enable the message port, because now,
when it actually matters, we must do so, or otherwise sent messages will
get stuck:
- `onmessage` attribute setter in DedicatedWorkerGlobalScope, because
  it implicitly sets the onmessage handler for the worker's underlying
  port.
- Stream API operations where the message port enabling steps were
  previously marked as FIXMEs.
2025-06-08 18:26:13 +02:00
Timothy Flynn
95fc0a8070 LibWeb: Implement TransformStream transfer 2025-05-21 06:54:44 -04:00
Timothy Flynn
cca08ad833 LibWeb: Implement WritableStream transfer 2025-05-21 06:54:44 -04:00
Timothy Flynn
312db85a84 LibWeb: Implement ReadableStream transfer 2025-05-21 06:54:44 -04:00
Timothy Flynn
7e225b496d LibWeb: Implement transferable streams AOs
These AOs are common between transferable ReadableStream, WritableStream
and TransformStream objects.
2025-05-21 06:54:44 -04:00
Timothy Flynn
7280ed6312 Meta: Enforce newlines around namespaces
This has come up several times during code review, so let's just enforce
it using a new clang-format 20 option.
2025-05-14 02:01:59 -06:00
Timothy Flynn
0cd5e99066 LibWeb: Use the correct target realm to tee a stream
We currently store Web::Fetch::Infrastructure::Response objects in the
HTTP cache. They are associated with their original realm, but when we
use a cached response, we clone it into the target realm. For example,
two <iframe> objects loading the same HTML will be in different realms.

When we clone the response, we must use the target realm throughout the
entire cloning process. We neglected to do this for the cloned response
body stream, which is cloned via teeing. The result was the the stream
for the "cloned" response was created in the original realm, causing
issues down the line when reading from that stream tried to handle read
promises on behalf of the original realm. There are protections in place
to prevent this from happening, and the cached response read would never
complete.
2025-04-30 09:30:15 -04:00
Timothy Flynn
6cc5ac8f82 LibWeb: Remove unused VM from ReadLoopReadRequest 2025-04-30 09:30:15 -04:00
Andreas Kling
a6dfc74e93 LibWeb: Only set prototype once for object with IDL interface
Before this change, we were going through the chain of base classes for
each IDL interface object and having them set the prototype to their
prototype.

Instead of doing that, reorder things so that we set the right prototype
immediately in Foo::initialize(), and then don't bother in all the base
class overrides.

This knocks off a ~1% profile item on Speedometer 3.
2025-04-20 18:43:11 +02:00
Timothy Flynn
629cd3c42a LibWeb: Sort remaining stream AOs (mostly) in spec order
The remaining AOs can stay where they are. This patch just sorts them in
spec order to match the other AO files. Section 8.1 is last, however, as
these are all templates and need the declarations of other AOs above.
2025-04-18 06:55:40 -04:00
Timothy Flynn
3e8c6dbaff LibWeb: Move TransformStream AOs into their own file
The main streams AO file has gotten very large, and is a bit difficult
to navigate. In an effort to improve DX, this migrates TransformStream
AOs to their own file.
2025-04-18 06:55:40 -04:00
Timothy Flynn
26c01f0957 LibWeb: Move WritableStream AOs into their own file
The main streams AO file has gotten very large, and is a bit difficult
to navigate. In an effort to improve DX, this migrates WritableStream
AOs to their own file.
2025-04-18 06:55:40 -04:00
Timothy Flynn
a9ddd427cb LibWeb: Move ReadableStream AOs into their own file
The main streams AO file has gotten very large, and is a bit difficult
to navigate. In an effort to improve DX, this migrates ReadableStream
AOs to their own file. And the helper classes used for the tee and pipe-
to operations are also in their own files.
2025-04-18 06:55:40 -04:00
Timothy Flynn
c35ef36293 LibWeb: Fix typos in ReadableStream AO names 2025-04-18 06:55:40 -04:00
Timothy Flynn
955f6fc9cb LibWeb: Fulfill TransformStream promises with the correct "reason"
We need to use the reason provided to the abort algorithm, not the one
from the resolved cancel promise (which will be undefined).
2025-04-16 13:15:33 -04:00
Timothy Flynn
3fdad8fe22 LibWeb: Update spec steps for closing TransformStreams
This was actually an older change to the Streams spec that we missed
when we implemented TransformStreams. This fixes a crash in the imported
WPT tests.

See: https://github.com/whatwg/streams/commit/007d729
2025-04-16 11:39:25 -04:00