OLD | NEW |
1 //===- BitstreamReader.h - Low-level bitstream reader interface -*- C++ -*-===// | 1 //===- BitstreamReader.h - Low-level bitstream reader interface -*- C++ -*-===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This header defines the BitstreamReader class. This class can be used to | 10 // This header defines the BitstreamReader class. This class can be used to |
11 // read an arbitrary bitstream, regardless of its contents. | 11 // read an arbitrary bitstream, regardless of its contents. |
12 // | 12 // |
13 //===----------------------------------------------------------------------===// | 13 //===----------------------------------------------------------------------===// |
14 | 14 |
15 #ifndef BITSTREAM_READER_H | 15 #ifndef BITSTREAM_READER_H |
16 #define BITSTREAM_READER_H | 16 #define BITSTREAM_READER_H |
17 | 17 |
| 18 #include "llvm/ADT/OwningPtr.h" |
18 #include "llvm/Bitcode/BitCodes.h" | 19 #include "llvm/Bitcode/BitCodes.h" |
| 20 #include "llvm/Support/BitcodeStream.h" |
19 #include <climits> | 21 #include <climits> |
20 #include <string> | 22 #include <string> |
21 #include <vector> | 23 #include <vector> |
22 | 24 |
23 namespace llvm { | 25 namespace llvm { |
24 | 26 |
25 class Deserializer; | 27 class Deserializer; |
| 28 |
| 29 class BitstreamBytes { |
| 30 public: |
| 31 BitstreamBytes() { } |
| 32 |
| 33 virtual ~BitstreamBytes() {} |
| 34 |
| 35 // Returns true if pos is the ending stream position (one byte past the last |
| 36 // valid byte). |
| 37 // May block until Pos bytes have been read, or EOF is reached. |
| 38 virtual bool isEndPos(size_t Pos) = 0; |
| 39 |
| 40 // Returns the ending stream position (one byte past the last valid byte). |
| 41 // May block until EOF is reached. |
| 42 virtual size_t getEndPos() = 0; |
| 43 |
| 44 // Returns true if seeking to Pos is within the stream or one past the end. |
| 45 // May block until Pos bytes have been read, or EOF is reached. |
| 46 virtual bool canSkipToPos(size_t Pos) = 0; |
| 47 |
| 48 // Returns the in memory address of Pos from the beginning of the stream. |
| 49 // May block until Pos bytes have been read, or EOF is reached. |
| 50 // Note that the first byte past the end may be skipped to, but may not have |
| 51 // its address taken. |
| 52 virtual const unsigned char *addressOf(size_t Pos) = 0; |
| 53 |
| 54 // Returns the character at Pos from the beginning of the stream. |
| 55 // May block until Pos bytes have been read, or EOF is reached. |
| 56 virtual unsigned char getByte(size_t Pos) = 0; |
| 57 |
| 58 // Returns the word at Pos from the beginning of the stream. |
| 59 // (Pos is still counted in bytes, as in the rest of the methods) |
| 60 // May block until Pos bytes have been read, or EOF is reached. |
| 61 virtual uint32_t getWord(size_t Pos) = 0; |
| 62 |
| 63 private: |
| 64 BitstreamBytes(const BitstreamBytes&); // DO NOT IMPLEMENT |
| 65 void operator=(const BitstreamBytes&); // DO NOT IMPLEMENT |
| 66 }; |
| 67 |
| 68 class MemoryBitstreamBytes : public BitstreamBytes { |
| 69 public: |
| 70 MemoryBitstreamBytes() { } |
| 71 |
| 72 MemoryBitstreamBytes(const unsigned char *Start, const unsigned char *End) |
| 73 : FirstChar(Start), LastChar(End) { |
| 74 } |
| 75 |
| 76 virtual ~MemoryBitstreamBytes() {} |
| 77 |
| 78 virtual bool isEndPos(size_t Pos) { |
| 79 return Pos == static_cast<size_t>(LastChar-FirstChar); |
| 80 } |
| 81 |
| 82 virtual size_t getEndPos() { |
| 83 return static_cast<size_t>(LastChar-FirstChar); |
| 84 } |
| 85 |
| 86 virtual bool canSkipToPos(size_t Pos) { |
| 87 return Pos <= static_cast<size_t>(LastChar-FirstChar); |
| 88 } |
| 89 |
| 90 virtual const unsigned char *addressOf(size_t Pos) { |
| 91 assert(canSkipToPos(Pos) && Pos != static_cast<size_t>(LastChar-FirstChar) |
| 92 && "taking address outside of buffer"); |
| 93 return FirstChar + Pos; |
| 94 } |
| 95 |
| 96 virtual unsigned char getByte(size_t Pos) { |
| 97 assert(canSkipToPos(Pos) && Pos != static_cast<size_t>(LastChar-FirstChar) |
| 98 && "indexing outside of buffer"); |
| 99 return *(FirstChar + Pos); |
| 100 } |
| 101 |
| 102 virtual uint32_t getWord(size_t Pos) { |
| 103 assert(canSkipToPos(Pos + 3) && |
| 104 (Pos + 3) != static_cast<size_t>(LastChar-FirstChar) && |
| 105 "indexing outside of buffer"); |
| 106 const unsigned char *p = FirstChar + Pos; |
| 107 return *p << 0 | |
| 108 *(p + 1) << 8 | |
| 109 *(p + 2) << 16 | |
| 110 *(p + 3) << 24; |
| 111 } |
| 112 |
| 113 private: |
| 114 const unsigned char *FirstChar; |
| 115 const unsigned char *LastChar; |
| 116 |
| 117 MemoryBitstreamBytes(const MemoryBitstreamBytes&); // DO NOT IMPLEMENT |
| 118 void operator=(const MemoryBitstreamBytes&); // DO NOT IMPLEMENT |
| 119 }; |
| 120 |
| 121 class LazyBitstreamBytes : public BitstreamBytes { |
| 122 public: |
| 123 LazyBitstreamBytes(BitcodeStreamer *streamer) : |
| 124 Bytes(kChunkSize), Streamer(streamer), BytesRead(0), BytesSkipped(0), |
| 125 BitcodeSize(0), EOFReached(false) { |
| 126 BytesRead = streamer->GetBytes(&Bytes[0], kChunkSize); |
| 127 } |
| 128 |
| 129 virtual ~LazyBitstreamBytes() {} |
| 130 |
| 131 virtual bool isEndPos(size_t Pos) { |
| 132 if (BitcodeSize) return Pos == BitcodeSize; |
| 133 fetchToPos(Pos); |
| 134 return Pos == BytesRead; |
| 135 } |
| 136 |
| 137 virtual size_t getEndPos() { |
| 138 if (BitcodeSize) return BitcodeSize; |
| 139 size_t pos = BytesRead + kChunkSize; |
| 140 // keep fetching until we run out of bytes |
| 141 while (fetchToPos(pos)) pos += kChunkSize; |
| 142 return BitcodeSize; |
| 143 } |
| 144 |
| 145 // If the bitcode has a header, then its size is known, and we don't have to |
| 146 // block until we actually want to read it. |
| 147 virtual bool canSkipToPos(size_t Pos) { |
| 148 if (BitcodeSize && Pos <= BitcodeSize) return true; |
| 149 return fetchToPos(Pos) || Pos == BitcodeSize; |
| 150 } |
| 151 |
| 152 virtual const unsigned char *addressOf(size_t Pos) { |
| 153 assert(0 && "addressOf inside streaming bitstreams not allowed"); |
| 154 return NULL; |
| 155 } |
| 156 |
| 157 virtual unsigned char getByte(size_t Pos) { |
| 158 fetchToPos(Pos); |
| 159 assert(Pos < BytesRead && "indexing outside of buffer"); |
| 160 return Bytes[Pos + BytesSkipped]; |
| 161 } |
| 162 |
| 163 virtual uint32_t getWord(size_t Pos) { |
| 164 fetchToPos(Pos + 3); |
| 165 assert(Pos + 3 < BytesRead && "indexing outside of buffer"); |
| 166 size_t RealPos = Pos + BytesSkipped; |
| 167 return (Bytes[RealPos + 0] << 0) | |
| 168 (Bytes[RealPos + 1] << 8) | |
| 169 (Bytes[RealPos + 2] << 16) | |
| 170 (Bytes[RealPos + 3] << 24); |
| 171 } |
| 172 |
| 173 // Drop s bytes from the front of the stream, pushing the positions of the |
| 174 // remaining bytes down by s. This is used to skip past the bitcode header, |
| 175 // since we don't know a priori if it's present, and we can't put bytes |
| 176 // back into the stream once we've read them. |
| 177 bool dropLeadingBytes(size_t s) { |
| 178 if (BytesRead < s) return true; |
| 179 BytesSkipped = s; |
| 180 BytesRead -= s; |
| 181 return false; |
| 182 } |
| 183 |
| 184 void setKnownBitcodeSize(size_t size) { |
| 185 BitcodeSize = size; |
| 186 } |
| 187 |
| 188 private: |
| 189 const static uint32_t kChunkSize = 4096 * 4; |
| 190 std::vector<unsigned char> Bytes; |
| 191 OwningPtr<BitcodeStreamer> Streamer; |
| 192 size_t BytesRead; // Bytes read from stream |
| 193 size_t BytesSkipped;// Bytes skipped at start of stream (e.g. wrapper/header) |
| 194 size_t BitcodeSize; // 0 if unknown, set if wrapper was seen or EOF reached |
| 195 bool EOFReached; |
| 196 |
| 197 // fetch enough bytes such that Pos can be read or EOF is reached |
| 198 // (i.e. BytesRead > Pos). Return true if Pos can be read. |
| 199 // Unlike most of the functions in BitcodeReader, returns true on success. |
| 200 bool fetchToPos(size_t Pos) { |
| 201 if (EOFReached) return Pos < BitcodeSize; |
| 202 while (Pos >= BytesRead) { |
| 203 Bytes.resize(BytesRead + kChunkSize); |
| 204 size_t bytes = Streamer->GetBytes(&Bytes[BytesRead + BytesSkipped], |
| 205 kChunkSize); |
| 206 BytesRead += bytes; |
| 207 if (bytes < kChunkSize) { |
| 208 if (BitcodeSize && BytesRead < Pos) |
| 209 assert(0 && "Unexpected short read fetching bitcode"); |
| 210 if (BytesRead <= Pos) { // reached EOF/ran out of bytes |
| 211 BitcodeSize = BytesRead; |
| 212 EOFReached = true; |
| 213 return false; |
| 214 } |
| 215 } |
| 216 } |
| 217 return true; |
| 218 } |
| 219 |
| 220 LazyBitstreamBytes(const LazyBitstreamBytes&); // DO NOT IMPLEMENT |
| 221 void operator=(const LazyBitstreamBytes&); // DO NOT IMPLEMENT |
| 222 }; |
26 | 223 |
27 class BitstreamReader { | 224 class BitstreamReader { |
28 public: | 225 public: |
29 /// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks. | 226 /// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks. |
30 /// These describe abbreviations that all blocks of the specified ID inherit. | 227 /// These describe abbreviations that all blocks of the specified ID inherit. |
31 struct BlockInfo { | 228 struct BlockInfo { |
32 unsigned BlockID; | 229 unsigned BlockID; |
33 std::vector<BitCodeAbbrev*> Abbrevs; | 230 std::vector<BitCodeAbbrev*> Abbrevs; |
34 std::string Name; | 231 std::string Name; |
35 | 232 |
36 std::vector<std::pair<unsigned, std::string> > RecordNames; | 233 std::vector<std::pair<unsigned, std::string> > RecordNames; |
37 }; | 234 }; |
38 private: | 235 private: |
39 /// FirstChar/LastChar - This remembers the first and last bytes of the | 236 OwningPtr<BitstreamBytes> Bytes; |
40 /// stream. | |
41 const unsigned char *FirstChar, *LastChar; | |
42 | 237 |
43 std::vector<BlockInfo> BlockInfoRecords; | 238 std::vector<BlockInfo> BlockInfoRecords; |
44 | 239 |
45 /// IgnoreBlockInfoNames - This is set to true if we don't care about the | 240 /// IgnoreBlockInfoNames - This is set to true if we don't care about the |
46 /// block/record name information in the BlockInfo block. Only llvm-bcanalyzer | 241 /// block/record name information in the BlockInfo block. Only llvm-bcanalyzer |
47 /// uses this. | 242 /// uses this. |
48 bool IgnoreBlockInfoNames; | 243 bool IgnoreBlockInfoNames; |
49 | 244 |
50 BitstreamReader(const BitstreamReader&); // NOT IMPLEMENTED | 245 BitstreamReader(const BitstreamReader&); // DO NOT IMPLEMENT |
51 void operator=(const BitstreamReader&); // NOT IMPLEMENTED | 246 void operator=(const BitstreamReader&); // DO NOT IMPLEMENT |
52 public: | 247 public: |
53 BitstreamReader() : FirstChar(0), LastChar(0), IgnoreBlockInfoNames(true) { | 248 BitstreamReader() : IgnoreBlockInfoNames(true) { |
54 } | 249 } |
55 | 250 |
56 BitstreamReader(const unsigned char *Start, const unsigned char *End) { | 251 BitstreamReader(const unsigned char *Start, const unsigned char *End) { |
57 IgnoreBlockInfoNames = true; | 252 IgnoreBlockInfoNames = true; |
58 init(Start, End); | 253 init(Start, End); |
59 } | 254 } |
60 | 255 |
| 256 BitstreamReader(BitstreamBytes *bsv) { |
| 257 Bytes.reset(bsv); |
| 258 } |
| 259 |
61 void init(const unsigned char *Start, const unsigned char *End) { | 260 void init(const unsigned char *Start, const unsigned char *End) { |
62 FirstChar = Start; | |
63 LastChar = End; | |
64 assert(((End-Start) & 3) == 0 &&"Bitcode stream not a multiple of 4 bytes"); | 261 assert(((End-Start) & 3) == 0 &&"Bitcode stream not a multiple of 4 bytes"); |
| 262 Bytes.reset(new MemoryBitstreamBytes(Start, End)); |
65 } | 263 } |
66 | 264 |
| 265 BitstreamBytes &getBytes() { return *Bytes; } |
| 266 |
67 ~BitstreamReader() { | 267 ~BitstreamReader() { |
68 // Free the BlockInfoRecords. | 268 // Free the BlockInfoRecords. |
69 while (!BlockInfoRecords.empty()) { | 269 while (!BlockInfoRecords.empty()) { |
70 BlockInfo &Info = BlockInfoRecords.back(); | 270 BlockInfo &Info = BlockInfoRecords.back(); |
71 // Free blockinfo abbrev info. | 271 // Free blockinfo abbrev info. |
72 for (unsigned i = 0, e = static_cast<unsigned>(Info.Abbrevs.size()); | 272 for (unsigned i = 0, e = static_cast<unsigned>(Info.Abbrevs.size()); |
73 i != e; ++i) | 273 i != e; ++i) |
74 Info.Abbrevs[i]->dropRef(); | 274 Info.Abbrevs[i]->dropRef(); |
75 BlockInfoRecords.pop_back(); | 275 BlockInfoRecords.pop_back(); |
76 } | 276 } |
77 } | 277 } |
78 | 278 |
79 const unsigned char *getFirstChar() const { return FirstChar; } | |
80 const unsigned char *getLastChar() const { return LastChar; } | |
81 | |
82 /// CollectBlockInfoNames - This is called by clients that want block/record | 279 /// CollectBlockInfoNames - This is called by clients that want block/record |
83 /// name information. | 280 /// name information. |
84 void CollectBlockInfoNames() { IgnoreBlockInfoNames = false; } | 281 void CollectBlockInfoNames() { IgnoreBlockInfoNames = false; } |
85 bool isIgnoringBlockInfoNames() { return IgnoreBlockInfoNames; } | 282 bool isIgnoringBlockInfoNames() { return IgnoreBlockInfoNames; } |
86 | 283 |
87 //===--------------------------------------------------------------------===// | 284 //===--------------------------------------------------------------------===// |
88 // Block Manipulation | 285 // Block Manipulation |
89 //===--------------------------------------------------------------------===// | 286 //===--------------------------------------------------------------------===// |
90 | 287 |
91 /// hasBlockInfoRecords - Return true if we've already read and processed the | 288 /// hasBlockInfoRecords - Return true if we've already read and processed the |
(...skipping 23 matching lines...) Expand all Loading... |
115 BlockInfoRecords.push_back(BlockInfo()); | 312 BlockInfoRecords.push_back(BlockInfo()); |
116 BlockInfoRecords.back().BlockID = BlockID; | 313 BlockInfoRecords.back().BlockID = BlockID; |
117 return BlockInfoRecords.back(); | 314 return BlockInfoRecords.back(); |
118 } | 315 } |
119 | 316 |
120 }; | 317 }; |
121 | 318 |
122 class BitstreamCursor { | 319 class BitstreamCursor { |
123 friend class Deserializer; | 320 friend class Deserializer; |
124 BitstreamReader *BitStream; | 321 BitstreamReader *BitStream; |
125 const unsigned char *NextChar; | 322 size_t NextChar; |
126 | 323 |
127 /// CurWord - This is the current data we have pulled from the stream but have | 324 /// CurWord - This is the current data we have pulled from the stream but have |
128 /// not returned to the client. | 325 /// not returned to the client. |
129 uint32_t CurWord; | 326 uint32_t CurWord; |
130 | 327 |
131 /// BitsInCurWord - This is the number of bits in CurWord that are valid. This | 328 /// BitsInCurWord - This is the number of bits in CurWord that are valid. This |
132 /// is always from [0...31] inclusive. | 329 /// is always from [0...31] inclusive. |
133 unsigned BitsInCurWord; | 330 unsigned BitsInCurWord; |
134 | 331 |
135 // CurCodeSize - This is the declared size of code values used for the current | 332 // CurCodeSize - This is the declared size of code values used for the current |
(...skipping 13 matching lines...) Expand all Loading... |
149 SmallVector<Block, 8> BlockScope; | 346 SmallVector<Block, 8> BlockScope; |
150 | 347 |
151 public: | 348 public: |
152 BitstreamCursor() : BitStream(0), NextChar(0) { | 349 BitstreamCursor() : BitStream(0), NextChar(0) { |
153 } | 350 } |
154 BitstreamCursor(const BitstreamCursor &RHS) : BitStream(0), NextChar(0) { | 351 BitstreamCursor(const BitstreamCursor &RHS) : BitStream(0), NextChar(0) { |
155 operator=(RHS); | 352 operator=(RHS); |
156 } | 353 } |
157 | 354 |
158 explicit BitstreamCursor(BitstreamReader &R) : BitStream(&R) { | 355 explicit BitstreamCursor(BitstreamReader &R) : BitStream(&R) { |
159 NextChar = R.getFirstChar(); | 356 NextChar = 0; |
160 assert(NextChar && "Bitstream not initialized yet"); | |
161 CurWord = 0; | 357 CurWord = 0; |
162 BitsInCurWord = 0; | 358 BitsInCurWord = 0; |
163 CurCodeSize = 2; | 359 CurCodeSize = 2; |
164 } | 360 } |
165 | 361 |
166 void init(BitstreamReader &R) { | 362 void init(BitstreamReader &R) { |
167 freeState(); | 363 freeState(); |
168 | 364 |
169 BitStream = &R; | 365 BitStream = &R; |
170 NextChar = R.getFirstChar(); | 366 NextChar = 0; |
171 assert(NextChar && "Bitstream not initialized yet"); | |
172 CurWord = 0; | 367 CurWord = 0; |
173 BitsInCurWord = 0; | 368 BitsInCurWord = 0; |
174 CurCodeSize = 2; | 369 CurCodeSize = 2; |
175 } | 370 } |
176 | 371 |
177 ~BitstreamCursor() { | 372 ~BitstreamCursor() { |
178 freeState(); | 373 freeState(); |
179 } | 374 } |
180 | 375 |
181 void operator=(const BitstreamCursor &RHS) { | 376 void operator=(const BitstreamCursor &RHS) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 i != e; ++i) | 414 i != e; ++i) |
220 Abbrevs[i]->dropRef(); | 415 Abbrevs[i]->dropRef(); |
221 } | 416 } |
222 BlockScope.clear(); | 417 BlockScope.clear(); |
223 } | 418 } |
224 | 419 |
225 /// GetAbbrevIDWidth - Return the number of bits used to encode an abbrev #. | 420 /// GetAbbrevIDWidth - Return the number of bits used to encode an abbrev #. |
226 unsigned GetAbbrevIDWidth() const { return CurCodeSize; } | 421 unsigned GetAbbrevIDWidth() const { return CurCodeSize; } |
227 | 422 |
228 bool AtEndOfStream() const { | 423 bool AtEndOfStream() const { |
229 return NextChar == BitStream->getLastChar() && BitsInCurWord == 0; | 424 return BitStream->getBytes().isEndPos(NextChar) && BitsInCurWord == 0; |
230 } | 425 } |
231 | 426 |
232 /// GetCurrentBitNo - Return the bit # of the bit we are reading. | 427 /// GetCurrentBitNo - Return the bit # of the bit we are reading. |
233 uint64_t GetCurrentBitNo() const { | 428 uint64_t GetCurrentBitNo() const { |
234 return (NextChar-BitStream->getFirstChar())*CHAR_BIT - BitsInCurWord; | 429 return NextChar*CHAR_BIT - BitsInCurWord; |
235 } | 430 } |
236 | 431 |
237 BitstreamReader *getBitStreamReader() { | 432 BitstreamReader *getBitStreamReader() { |
238 return BitStream; | 433 return BitStream; |
239 } | 434 } |
240 const BitstreamReader *getBitStreamReader() const { | 435 const BitstreamReader *getBitStreamReader() const { |
241 return BitStream; | 436 return BitStream; |
242 } | 437 } |
243 | 438 |
244 | 439 |
245 /// JumpToBit - Reset the stream to the specified bit number. | 440 /// JumpToBit - Reset the stream to the specified bit number. |
246 void JumpToBit(uint64_t BitNo) { | 441 void JumpToBit(uint64_t BitNo) { |
247 uintptr_t ByteNo = uintptr_t(BitNo/8) & ~3; | 442 uintptr_t ByteNo = uintptr_t(BitNo/8) & ~3; |
248 uintptr_t WordBitNo = uintptr_t(BitNo) & 31; | 443 uintptr_t WordBitNo = uintptr_t(BitNo) & 31; |
249 assert(ByteNo <= (uintptr_t)(BitStream->getLastChar()- | 444 assert(BitStream->getBytes().canSkipToPos(ByteNo) && "Invalid location"); |
250 BitStream->getFirstChar()) && | |
251 "Invalid location"); | |
252 | 445 |
253 // Move the cursor to the right word. | 446 // Move the cursor to the right word. |
254 NextChar = BitStream->getFirstChar()+ByteNo; | 447 NextChar = ByteNo; |
255 BitsInCurWord = 0; | 448 BitsInCurWord = 0; |
256 CurWord = 0; | 449 CurWord = 0; |
257 | 450 |
258 // Skip over any bits that are already consumed. | 451 // Skip over any bits that are already consumed. |
259 if (WordBitNo) | 452 if (WordBitNo) |
260 Read(static_cast<unsigned>(WordBitNo)); | 453 Read(static_cast<unsigned>(WordBitNo)); |
261 } | 454 } |
262 | 455 |
263 | 456 |
264 uint32_t Read(unsigned NumBits) { | 457 uint32_t Read(unsigned NumBits) { |
265 assert(NumBits <= 32 && "Cannot return more than 32 bits!"); | 458 assert(NumBits <= 32 && "Cannot return more than 32 bits!"); |
266 // If the field is fully contained by CurWord, return it quickly. | 459 // If the field is fully contained by CurWord, return it quickly. |
267 if (BitsInCurWord >= NumBits) { | 460 if (BitsInCurWord >= NumBits) { |
268 uint32_t R = CurWord & ((1U << NumBits)-1); | 461 uint32_t R = CurWord & ((1U << NumBits)-1); |
269 CurWord >>= NumBits; | 462 CurWord >>= NumBits; |
270 BitsInCurWord -= NumBits; | 463 BitsInCurWord -= NumBits; |
271 return R; | 464 return R; |
272 } | 465 } |
273 | 466 |
274 // If we run out of data, stop at the end of the stream. | 467 // If we run out of data, stop at the end of the stream. |
275 if (NextChar == BitStream->getLastChar()) { | 468 if (BitStream->getBytes().isEndPos(NextChar)) { |
276 CurWord = 0; | 469 CurWord = 0; |
277 BitsInCurWord = 0; | 470 BitsInCurWord = 0; |
278 return 0; | 471 return 0; |
279 } | 472 } |
280 | 473 |
281 unsigned R = CurWord; | 474 unsigned R = CurWord; |
282 | 475 |
283 // Read the next word from the stream. | 476 // Read the next word from the stream. |
284 CurWord = (NextChar[0] << 0) | (NextChar[1] << 8) | | 477 CurWord = BitStream->getBytes().getWord(NextChar); |
285 (NextChar[2] << 16) | (NextChar[3] << 24); | |
286 NextChar += 4; | 478 NextChar += 4; |
287 | 479 |
288 // Extract NumBits-BitsInCurWord from what we just read. | 480 // Extract NumBits-BitsInCurWord from what we just read. |
289 unsigned BitsLeft = NumBits-BitsInCurWord; | 481 unsigned BitsLeft = NumBits-BitsInCurWord; |
290 | 482 |
291 // Be careful here, BitsLeft is in the range [1..32] inclusive. | 483 // Be careful here, BitsLeft is in the range [1..32] inclusive. |
292 R |= (CurWord & (~0U >> (32-BitsLeft))) << BitsInCurWord; | 484 R |= (CurWord & (~0U >> (32-BitsLeft))) << BitsInCurWord; |
293 | 485 |
294 // BitsLeft bits have just been used up from CurWord. | 486 // BitsLeft bits have just been used up from CurWord. |
295 if (BitsLeft != 32) | 487 if (BitsLeft != 32) |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 /// true. | 561 /// true. |
370 bool SkipBlock() { | 562 bool SkipBlock() { |
371 // Read and ignore the codelen value. Since we are skipping this block, we | 563 // Read and ignore the codelen value. Since we are skipping this block, we |
372 // don't care what code widths are used inside of it. | 564 // don't care what code widths are used inside of it. |
373 ReadVBR(bitc::CodeLenWidth); | 565 ReadVBR(bitc::CodeLenWidth); |
374 SkipToWord(); | 566 SkipToWord(); |
375 unsigned NumWords = Read(bitc::BlockSizeWidth); | 567 unsigned NumWords = Read(bitc::BlockSizeWidth); |
376 | 568 |
377 // Check that the block wasn't partially defined, and that the offset isn't | 569 // Check that the block wasn't partially defined, and that the offset isn't |
378 // bogus. | 570 // bogus. |
379 const unsigned char *const SkipTo = NextChar + NumWords*4; | 571 size_t SkipTo = NextChar + NumWords*4; |
380 if (AtEndOfStream() || SkipTo > BitStream->getLastChar() || | 572 if (AtEndOfStream() || !BitStream->getBytes().canSkipToPos(SkipTo)) |
381 SkipTo < BitStream->getFirstChar()) | |
382 return true; | 573 return true; |
383 | 574 |
384 NextChar = SkipTo; | 575 NextChar = SkipTo; |
385 return false; | 576 return false; |
386 } | 577 } |
387 | 578 |
388 /// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter | 579 /// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter |
389 /// the block, and return true if the block is valid. | 580 /// the block, and return true if the block is valid. |
390 bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = 0) { | 581 bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = 0) { |
391 // Save the current block's state on BlockScope. | 582 // Save the current block's state on BlockScope. |
(...skipping 10 matching lines...) Expand all Loading... |
402 } | 593 } |
403 } | 594 } |
404 | 595 |
405 // Get the codesize of this block. | 596 // Get the codesize of this block. |
406 CurCodeSize = ReadVBR(bitc::CodeLenWidth); | 597 CurCodeSize = ReadVBR(bitc::CodeLenWidth); |
407 SkipToWord(); | 598 SkipToWord(); |
408 unsigned NumWords = Read(bitc::BlockSizeWidth); | 599 unsigned NumWords = Read(bitc::BlockSizeWidth); |
409 if (NumWordsP) *NumWordsP = NumWords; | 600 if (NumWordsP) *NumWordsP = NumWords; |
410 | 601 |
411 // Validate that this block is sane. | 602 // Validate that this block is sane. |
412 if (CurCodeSize == 0 || AtEndOfStream() || | 603 if (CurCodeSize == 0 || AtEndOfStream()) |
413 NextChar+NumWords*4 > BitStream->getLastChar()) | |
414 return true; | 604 return true; |
415 | 605 |
416 return false; | 606 return false; |
417 } | 607 } |
418 | 608 |
419 bool ReadBlockEnd() { | 609 bool ReadBlockEnd() { |
420 if (BlockScope.empty()) return true; | 610 if (BlockScope.empty()) return true; |
421 | 611 |
422 // Block tail: | 612 // Block tail: |
423 // [END_BLOCK, <align4bytes>] | 613 // [END_BLOCK, <align4bytes>] |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
505 | 695 |
506 // Read all the elements. | 696 // Read all the elements. |
507 for (; NumElts; --NumElts) | 697 for (; NumElts; --NumElts) |
508 ReadAbbreviatedField(EltEnc, Vals); | 698 ReadAbbreviatedField(EltEnc, Vals); |
509 } else if (Op.getEncoding() == BitCodeAbbrevOp::Blob) { | 699 } else if (Op.getEncoding() == BitCodeAbbrevOp::Blob) { |
510 // Blob case. Read the number of bytes as a vbr6. | 700 // Blob case. Read the number of bytes as a vbr6. |
511 unsigned NumElts = ReadVBR(6); | 701 unsigned NumElts = ReadVBR(6); |
512 SkipToWord(); // 32-bit alignment | 702 SkipToWord(); // 32-bit alignment |
513 | 703 |
514 // Figure out where the end of this blob will be including tail padding. | 704 // Figure out where the end of this blob will be including tail padding. |
515 const unsigned char *NewEnd = NextChar+((NumElts+3)&~3); | 705 size_t NewEnd = NextChar+((NumElts+3)&~3); |
516 | 706 |
517 // If this would read off the end of the bitcode file, just set the | 707 // If this would read off the end of the bitcode file, just set the |
518 // record to empty and return. | 708 // record to empty and return. |
519 if (NewEnd > BitStream->getLastChar()) { | 709 if (!BitStream->getBytes().canSkipToPos(NewEnd)) { |
520 Vals.append(NumElts, 0); | 710 Vals.append(NumElts, 0); |
521 NextChar = BitStream->getLastChar(); | 711 NextChar = BitStream->getBytes().getEndPos(); |
522 break; | 712 break; |
523 } | 713 } |
524 | 714 |
525 // Otherwise, read the number of bytes. If we can return a reference to | 715 // Otherwise, read the number of bytes. If we can return a reference to |
526 // the data, do so to avoid copying it. | 716 // the data, do so to avoid copying it. |
527 if (BlobStart) { | 717 if (BlobStart) { |
528 *BlobStart = (const char*)NextChar; | 718 *BlobStart = (const char*)BitStream->getBytes().addressOf(NextChar); |
529 *BlobLen = NumElts; | 719 *BlobLen = NumElts; |
530 } else { | 720 } else { |
531 for (; NumElts; ++NextChar, --NumElts) | 721 for (; NumElts; ++NextChar, --NumElts) |
532 Vals.push_back(*NextChar); | 722 Vals.push_back(BitStream->getBytes().getByte(NextChar)); |
533 } | 723 } |
534 // Skip over tail padding. | 724 // Skip over tail padding. |
535 NextChar = NewEnd; | 725 NextChar = NewEnd; |
536 } else { | 726 } else { |
537 ReadAbbreviatedField(Op, Vals); | 727 ReadAbbreviatedField(Op, Vals); |
538 } | 728 } |
539 } | 729 } |
540 | 730 |
541 unsigned Code = (unsigned)Vals[0]; | 731 unsigned Code = (unsigned)Vals[0]; |
542 Vals.erase(Vals.begin()); | 732 Vals.erase(Vals.begin()); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
636 break; | 826 break; |
637 } | 827 } |
638 } | 828 } |
639 } | 829 } |
640 } | 830 } |
641 }; | 831 }; |
642 | 832 |
643 } // End llvm namespace | 833 } // End llvm namespace |
644 | 834 |
645 #endif | 835 #endif |
OLD | NEW |