Skip to content

Commit 1828aca

Browse files
committed
[stdlib] update UnsafeMutableRawBufferPointer.storeBytes
- preserve previous version for ABI and source stability. - add new version without alignment restriction. - add explicit POD type enforcement in new version.
1 parent 4b3e7fa commit 1828aca

File tree

1 file changed

+31
-1
lines changed

1 file changed

+31
-1
lines changed

stdlib/public/core/UnsafeRawBufferPointer.swift.gyb

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,16 @@ extension Unsafe${Mutable}RawBufferPointer {
442442
/// type `U`. Calling `storeBytes(of:toByteOffset:as:)` does not change the
443443
/// bound type of the memory.
444444
///
445+
/// - Note: A trivial type can be copied with just a bit-for-bit copy without
446+
/// any indirection or reference-counting operations. Generally, native
447+
/// Swift types that do not contain strong or weak references or other
448+
/// forms of indirection are trivial, as are imported C structs and enums.
449+
///
450+
/// If you need to store into memory a copy of a value of a type that isn't
451+
/// trivial, you cannot use the `storeBytes(of:toByteOffset:as:)` method.
452+
/// Instead, you must know either initialize the memory or,
453+
/// if you know the memory was already bound to `type`, assign to the memory.
454+
///
445455
/// - Parameters:
446456
/// - value: The value to store as raw bytes.
447457
/// - offset: The offset in bytes into the buffer pointer's memory to begin
@@ -452,14 +462,34 @@ extension Unsafe${Mutable}RawBufferPointer {
452462
/// must be initialized to a value of a type that is layout compatible
453463
/// with `type`.
454464
@inlinable
465+
@_alwaysEmitIntoClient
466+
@_silgen_name("_swift_seNNNN_UnsafeMutableRawBufferPointer_storeBytes")
455467
public func storeBytes<T>(
456468
of value: T, toByteOffset offset: Int = 0, as type: T.Type
457469
) {
458470
_debugPrecondition(offset >= 0, "${Self}.storeBytes with negative offset")
459471
_debugPrecondition(offset + MemoryLayout<T>.size <= self.count,
460472
"${Self}.storeBytes out of bounds")
461473

462-
baseAddress!.storeBytes(of: value, toByteOffset: offset, as: T.self)
474+
let pointer = baseAddress._unsafelyUnwrappedUnchecked
475+
pointer.storeBytes(of: value, toByteOffset: offset, as: T.self)
476+
}
477+
478+
// This unavailable implementation uses the expected mangled name
479+
// of `storeBytes<T>(of:toByteOffset:as:)`, and provides an entry point for
480+
// any binary compiled against the stlib binary for Swift 5.6 and older.
481+
@available(*, unavailable)
482+
@_silgen_name("$sSw10storeBytes2of12toByteOffset2asyx_SixmtlF")
483+
@usableFromInline func _legacy_se0349_storeBytes<T>(
484+
of value: T, toByteOffset offset: Int = 0, as type: T.Type
485+
) {
486+
_debugPrecondition(offset >= 0, "${Self}.storeBytes with negative offset")
487+
_debugPrecondition(offset + MemoryLayout<T>.size <= self.count,
488+
"${Self}.storeBytes out of bounds")
489+
490+
baseAddress!._legacy_se0349_storeBytes_internal(
491+
of: value, toByteOffset: offset, as: T.self
492+
)
463493
}
464494

465495
/// Copies the bytes from the given buffer to this buffer's memory.

0 commit comments

Comments
 (0)