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 |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |