Replace the generated C++ legacy codec implementations with a
small Rust wrapper around encoding_rs.
This keeps the existing LibTextCodec API while moving label lookup,
legacy decode/encode, validation, and streaming decoder state to Rust.
The generated index data and generator are no longer needed.
It also fixes several TextDecoder EOF cases due to a more correct
implementation. encoding_rs finalizes decoders according to the
Encoding Standard, so incomplete UTF-8/Big5 tails and malformed
UTF-16 surrogate tails produce the required single replacement at
end-of-queue instead of being dropped, buffered, or double-counted
by our old hand-written decoders.
The display list can now refer to canvas ids, but WebContent still had
no channel for creating or updating those canvas resources in the
Compositor. Both 2D and WebGL canvases would have had to grow the IPC
plumbing in the same commit that changes the rendering contexts.
This adds the Compositor-side CanvasHost, WebContent transport objects,
and the IPC/CMake pieces needed to allocate, update, read back, and
destroy remote canvas contexts. The rendering contexts are not switched
over yet, keeping this as plumbing for later commits.
Moving WebGL execution into the Compositor needs a serializable command
stream and a client-side proxy that can queue commands before sending
them over IPC. The existing generator metadata only described direct GL
wrappers, so generated code could not distinguish async commands from
sync calls or object factory methods.
This teaches the WebGL metadata and generators about command streams and
adds the unused LibWeb proxy/list types. No rendering behavior changes
yet; the later host wiring can build on these generated interfaces
without mixing the metadata churn into that commit.
Use the Rust bytecode dumper's basic block collection logic for the
metadata block count. This removes the last C++ bytecode label walk and
lets us delete the generated C++ label and operand visitor helpers.
Generate Rust bytecode dump helpers from Bytecode.def and route
Executable::dump() through them for instruction stream formatting.
Add a small Rust runtime::value helper for decoding encoded LibJS
Values so immediate Value operands are formatted on the Rust side. C++
callbacks remain only for local names and GC-backed Value payloads that
still need LibJS object access.
Remove the generated C++ to_byte_string_impl() methods and the old
Instruction::to_byte_string() dispatch. The bytecode dump tests cover
output compatibility.
Remove the C++ bytecode interpreter dispatch loop now that AsmInt is the
only bytecode execution engine. Keep the existing AsmInt fallback path
for instructions that have not yet been moved into assembly or C++ slow
path handlers.
[Replaceable] readonly attributes still need JS accessor setters for
replacement and receiver checks. Remove the include_replaceable opt-in
so the binding generator handles them consistently.
LibWeb's WebGL implementation currently reaches ANGLE by calling glFoo()
throughout the WebGL context and extension code. That ties the WebGL
spec layer to the concrete GL executor. A future backend that records
operations, sends them to another process, or executes them from the
Compositor would otherwise need to duplicate the WebGL logic or edit
every call site again.
Introduce GLFunctions as an explicit boundary between WebGL semantics
and GL execution. GLFunctions.json lists the GL entry points used by the
implementation, and the generator emits one forwarding method per entry
point. OpenGLContext implements those methods today, so the current
in-process ANGLE path keeps the same behavior while all callers go
through a single replaceable interface.
That boundary is needed before canvas/WebGL rendering can move to the
Compositor: the WebGL context code can keep doing validation, state
tracking, and spec-visible error handling in LibWeb, while a later
implementation can record the same GL calls and replay them where the
canvas surface is produced. The JSON source also gives the recorder and
replayer one shared description of argument shapes, avoiding two
hand-written views of the GL API drifting apart.
When generating global mixins, only define regular members from the
[Global] interface itself on the global object. Inherited members remain
available through the prototype chain.
This was found due to a timeout on:
https://wpt.live/html/dom/idlharness.any.worker.html
Installing inherited members created fresh own functions on worker
globals, so self.importScripts differed from
WorkerGlobalScope.prototype.importScripts. That confused idlharness into
taking its null-this check path for importScripts, which then attempted
to import "null" and timed out.
EventHandler attributes are nullable callback function attributes with
[LegacyTreatNonObjectAsNull]. Assigning a non-object value should
produce null, but assigning an object value should preserve that object
as the callback value, even when the object is not callable.
Previously, object values such as `{ handleEvent() {} }` could pass the
nullable conversion and then be converted to null by the inner callback
function conversion. This made MessagePort.onmessage in the fixed test
return null after such an assignment.
Handle the non-object-to-null rule in nullable conversion, and let the
legacy callback conversion wrap object values without rejecting them for
not being callable.
Fixes a regression in the python port of the IDL generator.
Replace the generated public suffix table and custom matcher with a
direct LibURL PublicSuffixData implementation backed by libpsl. This
drops our PSL download/generator path and uses the same library already
used by libcurl.
Performance is comparable before and after, while LibURL binary size
is smaller.
When converting an object to a union containing a sequence, Web IDL
first gets @@iterator to decide whether the sequence arm applies, then
creates the sequence from the iterable using that same method.
The generator instead called sequence_to_idl_value(), which repeated the
@@iterator lookup. Split out create_sequence_from_iterable() and use it
from union sequence/FrozenArray conversion so overridden Symbol.iterator
accessors are only observed once.
Do not emit an unimplemented prototype property for an operation name
when at least one overload with that name is implemented. The overload
resolver already filters FIXME overloads out of the native overload set,
so defining an unimplemented property afterwards replaces the working
function with undefined.
This lets WebGL2RenderingContext.texImage2D keep its implemented WebGL1
and typed-array overloads even though the PBO-offset overload remains
marked FIXME.
Stop emitting every generated CSS property accessor as an IDL attribute.
Instead, generate a compact CSSStyleProperties initializer that installs
all property aliases from a table and dispatches through one native
function class carrying the UTF-16 property name.
This keeps the generated binding file focused on cssFloat and moves the
large property list into a simple generated table.
Emit each generated attribute name once and reuse that UTF-16 id when
creating the getter, creating the setter, and defining the accessor.
This avoids repeating the same Utf16FlyString literal at every generated
attribute binding.
Move the remaining CSSStyleDeclaration property-name APIs to
Utf16FlyString. This lets CSSOM binding and generated accessor code
pass JS property names without first constructing FlyString values.
Keep internal custom-property and descriptor storage unchanged for now.
Those remaining FlyString conversions are at storage boundaries that
will be migrated in follow-up commits.
Change get_property_value() to take a Utf16FlyString so generated CSS
property accessors can pass their JS property names through without
constructing FlyString instances first.
Keep the existing internal descriptor and custom-property storage shape
for now, and convert at those boundaries while the remaining CSS
property APIs are migrated separately.
PublicSuffixData handled trailing-dot hosts incorrectly when a PSL rule
matched, causing returned public suffix and registrable-domain results
to drop the trailing dot.
Make PublicSuffixData skip leading dots for matching, ignore a single
trailing dot while running the PSL algorithm, and append that trailing
dot back to returned results.
Public suffix matching could fail when callers passed host text that
was not already in the same form as the generated PSL table. In
particular, uppercase ASCII hosts like EXAMPLE.COM and UTF-8 IDN hosts
could miss matches even though URL hosts are canonically represented as
lowercase ASCII/IDNA.
Make the PublicSuffixData API difficult to misuse by routing all
invocations through URL::Host overloads so that the canonical hostname
is always what is matched against.
Move the registrable-domain helper from URL into PublicSuffixData and
name it find_matching_registrable_domain().
This keeps it alongside find_matching_public_suffix(), making it clear
that both APIs only return results matched from the PSL data, while
Host::public_suffix() implements the URL Standard fallback to the
top-level domain.
Rename PublicSuffixData's raw lookup helpers to make it clear that they
only return public suffixes matched from the PSL data.
This distinguishes them from Host::public_suffix(), which implements the
URL Standard definition and falls back to the top-level domain when no
PSL rule matches.
We need both layers because address bar handling needs the raw lookup to
decide whether input should be treated as a URL or as a search.
Move the overload-resolution metadata types into LibWeb::WebIDL and
update the Python generator and overload resolver to use them.
LibIDL no longer has any users after the C++ bindings generator removal,
so remove the library and unlink it from LibWeb.
Replace the Lagom C++ bindings generator invocation with the new Python
generator under Meta/Generators/libweb_bindings.
Fold the exposed-interface generation into the same generator entry
point, and keep generated overload metadata using the existing LibIDL
types for now.
The generated public suffix table stores each entry with it's labels
reversed, but the lookup we were using didn't reverse its input before
searching. This led to multi-label public suffixes not matching when
they should have.
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.
Style invalidation kept the list of properties that require rebuilding
the accumulated visual context tree in StyleInvalidation.cpp. That made
the classification separate from the existing property metadata used for
layout and stacking-context invalidation.
Move that classification into Properties.json and teach the PropertyID
generator to emit property_affects_accumulated_visual_contexts(). Style
invalidation now uses the generated predicate, preserving the existing
property set and behavior while making future classification changes
data-driven.
Add cqw/cqh/cqi/cqb/cqmin/cqmax to the unit tables and generated
helpers, then thread them through the shared length resolution path.
Length::ResolutionContext now carries the subject element and whether
its inline axis is horizontal. Container units need that extra context:
the nearest eligible query container is selected from the subject
element's flat-tree ancestors, and cqi/cqb/cqmin/cqmax map logical axes
through the subject's writing mode before resolving to a physical width
or height.
Teach Length to resolve each axis against the selected container's
content box, fall back to viewport lengths when no eligible container
exists, and mark size-container dependencies so post-layout
recomputation can happen when layout is not up to date.
Also expose the new units through Typed OM, reject them for
computationally independent `@property` initial values, and add focused
font-size coverage.
Generated try_* proxy methods for synchronous messages with a single
output declared IPCErrorOr<T>, but returned the whole response object
instead of the output payload. That made helpers with named bool
responses unusable once callers started using the fallible path.
Share the same single-output accessor logic used by the infallible sync
helpers so fallible generated helpers return the declared payload type.
Restricted pseudo-elements (like ::placeholder, ::first-letter,
::first-line, and ::selection) use property whitelists. These
whitelists did not include transition or animation properties.
As a result, pseudo_element_supports_property() rejected transition and
animation declarations during cascade filtering. This caused
transition-duration and transition-delay to resolve to their initial
values (0s), which triggered the zero-second optimization in
compute_transitioned_properties() and prevented transition
registration.
This change introduces a fast-path check in the generated function
pseudo_element_supports_property() to automatically accept all CSS
transition and animation properties on any styleable pseudo-element.
`<media-feature>` and the upcoming `<size-feature>` from `@container`,
share the same syntax and almost all of their behaviour. To avoid a lot
of duplication, pull as much as possible into a FeatureQuery template
class that they will both inherit from.
MediaFeatureValue is renamed FeatureValue as it's also shared by both.
No behaviour change.
Dynamic environment binding opcodes lost the old coordinate warmup.
They were split away from the static coordinate opcodes. Hot closures
and eval-sensitive functions then resolved the same binding by name on
every execution, which regressed JS benchmark throughput badly.
Give each dynamic environment opcode a per-executable coordinate cache
slot. The cache keeps the bytecode stream immutable while letting both
interpreters take a direct declarative environment fast path after the
first lookup. Keep the existing eval invalidation behavior and only warm
caches for declarative-only chains so with environments continue to
observe object shadowing.
Reject cached bytecode that uses the no-cache sentinel for dynamic
environment coordinate cache operands, since execution indexes those
cache arrays unconditionally.
Rebaseline bytecode expectations for the instruction size changes. Add
coverage for with-object shadowing across repeated dynamic lookups and
for rejecting corrupt dynamic environment cache indices.
Add separate bytecode instructions for environment lookups that must
stay dynamic, such as eval- and with-sensitive scopes. Keep the
coordinate variants for eagerly resolved declarative environments so
their operands can be treated as immutable at runtime.
This removes cached-coordinate mutation from the interpreter paths and
updates the bytecode expectations for the new dynamic lookup opcodes.
Store compact cache indexes in bytecode instructions instead of raw
pointers to the executable cache vectors. This keeps the instruction
stream independent from heap addresses and removes pointer fixups when
materializing cached bytecode.
Resolve the mutable cache pointers at execution time from the current
Executable. Bytecode test expectations are updated for the smaller cache
operands and resulting instruction offsets.
Port Bindings/Forward.h generation into
generate_window_or_worker_interfaces.py and remove the old C++
generate_forward_header path from BindingsGenerator.
The the presence of a value in the Optional[OpDef] already indicated
whether the loop was in an op. The `in_op` variable was decoupling the
check for a current op from the usage of the current op, so type
checking couldn't determine that None was impossible where it was used.
The WasmPrimitiveValue.value field was assigned None in some cases, but
its type didn't indicate it could store it.
Also, parse_value() took dict[str, str], but treats it as dict[str, Any]
with the possibility to store values of type str, or more recursive
list[dict[str, Any]].
This changes the shape of the parsed value when we don't have a fallback
color for a `<url>` value from having no second value in the
`StyleValueList` to having an `EmptyOptionalStyleValue`.
Avoids us having to maintain a separate hardcoded list.
This does mean we don't support parsing of `decibel` but it's not used
anywhere yet and will be supported automatically when added to
Units.json