This precondition checks to make sure that the content-providing
collection isn't larger than the allocated buffer, but was preventing
using a buffer that is the exact same size as the collection.
This isn't a "complete" port of the standard library for embedded Swift, but
something that should serve as a starting point for further iterations on the
stdlib.
- General CMake logic for building a library as ".swiftmodule only" (ONLY_SWIFTMODULE).
- CMake logic in stdlib/public/core/CMakeLists.txt to start building the embedded stdlib for a handful of hardcoded target triples.
- Lots of annotations throughout the standard library to make types, functions, protocols unavailable in embedded Swift (@_unavailableInEmbedded).
- Mainly this is about stdlib functionality that relies on existentials, type erasure, metatypes, reflection, string interpolations.
- We rely on function body removal of unavailable functions to eliminate the actual problematic SIL code (existentials).
- Many .swift files are not included in the compilation of embedded stdlib at all, to simplify the scope of the annotations.
- EmbeddedStubs.swift is used to stub out (as unavailable and fatalError'd) the missing functionality.
Swift tends to emit unnecessary checks and traps when iterating unsafe
raw buffer pointers. These traps are confirming that the position
pointer isn't nil, but this check is redundant with the bounds check
that is already present. We can safely remove it.
We trust the internal implementation of the stdlib to not cause any unintentional buffer overflows.
In such cases we can use the "unprotected" address-to-pointer conversions.
This avoids inserting stack protections where it's not needed.
Those functions work the same way as their "unprotected" counterparts, except that they don't trigger stack protection for the pointers.
* `_withUnprotectedUnsafeMutablePointer`
* `_withUnprotectedUnsafePointer`
* `_withUnprotectedUnsafeBytes` (two times)
- preserve previous version for ABI and source stability.
- add new version without alignment restriction.
- add explicit POD type enforcement in new version.
Here, as in UnsafeMutableRawPointer.storeBytes(of:toByteOffset:as:)
"as" is an argument label and "type" is the parameter.
Because the function body doesn't use this -- it's just for type
information -- changing its name from "as" to "type" doesn't have
any impact there.
- The previous implementation trapped when the source buffer was empty. That behaviour is both not documented and unnecessary. If the source buffer is empty, its length is necessarily shorter or equal than the length of the destination.
- The updated version simply returns when the source buffer is empty.
To send them across actors, they need to be wrapped in an '@unchecked
Sendable' type. Typically such a wrapper type would be be responsible
for ensuring its uniqueness or immutability.
Inferring Sendability for arbitrary types that contain Unsafe*Pointers
would introduce race conditions without warning or any explicit
acknoledgement from the programmer that the pointer is in fact unique.
We have already done the hard work of unwrapping the optionals
that represent the first and last pointer, and calling `self.count` does it all over again. Use the distance between the unwrapped pointers instead.