@@ -12,35 +12,8 @@ import Foundation
1212import TSCBasic
1313
1414extension Bitcode {
15- /// Parse a bitstream from data.
16- @available ( * , deprecated, message: " Use Bitcode.init(bytes:) instead " )
17- public init ( data: Data ) throws {
18- precondition ( data. count > 4 )
19- try self . init ( bytes: ByteString ( data) )
20- }
21-
22- public init ( bytes: ByteString ) throws {
23- precondition ( bytes. count > 4 )
24- var reader = BitstreamReader ( buffer: bytes)
25- let signature = try reader. readSignature ( )
26- var visitor = CollectingVisitor ( )
27- try reader. readBlock ( id: BitstreamReader . fakeTopLevelBlockID,
28- abbrevWidth: 2 ,
29- abbrevInfo: [ ] ,
30- visitor: & visitor)
31- self . init ( signature: signature,
32- elements: visitor. finalizeTopLevelElements ( ) ,
33- blockInfo: reader. blockInfo)
34- }
35-
3615 /// Traverse a bitstream using the specified `visitor`, which will receive
3716 /// callbacks when blocks and records are encountered.
38- @available ( * , deprecated, message: " Use Bitcode.read(bytes:using:) instead " )
39- public static func read< Visitor: BitstreamVisitor > ( stream data: Data , using visitor: inout Visitor ) throws {
40- precondition ( data. count > 4 )
41- try Self . read ( bytes: ByteString ( data) , using: & visitor)
42- }
43-
4417 public static func read< Visitor: BitstreamVisitor > ( bytes: ByteString , using visitor: inout Visitor ) throws {
4518 precondition ( bytes. count > 4 )
4619 var reader = BitstreamReader ( buffer: bytes)
@@ -204,15 +177,21 @@ private struct BitstreamReader {
204177 }
205178 }
206179
207- mutating func readAbbreviatedRecord( _ abbrev: Bitstream . Abbreviation ) throws -> BitcodeElement . Record {
180+ mutating func withAbbreviatedRecord(
181+ _ abbrev: Bitstream . Abbreviation ,
182+ body: ( BitcodeElement . Record ) throws -> Void
183+ ) throws {
208184 let code = try readSingleAbbreviatedRecordOperand ( abbrev. operands. first!)
209185
210186 let lastOperand = abbrev. operands. last!
211187 let lastRegularOperandIndex : Int = abbrev. operands. endIndex - ( lastOperand. isPayload ? 1 : 0 )
212188
213- var fields = [ UInt64] ( )
214- for op in abbrev. operands [ 1 ..< lastRegularOperandIndex] {
215- fields. append ( try readSingleAbbreviatedRecordOperand ( op) )
189+ // Safety: `lastRegularOperandIndex` is always at least 1.
190+ let fields = UnsafeMutableBufferPointer< UInt64> . allocate( capacity: lastRegularOperandIndex - 1 )
191+ defer { fields. deallocate ( ) }
192+
193+ for (idx, op) in abbrev. operands [ 1 ..< lastRegularOperandIndex] . enumerated ( ) {
194+ fields [ idx] = try readSingleAbbreviatedRecordOperand ( op)
216195 }
217196
218197 let payload : BitcodeElement . Record . Payload
@@ -234,14 +213,14 @@ private struct BitstreamReader {
234213 case . blob:
235214 let length = Int ( try cursor. readVBR ( 6 ) )
236215 try cursor. advance ( toBitAlignment: 32 )
237- payload = . blob( try Data ( cursor. read ( bytes: length) ) )
216+ payload = . blob( try cursor. read ( bytes: length) )
238217 try cursor. advance ( toBitAlignment: 32 )
239218 default :
240219 fatalError ( )
241220 }
242221 }
243222
244- return . init( id: code, fields: fields, payload: payload)
223+ return try body ( . init( id: code, fields: UnsafeBufferPointer ( fields) , payload: payload) )
245224 }
246225
247226 mutating func readBlockInfoBlock( abbrevWidth: Int ) throws {
@@ -341,17 +320,20 @@ private struct BitstreamReader {
341320 case Bitstream . AbbreviationID. unabbreviatedRecord. rawValue:
342321 let code = try cursor. readVBR ( 6 )
343322 let numOps = try cursor. readVBR ( 6 )
344- var operands = [ UInt64] ( )
345- for _ in 0 ..< numOps {
346- operands. append ( try cursor. readVBR ( 6 ) )
323+ let operands = UnsafeMutableBufferPointer< UInt64> . allocate( capacity: Int ( numOps) )
324+ defer { operands. deallocate ( ) }
325+ for i in 0 ..< Int ( numOps) {
326+ operands [ i] = try cursor. readVBR ( 6 )
347327 }
348- try visitor. visit ( record: . init( id: code, fields: operands, payload: . none) )
328+ try visitor. visit ( record: . init( id: code, fields: UnsafeBufferPointer ( operands) , payload: . none) )
349329
350330 case let abbrevID:
351331 guard Int ( abbrevID) - 4 < abbrevInfo. count else {
352332 throw Error . noSuchAbbrev ( blockID: id, abbrevID: Int ( abbrevID) )
353333 }
354- try visitor. visit ( record: try readAbbreviatedRecord ( abbrevInfo [ Int ( abbrevID) - 4 ] ) )
334+ try withAbbreviatedRecord ( abbrevInfo [ Int ( abbrevID) - 4 ] ) { record in
335+ try visitor. visit ( record: record)
336+ }
355337 }
356338 }
357339
0 commit comments