From 3425a6dbb16e5fa7ad4b735eff4533c279d61442 Mon Sep 17 00:00:00 2001 From: Brian Gontowski Date: Thu, 11 Jun 2020 14:45:00 +0900 Subject: [PATCH 1/4] Added protocol to support CVarArg objects that need to be retained --- stdlib/public/core/VarArgs.swift | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/stdlib/public/core/VarArgs.swift b/stdlib/public/core/VarArgs.swift index 8576a86568b01..08d04eaa37a94 100644 --- a/stdlib/public/core/VarArgs.swift +++ b/stdlib/public/core/VarArgs.swift @@ -63,6 +63,15 @@ protocol _CVarArgAligned: CVarArg { var _cVarArgAlignment: Int { get } } +/// Some pointers require an alternate object to be retained. The object +/// that is returned will be used with _cVarArgEncoding and held until +/// the closure is complete. This is required since autoreleased storage +/// is available on all platforms. +public protocol _CVarArgObject: CVarArg { + /// Returns the alternate object that should be encoded. + var _cVarArgObject: CVarArg { get } +} + #if arch(x86_64) @usableFromInline internal let _countGPRegisters = 6 @@ -462,6 +471,9 @@ final internal class __VaListBuilder { @usableFromInline // c-abi internal var storage: ContiguousArray + @usableFromInline // c-abi + internal var retainer = [CVarArg]() + @inlinable // c-abi internal init() { // prepare the register save area @@ -473,6 +485,14 @@ final internal class __VaListBuilder { @inlinable // c-abi internal func append(_ arg: CVarArg) { + var arg = arg + + // We may need to retain an object that provides a pointer value. + if let obj = arg as? _CVarArgObject { + arg = obj._cVarArgObject + retainer.append(arg) + } + var encoded = arg._cVarArgEncoding #if arch(x86_64) || arch(arm64) @@ -560,6 +580,14 @@ final internal class __VaListBuilder { @inlinable // c-abi internal func append(_ arg: CVarArg) { + var arg = arg + + // We may need to retain an object that provides a pointer value. + if let obj = arg as? _CVarArgObject { + arg = obj._cVarArgObject + retainer.append(arg) + } + // Write alignment padding if necessary. // This is needed on architectures where the ABI alignment of some // supported vararg type is greater than the alignment of Int, such @@ -665,6 +693,9 @@ final internal class __VaListBuilder { @usableFromInline // c-abi internal var storage: UnsafeMutablePointer? + @usableFromInline // c-abi + internal var retainer = [CVarArg]() + internal static var alignedStorageForEmptyVaLists: Double = 0 } From 0e7749bcde5eb1bc9fec82ef0eb3896ec8d6de6f Mon Sep 17 00:00:00 2001 From: Brian Gontowski Date: Thu, 11 Jun 2020 15:11:07 +0900 Subject: [PATCH 2/4] Fixed comment --- stdlib/public/core/VarArgs.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/public/core/VarArgs.swift b/stdlib/public/core/VarArgs.swift index 08d04eaa37a94..16d8eb97e2bd2 100644 --- a/stdlib/public/core/VarArgs.swift +++ b/stdlib/public/core/VarArgs.swift @@ -66,7 +66,7 @@ protocol _CVarArgAligned: CVarArg { /// Some pointers require an alternate object to be retained. The object /// that is returned will be used with _cVarArgEncoding and held until /// the closure is complete. This is required since autoreleased storage -/// is available on all platforms. +/// is not available on all platforms. public protocol _CVarArgObject: CVarArg { /// Returns the alternate object that should be encoded. var _cVarArgObject: CVarArg { get } From 17c77ba703b32c11e127573d414d31c9ec635188 Mon Sep 17 00:00:00 2001 From: Brian Gontowski Date: Sat, 22 Aug 2020 11:36:15 +0900 Subject: [PATCH 3/4] Only use _CVarArgObject on non-ObjC platforms --- stdlib/public/core/VarArgs.swift | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/stdlib/public/core/VarArgs.swift b/stdlib/public/core/VarArgs.swift index 16d8eb97e2bd2..53774a5f62aa2 100644 --- a/stdlib/public/core/VarArgs.swift +++ b/stdlib/public/core/VarArgs.swift @@ -63,6 +63,7 @@ protocol _CVarArgAligned: CVarArg { var _cVarArgAlignment: Int { get } } +#if !_runtime(_ObjC) /// Some pointers require an alternate object to be retained. The object /// that is returned will be used with _cVarArgEncoding and held until /// the closure is complete. This is required since autoreleased storage @@ -71,6 +72,7 @@ public protocol _CVarArgObject: CVarArg { /// Returns the alternate object that should be encoded. var _cVarArgObject: CVarArg { get } } +#endif #if arch(x86_64) @usableFromInline @@ -471,8 +473,10 @@ final internal class __VaListBuilder { @usableFromInline // c-abi internal var storage: ContiguousArray +#if !_runtime(_ObjC) @usableFromInline // c-abi internal var retainer = [CVarArg]() +#endif @inlinable // c-abi internal init() { @@ -487,11 +491,13 @@ final internal class __VaListBuilder { internal func append(_ arg: CVarArg) { var arg = arg +#if !_runtime(_ObjC) // We may need to retain an object that provides a pointer value. if let obj = arg as? _CVarArgObject { arg = obj._cVarArgObject retainer.append(arg) } +#endif var encoded = arg._cVarArgEncoding @@ -582,11 +588,13 @@ final internal class __VaListBuilder { internal func append(_ arg: CVarArg) { var arg = arg +#if !_runtime(_ObjC) // We may need to retain an object that provides a pointer value. if let obj = arg as? _CVarArgObject { arg = obj._cVarArgObject retainer.append(arg) } +#endif // Write alignment padding if necessary. // This is needed on architectures where the ABI alignment of some @@ -693,8 +701,10 @@ final internal class __VaListBuilder { @usableFromInline // c-abi internal var storage: UnsafeMutablePointer? +#if !_runtime(_ObjC) @usableFromInline // c-abi internal var retainer = [CVarArg]() +#endif internal static var alignedStorageForEmptyVaLists: Double = 0 } From 515c371be434ff49debfd145ebd9047bd148d47f Mon Sep 17 00:00:00 2001 From: Brian Gontowski Date: Sat, 22 Aug 2020 13:08:12 +0900 Subject: [PATCH 4/4] Avoid a warning when not modifying arg --- stdlib/public/core/VarArgs.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stdlib/public/core/VarArgs.swift b/stdlib/public/core/VarArgs.swift index 53774a5f62aa2..40a134baedaf1 100644 --- a/stdlib/public/core/VarArgs.swift +++ b/stdlib/public/core/VarArgs.swift @@ -489,9 +489,9 @@ final internal class __VaListBuilder { @inlinable // c-abi internal func append(_ arg: CVarArg) { +#if !_runtime(_ObjC) var arg = arg -#if !_runtime(_ObjC) // We may need to retain an object that provides a pointer value. if let obj = arg as? _CVarArgObject { arg = obj._cVarArgObject @@ -586,9 +586,9 @@ final internal class __VaListBuilder { @inlinable // c-abi internal func append(_ arg: CVarArg) { +#if !_runtime(_ObjC) var arg = arg -#if !_runtime(_ObjC) // We may need to retain an object that provides a pointer value. if let obj = arg as? _CVarArgObject { arg = obj._cVarArgObject