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/Bitcode/BitcodeStream.h" |
19 #include <climits> | 21 #include <climits> |
20 #include <string> | 22 #include <string> |
21 #include <vector> | 23 #include <vector> |
22 | 24 #include <stdio.h> |
23 namespace llvm { | 25 namespace llvm { |
24 | 26 |
25 class Deserializer; | 27 class Deserializer; |
26 | 28 |
| 29 class BitstreamVector { |
| 30 public: |
| 31 BitstreamVector() { } |
| 32 |
| 33 virtual ~BitstreamVector() { } |
| 34 |
| 35 // Is Pos the ending file position (one byte past the last valid byte). |
| 36 // May block until Pos bytes have been read, or EOF is reached. |
| 37 virtual bool isEndPos(size_t Pos) = 0; |
| 38 |
| 39 // Returns the ending file position (one byte past the last valid byte). |
| 40 // May block until EOF is reached. |
| 41 virtual size_t getEndPos() = 0; |
| 42 |
| 43 // Returns true if seeking to Pos is within the file. |
| 44 // May block until Pos bytes have been read, or EOF is reached. |
| 45 virtual bool canSkipToPos(size_t Pos) = 0; |
| 46 |
| 47 // Returns the in memory address of Pos from the beginning of the file. |
| 48 // May block until Pos bytes have been read, or EOF is reached. |
| 49 // Returned pointer may be invalidated by subsequent calls to other methods. |
| 50 virtual const unsigned char* addressOf(size_t Pos) = 0; |
| 51 |
| 52 // Returns the character at Pos from the beginning of the file. |
| 53 // May block until Pos bytes have been read, or EOF is reached. |
| 54 unsigned char operator[](size_t Pos) { |
| 55 return *addressOf(Pos); |
| 56 } |
| 57 |
| 58 private: |
| 59 BitstreamVector(const BitstreamVector&); // NOT IMPLEMENTED |
| 60 void operator=(const BitstreamVector&); // NOT IMPLEMENTED |
| 61 }; |
| 62 |
| 63 class MemoryBitstreamVector : public BitstreamVector { |
| 64 public: |
| 65 MemoryBitstreamVector() { } |
| 66 |
| 67 MemoryBitstreamVector(const unsigned char* Start, const unsigned char* End) |
| 68 : FirstChar(Start), LastChar(End) { |
| 69 } |
| 70 |
| 71 virtual ~MemoryBitstreamVector() { } |
| 72 |
| 73 virtual bool isEndPos(size_t Pos) { |
| 74 return Pos == static_cast<size_t>(LastChar-FirstChar); |
| 75 } |
| 76 |
| 77 virtual size_t getEndPos() { |
| 78 return static_cast<size_t>(LastChar-FirstChar); |
| 79 } |
| 80 |
| 81 virtual bool canSkipToPos(size_t Pos) { |
| 82 return Pos <= static_cast<size_t>(LastChar-FirstChar); |
| 83 } |
| 84 |
| 85 virtual const unsigned char* addressOf(size_t Pos) { |
| 86 assert(canSkipToPos(Pos) && Pos != static_cast<size_t>(LastChar-FirstChar) |
| 87 && "taking address outside of buffer"); |
| 88 return FirstChar + Pos; |
| 89 } |
| 90 |
| 91 private: |
| 92 const unsigned char* FirstChar; |
| 93 const unsigned char* LastChar; |
| 94 |
| 95 MemoryBitstreamVector(const MemoryBitstreamVector&); // NOT IMPLEMENTED |
| 96 void operator=(const MemoryBitstreamVector&); // NOT IMPLEMENTED |
| 97 }; |
| 98 |
| 99 class LazyBitstreamVector : public MemoryBitstreamVector { |
| 100 public: |
| 101 LazyBitstreamVector(StreamChunkCallback cb) : Bytes(kChunkSize), |
| 102 GetMoreBytes(cb), BytesRead(0), BytesSkipped(0), BitcodeSize(0) { |
| 103 BytesRead = GetMoreBytes(&Bytes[0], kChunkSize); |
| 104 f = fopen("bc.out", "w"); |
| 105 fwrite(&Bytes[0], 1,BytesRead, f); |
| 106 } |
| 107 |
| 108 virtual ~LazyBitstreamVector() {fclose(f); } |
| 109 |
| 110 virtual bool isEndPos(size_t Pos) { |
| 111 if (BitcodeSize) return Pos == BitcodeSize; |
| 112 fetchToPos(Pos); |
| 113 return Pos == BytesRead; |
| 114 } |
| 115 |
| 116 virtual size_t getEndPos() { |
| 117 if (BitcodeSize) return BitcodeSize; |
| 118 size_t pos = BytesRead + kChunkSize; |
| 119 while(fetchToPos(pos)) pos += kChunkSize; |
| 120 return BytesRead; |
| 121 } |
| 122 |
| 123 // If the bitcode has a header, then its size is known, and we don't have to |
| 124 // block until we actually want to read it. |
| 125 // TODO(dschuff): wrap pexe files in a bitcode header. |
| 126 virtual bool canSkipToPos(size_t Pos) { |
| 127 if (BitcodeSize && Pos <= BitcodeSize) return true; |
| 128 return fetchToPos(Pos); |
| 129 } |
| 130 |
| 131 virtual const unsigned char* addressOf(size_t Pos) { |
| 132 assert(canSkipToPos(Pos) && Pos != BytesRead |
| 133 && "taking address outside of buffer"); |
| 134 fetchToPos(Pos); |
| 135 return &Bytes[Pos + BytesSkipped]; |
| 136 } |
| 137 |
| 138 // Drop s bytes from the front of the vector, pushing the positions of the |
| 139 // remaining bytes down by s. This is used to skip past the bitcode header, |
| 140 // since we don't know a priori if it's present, and we can't put bytes |
| 141 // back into the stream once we've read them. |
| 142 bool dropLeadingBytes(size_t s) { |
| 143 if (BytesRead < s) return true; |
| 144 BytesSkipped = s; |
| 145 BytesRead -= s; |
| 146 return false; |
| 147 } |
| 148 |
| 149 void setKnownBitcodeSize(size_t size) { |
| 150 BitcodeSize = size; |
| 151 } |
| 152 |
| 153 private: |
| 154 const static uint32_t kChunkSize = 4096; |
| 155 std::vector<unsigned char> Bytes; |
| 156 StreamChunkCallback GetMoreBytes; |
| 157 size_t BytesRead; |
| 158 size_t BytesSkipped; |
| 159 size_t BitcodeSize; |
| 160 FILE *f; |
| 161 |
| 162 // Unlike most of the functions in BitcodeReader, returns true on success |
| 163 bool fetchToPos(size_t Pos) { |
| 164 while (Pos > BytesRead) { |
| 165 Bytes.resize(BytesRead + kChunkSize); |
| 166 size_t bytes = GetMoreBytes(&Bytes[BytesRead + BytesSkipped], kChunkSize); |
| 167 fwrite(&Bytes[BytesRead + BytesSkipped], 1, bytes, f); |
| 168 BytesRead += bytes; |
| 169 if (bytes < kChunkSize) { |
| 170 if (BitcodeSize && BytesRead < Pos) |
| 171 assert(0 && "Unexpected short read fetching bitcode"); |
| 172 if (BytesRead < Pos) return false; |
| 173 } |
| 174 } |
| 175 return true; |
| 176 } |
| 177 |
| 178 LazyBitstreamVector(const LazyBitstreamVector&); // NOT IMPLEMENTED |
| 179 void operator=(const LazyBitstreamVector&); // NOT IMPLEMENTED |
| 180 }; |
| 181 |
27 class BitstreamReader { | 182 class BitstreamReader { |
28 public: | 183 public: |
29 /// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks. | 184 /// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks. |
30 /// These describe abbreviations that all blocks of the specified ID inherit. | 185 /// These describe abbreviations that all blocks of the specified ID inherit. |
31 struct BlockInfo { | 186 struct BlockInfo { |
32 unsigned BlockID; | 187 unsigned BlockID; |
33 std::vector<BitCodeAbbrev*> Abbrevs; | 188 std::vector<BitCodeAbbrev*> Abbrevs; |
34 std::string Name; | 189 std::string Name; |
35 | 190 |
36 std::vector<std::pair<unsigned, std::string> > RecordNames; | 191 std::vector<std::pair<unsigned, std::string> > RecordNames; |
37 }; | 192 }; |
38 private: | 193 private: |
39 /// FirstChar/LastChar - This remembers the first and last bytes of the | 194 OwningPtr<BitstreamVector> BSV; |
40 /// stream. | |
41 const unsigned char *FirstChar, *LastChar; | |
42 | 195 |
43 std::vector<BlockInfo> BlockInfoRecords; | 196 std::vector<BlockInfo> BlockInfoRecords; |
44 | 197 |
45 /// IgnoreBlockInfoNames - This is set to true if we don't care about the | 198 /// 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 | 199 /// block/record name information in the BlockInfo block. Only llvm-bcanalyzer |
47 /// uses this. | 200 /// uses this. |
48 bool IgnoreBlockInfoNames; | 201 bool IgnoreBlockInfoNames; |
49 | 202 |
50 BitstreamReader(const BitstreamReader&); // NOT IMPLEMENTED | 203 BitstreamReader(const BitstreamReader&); // NOT IMPLEMENTED |
51 void operator=(const BitstreamReader&); // NOT IMPLEMENTED | 204 void operator=(const BitstreamReader&); // NOT IMPLEMENTED |
52 public: | 205 public: |
53 BitstreamReader() : FirstChar(0), LastChar(0), IgnoreBlockInfoNames(true) { | 206 BitstreamReader() : IgnoreBlockInfoNames(true) { |
54 } | 207 } |
55 | 208 |
56 BitstreamReader(const unsigned char *Start, const unsigned char *End) { | 209 BitstreamReader(const unsigned char *Start, const unsigned char *End) { |
57 IgnoreBlockInfoNames = true; | 210 IgnoreBlockInfoNames = true; |
58 init(Start, End); | 211 init(Start, End); |
59 } | 212 } |
60 | 213 |
| 214 BitstreamReader(BitstreamVector* bsv) { |
| 215 BSV.reset(bsv); |
| 216 } |
| 217 |
61 void init(const unsigned char *Start, const unsigned char *End) { | 218 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"); | 219 assert(((End-Start) & 3) == 0 &&"Bitcode stream not a multiple of 4 bytes"); |
| 220 BSV.reset(new MemoryBitstreamVector(Start, End)); |
65 } | 221 } |
66 | 222 |
| 223 BitstreamVector& getBSV() { return *BSV; } |
| 224 |
67 ~BitstreamReader() { | 225 ~BitstreamReader() { |
68 // Free the BlockInfoRecords. | 226 // Free the BlockInfoRecords. |
69 while (!BlockInfoRecords.empty()) { | 227 while (!BlockInfoRecords.empty()) { |
70 BlockInfo &Info = BlockInfoRecords.back(); | 228 BlockInfo &Info = BlockInfoRecords.back(); |
71 // Free blockinfo abbrev info. | 229 // Free blockinfo abbrev info. |
72 for (unsigned i = 0, e = static_cast<unsigned>(Info.Abbrevs.size()); | 230 for (unsigned i = 0, e = static_cast<unsigned>(Info.Abbrevs.size()); |
73 i != e; ++i) | 231 i != e; ++i) |
74 Info.Abbrevs[i]->dropRef(); | 232 Info.Abbrevs[i]->dropRef(); |
75 BlockInfoRecords.pop_back(); | 233 BlockInfoRecords.pop_back(); |
76 } | 234 } |
77 } | 235 } |
78 | 236 |
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 | 237 /// CollectBlockInfoNames - This is called by clients that want block/record |
83 /// name information. | 238 /// name information. |
84 void CollectBlockInfoNames() { IgnoreBlockInfoNames = false; } | 239 void CollectBlockInfoNames() { IgnoreBlockInfoNames = false; } |
85 bool isIgnoringBlockInfoNames() { return IgnoreBlockInfoNames; } | 240 bool isIgnoringBlockInfoNames() { return IgnoreBlockInfoNames; } |
86 | 241 |
87 //===--------------------------------------------------------------------===// | 242 //===--------------------------------------------------------------------===// |
88 // Block Manipulation | 243 // Block Manipulation |
89 //===--------------------------------------------------------------------===// | 244 //===--------------------------------------------------------------------===// |
90 | 245 |
91 /// hasBlockInfoRecords - Return true if we've already read and processed the | 246 /// hasBlockInfoRecords - Return true if we've already read and processed the |
(...skipping 23 matching lines...) Expand all Loading... |
115 BlockInfoRecords.push_back(BlockInfo()); | 270 BlockInfoRecords.push_back(BlockInfo()); |
116 BlockInfoRecords.back().BlockID = BlockID; | 271 BlockInfoRecords.back().BlockID = BlockID; |
117 return BlockInfoRecords.back(); | 272 return BlockInfoRecords.back(); |
118 } | 273 } |
119 | 274 |
120 }; | 275 }; |
121 | 276 |
122 class BitstreamCursor { | 277 class BitstreamCursor { |
123 friend class Deserializer; | 278 friend class Deserializer; |
124 BitstreamReader *BitStream; | 279 BitstreamReader *BitStream; |
125 const unsigned char *NextChar; | 280 size_t NextChar; |
126 | 281 |
127 /// CurWord - This is the current data we have pulled from the stream but have | 282 /// CurWord - This is the current data we have pulled from the stream but have |
128 /// not returned to the client. | 283 /// not returned to the client. |
129 uint32_t CurWord; | 284 uint32_t CurWord; |
130 | 285 |
131 /// BitsInCurWord - This is the number of bits in CurWord that are valid. This | 286 /// BitsInCurWord - This is the number of bits in CurWord that are valid. This |
132 /// is always from [0...31] inclusive. | 287 /// is always from [0...31] inclusive. |
133 unsigned BitsInCurWord; | 288 unsigned BitsInCurWord; |
134 | 289 |
135 // CurCodeSize - This is the declared size of code values used for the current | 290 // 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; | 304 SmallVector<Block, 8> BlockScope; |
150 | 305 |
151 public: | 306 public: |
152 BitstreamCursor() : BitStream(0), NextChar(0) { | 307 BitstreamCursor() : BitStream(0), NextChar(0) { |
153 } | 308 } |
154 BitstreamCursor(const BitstreamCursor &RHS) : BitStream(0), NextChar(0) { | 309 BitstreamCursor(const BitstreamCursor &RHS) : BitStream(0), NextChar(0) { |
155 operator=(RHS); | 310 operator=(RHS); |
156 } | 311 } |
157 | 312 |
158 explicit BitstreamCursor(BitstreamReader &R) : BitStream(&R) { | 313 explicit BitstreamCursor(BitstreamReader &R) : BitStream(&R) { |
159 NextChar = R.getFirstChar(); | 314 NextChar = 0; |
160 assert(NextChar && "Bitstream not initialized yet"); | |
161 CurWord = 0; | 315 CurWord = 0; |
162 BitsInCurWord = 0; | 316 BitsInCurWord = 0; |
163 CurCodeSize = 2; | 317 CurCodeSize = 2; |
164 } | 318 } |
165 | 319 |
166 void init(BitstreamReader &R) { | 320 void init(BitstreamReader &R) { |
167 freeState(); | 321 freeState(); |
168 | 322 |
169 BitStream = &R; | 323 BitStream = &R; |
170 NextChar = R.getFirstChar(); | 324 NextChar = 0; |
171 assert(NextChar && "Bitstream not initialized yet"); | |
172 CurWord = 0; | 325 CurWord = 0; |
173 BitsInCurWord = 0; | 326 BitsInCurWord = 0; |
174 CurCodeSize = 2; | 327 CurCodeSize = 2; |
175 } | 328 } |
176 | 329 |
177 ~BitstreamCursor() { | 330 ~BitstreamCursor() { |
178 freeState(); | 331 freeState(); |
179 } | 332 } |
180 | 333 |
181 void operator=(const BitstreamCursor &RHS) { | 334 void operator=(const BitstreamCursor &RHS) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 i != e; ++i) | 372 i != e; ++i) |
220 Abbrevs[i]->dropRef(); | 373 Abbrevs[i]->dropRef(); |
221 } | 374 } |
222 BlockScope.clear(); | 375 BlockScope.clear(); |
223 } | 376 } |
224 | 377 |
225 /// GetAbbrevIDWidth - Return the number of bits used to encode an abbrev #. | 378 /// GetAbbrevIDWidth - Return the number of bits used to encode an abbrev #. |
226 unsigned GetAbbrevIDWidth() const { return CurCodeSize; } | 379 unsigned GetAbbrevIDWidth() const { return CurCodeSize; } |
227 | 380 |
228 bool AtEndOfStream() const { | 381 bool AtEndOfStream() const { |
229 return NextChar == BitStream->getLastChar() && BitsInCurWord == 0; | 382 return BitStream->getBSV().isEndPos(NextChar) && BitsInCurWord == 0; |
230 } | 383 } |
231 | 384 |
232 /// GetCurrentBitNo - Return the bit # of the bit we are reading. | 385 /// GetCurrentBitNo - Return the bit # of the bit we are reading. |
233 uint64_t GetCurrentBitNo() const { | 386 uint64_t GetCurrentBitNo() const { |
234 return (NextChar-BitStream->getFirstChar())*CHAR_BIT - BitsInCurWord; | 387 return NextChar*CHAR_BIT - BitsInCurWord; |
235 } | 388 } |
236 | 389 |
237 BitstreamReader *getBitStreamReader() { | 390 BitstreamReader *getBitStreamReader() { |
238 return BitStream; | 391 return BitStream; |
239 } | 392 } |
240 const BitstreamReader *getBitStreamReader() const { | 393 const BitstreamReader *getBitStreamReader() const { |
241 return BitStream; | 394 return BitStream; |
242 } | 395 } |
243 | 396 |
244 | 397 |
245 /// JumpToBit - Reset the stream to the specified bit number. | 398 /// JumpToBit - Reset the stream to the specified bit number. |
246 void JumpToBit(uint64_t BitNo) { | 399 void JumpToBit(uint64_t BitNo) { |
247 uintptr_t ByteNo = uintptr_t(BitNo/8) & ~3; | 400 uintptr_t ByteNo = uintptr_t(BitNo/8) & ~3; |
248 uintptr_t WordBitNo = uintptr_t(BitNo) & 31; | 401 uintptr_t WordBitNo = uintptr_t(BitNo) & 31; |
249 assert(ByteNo <= (uintptr_t)(BitStream->getLastChar()- | 402 assert(BitStream->getBSV().canSkipToPos(ByteNo) && "Invalid location"); |
250 BitStream->getFirstChar()) && | |
251 "Invalid location"); | |
252 | 403 |
253 // Move the cursor to the right word. | 404 // Move the cursor to the right word. |
254 NextChar = BitStream->getFirstChar()+ByteNo; | 405 NextChar = ByteNo; |
255 BitsInCurWord = 0; | 406 BitsInCurWord = 0; |
256 CurWord = 0; | 407 CurWord = 0; |
257 | 408 |
258 // Skip over any bits that are already consumed. | 409 // Skip over any bits that are already consumed. |
259 if (WordBitNo) | 410 if (WordBitNo) |
260 Read(static_cast<unsigned>(WordBitNo)); | 411 Read(static_cast<unsigned>(WordBitNo)); |
261 } | 412 } |
262 | 413 |
263 | 414 |
264 uint32_t Read(unsigned NumBits) { | 415 uint32_t Read(unsigned NumBits) { |
265 assert(NumBits <= 32 && "Cannot return more than 32 bits!"); | 416 assert(NumBits <= 32 && "Cannot return more than 32 bits!"); |
266 // If the field is fully contained by CurWord, return it quickly. | 417 // If the field is fully contained by CurWord, return it quickly. |
267 if (BitsInCurWord >= NumBits) { | 418 if (BitsInCurWord >= NumBits) { |
268 uint32_t R = CurWord & ((1U << NumBits)-1); | 419 uint32_t R = CurWord & ((1U << NumBits)-1); |
269 CurWord >>= NumBits; | 420 CurWord >>= NumBits; |
270 BitsInCurWord -= NumBits; | 421 BitsInCurWord -= NumBits; |
271 return R; | 422 return R; |
272 } | 423 } |
273 | 424 |
274 // If we run out of data, stop at the end of the stream. | 425 // If we run out of data, stop at the end of the stream. |
275 if (NextChar == BitStream->getLastChar()) { | 426 if (BitStream->getBSV().isEndPos(NextChar)) { |
276 CurWord = 0; | 427 CurWord = 0; |
277 BitsInCurWord = 0; | 428 BitsInCurWord = 0; |
278 return 0; | 429 return 0; |
279 } | 430 } |
280 | 431 |
281 unsigned R = CurWord; | 432 unsigned R = CurWord; |
282 | 433 |
283 // Read the next word from the stream. | 434 // Read the next word from the stream. |
284 CurWord = (NextChar[0] << 0) | (NextChar[1] << 8) | | 435 CurWord = (BitStream->getBSV()[NextChar+0] << 0) | |
285 (NextChar[2] << 16) | (NextChar[3] << 24); | 436 (BitStream->getBSV()[NextChar+1] << 8) | |
| 437 (BitStream->getBSV()[NextChar+2] << 16) | |
| 438 (BitStream->getBSV()[NextChar+3] << 24); |
286 NextChar += 4; | 439 NextChar += 4; |
287 | 440 |
288 // Extract NumBits-BitsInCurWord from what we just read. | 441 // Extract NumBits-BitsInCurWord from what we just read. |
289 unsigned BitsLeft = NumBits-BitsInCurWord; | 442 unsigned BitsLeft = NumBits-BitsInCurWord; |
290 | 443 |
291 // Be careful here, BitsLeft is in the range [1..32] inclusive. | 444 // Be careful here, BitsLeft is in the range [1..32] inclusive. |
292 R |= (CurWord & (~0U >> (32-BitsLeft))) << BitsInCurWord; | 445 R |= (CurWord & (~0U >> (32-BitsLeft))) << BitsInCurWord; |
293 | 446 |
294 // BitsLeft bits have just been used up from CurWord. | 447 // BitsLeft bits have just been used up from CurWord. |
295 if (BitsLeft != 32) | 448 if (BitsLeft != 32) |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 /// true. | 522 /// true. |
370 bool SkipBlock() { | 523 bool SkipBlock() { |
371 // Read and ignore the codelen value. Since we are skipping this block, we | 524 // 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. | 525 // don't care what code widths are used inside of it. |
373 ReadVBR(bitc::CodeLenWidth); | 526 ReadVBR(bitc::CodeLenWidth); |
374 SkipToWord(); | 527 SkipToWord(); |
375 unsigned NumWords = Read(bitc::BlockSizeWidth); | 528 unsigned NumWords = Read(bitc::BlockSizeWidth); |
376 | 529 |
377 // Check that the block wasn't partially defined, and that the offset isn't | 530 // Check that the block wasn't partially defined, and that the offset isn't |
378 // bogus. | 531 // bogus. |
379 const unsigned char *const SkipTo = NextChar + NumWords*4; | 532 size_t SkipTo = NextChar + NumWords*4; |
380 if (AtEndOfStream() || SkipTo > BitStream->getLastChar() || | 533 if (AtEndOfStream() || !BitStream->getBSV().canSkipToPos(SkipTo)) |
381 SkipTo < BitStream->getFirstChar()) | |
382 return true; | 534 return true; |
383 | 535 |
384 NextChar = SkipTo; | 536 NextChar = SkipTo; |
385 return false; | 537 return false; |
386 } | 538 } |
387 | 539 |
388 /// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter | 540 /// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter |
389 /// the block, and return true if the block is valid. | 541 /// the block, and return true if the block is valid. |
390 bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = 0) { | 542 bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = 0) { |
391 // Save the current block's state on BlockScope. | 543 // Save the current block's state on BlockScope. |
(...skipping 11 matching lines...) Expand all Loading... |
403 } | 555 } |
404 | 556 |
405 // Get the codesize of this block. | 557 // Get the codesize of this block. |
406 CurCodeSize = ReadVBR(bitc::CodeLenWidth); | 558 CurCodeSize = ReadVBR(bitc::CodeLenWidth); |
407 SkipToWord(); | 559 SkipToWord(); |
408 unsigned NumWords = Read(bitc::BlockSizeWidth); | 560 unsigned NumWords = Read(bitc::BlockSizeWidth); |
409 if (NumWordsP) *NumWordsP = NumWords; | 561 if (NumWordsP) *NumWordsP = NumWords; |
410 | 562 |
411 // Validate that this block is sane. | 563 // Validate that this block is sane. |
412 if (CurCodeSize == 0 || AtEndOfStream() || | 564 if (CurCodeSize == 0 || AtEndOfStream() || |
413 NextChar+NumWords*4 > BitStream->getLastChar()) | 565 !BitStream->getBSV().canSkipToPos(NextChar+NumWords*4)) |
414 return true; | 566 return true; |
415 | 567 |
416 return false; | 568 return false; |
417 } | 569 } |
418 | 570 |
419 bool ReadBlockEnd() { | 571 bool ReadBlockEnd() { |
420 if (BlockScope.empty()) return true; | 572 if (BlockScope.empty()) return true; |
421 | 573 |
422 // Block tail: | 574 // Block tail: |
423 // [END_BLOCK, <align4bytes>] | 575 // [END_BLOCK, <align4bytes>] |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
505 | 657 |
506 // Read all the elements. | 658 // Read all the elements. |
507 for (; NumElts; --NumElts) | 659 for (; NumElts; --NumElts) |
508 ReadAbbreviatedField(EltEnc, Vals); | 660 ReadAbbreviatedField(EltEnc, Vals); |
509 } else if (Op.getEncoding() == BitCodeAbbrevOp::Blob) { | 661 } else if (Op.getEncoding() == BitCodeAbbrevOp::Blob) { |
510 // Blob case. Read the number of bytes as a vbr6. | 662 // Blob case. Read the number of bytes as a vbr6. |
511 unsigned NumElts = ReadVBR(6); | 663 unsigned NumElts = ReadVBR(6); |
512 SkipToWord(); // 32-bit alignment | 664 SkipToWord(); // 32-bit alignment |
513 | 665 |
514 // Figure out where the end of this blob will be including tail padding. | 666 // Figure out where the end of this blob will be including tail padding. |
515 const unsigned char *NewEnd = NextChar+((NumElts+3)&~3); | 667 size_t NewEnd = NextChar+((NumElts+3)&~3); |
516 | 668 |
517 // If this would read off the end of the bitcode file, just set the | 669 // If this would read off the end of the bitcode file, just set the |
518 // record to empty and return. | 670 // record to empty and return. |
519 if (NewEnd > BitStream->getLastChar()) { | 671 if (!BitStream->getBSV().canSkipToPos(NewEnd)) { |
520 Vals.append(NumElts, 0); | 672 Vals.append(NumElts, 0); |
521 NextChar = BitStream->getLastChar(); | 673 NextChar = BitStream->getBSV().getEndPos(); |
522 break; | 674 break; |
523 } | 675 } |
524 | 676 |
525 // Otherwise, read the number of bytes. If we can return a reference to | 677 // Otherwise, read the number of bytes. If we can return a reference to |
526 // the data, do so to avoid copying it. | 678 // the data, do so to avoid copying it. |
527 if (BlobStart) { | 679 if (BlobStart) { |
528 *BlobStart = (const char*)NextChar; | 680 *BlobStart = (const char*)BitStream->getBSV().addressOf(NextChar); |
529 *BlobLen = NumElts; | 681 *BlobLen = NumElts; |
530 } else { | 682 } else { |
531 for (; NumElts; ++NextChar, --NumElts) | 683 for (; NumElts; ++NextChar, --NumElts) |
532 Vals.push_back(*NextChar); | 684 Vals.push_back(BitStream->getBSV()[NextChar]); |
533 } | 685 } |
534 // Skip over tail padding. | 686 // Skip over tail padding. |
535 NextChar = NewEnd; | 687 NextChar = NewEnd; |
536 } else { | 688 } else { |
537 ReadAbbreviatedField(Op, Vals); | 689 ReadAbbreviatedField(Op, Vals); |
538 } | 690 } |
539 } | 691 } |
540 | 692 |
541 unsigned Code = (unsigned)Vals[0]; | 693 unsigned Code = (unsigned)Vals[0]; |
542 Vals.erase(Vals.begin()); | 694 Vals.erase(Vals.begin()); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
636 break; | 788 break; |
637 } | 789 } |
638 } | 790 } |
639 } | 791 } |
640 } | 792 } |
641 }; | 793 }; |
642 | 794 |
643 } // End llvm namespace | 795 } // End llvm namespace |
644 | 796 |
645 #endif | 797 #endif |
OLD | NEW |