Add the proper annotations for the Cell and Cell::Visitor classes to be
visible in Swift. This lets us remove some OpaquePointer shinangians in
the Swift bindings.
This patch adds a workaround for a Swift issue where boolean bitfields
with getters and setters in SWIFT_UNSAFE_REFERENCE types are improperly
imported, causing an ICE.
Previously, all `GC::Cell` derived classes were Weakable. Marking only
those classes that require this functionality as Weakable allows us to
reduce the memory footprint of some frequently used classes.
Previously, we would only keep the cell that must survive alive, but
none of it's edges.
This cropped up with a GC UAF in must_survive_garbage_collection of
WebSocket in .NET's SignalR frontend implementation, where an
out-of-scope WebSocket had it's underlying EventTarget properties
garbage collected, and must_survive_garbage_collection read from the
destroyed EventTarget properties.
See: https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/clients/ts/signalr/src/WebSocketTransport.ts#L81
Found on https://www.formula1.com/ during a live session.
Co-Authored-By: Tim Flynn <trflynn89@pm.me>
Before this change, it was possible for a second GC to get triggered
in the middle of a first GC, due to allocations happening in the
FinalizationRegistry cleanup host hook. To avoid this causing problems,
we add a "post-GC task" mechanism and use that to invoke the host hook
once all other GC activity is finished, and we've unset the "collecting
garbage" flag.
Note that the test included here only fails reliably when running with
the -g flag (collect garbage after each allocation).
Fixes#3051
Whenever we create a GC function, it should always be so that we can
pass it to a platform event loop spin, HTML event loop spin, or some
queued task on the HTML event loop. For every use case, any local
variables will be out of scope by the time the function executes.
Lazily coercing might have made sense in the past, but since hashing
and comparing requires the `PropertyKey` to be coerced, and since a
`PropertyKey` will be used to index into a hashmap 99% of the time,
which will hash the `PropertyKey` and use it in comparisons, the
extra complexity and branching produced by lazily coercing has
become more trouble than it is worth.
Remove the lazy coercions, which then also neatly allows us to
switch to a `Variant`-based implementation.
This includes a protocol for creating LibGC Heap allocated Swift
objects. Pay no attention to the Unmanaged shenanigans, they are
all behind the curtain.
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.
While we don't want arbitrary callers deferring GC, we do want
deferral to be available to the Swift. In order for Swift to
understand the RAII nature of DeferGC, we need to mark it as
non-copyable.
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