Skip to content

Commit 3425a6d

Browse files
committed
Added protocol to support CVarArg objects that need to be retained
1 parent 122deaa commit 3425a6d

File tree

1 file changed

+31
-0
lines changed

1 file changed

+31
-0
lines changed

stdlib/public/core/VarArgs.swift

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

66+
/// Some pointers require an alternate object to be retained. The object
67+
/// that is returned will be used with _cVarArgEncoding and held until
68+
/// the closure is complete. This is required since autoreleased storage
69+
/// is available on all platforms.
70+
public protocol _CVarArgObject: CVarArg {
71+
/// Returns the alternate object that should be encoded.
72+
var _cVarArgObject: CVarArg { get }
73+
}
74+
6675
#if arch(x86_64)
6776
@usableFromInline
6877
internal let _countGPRegisters = 6
@@ -462,6 +471,9 @@ final internal class __VaListBuilder {
462471
@usableFromInline // c-abi
463472
internal var storage: ContiguousArray<Int>
464473

474+
@usableFromInline // c-abi
475+
internal var retainer = [CVarArg]()
476+
465477
@inlinable // c-abi
466478
internal init() {
467479
// prepare the register save area
@@ -473,6 +485,14 @@ final internal class __VaListBuilder {
473485

474486
@inlinable // c-abi
475487
internal func append(_ arg: CVarArg) {
488+
var arg = arg
489+
490+
// We may need to retain an object that provides a pointer value.
491+
if let obj = arg as? _CVarArgObject {
492+
arg = obj._cVarArgObject
493+
retainer.append(arg)
494+
}
495+
476496
var encoded = arg._cVarArgEncoding
477497

478498
#if arch(x86_64) || arch(arm64)
@@ -560,6 +580,14 @@ final internal class __VaListBuilder {
560580

561581
@inlinable // c-abi
562582
internal func append(_ arg: CVarArg) {
583+
var arg = arg
584+
585+
// We may need to retain an object that provides a pointer value.
586+
if let obj = arg as? _CVarArgObject {
587+
arg = obj._cVarArgObject
588+
retainer.append(arg)
589+
}
590+
563591
// Write alignment padding if necessary.
564592
// This is needed on architectures where the ABI alignment of some
565593
// supported vararg type is greater than the alignment of Int, such
@@ -665,6 +693,9 @@ final internal class __VaListBuilder {
665693
@usableFromInline // c-abi
666694
internal var storage: UnsafeMutablePointer<Int>?
667695

696+
@usableFromInline // c-abi
697+
internal var retainer = [CVarArg]()
698+
668699
internal static var alignedStorageForEmptyVaLists: Double = 0
669700
}
670701

0 commit comments

Comments
 (0)