Skip to content

Commit b4998fb

Browse files
committed
[SDK] Modernize array initialization pattern in ModelIO overlay
We have nondeterministic test failures indicating a memory safety issue in ModelIO’s overlay. This switches the overlay’s property implementations to use the new `Array(unsafeUninitializedCount:,initializedWith:)` initializer rather than the potentially unreliable `&values[0]` pattern. rdar://problem/50449570
1 parent 7beb358 commit b4998fb

File tree

1 file changed

+87
-76
lines changed

1 file changed

+87
-76
lines changed

stdlib/public/Darwin/ModelIO/ModelIO.swift

Lines changed: 87 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,28 @@
1313
@_exported import ModelIO
1414
import simd
1515

16+
extension Array {
17+
fileprivate init(
18+
unsafeUninitializedCount count: Int,
19+
initializedWith initializer: (UnsafeMutablePointer<Element>) -> Void
20+
) {
21+
self.init(unsafeUninitializedCapacity: count) { buffer, initializedCount in
22+
initializer(buffer.baseAddress!)
23+
initializedCount = count
24+
}
25+
}
26+
}
27+
1628
@available(macOS, introduced: 10.13)
1729
@available(iOS, introduced: 11.0)
1830
@available(tvOS, introduced: 11.0)
1931
extension MDLMatrix4x4Array {
2032
@nonobjc public var float4x4Array: [float4x4] {
2133
get {
2234
let count = elementCount
23-
var values = [float4x4](repeating: float4x4(), count: Int(count))
24-
__getFloat4x4Array(&values[0], maxCount: count)
25-
return values
35+
return [float4x4](unsafeUninitializedCount: count) { ptr in
36+
__getFloat4x4Array(ptr, maxCount: count)
37+
}
2638
}
2739
set(array) {
2840
__setFloat4x4(array, count: array.count)
@@ -32,9 +44,9 @@ extension MDLMatrix4x4Array {
3244
@nonobjc public var double4x4Array: [double4x4] {
3345
get {
3446
let count = elementCount
35-
var values = [double4x4](repeating: double4x4(), count: Int(count))
36-
__getDouble4x4Array(&values[0], maxCount: count)
37-
return values
47+
return [double4x4](unsafeUninitializedCount: count) { ptr in
48+
__getDouble4x4Array(ptr, maxCount: count)
49+
}
3850
}
3951
set(array) {
4052
__setDouble4x4(array, count: array.count)
@@ -50,9 +62,9 @@ extension MDLMatrix4x4Array {
5062
extension MDLAnimatedValue {
5163
@nonobjc public var times: [TimeInterval] {
5264
get {
53-
var times = [TimeInterval](repeating: 0, count: Int(timeSampleCount))
54-
__getTimes(&times[0], maxCount: timeSampleCount)
55-
return times
65+
return [TimeInterval](unsafeUninitializedCount: timeSampleCount) { ptr in
66+
__getTimes(ptr, maxCount: timeSampleCount)
67+
}
5668
}
5769
}
5870
}
@@ -70,15 +82,15 @@ extension MDLAnimatedScalarArray {
7082
}
7183

7284
@nonobjc public func floatArray(atTime time: TimeInterval) -> [Float] {
73-
var values = [Float](repeating: 0, count: Int(elementCount))
74-
__getFloat(&values[0], maxCount: elementCount, atTime: time)
75-
return values
85+
return [Float](unsafeUninitializedCount: elementCount) { ptr in
86+
__getFloat(ptr, maxCount: elementCount, atTime: time)
87+
}
7688
}
7789

7890
@nonobjc public func doubleArray(atTime time: TimeInterval) -> [Double] {
79-
var values = [Double](repeating: 0, count: Int(elementCount))
80-
__getDouble(&values[0], maxCount: elementCount, atTime: time)
81-
return values
91+
return [Double](unsafeUninitializedCount: elementCount) { ptr in
92+
__getDouble(ptr, maxCount: elementCount, atTime: time)
93+
}
8294
}
8395

8496
@nonobjc public func reset(floatArray array:[Float], atTimes times: [TimeInterval]){
@@ -92,18 +104,18 @@ extension MDLAnimatedScalarArray {
92104
@nonobjc public var floatArray: [Float] {
93105
get {
94106
let count = elementCount * timeSampleCount
95-
var values = [Float](repeating: 0, count: Int(count))
96-
__getFloat(&values[0], maxCount: count)
97-
return values
107+
return [Float](unsafeUninitializedCount: count) { ptr in
108+
__getFloat(ptr, maxCount: count)
109+
}
98110
}
99111
}
100112

101113
@nonobjc public var doubleArray: [Double] {
102114
get {
103115
let count = elementCount * timeSampleCount
104-
var values = [Double](repeating: 0, count: Int(count))
105-
__getDouble(&values[0], maxCount: count)
106-
return values
116+
return [Double](unsafeUninitializedCount: count) { ptr in
117+
__getDouble(ptr, maxCount: count)
118+
}
107119
}
108120
}
109121
}
@@ -121,15 +133,15 @@ extension MDLAnimatedVector3Array {
121133
}
122134

123135
@nonobjc public func float3Array(atTime time: TimeInterval) -> [SIMD3<Float>] {
124-
var values = [SIMD3<Float>](repeating: SIMD3<Float>(), count: Int(elementCount))
125-
__getFloat3Array(&values[0], maxCount: elementCount, atTime: time)
126-
return values
136+
return [SIMD3<Float>](unsafeUninitializedCount: elementCount) { ptr in
137+
__getFloat3Array(ptr, maxCount: elementCount, atTime: time)
138+
}
127139
}
128140

129141
@nonobjc public func double3Array(atTime time: TimeInterval) -> [SIMD3<Double>] {
130-
var values = [SIMD3<Double>](repeating: SIMD3<Double>(), count: Int(elementCount))
131-
__getDouble3Array(&values[0], maxCount: elementCount, atTime: time)
132-
return values
142+
return [SIMD3<Double>](unsafeUninitializedCount: elementCount) { ptr in
143+
__getDouble3Array(ptr, maxCount: elementCount, atTime: time)
144+
}
133145
}
134146

135147
@nonobjc public func reset(float3Array array:[SIMD3<Float>], atTimes times: [TimeInterval]){
@@ -143,18 +155,18 @@ extension MDLAnimatedVector3Array {
143155
@nonobjc public var float3Array: [SIMD3<Float>] {
144156
get {
145157
let count = elementCount * timeSampleCount
146-
var values = [SIMD3<Float>](repeating: SIMD3<Float>(), count: Int(count))
147-
__getFloat3Array(&values[0], maxCount: count)
148-
return values
158+
return [SIMD3<Float>](unsafeUninitializedCount: count) { ptr in
159+
__getFloat3Array(ptr, maxCount: count)
160+
}
149161
}
150162
}
151163

152164
@nonobjc public var double3Array: [SIMD3<Double>] {
153165
get {
154166
let count = elementCount * timeSampleCount
155-
var values = [SIMD3<Double>](repeating: SIMD3<Double>(), count: Int(count))
156-
__getDouble3Array(&values[0], maxCount: count)
157-
return values
167+
return [SIMD3<Double>](unsafeUninitializedCount: count) { ptr in
168+
__getDouble3Array(ptr, maxCount: count)
169+
}
158170
}
159171
}
160172
}
@@ -172,15 +184,15 @@ extension MDLAnimatedQuaternionArray {
172184
}
173185

174186
@nonobjc public func floatQuaternionArray(atTime time: TimeInterval) -> [simd_quatf] {
175-
var values = [simd_quatf](repeating: simd_quatf(), count: Int(elementCount))
176-
__getFloat(&values[0], maxCount: elementCount, atTime: time)
177-
return values
187+
return [simd_quatf](unsafeUninitializedCount: elementCount) { ptr in
188+
__getFloat(ptr, maxCount: elementCount, atTime: time)
189+
}
178190
}
179191

180192
@nonobjc public func doubleQuaternionArray(atTime time: TimeInterval) -> [simd_quatd] {
181-
var values = [simd_quatd](repeating: simd_quatd(), count: Int(elementCount))
182-
__getDouble(&values[0], maxCount: elementCount, atTime: time)
183-
return values
193+
return [simd_quatd](unsafeUninitializedCount: elementCount) { ptr in
194+
__getDouble(ptr, maxCount: elementCount, atTime: time)
195+
}
184196
}
185197

186198
@nonobjc public func reset(floatQuaternionArray array:[simd_quatf], atTimes times: [TimeInterval]){
@@ -194,18 +206,18 @@ extension MDLAnimatedQuaternionArray {
194206
@nonobjc public var floatQuaternionArray : [simd_quatf] {
195207
get {
196208
let count = elementCount * timeSampleCount
197-
var values = [simd_quatf](repeating: simd_quatf(), count: Int(count))
198-
__getFloat(&values[0], maxCount: count)
199-
return values
209+
return [simd_quatf](unsafeUninitializedCount: count) { ptr in
210+
__getFloat(ptr, maxCount: count)
211+
}
200212
}
201213
}
202214

203215
@nonobjc public var doubleQuaternionArray: [simd_quatd] {
204216
get {
205217
let count = elementCount * timeSampleCount
206-
var values = [simd_quatd](repeating: simd_quatd(), count: Int(count))
207-
__getDouble(&values[0], maxCount: count)
208-
return values
218+
return [simd_quatd](unsafeUninitializedCount: count) { ptr in
219+
__getDouble(ptr, maxCount: count)
220+
}
209221
}
210222
}
211223
}
@@ -224,17 +236,17 @@ extension MDLAnimatedScalar {
224236

225237
@nonobjc public var floatArray: [Float] {
226238
get {
227-
var values = [Float](repeating: 0, count: Int(timeSampleCount))
228-
__getFloatArray(&values[0], maxCount: timeSampleCount)
229-
return values
239+
return [Float](unsafeUninitializedCount: timeSampleCount) { ptr in
240+
__getFloatArray(ptr, maxCount: timeSampleCount)
241+
}
230242
}
231243
}
232244

233245
@nonobjc public var doubleArray: [Double] {
234246
get {
235-
var values = [Double](repeating: 0, count: Int(timeSampleCount))
236-
__getDoubleArray(&values[0], maxCount: timeSampleCount)
237-
return values
247+
return [Double](unsafeUninitializedCount: timeSampleCount) { ptr in
248+
__getDoubleArray(ptr, maxCount: timeSampleCount)
249+
}
238250
}
239251
}
240252
}
@@ -253,17 +265,17 @@ extension MDLAnimatedVector2 {
253265

254266
@nonobjc public var float2Array: [SIMD2<Float>] {
255267
get {
256-
var values = [SIMD2<Float>](repeating: SIMD2<Float>(), count: Int(timeSampleCount))
257-
__getFloat2Array(&values[0], maxCount: timeSampleCount)
258-
return values
268+
return [SIMD2<Float>](unsafeUninitializedCount: timeSampleCount) { ptr in
269+
__getFloat2Array(ptr, maxCount: timeSampleCount)
270+
}
259271
}
260272
}
261273

262274
@nonobjc public var double2Array: [SIMD2<Double>] {
263275
get {
264-
var values = [SIMD2<Double>](repeating: SIMD2<Double>(), count: Int(timeSampleCount))
265-
__getDouble2Array(&values[0], maxCount: timeSampleCount)
266-
return values
276+
return [SIMD2<Double>](unsafeUninitializedCount: timeSampleCount) { ptr in
277+
__getDouble2Array(ptr, maxCount: timeSampleCount)
278+
}
267279
}
268280
}
269281
}
@@ -282,17 +294,17 @@ extension MDLAnimatedVector3 {
282294

283295
@nonobjc public var float3Array: [SIMD3<Float>] {
284296
get {
285-
var values = [SIMD3<Float>](repeating: SIMD3<Float>(), count: Int(timeSampleCount))
286-
__getFloat3Array(&values[0], maxCount: timeSampleCount)
287-
return values
297+
return [SIMD3<Float>](unsafeUninitializedCount: timeSampleCount) { ptr in
298+
__getFloat3Array(ptr, maxCount: timeSampleCount)
299+
}
288300
}
289301
}
290302

291303
@nonobjc public var double3Array: [SIMD3<Double>] {
292304
get {
293-
var values = [SIMD3<Double>](repeating: SIMD3<Double>(), count: Int(timeSampleCount))
294-
__getDouble3Array(&values[0], maxCount: timeSampleCount)
295-
return values
305+
return [SIMD3<Double>](unsafeUninitializedCount: timeSampleCount) { ptr in
306+
__getDouble3Array(ptr, maxCount: timeSampleCount)
307+
}
296308
}
297309
}
298310
}
@@ -311,17 +323,17 @@ extension MDLAnimatedVector4 {
311323

312324
@nonobjc public var float4Array: [SIMD4<Float>] {
313325
get {
314-
var values = [SIMD4<Float>](repeating: SIMD4<Float>(), count: Int(timeSampleCount))
315-
__getFloat4Array(&values[0], maxCount: timeSampleCount)
316-
return values
326+
return [SIMD4<Float>](unsafeUninitializedCount: timeSampleCount) { ptr in
327+
__getFloat4Array(ptr, maxCount: timeSampleCount)
328+
}
317329
}
318330
}
319331

320332
@nonobjc public var double4Array: [SIMD4<Double>] {
321333
get {
322-
var values = [SIMD4<Double>](repeating: SIMD4<Double>(), count: Int(timeSampleCount))
323-
__getDouble4Array(&values[0], maxCount: timeSampleCount)
324-
return values
334+
return [SIMD4<Double>](unsafeUninitializedCount: timeSampleCount) { ptr in
335+
__getDouble4Array(ptr, maxCount: timeSampleCount)
336+
}
325337
}
326338
}
327339
}
@@ -340,18 +352,17 @@ extension MDLAnimatedMatrix4x4 {
340352

341353
@nonobjc public var float4x4Array: [float4x4] {
342354
get {
343-
var values = [float4x4](repeating: float4x4(), count: Int(timeSampleCount))
344-
__getFloat4x4Array(&values[0], maxCount: timeSampleCount)
345-
return values
355+
return [float4x4](unsafeUninitializedCount: timeSampleCount) { ptr in
356+
__getFloat4x4Array(ptr, maxCount: timeSampleCount)
357+
}
346358
}
347359
}
348360

349361
@nonobjc public var double4x4Array: [double4x4] {
350362
get {
351-
var values = [double4x4](repeating: double4x4(), count: Int(timeSampleCount))
352-
__getDouble4x4Array(&values[0], maxCount: timeSampleCount)
353-
return values
363+
return [double4x4](unsafeUninitializedCount: timeSampleCount) { ptr in
364+
__getDouble4x4Array(ptr, maxCount: timeSampleCount)
365+
}
354366
}
355367
}
356368
}
357-

0 commit comments

Comments
 (0)