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.
Return from the jsapi calls when we have a module that satisfies the
state required by the spec, and let jit compilation (if it's happening)
continue in the background.
This also means we no longer do the full compilation pipeline for
validate().
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.
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.
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.
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.
NativeFunction previously stored an AK::Function for every builtin,
even when the callable was just a plain C++ entry point. That mixed
together two different representations, made simple builtins carry
capture storage they did not need, and forced the GC to treat every
native function as if it might contain captured JS values.
Introduce RawNativeFunction for plain NativeFunctionPointer callees
and keep AK::Function-backed callables on a CapturingNativeFunction
subclass. Update the straightforward native registrations in LibJS
and LibWeb to use the raw representation, while leaving exported
Wasm functions on the capturing path because they still capture
state.
Wrap UniversalGlobalScope's byte-length strategy lambda in
Function<...> explicitly so it keeps selecting the capturing
NativeFunction::create overload.
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.
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.
We once again ignore any mention of atomic operations on
[[ArrayBufferByteLengthData]]. This commit also fixes a couple bugs
where we forget to set Data Blocks as Shared.
An upcoming commit will migrate the contents of Headers.h/cpp to LibHTTP
for use outside of LibWeb. These CORS and MIME helpers depend on other
LibWeb facilities, however, so they cannot be moved.
This commit adds the toResizableBuffer() and toFixedLengthBuffer()
methods to WebAssembly.Memory. This includes the necessary hook to
HostResizeArrayBuffer. Some modifications to function signatures in
LibWeb/WebAssembly/Memory.h were also made (changing the return type
from WebIDL::ExceptionOr to JS::ThrowCompletionOr) to allow the use of
some code in the aforementioned hook.
Note: the hook for HostGrowSharedArrayBuffer isn't implemented, since
LibJS doesn't seem to have complete support for growable
SharedArrayBuffers; the relevant methods/getters don't even exist on
the prototype, let alone HostGrowSharedArrayBuffer!
This should help pass the WebAssembly.Memory WPT tests included in
Interop 2025, except those pertaining to growable SharedArrayBuffers.
This cache is referenced by a few parts of the JS API spec, including
the threads spec (such as in toFixedLengthBuffer), as well as the
"refresh the Memory buffer" algorithm, which was implemented as a method
of Memory before this change.
Now, this algorithm can be implemented in a spec-like fashion (though it
mostly seems to add extra complexity). This change also fixes a bug
where memories that were re-exported from an imported WebAssembly.Memory
were given a distinct WebAssembly.Memory object, since the caching that
existed in Instance.cpp was instance-local, not global to the realm.
We also make Memory::m_buffer non-lazy, since we have to implement
"initialize a memory object" correctly anyway.
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
The spec tells us to reject the promise with a RuntimeError instead of a
LinkError whenever the module's start function fails during module
instantiation. Fixes 1 WPT subtest in `wasm/core`.
1. Fix typos in some macro invocations of these error types. We now use
a single xmacro to instantiate error definitions to prevent such
errors in the future.
2. Use the "WebAssembly." prefix as needed.
3. Allocate the error constructors and prototypes with `realm.create`
rather than `heap.allocate`. The latter does not invoke `initialize`
methods. This exposed the next issue:
4. Use the correct intrinsic prototype in the error constructor. We were
using the base native error prototype. We unfortunately cannot invoke
OrdinaryCreateFromConstructor from LibJS directly with the correct
prototype, so an implementation was added here.
5. Use intrinsic accessors to create the constructors. I don't think
this one was actually a fix, but it makes the setup look more like
other built-ins.
Replace the implementation of maths in `UnsignedBigInteger`
and `SignedBigInteger` with LibTomMath. This gives benefits in terms of
less code to maintain, correctness and speed.
These changes also remove now-unsued methods and improve the error
propagation for functions allocating lots of memory. Additionally, the
new implementation is always trimmed and won't have dangling zeros when
exporting it.
...instead of specially handling JS::Completion.
This makes it possible for LibWeb/LibJS to have full control over how
these things are made, stored, and visited (whenever).
Fixes an issue where we couldn't roundtrip a JS exception through Wasm.
Instead, let JS::NativeFunction store the AK::Function directly, and
take care of conservatively marking its captured data.
This avoids an extra GC allocation for every JS::NativeFunction.
The fast path of to_i32() can be neatly inlined everywhere, and we still
have to_i32_slow_case() for non-trivial conversions.
For to_u32(), it really can just be implemented as a static cast to i32!