mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[embedded] Add Set to the embedded stdlib
This commit is contained in:
@@ -31,9 +31,15 @@ internal struct _BridgeStorage<NativeClass: AnyObject> {
|
||||
|
||||
// rawValue is passed inout to _isUnique. Although its value
|
||||
// is unchanged, it must appear mutable to the optimizer.
|
||||
#if !$Embedded
|
||||
@usableFromInline
|
||||
internal var rawValue: Builtin.BridgeObject
|
||||
#else
|
||||
@usableFromInline
|
||||
internal var rawValue: NativeClass
|
||||
#endif
|
||||
|
||||
#if !$Embedded
|
||||
@inlinable
|
||||
@inline(__always)
|
||||
internal init(native: Native, isFlagged flag: Bool) {
|
||||
@@ -46,13 +52,16 @@ internal struct _BridgeStorage<NativeClass: AnyObject> {
|
||||
native,
|
||||
flag ? (1 as UInt) << _objectPointerLowSpareBitShift : 0)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if _runtime(_ObjC)
|
||||
@inlinable
|
||||
@inline(__always)
|
||||
internal init(objC: ObjC) {
|
||||
_internalInvariant(_usesNativeSwiftReferenceCounting(NativeClass.self))
|
||||
rawValue = _makeObjCBridgeObject(objC)
|
||||
}
|
||||
#endif
|
||||
|
||||
@inlinable
|
||||
@inline(__always)
|
||||
@@ -65,7 +74,7 @@ internal struct _BridgeStorage<NativeClass: AnyObject> {
|
||||
@inlinable
|
||||
@inline(__always)
|
||||
internal init(taggedPayload: UInt) {
|
||||
rawValue = _bridgeObject(taggingPayload: taggedPayload)
|
||||
rawValue = Builtin.reinterpretCast(taggedPayload)
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -84,9 +93,13 @@ internal struct _BridgeStorage<NativeClass: AnyObject> {
|
||||
@inlinable
|
||||
internal var isNative: Bool {
|
||||
@inline(__always) get {
|
||||
#if !$Embedded
|
||||
let result = Builtin.classifyBridgeObject(rawValue)
|
||||
return !Bool(Builtin.or_Int1(result.isObjCObject,
|
||||
result.isObjCTaggedPointer))
|
||||
#else
|
||||
return true
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,9 +113,13 @@ internal struct _BridgeStorage<NativeClass: AnyObject> {
|
||||
@inlinable
|
||||
internal var isUnflaggedNative: Bool {
|
||||
@inline(__always) get {
|
||||
#if !$Embedded
|
||||
return (_bitPattern(rawValue) &
|
||||
(_bridgeObjectTaggedPointerBits | _objCTaggedPointerBits |
|
||||
_objectPointerIsObjCBit | _BridgeStorage.flagMask)) == 0
|
||||
#else
|
||||
return true
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +134,7 @@ internal struct _BridgeStorage<NativeClass: AnyObject> {
|
||||
internal var nativeInstance: Native {
|
||||
@inline(__always) get {
|
||||
_internalInvariant(isNative)
|
||||
return Builtin.castReferenceFromBridgeObject(rawValue)
|
||||
return rawValue
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,8 +142,10 @@ internal struct _BridgeStorage<NativeClass: AnyObject> {
|
||||
internal var unflaggedNativeInstance: Native {
|
||||
@inline(__always) get {
|
||||
_internalInvariant(isNative)
|
||||
#if !$Embedded
|
||||
_internalInvariant(_nonPointerBits(rawValue) == 0)
|
||||
return Builtin.reinterpretCast(rawValue)
|
||||
#endif
|
||||
return rawValue
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,6 +170,7 @@ internal struct _BridgeStorage<NativeClass: AnyObject> {
|
||||
Builtin.endCOWMutation(&rawValue)
|
||||
}
|
||||
|
||||
#if _runtime(_ObjC)
|
||||
@inlinable
|
||||
internal var objCInstance: ObjC {
|
||||
@inline(__always) get {
|
||||
@@ -158,4 +178,5 @@ internal struct _BridgeStorage<NativeClass: AnyObject> {
|
||||
return Builtin.castReferenceFromBridgeObject(rawValue)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -725,9 +725,11 @@ func _isUnique_native<T>(_ object: inout T) -> Bool {
|
||||
// This could be a bridge object, single payload enum, or plain old
|
||||
// reference. Any case it's non pointer bits must be zero, so
|
||||
// force cast it to BridgeObject and check the spare bits.
|
||||
#if !$Embedded
|
||||
_internalInvariant(
|
||||
(_bitPattern(Builtin.reinterpretCast(object)) & _objectPointerSpareBits)
|
||||
== 0)
|
||||
#endif
|
||||
_internalInvariant(_usesNativeSwiftReferenceCounting(
|
||||
type(of: Builtin.reinterpretCast(object) as AnyObject)))
|
||||
return Bool(Builtin.isUnique_native(&object))
|
||||
|
||||
@@ -43,10 +43,10 @@ split_embedded_sources(
|
||||
EMBEDDED Assert.swift
|
||||
EMBEDDED AssertCommon.swift
|
||||
EMBEDDED BidirectionalCollection.swift
|
||||
NORMAL Bitset.swift
|
||||
EMBEDDED Bitset.swift
|
||||
EMBEDDED Bool.swift
|
||||
NORMAL BridgeObjectiveC.swift
|
||||
NORMAL BridgeStorage.swift
|
||||
EMBEDDED BridgeStorage.swift
|
||||
NORMAL BridgingBuffer.swift
|
||||
EMBEDDED Builtin.swift
|
||||
EMBEDDED BuiltinMath.swift
|
||||
@@ -89,7 +89,7 @@ split_embedded_sources(
|
||||
# END WORKAROUND
|
||||
EMBEDDED Hasher.swift
|
||||
NORMAL Hashing.swift
|
||||
NORMAL HashTable.swift
|
||||
EMBEDDED HashTable.swift
|
||||
EMBEDDED Identifiable.swift
|
||||
EMBEDDED Indices.swift
|
||||
NORMAL InputStream.swift
|
||||
@@ -111,7 +111,7 @@ split_embedded_sources(
|
||||
EMBEDDED Misc.swift
|
||||
EMBEDDED MutableCollection.swift
|
||||
NORMAL NativeDictionary.swift
|
||||
NORMAL NativeSet.swift
|
||||
EMBEDDED NativeSet.swift
|
||||
NORMAL NewtypeWrapper.swift
|
||||
NORMAL NFC.swift
|
||||
NORMAL NFD.swift
|
||||
@@ -139,15 +139,15 @@ split_embedded_sources(
|
||||
EMBEDDED SipHash.swift
|
||||
EMBEDDED Sequence.swift
|
||||
EMBEDDED SequenceAlgorithms.swift
|
||||
NORMAL Set.swift
|
||||
EMBEDDED Set.swift
|
||||
EMBEDDED SetAlgebra.swift
|
||||
NORMAL SetAnyHashableExtensions.swift
|
||||
NORMAL SetBridging.swift
|
||||
NORMAL SetBuilder.swift
|
||||
NORMAL SetCasting.swift
|
||||
NORMAL SetStorage.swift
|
||||
NORMAL SetVariant.swift
|
||||
NORMAL ShadowProtocols.swift
|
||||
EMBEDDED SetBuilder.swift
|
||||
EMBEDDED SetCasting.swift
|
||||
EMBEDDED SetStorage.swift
|
||||
EMBEDDED SetVariant.swift
|
||||
EMBEDDED ShadowProtocols.swift
|
||||
NORMAL Shims.swift
|
||||
EMBEDDED Slice.swift
|
||||
NORMAL SmallString.swift
|
||||
|
||||
@@ -275,3 +275,10 @@ public func swift_deletedMethodError() -> Never {
|
||||
public func swift_willThrow() throws {
|
||||
}
|
||||
|
||||
@_silgen_name("arc4random_buf")
|
||||
public func arc4random_buf(buf: UnsafeMutableRawPointer, nbytes: Int)
|
||||
|
||||
@_silgen_name("swift_stdlib_random")
|
||||
public func swift_stdlib_random(_ buf: UnsafeMutableRawPointer, _ nbytes: Int) {
|
||||
arc4random_buf(buf: buf, nbytes: nbytes)
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ extension _HashTable {
|
||||
}
|
||||
|
||||
internal static func hashSeed(
|
||||
for object: AnyObject,
|
||||
for object: Builtin.NativeObject,
|
||||
scale: Int8
|
||||
) -> Int {
|
||||
// We generate a new hash seed whenever a new hash table is allocated and
|
||||
|
||||
@@ -251,6 +251,16 @@ extension Hasher {
|
||||
}
|
||||
}
|
||||
|
||||
#if $Embedded
|
||||
@usableFromInline
|
||||
var _swift_stdlib_Hashing_parameters: _SwiftHashingParameters = {
|
||||
var seed0: UInt64 = 0, seed1: UInt64 = 0
|
||||
swift_stdlib_random(&seed0, MemoryLayout<UInt64>.size)
|
||||
swift_stdlib_random(&seed1, MemoryLayout<UInt64>.size)
|
||||
return .init(seed0: seed0, seed1: seed1, deterministic: false)
|
||||
}()
|
||||
#endif
|
||||
|
||||
/// The universal hash function used by `Set` and `Dictionary`.
|
||||
///
|
||||
/// `Hasher` can be used to map an arbitrary sequence of bytes to an integer
|
||||
|
||||
@@ -351,6 +351,7 @@ extension _NativeSet: _SetBuffer {
|
||||
// This function has a highly visible name to make it stand out in stack traces.
|
||||
@usableFromInline
|
||||
@inline(never)
|
||||
@_unavailableInEmbedded
|
||||
internal func ELEMENT_TYPE_OF_SET_VIOLATES_HASHABLE_REQUIREMENTS(
|
||||
_ elementType: Any.Type
|
||||
) -> Never {
|
||||
@@ -379,7 +380,11 @@ extension _NativeSet { // Insertions
|
||||
// because we'll need to compare elements in case of hash collisions.
|
||||
let (bucket, found) = find(element, hashValue: hashValue)
|
||||
guard !found else {
|
||||
#if !$Embedded
|
||||
ELEMENT_TYPE_OF_SET_VIOLATES_HASHABLE_REQUIREMENTS(Element.self)
|
||||
#else
|
||||
fatalError("duplicate elements in a Set")
|
||||
#endif
|
||||
}
|
||||
hashTable.insert(bucket)
|
||||
uncheckedInitialize(at: bucket, to: element)
|
||||
@@ -418,7 +423,11 @@ extension _NativeSet { // Insertions
|
||||
if rehashed {
|
||||
let (b, f) = find(element)
|
||||
if f {
|
||||
#if !$Embedded
|
||||
ELEMENT_TYPE_OF_SET_VIOLATES_HASHABLE_REQUIREMENTS(Element.self)
|
||||
#else
|
||||
fatalError("duplicate elements in a Set")
|
||||
#endif
|
||||
}
|
||||
bucket = b
|
||||
}
|
||||
@@ -437,7 +446,11 @@ extension _NativeSet { // Insertions
|
||||
if rehashed {
|
||||
let (b, f) = find(element)
|
||||
if f != found {
|
||||
#if !$Embedded
|
||||
ELEMENT_TYPE_OF_SET_VIOLATES_HASHABLE_REQUIREMENTS(Element.self)
|
||||
#else
|
||||
fatalError("duplicate elements in a Set")
|
||||
#endif
|
||||
}
|
||||
bucket = b
|
||||
}
|
||||
|
||||
@@ -448,12 +448,14 @@ extension Set: Hashable {
|
||||
}
|
||||
}
|
||||
|
||||
@_unavailableInEmbedded
|
||||
extension Set: _HasCustomAnyHashableRepresentation {
|
||||
public __consuming func _toCustomAnyHashable() -> AnyHashable? {
|
||||
return AnyHashable(_box: _SetAnyHashableBox(self))
|
||||
}
|
||||
}
|
||||
|
||||
@_unavailableInEmbedded
|
||||
internal struct _SetAnyHashableBox<Element: Hashable>: _AnyHashableBox {
|
||||
internal let _value: Set<Element>
|
||||
internal let _canonical: Set<AnyHashable>
|
||||
@@ -1034,6 +1036,7 @@ extension Set: SetAlgebra {
|
||||
}
|
||||
}
|
||||
|
||||
@_unavailableInEmbedded
|
||||
extension Set: CustomStringConvertible, CustomDebugStringConvertible {
|
||||
/// A string that represents the contents of the set.
|
||||
public var description: String {
|
||||
|
||||
@@ -41,6 +41,7 @@ extension Set {
|
||||
/// - Precondition: `BaseValue` is a base class or base `@objc`
|
||||
/// protocol (such as `AnyObject`) of `DerivedValue`.
|
||||
@inlinable
|
||||
@_unavailableInEmbedded
|
||||
public func _setUpCast<DerivedValue, BaseValue>(
|
||||
_ source: Set<DerivedValue>
|
||||
) -> Set<BaseValue> {
|
||||
@@ -57,6 +58,7 @@ public func _setUpCast<DerivedValue, BaseValue>(
|
||||
|
||||
/// Called by the casting machinery.
|
||||
@_silgen_name("_swift_setDownCastIndirect")
|
||||
@_unavailableInEmbedded
|
||||
internal func _setDownCastIndirect<SourceValue, TargetValue>(
|
||||
_ source: UnsafePointer<Set<SourceValue>>,
|
||||
_ target: UnsafeMutablePointer<Set<TargetValue>>) {
|
||||
@@ -71,6 +73,7 @@ internal func _setDownCastIndirect<SourceValue, TargetValue>(
|
||||
/// - Precondition: `DerivedValue` is a subtype of `BaseValue` and both
|
||||
/// are reference types.
|
||||
@inlinable
|
||||
@_unavailableInEmbedded
|
||||
public func _setDownCast<BaseValue, DerivedValue>(_ source: Set<BaseValue>)
|
||||
-> Set<DerivedValue> {
|
||||
|
||||
@@ -99,6 +102,7 @@ public func _setDownCast<BaseValue, DerivedValue>(_ source: Set<BaseValue>)
|
||||
|
||||
/// Called by the casting machinery.
|
||||
@_silgen_name("_swift_setDownCastConditionalIndirect")
|
||||
@_unavailableInEmbedded
|
||||
internal func _setDownCastConditionalIndirect<SourceValue, TargetValue>(
|
||||
_ source: UnsafePointer<Set<SourceValue>>,
|
||||
_ target: UnsafeMutablePointer<Set<TargetValue>>
|
||||
@@ -118,6 +122,7 @@ internal func _setDownCastConditionalIndirect<SourceValue, TargetValue>(
|
||||
/// - Precondition: `DerivedValue` is a subtype of `BaseValue` and both
|
||||
/// are reference types.
|
||||
@inlinable
|
||||
@_unavailableInEmbedded
|
||||
public func _setDownCastConditional<BaseValue, DerivedValue>(
|
||||
_ source: Set<BaseValue>
|
||||
) -> Set<DerivedValue>? {
|
||||
|
||||
@@ -127,6 +127,22 @@ internal class __EmptySetSingleton: __RawSetStorage {
|
||||
#endif
|
||||
}
|
||||
|
||||
#if $Embedded
|
||||
public var _swiftEmptySetSingleton: (Int, Int, Int, Int, UInt8, UInt8, UInt16, UInt32, Int, Int, Int) =
|
||||
(
|
||||
/*isa*/0, /*refcount*/-1, // HeapObject header
|
||||
/*count*/0,
|
||||
/*capacity*/0,
|
||||
/*scale*/0,
|
||||
/*reservedScale*/0,
|
||||
/*extra*/0,
|
||||
/*age*/0,
|
||||
/*seed*/0,
|
||||
/*rawElements*/1,
|
||||
/*metadata*/-1
|
||||
)
|
||||
#endif
|
||||
|
||||
extension __RawSetStorage {
|
||||
/// The empty singleton that is used for every single Set that is created
|
||||
/// without any elements. The contents of the storage must never be mutated.
|
||||
@@ -364,7 +380,7 @@ extension _SetStorage {
|
||||
truncatingIfNeeded: ObjectIdentifier(storage).hashValue)
|
||||
}
|
||||
|
||||
storage._seed = seed ?? _HashTable.hashSeed(for: storage, scale: scale)
|
||||
storage._seed = seed ?? _HashTable.hashSeed(for: Builtin.castToNativeObject(storage), scale: scale)
|
||||
storage._rawElements = UnsafeMutableRawPointer(elementsAddr)
|
||||
|
||||
// Initialize hash table metadata.
|
||||
|
||||
@@ -88,6 +88,7 @@ internal func _isStackAllocationSafe(byteCount: Int, alignment: Int) -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
#if !$Embedded
|
||||
// Finally, take a slow path through the standard library to see if the
|
||||
// current environment can accept a larger stack allocation.
|
||||
guard #available(macOS 12.3, iOS 15.4, watchOS 8.5, tvOS 15.4, *) //SwiftStdlib 5.6
|
||||
@@ -95,6 +96,10 @@ internal func _isStackAllocationSafe(byteCount: Int, alignment: Int) -> Bool {
|
||||
return false
|
||||
}
|
||||
return swift_stdlib_isStackAllocationSafe(byteCount, alignment)
|
||||
#else
|
||||
return false
|
||||
#endif
|
||||
|
||||
#else
|
||||
fatalError("unsupported compiler")
|
||||
#endif
|
||||
|
||||
30
test/embedded/set-runtime.swift
Normal file
30
test/embedded/set-runtime.swift
Normal file
@@ -0,0 +1,30 @@
|
||||
// RUN: %target-run-simple-swift(%S/Inputs/print.swift -enable-experimental-feature Embedded -runtime-compatibility-version none -wmo -Xfrontend -disable-objc-interop) | %FileCheck %s
|
||||
// RUN: %target-run-simple-swift(%S/Inputs/print.swift -O -enable-experimental-feature Embedded -runtime-compatibility-version none -wmo -Xfrontend -disable-objc-interop) | %FileCheck %s
|
||||
// RUN: %target-run-simple-swift(%S/Inputs/print.swift -Osize -enable-experimental-feature Embedded -runtime-compatibility-version none -wmo -Xfrontend -disable-objc-interop) | %FileCheck %s
|
||||
|
||||
// REQUIRES: swift_in_compiler
|
||||
// REQUIRES: executable_test
|
||||
// REQUIRES: optimized_stdlib
|
||||
// REQUIRES: OS=macosx || OS=linux-gnu
|
||||
|
||||
@main
|
||||
struct Main {
|
||||
static func main() {
|
||||
var s: Set<Int> = [1, 2, 3]
|
||||
s.insert(42)
|
||||
s.sorted()
|
||||
s.allSatisfy { $0 > 0 }
|
||||
s.contains { $0 > 0 }
|
||||
s.map { $0 * 2 }
|
||||
s.filter { $0 > 0 }
|
||||
s.firstIndex(of: 42)
|
||||
s.min()
|
||||
s.max()
|
||||
s.reduce(0, +)
|
||||
// s.shuffled()
|
||||
// s.randomElement()
|
||||
print("OK!")
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: OK!
|
||||
30
test/embedded/stdlib-array.swift
Normal file
30
test/embedded/stdlib-array.swift
Normal file
@@ -0,0 +1,30 @@
|
||||
// RUN: %target-swift-frontend -target armv7-apple-none-macho -Xcc -D__MACH__ -emit-ir %s -enable-experimental-feature Embedded | %FileCheck %s
|
||||
// RUN: %target-swift-frontend -target arm64-apple-none-macho -Xcc -D__MACH__ -Xcc -D__arm64__ -Xcc -D__APPLE__ -emit-ir %s -enable-experimental-feature Embedded | %FileCheck %s
|
||||
|
||||
// REQUIRES: swift_in_compiler
|
||||
// REQUIRES: optimized_stdlib
|
||||
|
||||
public func test() {
|
||||
var array: [Int] = [1, 2, 3]
|
||||
array.append(42)
|
||||
array.append(contentsOf: [4, 5, 6])
|
||||
array = array.sorted()
|
||||
array.sort()
|
||||
array.allSatisfy { $0 > 0 }
|
||||
array.contains { $0 > 0 }
|
||||
array.map { $0 * 2 }
|
||||
array.filter { $0 > 0 }
|
||||
array.dropFirst().dropLast().drop(while: { $0 < 0 })
|
||||
array.firstIndex(of: 42)
|
||||
array.min()
|
||||
array.max()
|
||||
array.partition(by: { $0 > 0 })
|
||||
array.reduce(0, +)
|
||||
// array.shuffle()
|
||||
// array = array.shuffled()
|
||||
// array.randomElement()
|
||||
}
|
||||
|
||||
test()
|
||||
|
||||
// CHECK: define {{.*}}i32 @main(i32 %0, ptr %1)
|
||||
25
test/embedded/stdlib-set.swift
Normal file
25
test/embedded/stdlib-set.swift
Normal file
@@ -0,0 +1,25 @@
|
||||
// RUN: %target-swift-frontend -target armv7-apple-none-macho -Xcc -D__MACH__ -emit-ir %s -enable-experimental-feature Embedded | %FileCheck %s
|
||||
// RUN: %target-swift-frontend -target arm64-apple-none-macho -Xcc -D__MACH__ -Xcc -D__arm64__ -Xcc -D__APPLE__ -emit-ir %s -enable-experimental-feature Embedded | %FileCheck %s
|
||||
|
||||
// REQUIRES: swift_in_compiler
|
||||
// REQUIRES: optimized_stdlib
|
||||
|
||||
public func test() {
|
||||
var s: Set<Int> = [1, 2, 3]
|
||||
s.insert(42)
|
||||
s.sorted()
|
||||
s.allSatisfy { $0 > 0 }
|
||||
s.contains { $0 > 0 }
|
||||
s.map { $0 * 2 }
|
||||
s.filter { $0 > 0 }
|
||||
s.firstIndex(of: 42)
|
||||
s.min()
|
||||
s.max()
|
||||
s.reduce(0, +)
|
||||
// s.shuffled()
|
||||
// s.randomElement()
|
||||
}
|
||||
|
||||
test()
|
||||
|
||||
// CHECK: define {{.*}}i32 @main(i32 %0, ptr %1)
|
||||
@@ -36,6 +36,7 @@ public func test() {
|
||||
let opaque = unmanaged.toOpaque()
|
||||
let unmanaged2 = Unmanaged<MyClass>.fromOpaque(opaque)
|
||||
let o = unmanaged2.takeUnretainedValue()
|
||||
var s1: Set<Int> = [1, 2, 3]
|
||||
}
|
||||
|
||||
test()
|
||||
|
||||
Reference in New Issue
Block a user