15
15
#ifndef LLVM_BITCODE_BITSTREAMREADER_H
16
16
#define LLVM_BITCODE_BITSTREAMREADER_H
17
17
18
+ #include " llvm/ADT/ArrayRef.h"
18
19
#include " llvm/ADT/IntrusiveRefCntPtr.h"
19
20
#include " llvm/ADT/SmallVector.h"
20
21
#include " llvm/Bitcode/BitCodes.h"
21
22
#include " llvm/Support/Endian.h"
22
23
#include " llvm/Support/ErrorHandling.h"
23
24
#include " llvm/Support/MathExtras.h"
24
- #include " llvm/Support/StreamingMemoryObject .h"
25
+ #include " llvm/Support/MemoryBuffer .h"
25
26
#include < algorithm>
26
27
#include < cassert>
27
28
#include < climits>
@@ -50,32 +51,25 @@ class BitstreamReader {
50
51
};
51
52
52
53
private:
53
- std::unique_ptr<MemoryObject > BitcodeBytes;
54
+ ArrayRef< uint8_t > BitcodeBytes;
54
55
55
56
std::vector<BlockInfo> BlockInfoRecords;
56
57
57
58
// / This is set to true if we don't care about the block/record name
58
59
// / information in the BlockInfo block. Only llvm-bcanalyzer uses this.
59
- bool IgnoreBlockInfoNames;
60
+ bool IgnoreBlockInfoNames = true ;
60
61
61
62
public:
62
- BitstreamReader () : IgnoreBlockInfoNames(true ) {
63
- }
64
-
65
- BitstreamReader (const unsigned char *Start, const unsigned char *End)
66
- : IgnoreBlockInfoNames(true ) {
67
- init (Start, End);
68
- }
69
-
70
- BitstreamReader (std::unique_ptr<MemoryObject> BitcodeBytes)
71
- : BitcodeBytes(std::move(BitcodeBytes)), IgnoreBlockInfoNames(true ) {}
72
-
73
- void init (const unsigned char *Start, const unsigned char *End) {
74
- assert (((End-Start) & 3 ) == 0 &&" Bitcode stream not a multiple of 4 bytes" );
75
- BitcodeBytes.reset (getNonStreamedMemoryObject (Start, End));
76
- }
63
+ BitstreamReader () = default ;
64
+ BitstreamReader (ArrayRef<uint8_t > BitcodeBytes)
65
+ : BitcodeBytes(BitcodeBytes) {}
66
+ BitstreamReader (StringRef BitcodeBytes)
67
+ : BitcodeBytes(reinterpret_cast <const uint8_t *>(BitcodeBytes.data()),
68
+ BitcodeBytes.size()) {}
69
+ BitstreamReader (MemoryBufferRef BitcodeBytes)
70
+ : BitstreamReader(BitcodeBytes.getBuffer()) {}
77
71
78
- MemoryObject & getBitcodeBytes () { return * BitcodeBytes; }
72
+ ArrayRef< uint8_t > getBitcodeBytes () { return BitcodeBytes; }
79
73
80
74
// / This is called by clients that want block/record name information.
81
75
void CollectBlockInfoNames () { IgnoreBlockInfoNames = false ; }
@@ -131,9 +125,6 @@ class SimpleBitstreamCursor {
131
125
BitstreamReader *R = nullptr ;
132
126
size_t NextChar = 0 ;
133
127
134
- // The size of the bicode. 0 if we don't know it yet.
135
- size_t Size = 0 ;
136
-
137
128
public:
138
129
// / This is the current data we have pulled from the stream but have not
139
130
// / returned to the client. This is specifically and intentionally defined to
@@ -159,17 +150,11 @@ class SimpleBitstreamCursor {
159
150
160
151
bool canSkipToPos (size_t pos) const {
161
152
// pos can be skipped to if it is a valid address or one byte past the end.
162
- return pos == 0 ||
163
- R->getBitcodeBytes ().isValidAddress (static_cast <uint64_t >(pos - 1 ));
153
+ return pos <= R->getBitcodeBytes ().size ();
164
154
}
165
155
166
156
bool AtEndOfStream () {
167
- if (BitsInCurWord != 0 )
168
- return false ;
169
- if (Size != 0 )
170
- return Size <= NextChar;
171
- fillCurWord ();
172
- return BitsInCurWord == 0 ;
157
+ return BitsInCurWord == 0 && R->getBitcodeBytes ().size () <= NextChar;
173
158
}
174
159
175
160
// / Return the bit # of the bit we are reading.
@@ -218,7 +203,7 @@ class SimpleBitstreamCursor {
218
203
219
204
// / Get a pointer into the bitstream at the specified byte offset.
220
205
const uint8_t *getPointerToByte (uint64_t ByteNo, uint64_t NumBytes) {
221
- return R->getBitcodeBytes ().getPointer (ByteNo, NumBytes) ;
206
+ return R->getBitcodeBytes ().data () + ByteNo ;
222
207
}
223
208
224
209
// / Get a pointer into the bitstream at the specified bit offset.
@@ -230,26 +215,25 @@ class SimpleBitstreamCursor {
230
215
}
231
216
232
217
void fillCurWord () {
233
- if (Size != 0 && NextChar >= Size )
218
+ ArrayRef<uint8_t > Buf = R->getBitcodeBytes ();
219
+ if (NextChar >= Buf.size ())
234
220
report_fatal_error (" Unexpected end of file" );
235
221
236
222
// Read the next word from the stream.
237
- uint8_t Array[sizeof (word_t )] = {0 };
238
-
239
- uint64_t BytesRead =
240
- R->getBitcodeBytes ().readBytes (Array, sizeof (Array), NextChar);
241
-
242
- // If we run out of data, stop at the end of the stream.
243
- if (BytesRead == 0 ) {
223
+ const uint8_t *NextCharPtr = Buf.data () + NextChar;
224
+ unsigned BytesRead;
225
+ if (Buf.size () >= NextChar + sizeof (word_t )) {
226
+ BytesRead = sizeof (word_t );
227
+ CurWord =
228
+ support::endian::read <word_t , support::little, support::unaligned>(
229
+ NextCharPtr);
230
+ } else {
231
+ // Short read.
232
+ BytesRead = Buf.size () - NextChar;
244
233
CurWord = 0 ;
245
- BitsInCurWord = 0 ;
246
- Size = NextChar;
247
- return ;
234
+ for (unsigned B = 0 ; B != BytesRead; ++B)
235
+ CurWord |= NextCharPtr[B] << (B * 8 );
248
236
}
249
-
250
- CurWord =
251
- support::endian::read <word_t , support::little, support::unaligned>(
252
- Array);
253
237
NextChar += BytesRead;
254
238
BitsInCurWord = BytesRead * 8 ;
255
239
}
@@ -278,9 +262,9 @@ class SimpleBitstreamCursor {
278
262
279
263
fillCurWord ();
280
264
281
- // If we run out of data, stop at the end of the stream .
265
+ // If we run out of data, abort .
282
266
if (BitsLeft > BitsInCurWord)
283
- return 0 ;
267
+ report_fatal_error ( " Unexpected end of file " ) ;
284
268
285
269
word_t R2 = CurWord & (~word_t (0 ) >> (BitsInWord - BitsLeft));
286
270
@@ -346,31 +330,7 @@ class SimpleBitstreamCursor {
346
330
}
347
331
348
332
// / Skip to the end of the file.
349
- void skipToEnd () { NextChar = R->getBitcodeBytes ().getExtent (); }
350
-
351
- // / Prevent the cursor from reading past a byte boundary.
352
- // /
353
- // / Prevent the cursor from requesting byte reads past \c Limit. This is
354
- // / useful when working with a cursor on a StreamingMemoryObject, when it's
355
- // / desirable to avoid invalidating the result of getPointerToByte().
356
- // /
357
- // / If \c Limit is on a word boundary, AtEndOfStream() will return true if
358
- // / the cursor position reaches or exceeds \c Limit, regardless of the true
359
- // / number of available bytes. Otherwise, AtEndOfStream() returns true when
360
- // / it reaches or exceeds the next word boundary.
361
- void setArtificialByteLimit (uint64_t Limit) {
362
- assert (getCurrentByteNo () < Limit && " Move cursor before lowering limit" );
363
-
364
- // Round to word boundary.
365
- Limit = alignTo (Limit, sizeof (word_t ));
366
-
367
- // Only change size if the new one is lower.
368
- if (!Size || Size > Limit)
369
- Size = Limit;
370
- }
371
-
372
- // / Return the Size, if known.
373
- uint64_t getSizeIfKnown () const { return Size ; }
333
+ void skipToEnd () { NextChar = R->getBitcodeBytes ().size (); }
374
334
};
375
335
376
336
// / When advancing through a bitstream cursor, each advance can discover a few
@@ -470,6 +430,9 @@ class BitstreamCursor : SimpleBitstreamCursor {
470
430
// / Advance the current bitstream, returning the next entry in the stream.
471
431
BitstreamEntry advance (unsigned Flags = 0 ) {
472
432
while (true ) {
433
+ if (AtEndOfStream ())
434
+ return BitstreamEntry::getError ();
435
+
473
436
unsigned Code = ReadCode ();
474
437
if (Code == bitc::END_BLOCK) {
475
438
// Pop the end of the block unless Flags tells us not to.
0 commit comments