@@ -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
6877internal 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