Skip to content

Commit ef03958

Browse files
committed
Move C-compatible decls into Swift again
1 parent 083767b commit ef03958

3 files changed

Lines changed: 62 additions & 82 deletions

File tree

Sources/Testing/ABI/EntryPoints/Library.swift

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ internal import _TestingInternals
1313

1414
/// A type representing a testing library such as Swift Testing or XCTest.
1515
@_spi(Experimental)
16-
public struct Library: Sendable {
17-
/// The underlying instance of ``SWTLibrary``.
16+
@frozen public struct Library: Sendable {
17+
/// The underlying instance of ``Library/Record``.
1818
///
1919
/// - Important: The in-memory layout of ``Library`` must _exactly_ match the
20-
/// layout of this type. As such, it must not contain any other stored
21-
/// properties.
22-
nonisolated(unsafe) var rawValue: SWTLibrary
20+
/// layout of ``Library/Record``. As such, ``Library`` must not contain any
21+
/// other stored properties.
22+
nonisolated(unsafe) var rawValue: Record
2323

2424
/// The human-readable name of this library.
2525
///
@@ -149,6 +149,42 @@ public struct Library: Sendable {
149149
}
150150

151151
#if !SWT_NO_RUNTIME_LIBRARY_DISCOVERY
152+
// MARK: - C structure
153+
154+
extension Library {
155+
@usableFromInline typealias EntryPoint = @convention(c) (
156+
_ configurationJSON: UnsafeRawPointer,
157+
_ configurationJSONByteCount: Int,
158+
_ reserved: UInt,
159+
_ context: UnsafeRawPointer?,
160+
_ recordJSONHandler: EntryPointRecordJSONHandler,
161+
_ completionHandler: EntryPointCompletionHandler
162+
) -> Void
163+
164+
@usableFromInline typealias EntryPointRecordJSONHandler = @convention(c) (
165+
_ recordJSON: UnsafeRawPointer,
166+
_ recordJSONByteCount: Int,
167+
_ reserved: UInt,
168+
_ context: UnsafeRawPointer?
169+
) -> Void
170+
171+
@usableFromInline typealias EntryPointCompletionHandler = @convention(c) (
172+
_ resultJSON: UnsafeRawPointer,
173+
_ resultJSONByteCount: Int,
174+
_ reserved: UInt,
175+
_ context: UnsafeRawPointer?
176+
) -> Void
177+
178+
/// A type that provides the C-compatible in-memory layout of the ``Library``
179+
/// Swift type.
180+
@usableFromInline typealias Record = (
181+
name: UnsafePointer<CChar>,
182+
canonicalHint: UnsafePointer<CChar>,
183+
entryPoint: EntryPoint,
184+
reserved: (UInt, UInt, UInt, UInt, UInt)
185+
)
186+
}
187+
152188
// MARK: - Discovery
153189

154190
/// A helper protocol that prevents the conformance of ``Library`` to
@@ -167,11 +203,11 @@ extension Library: _DiscoverableAsTestContent {
167203
@_spi(Experimental)
168204
extension Library {
169205
/// Perform a one-time check that the in-memory layout of ``Library`` matches
170-
/// that of ``SWTLibrary``.
206+
/// that of ``Library/Record``.
171207
private static let _validateMemoryLayout: Void = {
172-
assert(MemoryLayout<Library>.size == MemoryLayout<SWTLibrary>.size, "Library.size (\(MemoryLayout<Library>.size)) != SWTLibrary.size (\(MemoryLayout<SWTLibrary>.size)). Please file a bug report at https://github.com/swiftlang/swift-testing/issues/new")
173-
assert(MemoryLayout<Library>.stride == MemoryLayout<SWTLibrary>.stride, "Library.stride (\(MemoryLayout<Library>.stride)) != SWTLibrary.stride (\(MemoryLayout<SWTLibrary>.stride)). Please file a bug report at https://github.com/swiftlang/swift-testing/issues/new")
174-
assert(MemoryLayout<Library>.alignment == MemoryLayout<SWTLibrary>.alignment, "Library.alignment (\(MemoryLayout<Library>.alignment)) != SWTLibrary.alignment (\(MemoryLayout<SWTLibrary>.alignment)). Please file a bug report at https://github.com/swiftlang/swift-testing/issues/new")
208+
assert(MemoryLayout<Library>.size == MemoryLayout<Library.Record>.size, "Library.size (\(MemoryLayout<Library>.size)) != Library.Record.size (\(MemoryLayout<Library.Record>.size)). Please file a bug report at https://github.com/swiftlang/swift-testing/issues/new")
209+
assert(MemoryLayout<Library>.stride == MemoryLayout<Library.Record>.stride, "Library.stride (\(MemoryLayout<Library>.stride)) != Library.Record.stride (\(MemoryLayout<Library.Record>.stride)). Please file a bug report at https://github.com/swiftlang/swift-testing/issues/new")
210+
assert(MemoryLayout<Library>.alignment == MemoryLayout<Library.Record>.alignment, "Library.alignment (\(MemoryLayout<Library>.alignment)) != Library.Record.alignment (\(MemoryLayout<Library.Record>.alignment)). Please file a bug report at https://github.com/swiftlang/swift-testing/issues/new")
175211
}()
176212

177213
/// Create an instance of this type representing the testing library with the
@@ -210,7 +246,7 @@ extension Library {
210246
extension Library {
211247
/// The ABI entry point function for the testing library, thunked so that it
212248
/// is compatible with the ``Library`` ABI.
213-
private static let _libraryRecordEntryPoint: SWTLibraryEntryPoint = { configurationJSON, configurationJSONByteCount, _, context, recordJSONHandler, completionHandler in
249+
private static let _libraryRecordEntryPoint: Library.EntryPoint = { configurationJSON, configurationJSONByteCount, _, context, recordJSONHandler, completionHandler in
214250
#if !SWT_NO_RUNTIME_LIBRARY_DISCOVERY
215251
// Capture appropriate state from the arguments to forward into the canonical
216252
// entry point function.
@@ -238,14 +274,15 @@ extension Library {
238274
args.eventStreamOutputPath = nil
239275

240276
// Create an async context and run tests within it.
241-
let run = { [args] in
277+
let run = { @Sendable [args] in
242278
let context = UnsafeRawPointer(bitPattern: contextBitPattern)!
243279
let exitCode = await Testing.entryPoint(passing: args, eventHandler: eventHandler)
244280
var resultJSON = "\(exitCode)"
245281
resultJSON.withUTF8 { resultJSON in
246282
completionHandler(resultJSON.baseAddress!, resultJSON.count, 0, context)
247283
}
248284
}
285+
249286
#if !SWT_NO_UNSTRUCTURED_TASKS
250287
Task.detached { await run() }
251288
#else
@@ -262,7 +299,7 @@ extension Library {
262299
/// An instance of this type representing Swift Testing itself.
263300
public static let swiftTesting: Self = {
264301
Self(
265-
rawValue: .init(
302+
rawValue: (
266303
name: StaticString("Swift Testing").constUTF8CString,
267304
canonicalHint: StaticString("swift-testing").constUTF8CString,
268305
entryPoint: _libraryRecordEntryPoint,
@@ -289,6 +326,9 @@ private func _libraryRecordAccessor(_ outValue: UnsafeMutableRawPointer, _ type:
289326
// Check if the name of the testing library the caller wants is equivalent to
290327
// "Swift Testing", ignoring case and punctuation. (If the caller did not
291328
// specify a library name, the caller wants records for all libraries.)
329+
//
330+
// Other libraries may opt to compare their hint values differently or accept
331+
// multiple different strings/patterns.
292332
let hint = hint.map { $0.load(as: UnsafePointer<CChar>.self) }
293333
if let hint {
294334
guard let hint = String(validatingCString: hint),
@@ -298,10 +338,7 @@ private func _libraryRecordAccessor(_ outValue: UnsafeMutableRawPointer, _ type:
298338
}
299339

300340
// Initialize the provided memory to the (ABI-stable) library structure.
301-
_ = outValue.initializeMemory(
302-
as: SWTLibrary.self,
303-
to: Library.swiftTesting.rawValue
304-
)
341+
_ = outValue.initializeMemory(as: Library.self, to: .swiftTesting)
305342

306343
return true
307344
}

Sources/_TestingInternals/include/Library.h

Lines changed: 0 additions & 52 deletions
This file was deleted.

Tests/TestingTests/LibraryTests.swift

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ struct `Library tests` {
5151
// MARK: - Fixtures
5252

5353
extension Library {
54-
private static let _mockRecordEntryPoint: SWTLibraryEntryPoint = { configurationJSON, configurationJSONByteCount, _, context, recordJSONHandler, completionHandler in
54+
private static let _mockRecordEntryPoint: Library.EntryPoint = { configurationJSON, configurationJSONByteCount, _, context, recordJSONHandler, completionHandler in
5555
let tests: [[String: Any]] = [
5656
[
5757
"kind": "function",
@@ -133,16 +133,14 @@ extension Library {
133133
}
134134
}
135135

136-
static let mock: Self = {
137-
Self(
138-
rawValue: .init(
139-
name: StaticString("Mock Testing Library").constUTF8CString,
140-
canonicalHint: StaticString("mock").constUTF8CString,
141-
entryPoint: _mockRecordEntryPoint,
142-
reserved: (0, 0, 0, 0, 0)
143-
)
136+
static let mock = Self(
137+
rawValue: (
138+
name: StaticString("Mock Testing Library").constUTF8CString,
139+
canonicalHint: StaticString("mock").constUTF8CString,
140+
entryPoint: _mockRecordEntryPoint,
141+
reserved: (0, 0, 0, 0, 0)
144142
)
145-
}()
143+
)
146144
}
147145

148146
#if compiler(>=6.3) && hasFeature(CompileTimeValuesPreview)
@@ -196,10 +194,7 @@ private func _mockLibraryRecordAccessor(_ outValue: UnsafeMutableRawPointer, _ t
196194
}
197195

198196
// Initialize the provided memory to the (ABI-stable) library structure.
199-
_ = outValue.initializeMemory(
200-
as: SWTLibrary.self,
201-
to: Library.mock.rawValue
202-
)
197+
_ = outValue.initializeMemory(as: Library.self, to: .mock)
203198

204199
return true
205200
}

0 commit comments

Comments
 (0)