Chromium Code Reviews| 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 |