Skip to content

Commit 55e7050

Browse files
authored
Merge pull request #32311 from Molanda/string_varargs_object_protocol
Added protocol to support CVarArg objects that need to be retained
2 parents a084d04 + 515c371 commit 55e7050

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

stdlib/public/core/VarArgs.swift

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,17 @@ protocol _CVarArgAligned: CVarArg {
6363
var _cVarArgAlignment: Int { get }
6464
}
6565

66+
#if !_runtime(_ObjC)
67+
/// Some pointers require an alternate object to be retained. The object
68+
/// that is returned will be used with _cVarArgEncoding and held until
69+
/// the closure is complete. This is required since autoreleased storage
70+
/// is not available on all platforms.
71+
public protocol _CVarArgObject: CVarArg {
72+
/// Returns the alternate object that should be encoded.
73+
var _cVarArgObject: CVarArg { get }
74+
}
75+
#endif
76+
6677
#if arch(x86_64)
6778
@usableFromInline
6879
internal let _countGPRegisters = 6
@@ -462,6 +473,11 @@ final internal class __VaListBuilder {
462473
@usableFromInline // c-abi
463474
internal var storage: ContiguousArray<Int>
464475

476+
#if !_runtime(_ObjC)
477+
@usableFromInline // c-abi
478+
internal var retainer = [CVarArg]()
479+
#endif
480+
465481
@inlinable // c-abi
466482
internal init() {
467483
// prepare the register save area
@@ -473,6 +489,16 @@ final internal class __VaListBuilder {
473489

474490
@inlinable // c-abi
475491
internal func append(_ arg: CVarArg) {
492+
#if !_runtime(_ObjC)
493+
var arg = arg
494+
495+
// We may need to retain an object that provides a pointer value.
496+
if let obj = arg as? _CVarArgObject {
497+
arg = obj._cVarArgObject
498+
retainer.append(arg)
499+
}
500+
#endif
501+
476502
var encoded = arg._cVarArgEncoding
477503

478504
#if arch(x86_64) || arch(arm64)
@@ -560,6 +586,16 @@ final internal class __VaListBuilder {
560586

561587
@inlinable // c-abi
562588
internal func append(_ arg: CVarArg) {
589+
#if !_runtime(_ObjC)
590+
var arg = arg
591+
592+
// We may need to retain an object that provides a pointer value.
593+
if let obj = arg as? _CVarArgObject {
594+
arg = obj._cVarArgObject
595+
retainer.append(arg)
596+
}
597+
#endif
598+
563599
// Write alignment padding if necessary.
564600
// This is needed on architectures where the ABI alignment of some
565601
// supported vararg type is greater than the alignment of Int, such
@@ -665,6 +701,11 @@ final internal class __VaListBuilder {
665701
@usableFromInline // c-abi
666702
internal var storage: UnsafeMutablePointer<Int>?
667703

704+
#if !_runtime(_ObjC)
705+
@usableFromInline // c-abi
706+
internal var retainer = [CVarArg]()
707+
#endif
708+
668709
internal static var alignedStorageForEmptyVaLists: Double = 0
669710
}
670711

0 commit comments

Comments
 (0)