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

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

Issue 8393017: Bitcode streaming (Closed)
Patch Set: rebase against upstream LLVM 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
23 namespace llvm { 25 namespace llvm {
24 26
25 class Deserializer; 27 class Deserializer;
26 28
29 class BitstreamVector {
nlewycky 2011/11/05 00:45:06 This interface doesn't act much like a std::vector
30 public:
31 BitstreamVector() { }
32
33 virtual ~BitstreamVector() { }
34
35 // Is Pos the ending file position (one byte past the last valid byte).
nlewycky 2011/11/05 00:45:06 "Is Pos the ending file position (one byte past th
(google.com) Derek Schuff 2011/11/08 00:53:23 Done.
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;
nlewycky 2011/11/05 00:45:06 Extra space in "() = 0".
(google.com) Derek Schuff 2011/11/08 00:53:23 Done.
42
43 // Returns true if seeking to Pos is within the file or one past the end.
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 // Note that the first byte past the end may be skipped to, but may not have
50 // its address taken.
51 virtual const unsigned char* addressOf(size_t Pos) = 0;
52
53 // Returns the character at Pos from the beginning of the file.
54 // May block until Pos bytes have been read, or EOF is reached.
55 virtual unsigned char operator[](size_t Pos) = 0;
56
57 private:
58 BitstreamVector(const BitstreamVector&); // NOT IMPLEMENTED
59 void operator=(const BitstreamVector&); // NOT IMPLEMENTED
60 };
61
62 class MemoryBitstreamVector : public BitstreamVector {
63 public:
64 MemoryBitstreamVector() { }
65
66 MemoryBitstreamVector(const unsigned char* Start, const unsigned char* End)
67 : FirstChar(Start), LastChar(End) {
68 }
69
70 virtual ~MemoryBitstreamVector() { }
71
72 virtual bool isEndPos(size_t Pos) {
73 return Pos == static_cast<size_t>(LastChar-FirstChar);
74 }
75
76 virtual size_t getEndPos() {
77 return static_cast<size_t>(LastChar-FirstChar);
78 }
79
80 virtual bool canSkipToPos(size_t Pos) {
81 return Pos <= static_cast<size_t>(LastChar-FirstChar);
82 }
83
84 virtual const unsigned char* addressOf(size_t Pos) {
85 assert(canSkipToPos(Pos) && Pos != static_cast<size_t>(LastChar-FirstChar)
86 && "taking address outside of buffer");
87 return FirstChar + Pos;
88 }
89
90 virtual unsigned char operator [](size_t Pos) {
nlewycky 2011/11/05 00:45:06 This is confusing. Should it instead be returning
(google.com) Derek Schuff 2011/11/08 00:53:23 This container isn't supposed to be mutable. also,
91 assert(canSkipToPos(Pos) && Pos != static_cast<size_t>(LastChar-FirstChar)
92 && "indexing outside of buffer");
nlewycky 2011/11/05 00:45:06 Bad indent. (Can the && go on the previous line? W
(google.com) Derek Schuff 2011/11/08 00:53:23 Done.
93 return *(FirstChar + Pos);
94 }
95
96 private:
97 const unsigned char* FirstChar;
98 const unsigned char* LastChar;
99
100 MemoryBitstreamVector(const MemoryBitstreamVector&); // NOT IMPLEMENTED
101 void operator=(const MemoryBitstreamVector&); // NOT IMPLEMENTED
102 };
103
104 class LazyBitstreamVector : public BitstreamVector {
105 public:
106 LazyBitstreamVector(BitcodeStreamer* streamer) : Bytes(kChunkSize),
nlewycky 2011/11/05 00:45:06 Please most the constructor list to starting on th
(google.com) Derek Schuff 2011/11/08 00:53:23 Done.
107 Streamer(streamer), BytesRead(0), BytesSkipped(0), BitcodeSize(0),
108 EOFReached(false) {
109 BytesRead = streamer->GetBytes(&Bytes[0], kChunkSize);
110 }
111
112 virtual ~LazyBitstreamVector() {}
113
114 virtual bool isEndPos(size_t Pos) {
115 if (BitcodeSize) return Pos == BitcodeSize;
116 fetchToPos(Pos);
117 return Pos == BytesRead;
118 }
119
120 virtual size_t getEndPos() {
121 if (BitcodeSize) return BitcodeSize;
122 size_t pos = BytesRead + kChunkSize;
123 // keep fetching until we run out of bytes
124 while(fetchToPos(pos)) pos += kChunkSize;
125 return BitcodeSize;
126 }
127
128 // If the bitcode has a header, then its size is known, and we don't have to
129 // block until we actually want to read it.
130 virtual bool canSkipToPos(size_t Pos) {
131 if (BitcodeSize && Pos <= BitcodeSize) return true;
132 return fetchToPos(Pos) || Pos == BitcodeSize;
133 }
134
135 virtual const unsigned char* addressOf(size_t Pos) {
136 assert(0 && "addressOf inside streaming vectors not allowed");
137 return NULL;
138 }
139
140 virtual unsigned char operator [](size_t Pos) {
141 fetchToPos(Pos);
142 assert(Pos < BytesRead && "indexing outside of buffer");
143 return Bytes[Pos + BytesSkipped];
144 }
145
146 // Drop s bytes from the front of the vector, pushing the positions of the
147 // remaining bytes down by s. This is used to skip past the bitcode header,
148 // since we don't know a priori if it's present, and we can't put bytes
149 // back into the stream once we've read them.
150 bool dropLeadingBytes(size_t s) {
151 if (BytesRead < s) return true;
152 BytesSkipped = s;
153 BytesRead -= s;
154 return false;
155 }
156
157 void setKnownBitcodeSize(size_t size) {
158 BitcodeSize = size;
159 }
160
161 private:
162 const static uint32_t kChunkSize = 4096;
163 std::vector<unsigned char> Bytes;
164 OwningPtr<BitcodeStreamer> Streamer;
165 size_t BytesRead; // Bytes read from stream
166 size_t BytesSkipped;// Bytes skipped at start of stream (e.g. wrapper/header)
167 size_t BitcodeSize; // 0 if unknown, set if wrapper was seen or EOF reached
168 bool EOFReached;
169
170 // fetch enough bytes such that Pos can be read or EOF is reached
171 // (i.e. BytesRead > Pos). Return true if Pos can be read.
172 // Unlike most of the functions in BitcodeReader, returns true on success
173 bool fetchToPos(size_t Pos) {
174 if (EOFReached) return Pos < BitcodeSize;
175 while (Pos >= BytesRead) {
176 Bytes.resize(BytesRead + kChunkSize);
177 size_t bytes = Streamer->GetBytes(&Bytes[BytesRead + BytesSkipped],
178 kChunkSize);
179 BytesRead += bytes;
180 if (bytes < kChunkSize) {
181 if (BitcodeSize && BytesRead < Pos)
182 assert(0 && "Unexpected short read fetching bitcode");
183 if (BytesRead <= Pos) { // reached EOF/ran out of bytes
184 BitcodeSize = BytesRead;
185 EOFReached = true;
186 return false;
187 }
188 }
189 }
190 return true;
191 }
192
193 LazyBitstreamVector(const LazyBitstreamVector&); // NOT IMPLEMENTED
194 void operator=(const LazyBitstreamVector&); // NOT IMPLEMENTED
195 };
196
27 class BitstreamReader { 197 class BitstreamReader {
28 public: 198 public:
29 /// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks. 199 /// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks.
30 /// These describe abbreviations that all blocks of the specified ID inherit. 200 /// These describe abbreviations that all blocks of the specified ID inherit.
31 struct BlockInfo { 201 struct BlockInfo {
32 unsigned BlockID; 202 unsigned BlockID;
33 std::vector<BitCodeAbbrev*> Abbrevs; 203 std::vector<BitCodeAbbrev*> Abbrevs;
34 std::string Name; 204 std::string Name;
35 205
36 std::vector<std::pair<unsigned, std::string> > RecordNames; 206 std::vector<std::pair<unsigned, std::string> > RecordNames;
37 }; 207 };
38 private: 208 private:
39 /// FirstChar/LastChar - This remembers the first and last bytes of the 209 OwningPtr<BitstreamVector> BSV;
40 /// stream.
41 const unsigned char *FirstChar, *LastChar;
42 210
43 std::vector<BlockInfo> BlockInfoRecords; 211 std::vector<BlockInfo> BlockInfoRecords;
44 212
45 /// IgnoreBlockInfoNames - This is set to true if we don't care about the 213 /// 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 214 /// block/record name information in the BlockInfo block. Only llvm-bcanalyzer
47 /// uses this. 215 /// uses this.
48 bool IgnoreBlockInfoNames; 216 bool IgnoreBlockInfoNames;
49 217
50 BitstreamReader(const BitstreamReader&); // NOT IMPLEMENTED 218 BitstreamReader(const BitstreamReader&); // NOT IMPLEMENTED
51 void operator=(const BitstreamReader&); // NOT IMPLEMENTED 219 void operator=(const BitstreamReader&); // NOT IMPLEMENTED
52 public: 220 public:
53 BitstreamReader() : FirstChar(0), LastChar(0), IgnoreBlockInfoNames(true) { 221 BitstreamReader() : IgnoreBlockInfoNames(true) {
54 } 222 }
55 223
56 BitstreamReader(const unsigned char *Start, const unsigned char *End) { 224 BitstreamReader(const unsigned char *Start, const unsigned char *End) {
57 IgnoreBlockInfoNames = true; 225 IgnoreBlockInfoNames = true;
58 init(Start, End); 226 init(Start, End);
59 } 227 }
60 228
229 BitstreamReader(BitstreamVector* bsv) {
nlewycky 2011/11/05 00:45:06 * on the right
(google.com) Derek Schuff 2011/11/08 00:53:23 Done.
230 BSV.reset(bsv);
231 }
232
61 void init(const unsigned char *Start, const unsigned char *End) { 233 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"); 234 assert(((End-Start) & 3) == 0 &&"Bitcode stream not a multiple of 4 bytes");
235 BSV.reset(new MemoryBitstreamVector(Start, End));
65 } 236 }
66 237
238 BitstreamVector& getBSV() { return *BSV; }
nlewycky 2011/11/05 00:45:06 & on the right.
(google.com) Derek Schuff 2011/11/08 00:53:23 Done.
239
67 ~BitstreamReader() { 240 ~BitstreamReader() {
68 // Free the BlockInfoRecords. 241 // Free the BlockInfoRecords.
69 while (!BlockInfoRecords.empty()) { 242 while (!BlockInfoRecords.empty()) {
70 BlockInfo &Info = BlockInfoRecords.back(); 243 BlockInfo &Info = BlockInfoRecords.back();
71 // Free blockinfo abbrev info. 244 // Free blockinfo abbrev info.
72 for (unsigned i = 0, e = static_cast<unsigned>(Info.Abbrevs.size()); 245 for (unsigned i = 0, e = static_cast<unsigned>(Info.Abbrevs.size());
73 i != e; ++i) 246 i != e; ++i)
74 Info.Abbrevs[i]->dropRef(); 247 Info.Abbrevs[i]->dropRef();
75 BlockInfoRecords.pop_back(); 248 BlockInfoRecords.pop_back();
76 } 249 }
77 } 250 }
78 251
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 252 /// CollectBlockInfoNames - This is called by clients that want block/record
83 /// name information. 253 /// name information.
84 void CollectBlockInfoNames() { IgnoreBlockInfoNames = false; } 254 void CollectBlockInfoNames() { IgnoreBlockInfoNames = false; }
85 bool isIgnoringBlockInfoNames() { return IgnoreBlockInfoNames; } 255 bool isIgnoringBlockInfoNames() { return IgnoreBlockInfoNames; }
86 256
87 //===--------------------------------------------------------------------===// 257 //===--------------------------------------------------------------------===//
88 // Block Manipulation 258 // Block Manipulation
89 //===--------------------------------------------------------------------===// 259 //===--------------------------------------------------------------------===//
90 260
91 /// hasBlockInfoRecords - Return true if we've already read and processed the 261 /// hasBlockInfoRecords - Return true if we've already read and processed the
(...skipping 23 matching lines...) Expand all
115 BlockInfoRecords.push_back(BlockInfo()); 285 BlockInfoRecords.push_back(BlockInfo());
116 BlockInfoRecords.back().BlockID = BlockID; 286 BlockInfoRecords.back().BlockID = BlockID;
117 return BlockInfoRecords.back(); 287 return BlockInfoRecords.back();
118 } 288 }
119 289
120 }; 290 };
121 291
122 class BitstreamCursor { 292 class BitstreamCursor {
123 friend class Deserializer; 293 friend class Deserializer;
124 BitstreamReader *BitStream; 294 BitstreamReader *BitStream;
125 const unsigned char *NextChar; 295 size_t NextChar;
126 296
127 /// CurWord - This is the current data we have pulled from the stream but have 297 /// CurWord - This is the current data we have pulled from the stream but have
128 /// not returned to the client. 298 /// not returned to the client.
129 uint32_t CurWord; 299 uint32_t CurWord;
130 300
131 /// BitsInCurWord - This is the number of bits in CurWord that are valid. This 301 /// BitsInCurWord - This is the number of bits in CurWord that are valid. This
132 /// is always from [0...31] inclusive. 302 /// is always from [0...31] inclusive.
133 unsigned BitsInCurWord; 303 unsigned BitsInCurWord;
134 304
135 // CurCodeSize - This is the declared size of code values used for the current 305 // CurCodeSize - This is the declared size of code values used for the current
(...skipping 13 matching lines...) Expand all
149 SmallVector<Block, 8> BlockScope; 319 SmallVector<Block, 8> BlockScope;
150 320
151 public: 321 public:
152 BitstreamCursor() : BitStream(0), NextChar(0) { 322 BitstreamCursor() : BitStream(0), NextChar(0) {
153 } 323 }
154 BitstreamCursor(const BitstreamCursor &RHS) : BitStream(0), NextChar(0) { 324 BitstreamCursor(const BitstreamCursor &RHS) : BitStream(0), NextChar(0) {
155 operator=(RHS); 325 operator=(RHS);
156 } 326 }
157 327
158 explicit BitstreamCursor(BitstreamReader &R) : BitStream(&R) { 328 explicit BitstreamCursor(BitstreamReader &R) : BitStream(&R) {
159 NextChar = R.getFirstChar(); 329 NextChar = 0;
160 assert(NextChar && "Bitstream not initialized yet");
161 CurWord = 0; 330 CurWord = 0;
162 BitsInCurWord = 0; 331 BitsInCurWord = 0;
163 CurCodeSize = 2; 332 CurCodeSize = 2;
164 } 333 }
165 334
166 void init(BitstreamReader &R) { 335 void init(BitstreamReader &R) {
167 freeState(); 336 freeState();
168 337
169 BitStream = &R; 338 BitStream = &R;
170 NextChar = R.getFirstChar(); 339 NextChar = 0;
171 assert(NextChar && "Bitstream not initialized yet");
172 CurWord = 0; 340 CurWord = 0;
173 BitsInCurWord = 0; 341 BitsInCurWord = 0;
174 CurCodeSize = 2; 342 CurCodeSize = 2;
175 } 343 }
176 344
177 ~BitstreamCursor() { 345 ~BitstreamCursor() {
178 freeState(); 346 freeState();
179 } 347 }
180 348
181 void operator=(const BitstreamCursor &RHS) { 349 void operator=(const BitstreamCursor &RHS) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 i != e; ++i) 387 i != e; ++i)
220 Abbrevs[i]->dropRef(); 388 Abbrevs[i]->dropRef();
221 } 389 }
222 BlockScope.clear(); 390 BlockScope.clear();
223 } 391 }
224 392
225 /// GetAbbrevIDWidth - Return the number of bits used to encode an abbrev #. 393 /// GetAbbrevIDWidth - Return the number of bits used to encode an abbrev #.
226 unsigned GetAbbrevIDWidth() const { return CurCodeSize; } 394 unsigned GetAbbrevIDWidth() const { return CurCodeSize; }
227 395
228 bool AtEndOfStream() const { 396 bool AtEndOfStream() const {
229 return NextChar == BitStream->getLastChar() && BitsInCurWord == 0; 397 return BitStream->getBSV().isEndPos(NextChar) && BitsInCurWord == 0;
230 } 398 }
231 399
232 /// GetCurrentBitNo - Return the bit # of the bit we are reading. 400 /// GetCurrentBitNo - Return the bit # of the bit we are reading.
233 uint64_t GetCurrentBitNo() const { 401 uint64_t GetCurrentBitNo() const {
234 return (NextChar-BitStream->getFirstChar())*CHAR_BIT - BitsInCurWord; 402 return NextChar*CHAR_BIT - BitsInCurWord;
235 } 403 }
236 404
237 BitstreamReader *getBitStreamReader() { 405 BitstreamReader *getBitStreamReader() {
238 return BitStream; 406 return BitStream;
239 } 407 }
240 const BitstreamReader *getBitStreamReader() const { 408 const BitstreamReader *getBitStreamReader() const {
241 return BitStream; 409 return BitStream;
242 } 410 }
243 411
244 412
245 /// JumpToBit - Reset the stream to the specified bit number. 413 /// JumpToBit - Reset the stream to the specified bit number.
246 void JumpToBit(uint64_t BitNo) { 414 void JumpToBit(uint64_t BitNo) {
247 uintptr_t ByteNo = uintptr_t(BitNo/8) & ~3; 415 uintptr_t ByteNo = uintptr_t(BitNo/8) & ~3;
248 uintptr_t WordBitNo = uintptr_t(BitNo) & 31; 416 uintptr_t WordBitNo = uintptr_t(BitNo) & 31;
249 assert(ByteNo <= (uintptr_t)(BitStream->getLastChar()- 417 assert(BitStream->getBSV().canSkipToPos(ByteNo) && "Invalid location");
250 BitStream->getFirstChar()) &&
251 "Invalid location");
252 418
253 // Move the cursor to the right word. 419 // Move the cursor to the right word.
254 NextChar = BitStream->getFirstChar()+ByteNo; 420 NextChar = ByteNo;
255 BitsInCurWord = 0; 421 BitsInCurWord = 0;
256 CurWord = 0; 422 CurWord = 0;
257 423
258 // Skip over any bits that are already consumed. 424 // Skip over any bits that are already consumed.
259 if (WordBitNo) 425 if (WordBitNo)
260 Read(static_cast<unsigned>(WordBitNo)); 426 Read(static_cast<unsigned>(WordBitNo));
261 } 427 }
262 428
263 429
264 uint32_t Read(unsigned NumBits) { 430 uint32_t Read(unsigned NumBits) {
265 assert(NumBits <= 32 && "Cannot return more than 32 bits!"); 431 assert(NumBits <= 32 && "Cannot return more than 32 bits!");
266 // If the field is fully contained by CurWord, return it quickly. 432 // If the field is fully contained by CurWord, return it quickly.
267 if (BitsInCurWord >= NumBits) { 433 if (BitsInCurWord >= NumBits) {
268 uint32_t R = CurWord & ((1U << NumBits)-1); 434 uint32_t R = CurWord & ((1U << NumBits)-1);
269 CurWord >>= NumBits; 435 CurWord >>= NumBits;
270 BitsInCurWord -= NumBits; 436 BitsInCurWord -= NumBits;
271 return R; 437 return R;
272 } 438 }
273 439
274 // If we run out of data, stop at the end of the stream. 440 // If we run out of data, stop at the end of the stream.
275 if (NextChar == BitStream->getLastChar()) { 441 if (BitStream->getBSV().isEndPos(NextChar)) {
276 CurWord = 0; 442 CurWord = 0;
277 BitsInCurWord = 0; 443 BitsInCurWord = 0;
278 return 0; 444 return 0;
279 } 445 }
280 446
281 unsigned R = CurWord; 447 unsigned R = CurWord;
282 448
283 // Read the next word from the stream. 449 // Read the next word from the stream.
284 CurWord = (NextChar[0] << 0) | (NextChar[1] << 8) | 450 CurWord = (BitStream->getBSV()[NextChar+0] << 0) |
nlewycky 2011/11/05 00:45:06 Extra space in "<< 0"
(google.com) Derek Schuff 2011/11/08 00:53:23 Done.
285 (NextChar[2] << 16) | (NextChar[3] << 24); 451 (BitStream->getBSV()[NextChar+1] << 8) |
452 (BitStream->getBSV()[NextChar+2] << 16) |
453 (BitStream->getBSV()[NextChar+3] << 24);
286 NextChar += 4; 454 NextChar += 4;
287 455
288 // Extract NumBits-BitsInCurWord from what we just read. 456 // Extract NumBits-BitsInCurWord from what we just read.
289 unsigned BitsLeft = NumBits-BitsInCurWord; 457 unsigned BitsLeft = NumBits-BitsInCurWord;
290 458
291 // Be careful here, BitsLeft is in the range [1..32] inclusive. 459 // Be careful here, BitsLeft is in the range [1..32] inclusive.
292 R |= (CurWord & (~0U >> (32-BitsLeft))) << BitsInCurWord; 460 R |= (CurWord & (~0U >> (32-BitsLeft))) << BitsInCurWord;
293 461
294 // BitsLeft bits have just been used up from CurWord. 462 // BitsLeft bits have just been used up from CurWord.
295 if (BitsLeft != 32) 463 if (BitsLeft != 32)
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 /// true. 537 /// true.
370 bool SkipBlock() { 538 bool SkipBlock() {
371 // Read and ignore the codelen value. Since we are skipping this block, we 539 // 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. 540 // don't care what code widths are used inside of it.
373 ReadVBR(bitc::CodeLenWidth); 541 ReadVBR(bitc::CodeLenWidth);
374 SkipToWord(); 542 SkipToWord();
375 unsigned NumWords = Read(bitc::BlockSizeWidth); 543 unsigned NumWords = Read(bitc::BlockSizeWidth);
376 544
377 // Check that the block wasn't partially defined, and that the offset isn't 545 // Check that the block wasn't partially defined, and that the offset isn't
378 // bogus. 546 // bogus.
379 const unsigned char *const SkipTo = NextChar + NumWords*4; 547 size_t SkipTo = NextChar + NumWords*4;
380 if (AtEndOfStream() || SkipTo > BitStream->getLastChar() || 548 if (AtEndOfStream() || !BitStream->getBSV().canSkipToPos(SkipTo))
381 SkipTo < BitStream->getFirstChar())
382 return true; 549 return true;
383 550
384 NextChar = SkipTo; 551 NextChar = SkipTo;
385 return false; 552 return false;
386 } 553 }
387 554
388 /// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter 555 /// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter
389 /// the block, and return true if the block is valid. 556 /// the block, and return true if the block is valid.
390 bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = 0) { 557 bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = 0) {
391 // Save the current block's state on BlockScope. 558 // Save the current block's state on BlockScope.
(...skipping 10 matching lines...) Expand all
402 } 569 }
403 } 570 }
404 571
405 // Get the codesize of this block. 572 // Get the codesize of this block.
406 CurCodeSize = ReadVBR(bitc::CodeLenWidth); 573 CurCodeSize = ReadVBR(bitc::CodeLenWidth);
407 SkipToWord(); 574 SkipToWord();
408 unsigned NumWords = Read(bitc::BlockSizeWidth); 575 unsigned NumWords = Read(bitc::BlockSizeWidth);
409 if (NumWordsP) *NumWordsP = NumWords; 576 if (NumWordsP) *NumWordsP = NumWords;
410 577
411 // Validate that this block is sane. 578 // Validate that this block is sane.
412 if (CurCodeSize == 0 || AtEndOfStream() || 579 if (CurCodeSize == 0 || AtEndOfStream() || 0)
nlewycky 2011/11/05 00:45:06 || 0?
(google.com) Derek Schuff 2011/11/08 00:53:23 Done.
413 NextChar+NumWords*4 > BitStream->getLastChar()) 580 // !BitStream->getBSV().canSkipToPos(NextChar+NumWords*4))
nlewycky 2011/11/05 00:45:06 Delete commented out code.
(google.com) Derek Schuff 2011/11/08 00:53:23 Done.
414 return true; 581 return true;
415 582
416 return false; 583 return false;
417 } 584 }
418 585
419 bool ReadBlockEnd() { 586 bool ReadBlockEnd() {
420 if (BlockScope.empty()) return true; 587 if (BlockScope.empty()) return true;
421 588
422 // Block tail: 589 // Block tail:
423 // [END_BLOCK, <align4bytes>] 590 // [END_BLOCK, <align4bytes>]
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 672
506 // Read all the elements. 673 // Read all the elements.
507 for (; NumElts; --NumElts) 674 for (; NumElts; --NumElts)
508 ReadAbbreviatedField(EltEnc, Vals); 675 ReadAbbreviatedField(EltEnc, Vals);
509 } else if (Op.getEncoding() == BitCodeAbbrevOp::Blob) { 676 } else if (Op.getEncoding() == BitCodeAbbrevOp::Blob) {
510 // Blob case. Read the number of bytes as a vbr6. 677 // Blob case. Read the number of bytes as a vbr6.
511 unsigned NumElts = ReadVBR(6); 678 unsigned NumElts = ReadVBR(6);
512 SkipToWord(); // 32-bit alignment 679 SkipToWord(); // 32-bit alignment
513 680
514 // Figure out where the end of this blob will be including tail padding. 681 // Figure out where the end of this blob will be including tail padding.
515 const unsigned char *NewEnd = NextChar+((NumElts+3)&~3); 682 size_t NewEnd = NextChar+((NumElts+3)&~3);
516 683
517 // If this would read off the end of the bitcode file, just set the 684 // If this would read off the end of the bitcode file, just set the
518 // record to empty and return. 685 // record to empty and return.
519 if (NewEnd > BitStream->getLastChar()) { 686 if (!BitStream->getBSV().canSkipToPos(NewEnd)) {
520 Vals.append(NumElts, 0); 687 Vals.append(NumElts, 0);
521 NextChar = BitStream->getLastChar(); 688 NextChar = BitStream->getBSV().getEndPos();
522 break; 689 break;
523 } 690 }
524 691
525 // Otherwise, read the number of bytes. If we can return a reference to 692 // Otherwise, read the number of bytes. If we can return a reference to
526 // the data, do so to avoid copying it. 693 // the data, do so to avoid copying it.
527 if (BlobStart) { 694 if (BlobStart) {
528 *BlobStart = (const char*)NextChar; 695 *BlobStart = (const char*)BitStream->getBSV().addressOf(NextChar);
529 *BlobLen = NumElts; 696 *BlobLen = NumElts;
530 } else { 697 } else {
531 for (; NumElts; ++NextChar, --NumElts) 698 for (; NumElts; ++NextChar, --NumElts)
532 Vals.push_back(*NextChar); 699 Vals.push_back(BitStream->getBSV()[NextChar]);
533 } 700 }
534 // Skip over tail padding. 701 // Skip over tail padding.
535 NextChar = NewEnd; 702 NextChar = NewEnd;
536 } else { 703 } else {
537 ReadAbbreviatedField(Op, Vals); 704 ReadAbbreviatedField(Op, Vals);
538 } 705 }
539 } 706 }
540 707
541 unsigned Code = (unsigned)Vals[0]; 708 unsigned Code = (unsigned)Vals[0];
542 Vals.erase(Vals.begin()); 709 Vals.erase(Vals.begin());
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
636 break; 803 break;
637 } 804 }
638 } 805 }
639 } 806 }
640 } 807 }
641 }; 808 };
642 809
643 } // End llvm namespace 810 } // End llvm namespace
644 811
645 #endif 812 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698