diff --git a/Libraries/LibGC/Cell.h b/Libraries/LibGC/Cell.h index 45f2da8d5c9..7b7bbadd9d3 100644 --- a/Libraries/LibGC/Cell.h +++ b/Libraries/LibGC/Cell.h @@ -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)); } - void visit(Cell const& cell) + void visit(Cell const& cell) SWIFT_NAME(visitConstRef(_:)) { visit(const_cast(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. diff --git a/Libraries/LibGC/Heap+Swift.swift b/Libraries/LibGC/Heap+Swift.swift index 41eeff56baf..e48f8b0af1a 100644 --- a/Libraries/LibGC/Heap+Swift.swift +++ b/Libraries/LibGC/Heap+Swift.swift @@ -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 - 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) {} } diff --git a/Meta/CMake/FindSwiftTesting.cmake b/Meta/CMake/FindSwiftTesting.cmake index 7f46c36d96b..fd2eaa6b3ca 100644 --- a/Meta/CMake/FindSwiftTesting.cmake +++ b/Meta/CMake/FindSwiftTesting.cmake @@ -17,6 +17,7 @@ if (SWIFT_TESTING) cmake_path(GET _SWIFT_TESTING_DIR PARENT_PATH _SWIFT_TESTING_TARGETLESS_DIR) set_target_properties(SwiftTesting::SwiftTesting PROPERTIES INTERFACE_COMPILE_OPTIONS "$<$:SHELL:-load-plugin-library ${_SWIFT_TESTING_TARGETLESS_DIR}/host/plugins/libTestingMacros.so>" + INTERFACE_LINK_OPTIONS "-load-plugin-library;${_SWIFT_TESTING_TARGETLESS_DIR}/host/plugins/libTestingMacros.so" ) endif() endif() diff --git a/Tests/LibGC/CMakeLists.txt b/Tests/LibGC/CMakeLists.txt index da0f28f02a2..6b94ba5ecad 100644 --- a/Tests/LibGC/CMakeLists.txt +++ b/Tests/LibGC/CMakeLists.txt @@ -6,12 +6,21 @@ if (ENABLE_SWIFT) TestHeap.cpp TestInterop.cpp ) - # FIXME: Swift doesn't seem to like object libraries for @main target_sources(TestGCSwift PRIVATE ../Resources/SwiftTestMain.swift) + generate_clang_module_map(TestGCSwift) + set_target_properties(TestGCSwift PROPERTIES SUFFIX .swift-testing) target_include_directories(TestGCSwift PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(TestGCSwift PRIVATE AK LibGC SwiftTesting::SwiftTesting) + + get_property(testing_compile_options TARGET SwiftTesting::SwiftTesting PROPERTY INTERFACE_LINK_OPTIONS) + + add_swift_target_properties(TestGCSwift + LAGOM_LIBRARIES AK LibGC + COMPILE_DEFINITIONS LIBGC_WORKAROUND_BOOL_BITFIELD + COMPILE_OPTIONS ${testing_compile_options} -enable-experimental-feature Extern + ) add_test(NAME TestGCSwift COMMAND TestGCSwift) endif() diff --git a/Tests/LibGC/TestGCBindings.swift b/Tests/LibGC/TestGCBindings.swift index 36e2fde9224..e743ee5e6e7 100644 --- a/Tests/LibGC/TestGCBindings.swift +++ b/Tests/LibGC/TestGCBindings.swift @@ -6,14 +6,28 @@ import AK import GC -import GCTesting +@_exported import TestGCSwiftCxx import Testing -// FIXME: We want a type declared *here* for HeapString, but it gives a compiler warning: -// error: type 'GCString' cannot conform to protocol 'HeapAllocatable' because it has requirements that cannot be satisfied -// Even using the same exact code from LibGC/Heap+Swift.swift -// This is likely because one of the required types for HeapAllocatable is not fully imported from C++ and thus can't -// be re-exported by the GC module. +public struct HeapString: HeapAllocatable { + public var string: Swift.String + + public init(cell: GC.Cell) { + self.cell = cell + self.string = "" + } + + public static func create(on heap: GC.Heap, string: Swift.String) -> GC.Cell { + // 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: GC.Cell +} @Suite(.serialized) struct TestGCSwiftBindings { diff --git a/Tests/LibGC/TestInterop.cpp b/Tests/LibGC/TestInterop.cpp index f47f85e9f5b..3771ffa0ffe 100644 --- a/Tests/LibGC/TestInterop.cpp +++ b/Tests/LibGC/TestInterop.cpp @@ -7,9 +7,9 @@ #include "TestInterop.h" #include "TestHeap.h" #include -#include #include #include +#include #define COLLECT heap.collect_garbage(GC::Heap::CollectionType::CollectGarbage) #define COLLECT_ALL heap.collect_garbage(GC::Heap::CollectionType::CollectEverything) @@ -20,7 +20,7 @@ void test_interop() COLLECT_ALL; - auto string = GC::ForeignRef::allocate(heap, "Hello, World!"); + auto string = GC::ForeignRef::allocate(heap, "Hello, World!"); COLLECT; diff --git a/Tests/LibGC/module.modulemap b/Tests/LibGC/module.modulemap deleted file mode 100644 index 7ce75c11409..00000000000 --- a/Tests/LibGC/module.modulemap +++ /dev/null @@ -1,6 +0,0 @@ -module GCTesting { - header "TestHeap.h" - header "TestInterop.h" - requires cplusplus - export * -}