Skip to content

Commit 805dd70

Browse files
authored
Merge pull request swiftlang#72074 from glessard/toplevel-withbytes-typed-throws
[stdlib] convert `withUnsafeBytes()` to typed throws
2 parents 33f8fc4 + fd726cc commit 805dd70

File tree

4 files changed

+96
-18
lines changed

4 files changed

+96
-18
lines changed

stdlib/public/core/UnsafeRawBufferPointer.swift.gyb

Lines changed: 75 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,17 +1209,47 @@ extension ${Self} {
12091209
/// of the closure's execution.
12101210
/// - Returns: The return value, if any, of the `body` closure.
12111211
@inlinable
1212-
public func withUnsafeMutableBytes<T, Result>(
1212+
@_alwaysEmitIntoClient
1213+
public func withUnsafeMutableBytes<T, E: Error, Result>(
1214+
of value: inout T,
1215+
_ body: (UnsafeMutableRawBufferPointer) throws(E) -> Result
1216+
) throws(E) -> Result {
1217+
let pointer = UnsafeMutableRawPointer(Builtin.addressof(&value))
1218+
return try body(.init(start: pointer, count: MemoryLayout<T>.size))
1219+
}
1220+
1221+
/// ABI: Historical withUnsafeMutableBytes(of:_:) rethrows,
1222+
/// expressed as "throws", which is ABI-compatible with "rethrows".
1223+
@_silgen_name("$ss22withUnsafeMutableBytes2of_q_xz_q_SwKXEtKr0_lF")
1224+
@usableFromInline
1225+
func __abi_se0413_withUnsafeMutableBytes<T, Result>(
12131226
of value: inout T,
12141227
_ body: (UnsafeMutableRawBufferPointer) throws -> Result
1215-
) rethrows -> Result
1216-
{
1228+
) throws -> Result {
12171229
return try withUnsafeMutablePointer(to: &value) {
12181230
return try body(UnsafeMutableRawBufferPointer(
12191231
start: $0, count: MemoryLayout<T>.size))
12201232
}
12211233
}
12221234

1235+
/// Invokes the given closure with a buffer pointer covering the raw bytes of
1236+
/// the given argument.
1237+
///
1238+
/// This function is similar to `withUnsafeMutableBytes`, except that it
1239+
/// doesn't trigger stack protection for the pointer.
1240+
@_alwaysEmitIntoClient
1241+
public func _withUnprotectedUnsafeMutableBytes<T, E: Error, Result>(
1242+
of value: inout T,
1243+
_ body: (UnsafeMutableRawBufferPointer) throws(E) -> Result
1244+
) throws(E) -> Result {
1245+
#if $BuiltinUnprotectedAddressOf
1246+
let pointer = UnsafeMutableRawPointer(Builtin.unprotectedAddressOf(&value))
1247+
#else
1248+
let pointer = UnsafeMutableRawPointer(Builtin.addressof(&value))
1249+
#endif
1250+
return try body(.init(start: pointer, count: MemoryLayout<T>.size))
1251+
}
1252+
12231253
/// Invokes the given closure with a buffer pointer covering the raw bytes of
12241254
/// the given argument.
12251255
///
@@ -1244,11 +1274,23 @@ public func withUnsafeMutableBytes<T, Result>(
12441274
/// `withUnsafeMutableBytes(of:_:)` instead.
12451275
/// - Returns: The return value, if any, of the `body` closure.
12461276
@inlinable
1247-
public func withUnsafeBytes<T, Result>(
1277+
@_alwaysEmitIntoClient
1278+
public func withUnsafeBytes<T, E: Error, Result>(
1279+
of value: inout T,
1280+
_ body: (UnsafeRawBufferPointer) throws(E) -> Result
1281+
) throws(E) -> Result {
1282+
let address = UnsafeRawPointer(Builtin.addressof(&value))
1283+
return try body(.init(start: address, count: MemoryLayout<T>.size))
1284+
}
1285+
1286+
/// ABI: Historical withUnsafeBytes(of:_:) rethrows,
1287+
/// expressed as "throws", which is ABI-compatible with "rethrows".
1288+
@_silgen_name("$ss15withUnsafeBytes2of_q_xz_q_SWKXEtKr0_lF")
1289+
@usableFromInline
1290+
func __abi_se0413_withUnsafeBytes<T, Result>(
12481291
of value: inout T,
12491292
_ body: (UnsafeRawBufferPointer) throws -> Result
1250-
) rethrows -> Result
1251-
{
1293+
) throws -> Result {
12521294
return try withUnsafePointer(to: &value) {
12531295
try body(UnsafeRawBufferPointer(start: $0, count: MemoryLayout<T>.size))
12541296
}
@@ -1260,14 +1302,16 @@ public func withUnsafeBytes<T, Result>(
12601302
/// This function is similar to `withUnsafeBytes`, except that it
12611303
/// doesn't trigger stack protection for the pointer.
12621304
@_alwaysEmitIntoClient
1263-
public func _withUnprotectedUnsafeBytes<T, Result>(
1305+
public func _withUnprotectedUnsafeBytes<T, E: Error, Result>(
12641306
of value: inout T,
1265-
_ body: (UnsafeRawBufferPointer) throws -> Result
1266-
) rethrows -> Result
1267-
{
1268-
return try _withUnprotectedUnsafePointer(to: &value) {
1269-
try body(UnsafeRawBufferPointer(start: $0, count: MemoryLayout<T>.size))
1270-
}
1307+
_ body: (UnsafeRawBufferPointer) throws(E) -> Result
1308+
) throws(E) -> Result {
1309+
#if $BuiltinUnprotectedAddressOf
1310+
let p = UnsafeRawPointer(Builtin.unprotectedAddressOf(&value))
1311+
#else
1312+
let p = UnsafeRawPointer(Builtin.addressof(&value))
1313+
#endif
1314+
return try body(.init(start: p, count: MemoryLayout<T>.size))
12711315
}
12721316

12731317
/// Invokes the given closure with a buffer pointer covering the raw bytes of
@@ -1290,10 +1334,23 @@ public func _withUnprotectedUnsafeBytes<T, Result>(
12901334
/// `withUnsafeMutableBytes(of:_:)` instead.
12911335
/// - Returns: The return value, if any, of the `body` closure.
12921336
@inlinable
1293-
public func withUnsafeBytes<T, Result>(
1337+
@_alwaysEmitIntoClient
1338+
public func withUnsafeBytes<T, E: Error, Result>(
1339+
of value: T,
1340+
_ body: (UnsafeRawBufferPointer) throws(E) -> Result
1341+
) throws(E) -> Result {
1342+
let addr = UnsafeRawPointer(Builtin.addressOfBorrow(value))
1343+
return try body(.init(start: addr, count: MemoryLayout<T>.size))
1344+
}
1345+
1346+
/// ABI: Historical withUnsafeBytes(of:_:) rethrows,
1347+
/// expressed as "throws", which is ABI-compatible with "rethrows".
1348+
@_silgen_name("$ss15withUnsafeBytes2of_q_x_q_SWKXEtKr0_lF")
1349+
@usableFromInline
1350+
func __abi_se0413_withUnsafeBytes<T, Result>(
12941351
of value: T,
12951352
_ body: (UnsafeRawBufferPointer) throws -> Result
1296-
) rethrows -> Result {
1353+
) throws -> Result {
12971354
let addr = UnsafeRawPointer(Builtin.addressOfBorrow(value))
12981355
let buffer = UnsafeRawBufferPointer(start: addr, count: MemoryLayout<T>.size)
12991356
return try body(buffer)
@@ -1305,10 +1362,10 @@ public func withUnsafeBytes<T, Result>(
13051362
/// This function is similar to `withUnsafeBytes`, except that it
13061363
/// doesn't trigger stack protection for the pointer.
13071364
@_alwaysEmitIntoClient
1308-
public func _withUnprotectedUnsafeBytes<T, Result>(
1365+
public func _withUnprotectedUnsafeBytes<T, E: Error, Result>(
13091366
of value: T,
1310-
_ body: (UnsafeRawBufferPointer) throws -> Result
1311-
) rethrows -> Result {
1367+
_ body: (UnsafeRawBufferPointer) throws(E) -> Result
1368+
) throws(E) -> Result {
13121369
#if $BuiltinUnprotectedAddressOf
13131370
let addr = UnsafeRawPointer(Builtin.unprotectedAddressOfBorrow(value))
13141371
#else

test/SILOptimizer/stack_protection.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,16 @@ public func unprotectedUnsafeBytes() {
6464
}
6565
}
6666

67+
// CHECK-LABEL: sil @$s4test29unprotectedUnsafeMutableBytesyyF
68+
// CHECK-NOT: copy_addr
69+
// CHECK: } // end sil function '$s4test29unprotectedUnsafeMutableBytesyyF'
70+
public func unprotectedUnsafeMutableBytes() {
71+
var x = 0
72+
_withUnprotectedUnsafeMutableBytes(of: &x) {
73+
potentiallyBadCFunction($0.bindMemory(to: Int.self).baseAddress!)
74+
}
75+
}
76+
6777
// CHECK-LABEL: sil [stack_protection] @$s4test20overflowInCFunction2yyF
6878
// CHECK-NOT: copy_addr
6979
// CHECK: } // end sil function '$s4test20overflowInCFunction2yyF'

test/api-digester/Outputs/stability-stdlib-source-x86_64.swift.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ Func Sequence.map(_:) is now without @rethrows
4343
Constructor Result.init(catching:) has generic signature change from <Success, Failure where Failure == any Swift.Error> to <Success, Failure where Failure : Swift.Error>
4444
Func withUnsafePointer(to:_:) has generic signature change from <T, Result> to <T, E, Result where E : Swift.Error>
4545
Func withUnsafePointer(to:_:) is now without @rethrows
46+
Func withUnsafeBytes(of:_:) has generic signature change from <T, Result> to <T, E, Result where E : Swift.Error>
47+
Func withUnsafeBytes(of:_:) is now without @rethrows
48+
Func withUnsafeMutableBytes(of:_:) has generic signature change from <T, Result> to <T, E, Result where E : Swift.Error>
49+
Func withUnsafeMutableBytes(of:_:) is now without @rethrows
4650
Func withoutActuallyEscaping(_:do:) has generic signature change from <ClosureType, ResultType> to <ClosureType, ResultType, Failure where Failure : Swift.Error>
4751
Func withoutActuallyEscaping(_:do:) is now without @rethrows
4852

test/api-digester/stability-stdlib-abi-without-asserts.test

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,13 @@ Func withUnsafePointer(to:_:) has mangled name changing from 'Swift.withUnsafePo
110110
Func withUnsafePointer(to:_:) has been renamed to Func __abi_se0413_withUnsafePointer(to:_:)
111111
Func withUnsafePointer(to:_:) has mangled name changing from 'Swift.withUnsafePointer<A, B>(to: inout A, _: (Swift.UnsafePointer<A>) throws -> B) throws -> B' to 'Swift.__abi_se0413_withUnsafePointer<A, B>(to: inout A, _: (Swift.UnsafePointer<A>) throws -> B) throws -> B'
112112
Func withUnsafePointer(to:_:) is now without @rethrows
113+
Func withUnsafeBytes(of:_:) has been renamed to Func __abi_se0413_withUnsafeBytes(of:_:)
114+
Func withUnsafeBytes(of:_:) has mangled name changing from 'Swift.withUnsafeBytes<A, B>(of: A, _: (Swift.UnsafeRawBufferPointer) throws -> B) throws -> B' to 'Swift.__abi_se0413_withUnsafeBytes<A, B>(of: A, _: (Swift.UnsafeRawBufferPointer) throws -> B) throws -> B'
115+
Func withUnsafeBytes(of:_:) has mangled name changing from 'Swift.withUnsafeBytes<A, B>(of: inout A, _: (Swift.UnsafeRawBufferPointer) throws -> B) throws -> B' to 'Swift.__abi_se0413_withUnsafeBytes<A, B>(of: inout A, _: (Swift.UnsafeRawBufferPointer) throws -> B) throws -> B'
116+
Func withUnsafeBytes(of:_:) is now without @rethrows
117+
Func withUnsafeMutableBytes(of:_:) has been renamed to Func __abi_se0413_withUnsafeMutableBytes(of:_:)
118+
Func withUnsafeMutableBytes(of:_:) has mangled name changing from 'Swift.withUnsafeMutableBytes<A, B>(of: inout A, _: (Swift.UnsafeMutableRawBufferPointer) throws -> B) throws -> B' to 'Swift.__abi_se0413_withUnsafeMutableBytes<A, B>(of: inout A, _: (Swift.UnsafeMutableRawBufferPointer) throws -> B) throws -> B'
119+
Func withUnsafeMutableBytes(of:_:) is now without @rethrows
113120
Func withoutActuallyEscaping(_:do:) has been renamed to Func __abi_withoutActuallyEscaping(_:do:)
114121
Func withoutActuallyEscaping(_:do:) has mangled name changing from 'Swift.withoutActuallyEscaping<A, B>(_: A, do: (A) throws -> B) throws -> B' to 'Swift.__abi_withoutActuallyEscaping<A, B>(_: A, do: (A) throws -> B) throws -> B'
115122
Func withoutActuallyEscaping(_:do:) is now without @rethrows

0 commit comments

Comments
 (0)