Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Side by Side Diff: include/llvm/Bitcode/BitstreamReader.h

Issue 8393017: Bitcode streaming (Closed)
Patch Set: put destructors back, fix trailing whitespace Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | include/llvm/Bitcode/ReaderWriter.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | include/llvm/Bitcode/ReaderWriter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698