@@ -329,29 +329,29 @@ extension __SwiftNativeNSArrayWithContiguousStorage {
329329/// buffers used for Array storage.
330330@_fixed_layout // FIXME(sil-serialize-all)
331331@usableFromInline
332- @objc internal final class __SwiftDeferredNSArray
332+ @objc internal class __SwiftDeferredNSArray
333333 : __SwiftNativeNSArrayWithContiguousStorage {
334334
335335 // This stored property should be stored at offset zero. We perform atomic
336336 // operations on it.
337337 //
338338 // Do not access this property directly.
339339 @nonobjc
340- internal var _heapBufferBridged_DoNotUse : AnyObject ?
340+ internal final var _heapBufferBridged_DoNotUse : AnyObject ?
341341
342342 // When this class is allocated inline, this property can become a
343343 // computed one.
344344 @usableFromInline
345345 @nonobjc
346- internal let _nativeStorage : __ContiguousArrayStorageBase
346+ internal final let _nativeStorage : __ContiguousArrayStorageBase
347347
348348 @nonobjc
349- internal var _heapBufferBridgedPtr : UnsafeMutablePointer < AnyObject ? > {
349+ internal final var _heapBufferBridgedPtr : UnsafeMutablePointer < AnyObject ? > {
350350 return _getUnsafePointerToStoredProperties ( self ) . assumingMemoryBound (
351351 to: Optional< AnyObject> . self )
352352 }
353353
354- internal var _heapBufferBridged : __BridgingBufferStorage ? {
354+ internal final var _heapBufferBridged : __BridgingBufferStorage ? {
355355 if let ref =
356356 _stdlib_atomicLoadARCRef ( object: _heapBufferBridgedPtr) {
357357 return unsafeBitCast ( ref, to: __BridgingBufferStorage. self)
@@ -365,7 +365,7 @@ extension __SwiftNativeNSArrayWithContiguousStorage {
365365 self . _nativeStorage = _nativeStorage
366366 }
367367
368- internal func _destroyBridgedStorage( _ hb: __BridgingBufferStorage ? ) {
368+ internal final func _destroyBridgedStorage( _ hb: __BridgingBufferStorage ? ) {
369369 if let bridgedStorage = hb {
370370 withExtendedLifetime ( bridgedStorage) {
371371 let buffer = _BridgingBuffer ( bridgedStorage)
@@ -424,10 +424,71 @@ extension __SwiftNativeNSArrayWithContiguousStorage {
424424 /// This override allows the count to be read without triggering
425425 /// bridging of array elements.
426426 @objc
427- internal override var count : Int {
427+ internal override final var count : Int {
428428 return _nativeStorage. countAndCapacity. count
429429 }
430430}
431+
432+ /// A `__SwiftDeferredNSArray` which is used for static read-only Swift Arrays.
433+ ///
434+ /// In contrast to its base class, `__SwiftDeferredStaticNSArray` is generic
435+ /// over the element type. This is needed because the storage class of a static
436+ /// read-only array (`__StaticArrayStorage`) does _not_ provide the element
437+ /// type.
438+ internal final class __SwiftDeferredStaticNSArray < Element>
439+ : __SwiftDeferredNSArray {
440+
441+ internal override func withUnsafeBufferOfObjects< R> (
442+ _ body: ( UnsafeBufferPointer < AnyObject > ) throws -> R
443+ ) rethrows -> R {
444+ while true {
445+ var buffer : UnsafeBufferPointer < AnyObject >
446+
447+ // If we've already got a buffer of bridged objects, just use it
448+ if let bridgedStorage = _heapBufferBridged {
449+ let bridgingBuffer = _BridgingBuffer ( bridgedStorage)
450+ buffer = UnsafeBufferPointer (
451+ start: bridgingBuffer. baseAddress, count: bridgingBuffer. count)
452+ }
453+ else {
454+ // Static read-only arrays can only contain non-verbatim bridged
455+ // element types.
456+
457+ // Create buffer of bridged objects.
458+ let objects = getNonVerbatimBridgingBuffer ( )
459+
460+ // Atomically store a reference to that buffer in self.
461+ if !_stdlib_atomicInitializeARCRef(
462+ object: _heapBufferBridgedPtr, desired: objects. storage!) {
463+
464+ // Another thread won the race. Throw out our buffer.
465+ _destroyBridgedStorage (
466+ unsafeDowncast ( objects. storage!, to: __BridgingBufferStorage. self) )
467+ }
468+ continue // Try again
469+ }
470+
471+ defer { _fixLifetime ( self ) }
472+ return try body ( buffer)
473+ }
474+ }
475+
476+ internal func getNonVerbatimBridgingBuffer( ) -> _BridgingBuffer {
477+ _internalInvariant (
478+ !_isBridgedVerbatimToObjectiveC( Element . self) ,
479+ " Verbatim bridging should be handled separately " )
480+ let count = _nativeStorage. countAndCapacity. count
481+ let result = _BridgingBuffer ( count)
482+ let resultPtr = result. baseAddress
483+ let p = UnsafeMutablePointer < Element > ( Builtin . projectTailElems ( _nativeStorage, Element . self) )
484+ for i in 0 ..< count {
485+ ( resultPtr + i) . initialize ( to: _bridgeAnythingToObjectiveC ( p [ i] ) )
486+ }
487+ _fixLifetime ( self )
488+ return result
489+ }
490+ }
491+
431492#else
432493// Empty shim version for non-objc platforms.
433494@usableFromInline
0 commit comments