Skip to content

Commit f8c7bd9

Browse files
committed
[ASTGen] Cleanup string bridging
* BridgedString for ASTGen -> C++ string returnings * Null terminated C-strings for C++ -> ASTGen string arguments * UnsafeMutableRawPointer for C++ -> ASTGen diagnostic engine arguments
1 parent 0ada2e2 commit f8c7bd9

File tree

7 files changed

+146
-208
lines changed

7 files changed

+146
-208
lines changed

Diff for: lib/ASTGen/Sources/ASTGen/Bridge.swift

+34
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,40 @@ extension String {
4040
}
4141
}
4242

43+
/// Allocate a copy of the given string as a UTF-8 string.
44+
func allocateBridgedString(
45+
_ string: String,
46+
nullTerminated: Bool = false
47+
) -> BridgedString {
48+
var string = string
49+
return string.withUTF8 { utf8 in
50+
let capacity = utf8.count + (nullTerminated ? 1 : 0)
51+
let ptr = UnsafeMutablePointer<UInt8>.allocate(
52+
capacity: capacity
53+
)
54+
if let baseAddress = utf8.baseAddress {
55+
ptr.initialize(from: baseAddress, count: utf8.count)
56+
}
57+
58+
if nullTerminated {
59+
ptr[utf8.count] = 0
60+
}
61+
62+
return BridgedString(data: ptr, length: utf8.count)
63+
}
64+
}
65+
66+
@_cdecl("swift_ASTGen_freeBridgedString")
67+
public func freeBridgedString(bridged: BridgedString) {
68+
bridged.data?.deallocate()
69+
}
70+
71+
extension BridgedString {
72+
var isEmptyInitialized: Bool {
73+
return self.data == nil && self.length == 0
74+
}
75+
}
76+
4377
extension SyntaxProtocol {
4478
/// Obtains the bridged start location of the node excluding leading trivia in the source buffer provided by `astgen`
4579
///

Diff for: lib/ASTGen/Sources/ASTGen/DiagnosticsBridge.swift

+14-18
Original file line numberDiff line numberDiff line change
@@ -262,17 +262,16 @@ public func createQueuedDiagnostics() -> UnsafeRawPointer {
262262
/// Destroy the queued diagnostics.
263263
@_cdecl("swift_ASTGen_destroyQueuedDiagnostics")
264264
public func destroyQueuedDiagnostics(
265-
queuedDiagnosticsPtr: UnsafeMutablePointer<UInt8>
265+
queuedDiagnosticsPtr: UnsafeMutableRawPointer
266266
) {
267-
queuedDiagnosticsPtr.withMemoryRebound(to: QueuedDiagnostics.self, capacity: 1) { queuedDiagnostics in
268-
for (_, sourceFileID) in queuedDiagnostics.pointee.sourceFileIDs {
269-
sourceFileID.deinitialize(count: 1)
270-
sourceFileID.deallocate()
271-
}
272-
273-
queuedDiagnostics.deinitialize(count: 1)
274-
queuedDiagnostics.deallocate()
267+
let queuedDiagnostics = queuedDiagnosticsPtr.assumingMemoryBound(to: QueuedDiagnostics.self)
268+
for (_, sourceFileID) in queuedDiagnostics.pointee.sourceFileIDs {
269+
sourceFileID.deinitialize(count: 1)
270+
sourceFileID.deallocate()
275271
}
272+
273+
queuedDiagnostics.deinitialize(count: 1)
274+
queuedDiagnostics.deallocate()
276275
}
277276

278277
/// Diagnostic message used for thrown errors.
@@ -444,17 +443,14 @@ public func addQueuedDiagnostic(
444443
/// Render the queued diagnostics into a UTF-8 string.
445444
@_cdecl("swift_ASTGen_renderQueuedDiagnostics")
446445
public func renderQueuedDiagnostics(
447-
queuedDiagnosticsPtr: UnsafeMutablePointer<UInt8>,
446+
queuedDiagnosticsPtr: UnsafeMutableRawPointer,
448447
contextSize: Int,
449448
colorize: Int,
450-
renderedPointer: UnsafeMutablePointer<UnsafePointer<UInt8>?>,
451-
renderedLength: UnsafeMutablePointer<Int>
449+
renderedStringOutPtr: UnsafeMutablePointer<BridgedString>
452450
) {
453-
queuedDiagnosticsPtr.withMemoryRebound(to: QueuedDiagnostics.self, capacity: 1) { queuedDiagnostics in
454-
let formatter = DiagnosticsFormatter(contextSize: contextSize, colorize: colorize != 0)
455-
let renderedStr = formatter.annotateSources(in: queuedDiagnostics.pointee.grouped)
451+
let queuedDiagnostics = queuedDiagnosticsPtr.assumingMemoryBound(to: QueuedDiagnostics.self)
452+
let formatter = DiagnosticsFormatter(contextSize: contextSize, colorize: colorize != 0)
453+
let renderedStr = formatter.annotateSources(in: queuedDiagnostics.pointee.grouped)
456454

457-
(renderedPointer.pointee, renderedLength.pointee) =
458-
allocateUTF8String(renderedStr)
459-
}
455+
renderedStringOutPtr.pointee = allocateBridgedString(renderedStr)
460456
}

Diff for: lib/ASTGen/Sources/ASTGen/Macros.swift

+40-115
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,6 @@ extension MacroRole {
7676
}
7777
}
7878

79-
extension String {
80-
public init(bufferStart: UnsafePointer<UInt8>?, count: Int) {
81-
let buffer = UnsafeBufferPointer(start: bufferStart, count: count)
82-
self.init(decoding: buffer, as: UTF8.self)
83-
}
84-
}
85-
8679
/// Resolve a reference to type metadata into a macro, if posible.
8780
///
8881
/// Returns an unmanaged pointer to an ExportedMacro instance that describes
@@ -117,19 +110,17 @@ public func destroyMacro(
117110

118111
@_cdecl("swift_ASTGen_resolveExecutableMacro")
119112
public func resolveExecutableMacro(
120-
moduleName: UnsafePointer<UInt8>,
121-
moduleNameLength: Int,
122-
typeName: UnsafePointer<UInt8>,
123-
typeNameLength: Int,
113+
moduleName: UnsafePointer<CChar>,
114+
typeName: UnsafePointer<CChar>,
124115
pluginOpaqueHandle: UnsafeMutableRawPointer
125116
) -> UnsafeRawPointer {
126117
// NOTE: This doesn't actually resolve anything.
127118
// Executable plugins is "trusted" to have the macro implementation. If not,
128119
// the actual expansion fails.
129120
let exportedPtr = UnsafeMutablePointer<ExportedExecutableMacro>.allocate(capacity: 1)
130121
exportedPtr.initialize(to: .init(
131-
moduleName: String(bufferStart: moduleName, count: moduleNameLength),
132-
typeName: String(bufferStart: typeName, count: typeNameLength),
122+
moduleName: String(cString: moduleName),
123+
typeName: String(cString: typeName),
133124
plugin: CompilerPlugin(opaqueHandle: pluginOpaqueHandle)))
134125
return UnsafeRawPointer(exportedPtr)
135126
}
@@ -143,34 +134,6 @@ public func destroyExecutableMacro(
143134
macroPtr.deallocate()
144135
}
145136

146-
/// Allocate a copy of the given string as a UTF-8 string.
147-
func allocateUTF8String(
148-
_ string: String,
149-
nullTerminated: Bool = false
150-
) -> (UnsafePointer<UInt8>, Int) {
151-
var string = string
152-
return string.withUTF8 { utf8 in
153-
let capacity = utf8.count + (nullTerminated ? 1 : 0)
154-
let ptr = UnsafeMutablePointer<UInt8>.allocate(
155-
capacity: capacity
156-
)
157-
if let baseAddress = utf8.baseAddress {
158-
ptr.initialize(from: baseAddress, count: utf8.count)
159-
}
160-
161-
if nullTerminated {
162-
ptr[utf8.count] = 0
163-
}
164-
165-
return (UnsafePointer<UInt8>(ptr), utf8.count)
166-
}
167-
}
168-
169-
@_cdecl("swift_ASTGen_freeString")
170-
public func freeString(pointer: UnsafePointer<UInt8>?) {
171-
pointer?.deallocate()
172-
}
173-
174137
/// Diagnostics produced here.
175138
enum ASTGenMacroDiagnostic: DiagnosticMessage, FixItMessage {
176139
case thrownError(Error)
@@ -251,19 +214,16 @@ fileprivate func identifierFromStringLiteral(_ node: ExprSyntax) -> String? {
251214
/// argument matching the corresponding parameter.
252215
@_cdecl("swift_ASTGen_checkMacroDefinition")
253216
func checkMacroDefinition(
254-
diagEnginePtr: UnsafeMutablePointer<UInt8>,
217+
diagEnginePtr: UnsafeMutableRawPointer,
255218
sourceFilePtr: UnsafeRawPointer,
256219
macroLocationPtr: UnsafePointer<UInt8>,
257-
externalMacroPointer: UnsafeMutablePointer<UnsafePointer<UInt8>?>,
258-
externalMacroLength: UnsafeMutablePointer<Int>,
220+
externalMacroOutPtr: UnsafeMutablePointer<BridgedString>,
259221
replacementsPtr: UnsafeMutablePointer<UnsafeMutablePointer<Int>?>,
260222
numReplacementsPtr: UnsafeMutablePointer<Int>
261223
) -> Int {
262-
// Clear out the "out" parameters.
263-
externalMacroPointer.pointee = nil
264-
externalMacroLength.pointee = 0
265-
replacementsPtr.pointee = nil
266-
numReplacementsPtr.pointee = 0
224+
// Assert "out" parameters are initialized.
225+
assert(externalMacroOutPtr.pointee.isEmptyInitialized)
226+
assert(replacementsPtr.pointee == nil && numReplacementsPtr.pointee == 0)
267227

268228
let sourceFilePtr = sourceFilePtr.bindMemory(to: ExportedSourceFile.self, capacity: 1)
269229

@@ -304,8 +264,8 @@ func checkMacroDefinition(
304264
}
305265

306266
// Form the "ModuleName.TypeName" result string.
307-
(externalMacroPointer.pointee, externalMacroLength.pointee) =
308-
allocateUTF8String("\(module).\(type)", nullTerminated: true)
267+
externalMacroOutPtr.pointee =
268+
allocateBridgedString("\(module).\(type)", nullTerminated: true)
309269

310270
// Translate this into a use of #externalMacro.
311271
let expansionSourceSyntax: ExprSyntax =
@@ -368,15 +328,15 @@ func checkMacroDefinition(
368328
}
369329

370330
// Form the "ModuleName.TypeName" result string.
371-
(externalMacroPointer.pointee, externalMacroLength.pointee) =
372-
allocateUTF8String("\(module).\(type)", nullTerminated: true)
331+
externalMacroOutPtr.pointee =
332+
allocateBridgedString("\(module).\(type)", nullTerminated: true)
373333
return Int(BridgedMacroDefinitionKind.externalMacro.rawValue)
374334

375335
case let .expansion(expansionSyntax, replacements: replacements):
376336
// Provide the expansion syntax.
377-
(externalMacroPointer.pointee, externalMacroLength.pointee) =
378-
allocateUTF8String(expansionSyntax.trimmedDescription,
379-
nullTerminated: true)
337+
externalMacroOutPtr.pointee =
338+
allocateBridgedString(expansionSyntax.trimmedDescription,
339+
nullTerminated: true)
380340

381341

382342
// If there are no replacements, we're done.
@@ -429,44 +389,30 @@ public func freeExpansionReplacements(
429389
// Make an expansion result for '@_cdecl' function caller.
430390
func makeExpansionOutputResult(
431391
expandedSource: String?,
432-
outputPointer: UnsafeMutablePointer<UnsafePointer<UInt8>?>,
433-
outputLength: UnsafeMutablePointer<Int>
392+
outputPointer: UnsafeMutablePointer<BridgedString>
434393
) -> Int {
435394
guard var expandedSource = expandedSource else {
395+
outputPointer.pointee = BridgedString()
436396
return -1
437397
}
438-
439-
// Form the result buffer for our caller.
440-
expandedSource.withUTF8 { utf8 in
441-
let evaluatedResultPtr = UnsafeMutablePointer<UInt8>.allocate(capacity: utf8.count + 1)
442-
if let baseAddress = utf8.baseAddress {
443-
evaluatedResultPtr.initialize(from: baseAddress, count: utf8.count)
444-
}
445-
evaluatedResultPtr[utf8.count] = 0
446-
447-
outputPointer.pointee = UnsafePointer(evaluatedResultPtr)
448-
outputLength.pointee = utf8.count
449-
}
398+
outputPointer.pointee = allocateBridgedString(expandedSource, nullTerminated: true)
450399
return 0
451400
}
452401

453402
@_cdecl("swift_ASTGen_expandFreestandingMacro")
454403
@usableFromInline
455404
func expandFreestandingMacro(
456-
diagEnginePtr: UnsafeMutablePointer<UInt8>,
405+
diagEnginePtr: UnsafeMutableRawPointer,
457406
macroPtr: UnsafeRawPointer,
458407
macroKind: UInt8,
459-
discriminatorText: UnsafePointer<UInt8>,
460-
discriminatorTextLength: Int,
408+
discriminatorText: UnsafePointer<CChar>,
461409
rawMacroRole: UInt8,
462410
sourceFilePtr: UnsafeRawPointer,
463411
sourceLocationPtr: UnsafePointer<UInt8>?,
464-
expandedSourcePointer: UnsafeMutablePointer<UnsafePointer<UInt8>?>,
465-
expandedSourceLength: UnsafeMutablePointer<Int>
412+
expandedSourceOutPtr: UnsafeMutablePointer<BridgedString>
466413
) -> Int {
467414
// We didn't expand anything so far.
468-
expandedSourcePointer.pointee = nil
469-
expandedSourceLength.pointee = 0
415+
assert(expandedSourceOutPtr.pointee.isEmptyInitialized)
470416

471417
guard let sourceLocationPtr = sourceLocationPtr else {
472418
print("NULL source location")
@@ -486,10 +432,8 @@ func expandFreestandingMacro(
486432
return 1
487433
}
488434

489-
let discriminatorBuffer = UnsafeBufferPointer(
490-
start: discriminatorText, count: discriminatorTextLength
491-
)
492-
let discriminator = String(decoding: discriminatorBuffer, as: UTF8.self)
435+
436+
let discriminator = String(cString: discriminatorText)
493437

494438
let macroRole = MacroRole(rawMacroRole: rawMacroRole)
495439
let expandedSource: String?
@@ -514,15 +458,14 @@ func expandFreestandingMacro(
514458

515459
return makeExpansionOutputResult(
516460
expandedSource: expandedSource,
517-
outputPointer: expandedSourcePointer,
518-
outputLength: expandedSourceLength
461+
outputPointer: expandedSourceOutPtr
519462
)
520463
}
521464

522465
func expandFreestandingMacroIPC(
523466
macroPtr: UnsafeRawPointer,
524467
macroRole: MacroRole,
525-
diagEnginePtr: UnsafeMutablePointer<UInt8>,
468+
diagEnginePtr: UnsafeMutableRawPointer,
526469
expansionSyntax: FreestandingMacroExpansionSyntax,
527470
sourceFilePtr: UnsafePointer<ExportedSourceFile>,
528471
discriminator: String
@@ -597,7 +540,7 @@ func expandFreestandingMacroIPC(
597540
func expandFreestandingMacroInProcess(
598541
macroPtr: UnsafeRawPointer,
599542
macroRole: MacroRole,
600-
diagEnginePtr: UnsafeMutablePointer<UInt8>,
543+
diagEnginePtr: UnsafeMutableRawPointer,
601544
expansionSyntax: FreestandingMacroExpansionSyntax,
602545
sourceFilePtr: UnsafePointer<ExportedSourceFile>,
603546
discriminator: String
@@ -717,28 +660,23 @@ func findSyntaxNodeInSourceFile<Node: SyntaxProtocol>(
717660
@_cdecl("swift_ASTGen_expandAttachedMacro")
718661
@usableFromInline
719662
func expandAttachedMacro(
720-
diagEnginePtr: UnsafeMutablePointer<UInt8>,
663+
diagEnginePtr: UnsafeMutableRawPointer,
721664
macroPtr: UnsafeRawPointer,
722665
macroKind: UInt8,
723-
discriminatorText: UnsafePointer<UInt8>,
724-
discriminatorTextLength: Int,
725-
qualifiedTypeText: UnsafePointer<UInt8>,
726-
qualifiedTypeLength: Int,
727-
conformanceListText: UnsafePointer<UInt8>,
728-
conformanceListLength: Int,
666+
discriminatorText: UnsafePointer<CChar>,
667+
qualifiedTypeText: UnsafePointer<CChar>,
668+
conformanceListText: UnsafePointer<CChar>,
729669
rawMacroRole: UInt8,
730670
customAttrSourceFilePtr: UnsafeRawPointer,
731671
customAttrSourceLocPointer: UnsafePointer<UInt8>?,
732672
declarationSourceFilePtr: UnsafeRawPointer,
733673
attachedTo declarationSourceLocPointer: UnsafePointer<UInt8>?,
734674
parentDeclSourceFilePtr: UnsafeRawPointer?,
735675
parentDeclSourceLocPointer: UnsafePointer<UInt8>?,
736-
expandedSourcePointer: UnsafeMutablePointer<UnsafePointer<UInt8>?>,
737-
expandedSourceLength: UnsafeMutablePointer<Int>
676+
expandedSourceOutPtr: UnsafeMutablePointer<BridgedString>
738677
) -> Int {
739678
// We didn't expand anything so far.
740-
expandedSourcePointer.pointee = nil
741-
expandedSourceLength.pointee = 0
679+
assert(expandedSourceOutPtr.pointee.isEmptyInitialized)
742680

743681
// Dig out the custom attribute for the attached macro declarations.
744682
guard let customAttrNode = findSyntaxNodeInSourceFile(
@@ -772,21 +710,9 @@ func expandAttachedMacro(
772710
let declarationSourceFilePtr = declarationSourceFilePtr.bindMemory(to: ExportedSourceFile.self, capacity: 1)
773711
let parentDeclSourceFilePtr = parentDeclSourceFilePtr?.bindMemory(to: ExportedSourceFile.self, capacity: 1)
774712

775-
let discriminatorBuffer = UnsafeBufferPointer(
776-
start: discriminatorText, count: discriminatorTextLength
777-
)
778-
let discriminator = String(decoding: discriminatorBuffer, as: UTF8.self)
779-
780-
let qualifiedTypeBuffer = UnsafeBufferPointer(
781-
start: qualifiedTypeText, count: qualifiedTypeLength
782-
)
783-
let qualifiedType = String(decoding: qualifiedTypeBuffer, as: UTF8.self)
784-
785-
let conformanceListBuffer = UnsafeBufferPointer(
786-
start: conformanceListText, count: conformanceListLength
787-
)
788-
let conformanceList = String(decoding: conformanceListBuffer, as: UTF8.self)
789-
713+
let discriminator = String(cString: discriminatorText)
714+
let qualifiedType = String(cString: qualifiedTypeText)
715+
let conformanceList = String(cString: conformanceListText)
790716

791717
let expandedSource: String?
792718
switch MacroPluginKind(rawValue: macroKind)! {
@@ -822,13 +748,12 @@ func expandAttachedMacro(
822748

823749
return makeExpansionOutputResult(
824750
expandedSource: expandedSource,
825-
outputPointer: expandedSourcePointer,
826-
outputLength: expandedSourceLength
751+
outputPointer: expandedSourceOutPtr
827752
)
828753
}
829754

830755
func expandAttachedMacroIPC(
831-
diagEnginePtr: UnsafeMutablePointer<UInt8>,
756+
diagEnginePtr: UnsafeMutableRawPointer,
832757
macroPtr: UnsafeRawPointer,
833758
rawMacroRole: UInt8,
834759
discriminator: String,
@@ -962,7 +887,7 @@ func expandAttachedMacroIPC(
962887
}
963888

964889
func expandAttachedMacroInProcess(
965-
diagEnginePtr: UnsafeMutablePointer<UInt8>,
890+
diagEnginePtr: UnsafeMutableRawPointer,
966891
macroPtr: UnsafeRawPointer,
967892
rawMacroRole: UInt8,
968893
discriminator: String,

0 commit comments

Comments
 (0)