Skip to content

Commit 302e106

Browse files
authored
Merge pull request #70458 from kubamracek/embedded-random
[embedded] Make RNG APIs available on embedded Swift
2 parents 74d2127 + 26c1067 commit 302e106

12 files changed

+122
-20
lines changed

stdlib/public/core/Bool.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,6 @@ public struct Bool: Sendable {
133133
/// - Returns: Either `true` or `false`, randomly chosen with equal
134134
/// probability.
135135
@inlinable
136-
@_unavailableInEmbedded
137136
public static func random() -> Bool {
138137
var g = SystemRandomNumberGenerator()
139138
return Bool.random(using: &g)

stdlib/public/core/Collection.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -951,7 +951,6 @@ extension Collection {
951951
/// `RandomAccessCollection`; otherwise, O(*n*), where *n* is the length
952952
/// of the collection.
953953
@inlinable
954-
@_unavailableInEmbedded
955954
public func randomElement() -> Element? {
956955
var g = SystemRandomNumberGenerator()
957956
return randomElement(using: &g)

stdlib/public/core/CollectionAlgorithms.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,6 @@ extension Sequence {
571571
///
572572
/// - Complexity: O(*n*), where *n* is the length of the sequence.
573573
@inlinable
574-
@_unavailableInEmbedded
575574
public func shuffled() -> [Element] {
576575
var g = SystemRandomNumberGenerator()
577576
return shuffled(using: &g)
@@ -630,7 +629,6 @@ extension MutableCollection where Self: RandomAccessCollection {
630629
///
631630
/// - Complexity: O(*n*), where *n* is the length of the collection.
632631
@inlinable
633-
@_unavailableInEmbedded
634632
public mutating func shuffle() {
635633
var g = SystemRandomNumberGenerator()
636634
shuffle(using: &g)

stdlib/public/core/FloatingPointRandom.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,6 @@ extension BinaryFloatingPoint where Self.RawSignificand: FixedWidthInteger {
108108
/// `range` must be finite and non-empty.
109109
/// - Returns: A random value within the bounds of `range`.
110110
@inlinable
111-
@_unavailableInEmbedded
112111
public static func random(in range: Range<Self>) -> Self {
113112
var g = SystemRandomNumberGenerator()
114113
return Self.random(in: range, using: &g)
@@ -209,7 +208,6 @@ extension BinaryFloatingPoint where Self.RawSignificand: FixedWidthInteger {
209208
/// - Parameter range: The range in which to create a random value. Must be finite.
210209
/// - Returns: A random value within the bounds of `range`.
211210
@inlinable
212-
@_unavailableInEmbedded
213211
public static func random(in range: ClosedRange<Self>) -> Self {
214212
var g = SystemRandomNumberGenerator()
215213
return Self.random(in: range, using: &g)

stdlib/public/core/Integers.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2694,7 +2694,6 @@ extension FixedWidthInteger {
26942694
/// `range` must not be empty.
26952695
/// - Returns: A random value within the bounds of `range`.
26962696
@inlinable
2697-
@_unavailableInEmbedded
26982697
public static func random(in range: Range<Self>) -> Self {
26992698
var g = SystemRandomNumberGenerator()
27002699
return Self.random(in: range, using: &g)
@@ -2767,7 +2766,6 @@ extension FixedWidthInteger {
27672766
/// - Parameter range: The range in which to create a random value.
27682767
/// - Returns: A random value within the bounds of `range`.
27692768
@inlinable
2770-
@_unavailableInEmbedded
27712769
public static func random(in range: ClosedRange<Self>) -> Self {
27722770
var g = SystemRandomNumberGenerator()
27732771
return Self.random(in: range, using: &g)

stdlib/public/core/Random.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,6 @@ extension RandomNumberGenerator {
147147
/// from `/dev/urandom`.
148148
/// - Windows uses `BCryptGenRandom`.
149149
@frozen
150-
@_unavailableInEmbedded
151150
public struct SystemRandomNumberGenerator: RandomNumberGenerator, Sendable {
152151
/// Creates a new instance of the system's default random number generator.
153152
@inlinable

stdlib/public/core/SIMDVector.swift

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,6 @@ extension SIMD where Scalar: FixedWidthInteger {
565565

566566
/// Returns a vector with random values from within the specified range in
567567
/// all lanes, using the given generator as a source for randomness.
568-
@_unavailableInEmbedded
569568
@inlinable
570569
public static func random<T: RandomNumberGenerator>(
571570
in range: Range<Scalar>,
@@ -580,7 +579,6 @@ extension SIMD where Scalar: FixedWidthInteger {
580579

581580
/// Returns a vector with random values from within the specified range in
582581
/// all lanes.
583-
@_unavailableInEmbedded
584582
@inlinable
585583
public static func random(in range: Range<Scalar>) -> Self {
586584
var g = SystemRandomNumberGenerator()
@@ -589,7 +587,6 @@ extension SIMD where Scalar: FixedWidthInteger {
589587

590588
/// Returns a vector with random values from within the specified range in
591589
/// all lanes, using the given generator as a source for randomness.
592-
@_unavailableInEmbedded
593590
@inlinable
594591
public static func random<T: RandomNumberGenerator>(
595592
in range: ClosedRange<Scalar>,
@@ -604,7 +601,6 @@ extension SIMD where Scalar: FixedWidthInteger {
604601

605602
/// Returns a vector with random values from within the specified range in
606603
/// all lanes.
607-
@_unavailableInEmbedded
608604
@inlinable
609605
public static func random(in range: ClosedRange<Scalar>) -> Self {
610606
var g = SystemRandomNumberGenerator()
@@ -637,7 +633,6 @@ extension SIMD where Scalar: FloatingPoint {
637633
}
638634
}
639635

640-
@_unavailableInEmbedded
641636
extension SIMD
642637
where Scalar: BinaryFloatingPoint, Scalar.RawSignificand: FixedWidthInteger {
643638
/// Returns a vector with random values from within the specified range in
@@ -725,7 +720,6 @@ public struct SIMDMask<Storage>: SIMD
725720
}
726721
}
727722

728-
@_unavailableInEmbedded
729723
extension SIMDMask {
730724
/// Returns a vector mask with `true` or `false` randomly assigned in each
731725
/// lane, using the given generator as a source for randomness.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#include <stdlib.h>
2+
#include <stdio.h>
3+
#include <errno.h>
4+
#include <stdint.h>
5+
6+
#ifdef __linux__
7+
8+
ssize_t getrandom(void *buf, size_t len, unsigned int flags);
9+
10+
void arc4random_buf(void *buf, size_t nbytes) {
11+
while (nbytes > 0) {
12+
ssize_t actual_nbytes = 0;
13+
do {
14+
actual_nbytes = getrandom(buf, nbytes, 0);
15+
} while (actual_nbytes == -1 && errno == EINTR);
16+
17+
if (actual_nbytes == -1) {
18+
abort();
19+
}
20+
21+
buf = (uint8_t *)(buf) + actual_nbytes;
22+
nbytes -= actual_nbytes;
23+
}
24+
}
25+
26+
#endif
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -parse-as-library -enable-experimental-feature Embedded %s -c -o %t/a.o
3+
4+
// RUN: grep DEP\: %s | sed 's#// DEP\: ##' | sort > %t/allowed-dependencies.txt
5+
6+
// Linux/ELF doesn't use the "_" prefix in symbol mangling.
7+
// RUN: if [ %target-os == "linux-gnu" ]; then sed -E -i -e 's/^_(.*)$/\1/' %t/allowed-dependencies.txt; fi
8+
9+
// RUN: %llvm-nm --undefined-only --format=just-symbols %t/a.o | sort | tee %t/actual-dependencies.txt
10+
11+
// Fail if there is any entry in actual-dependencies.txt that's not in allowed-dependencies.txt
12+
// RUN: test -z "`comm -13 %t/allowed-dependencies.txt %t/actual-dependencies.txt`"
13+
14+
// DEP: ___stack_chk_fail
15+
// DEP: ___stack_chk_guard
16+
// DEP: _arc4random_buf
17+
// DEP: _free
18+
// DEP: _memset
19+
// DEP: _putchar
20+
// DEP: _posix_memalign
21+
22+
// RUN: %target-clang -x c -c %S/Inputs/print.c -o %t/print.o
23+
// RUN: %target-clang -x c -c %S/Inputs/linux-rng-support.c -o %t/linux-rng-support.o
24+
// RUN: %target-clang %t/a.o %t/print.o %t/linux-rng-support.o -o %t/a.out
25+
// RUN: %target-run %t/a.out | %FileCheck %s
26+
27+
// REQUIRES: swift_in_compiler
28+
// REQUIRES: executable_test
29+
// REQUIRES: optimized_stdlib
30+
// REQUIRES: OS=macosx || OS=linux-gnu
31+
// UNSUPPORTED: OS=linux-gnu && CPU=aarch64
32+
33+
@_silgen_name("putchar")
34+
@discardableResult
35+
func putchar(_: CInt) -> CInt
36+
37+
public func print(_ s: StaticString, terminator: StaticString = "\n") {
38+
var p = s.utf8Start
39+
while p.pointee != 0 {
40+
putchar(CInt(p.pointee))
41+
p += 1
42+
}
43+
p = terminator.utf8Start
44+
while p.pointee != 0 {
45+
putchar(CInt(p.pointee))
46+
p += 1
47+
}
48+
}
49+
50+
class MyClass {
51+
func foo() { print("MyClass.foo") }
52+
}
53+
54+
class MySubClass: MyClass {
55+
override func foo() { print("MySubClass.foo") }
56+
}
57+
58+
@main
59+
struct Main {
60+
static var objects: [MyClass] = []
61+
static func main() {
62+
print("Hello Embedded Swift!")
63+
// CHECK: Hello Embedded Swift!
64+
objects.append(MyClass())
65+
objects.append(MySubClass())
66+
for o in objects {
67+
o.foo()
68+
}
69+
// CHECK: MyClass.foo
70+
// CHECK: MySubClass.foo
71+
print(Bool.random() ? "you won" : "you lost")
72+
// CHECK: you {{won|lost}}
73+
}
74+
}

test/embedded/stdlib-array.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ public func test() {
2121
array.max()
2222
array.partition(by: { $0 > 0 })
2323
array.reduce(0, +)
24-
// array.shuffle()
25-
// array = array.shuffled()
26-
// array.randomElement()
24+
array.shuffle()
25+
array = array.shuffled()
26+
array.randomElement()
2727
}
2828

2929
test()

0 commit comments

Comments
 (0)