LibGC: Teach Swift bindings about Cell and Cell::Visitor

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 commit is contained in:
Andrew Kaster 2025-03-22 19:01:41 -06:00 committed by Andrew Kaster
commit 8554ee386e
Notes: github-actions[bot] 2025-04-03 22:49:27 +00:00
7 changed files with 43 additions and 48 deletions

View file

@ -72,17 +72,17 @@ public:
visit_impl(*cell);
}
void visit(Cell& cell)
void visit(Cell& cell) SWIFT_NAME(visitRef(_:))
{
visit_impl(cell);
}
void visit(Cell const* cell)
void visit(Cell const* cell) SWIFT_NAME(visitConst(_:))
{
visit(const_cast<Cell*>(cell));
}
void visit(Cell const& cell)
void visit(Cell const& cell) SWIFT_NAME(visitConstRef(_:))
{
visit(const_cast<Cell&>(cell));
}
@ -157,7 +157,7 @@ public:
}
}
void visit(NanBoxedValue const& value);
void visit(NanBoxedValue const& value) SWIFT_NAME(visitValue(_:));
// Allow explicitly ignoring a GC-allocated member in a visit_edges implementation instead
// of just not using it.

View file

@ -15,38 +15,15 @@ extension GC.Heap {
}
}
// FIXME: Cell and Cell::Visitor are not imported properly, so we have to treat them as OpaquePointer
public protocol HeapAllocatable {
static func allocate(on heap: GC.Heap) -> UnsafeMutablePointer<Self>
init(cell: OpaquePointer)
init(cell: GC.Cell)
func finalize()
func visitEdges(_ visitor: OpaquePointer)
func visitEdges(_ visitor: GC.Cell.Visitor)
var cell: OpaquePointer { get }
}
// FIXME: Figure out why other modules can't conform to HeapAllocatable
public struct HeapString: HeapAllocatable {
public var string: Swift.String
public init(cell: OpaquePointer) {
self.cell = cell
self.string = ""
}
// FIXME: HeapAllocatable cannot be exposed to C++ yet, so we're off to void* paradise
public static func create(on heap: GC.Heap, string: Swift.String) -> OpaquePointer {
// NOTE: GC must be deferred so that a collection during allocation doesn't get tripped
// up looking for the Cell pointer on the stack or in a register when it might only exist in the heap
precondition(heap.is_gc_deferred())
let heapString = allocate(on: heap)
heapString.pointee.string = string
return heapString.pointee.cell
}
public var cell: OpaquePointer
var cell: GC.Cell { get }
}
// Here be dragons
@ -64,7 +41,7 @@ func asHeapAllocatableType(_ typeMetadata: UnsafeMutableRawPointer) -> any HeapA
}
extension HeapAllocatable {
fileprivate static func initializeFromFFI(at this: UnsafeMutableRawPointer, cell: OpaquePointer) {
fileprivate static func initializeFromFFI(at this: UnsafeMutableRawPointer, cell: GC.Cell) {
this.assumingMemoryBound(to: Self.self).initialize(to: Self.self.init(cell: cell))
}
@ -76,7 +53,7 @@ extension HeapAllocatable {
this.assumingMemoryBound(to: Self.self).pointee.finalize()
}
fileprivate static func visitEdgesFromFFI(at this: UnsafeMutableRawPointer, visitor: OpaquePointer) {
fileprivate static func visitEdgesFromFFI(at this: UnsafeMutableRawPointer, visitor: GC.Cell.Visitor) {
this.assumingMemoryBound(to: Self.self).pointee.visitEdges(visitor)
}
@ -101,5 +78,5 @@ extension HeapAllocatable {
}
public func finalize() {}
public func visitEdges(_ visitor: OpaquePointer) {}
public func visitEdges(_ visitor: GC.Cell.Visitor) {}
}