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.
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.
This introduces a new MUST_UPCALL macro that expands to
[[clang::annotate("must_upcall")]] on Clang. When placed on a virtual
function, the Clang plugin will verify that all overrides call their
base class implementation.
This generalizes the existing Base::visit_edges() check to work with
any annotated virtual function. The first use is Cell::visit_edges(),
but this can be applied to other functions that require upcalls.
The plugin checks for calls via either Base:: (the common typedef
pattern) or the explicit parent class name.
When a GC::Cell subclass overrides must_survive_garbage_collection(),
it must also declare:
static constexpr bool OVERRIDES_MUST_SURVIVE_GARBAGE_COLLECTION = true;
Similarly, when overriding finalize(), it must declare:
static constexpr bool OVERRIDES_FINALIZE = true;
These flags are used by the GC infrastructure to optimize traversal.
The plugin now verifies these flags are present and set to true.
This extends the LibJSGC Clang plugin to detect GC pointers (GC::Ptr,
GC::Ref, JS::Value, etc.) inside non-GC-allocated struct/class members.
When a GC::Cell has a member of a non-Cell type that contains GC
pointers, we now enforce that:
1. The non-Cell type must have a visit_edges(GC::Cell::Visitor&) method
2. The Cell's visit_edges must access that member (presumably to call
its visit_edges)
The check works recursively, so nested structs and containers like
Vector<GC::Ptr<T>> or HashMap<K, GC::Ptr<V>> are handled correctly.
GC infrastructure types (Root, Heap, etc.) and AK library types are
excluded from these checks as they handle visitation differently.
Instead of ignoring fields using forward-delcared types, always assume
they inherit from GC::Cell. This improves the worst case from a missed
unvisited field, to a slightly wrong error message.
Fixes#5959.
This will allow us to use the GC to manage the lifetime of objects
that are not C++ objects, such as Swift objects. In the future we
could expand this cursed FFI to other languages as well.
Resulting in a massive rename across almost everywhere! Alongside the
namespace change, we now have the following names:
* JS::NonnullGCPtr -> GC::Ref
* JS::GCPtr -> GC::Ptr
* JS::HeapFunction -> GC::Function
* JS::CellImpl -> GC::Cell
* JS::Handle -> GC::Root
Instead, smuggle it in as a `void*` private data and let Javascript
aware code cast out that pointer to a VM&.
In order to make this split, rename JS::Cell to JS::CellImpl. Once we
have a LibGC, this will become GC::Cell. CellImpl then has no specific
knowledge of the VM& and Realm&. That knowledge is instead put into
JS::Cell, which inherits from CellImpl. JS::Cell is responsible for
JavaScript's realm initialization, as well as converting of the void*
private data to what it knows should be the VM&.
GC-allocated objects should never have JS::SafeFunction/JS::Handle
fields.
For now the plugin only emits warnings here, as there are many cases
of this occurring in the codebase that aren't trivial to fix. It is also
behind a CMake flag since it is a _very_ loud warning.
Now that the lambda capture plugin isn't full of false-positives, we can
make the jump and start halting builds for these errors. It also allows
these plugins to be useful in CI.