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

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

Issue 8393017: Bitcode streaming (Closed)
Patch Set: Created 9 years, 1 month 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
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/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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698