| OLD | NEW |
| 1 //===- NaClBitstreamReader.h -----------------------------------*- C++ -*-===// | 1 //===- NaClBitstreamReader.h -----------------------------------*- C++ -*-===// |
| 2 // Low-level bitstream reader interface | 2 // Low-level bitstream reader interface |
| 3 // | 3 // |
| 4 // The LLVM Compiler Infrastructure | 4 // The LLVM Compiler Infrastructure |
| 5 // | 5 // |
| 6 // This file is distributed under the University of Illinois Open Source | 6 // This file is distributed under the University of Illinois Open Source |
| 7 // License. See LICENSE.TXT for details. | 7 // License. See LICENSE.TXT for details. |
| 8 // | 8 // |
| 9 //===----------------------------------------------------------------------===// | 9 //===----------------------------------------------------------------------===// |
| 10 // | 10 // |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 Info.Abbrevs[i]->dropRef(); | 83 Info.Abbrevs[i]->dropRef(); |
| 84 BlockInfoRecords.pop_back(); | 84 BlockInfoRecords.pop_back(); |
| 85 } | 85 } |
| 86 } | 86 } |
| 87 | 87 |
| 88 /// \brief Returns the initial address (after the header) of the input stream. | 88 /// \brief Returns the initial address (after the header) of the input stream. |
| 89 size_t getInitialAddress() const { | 89 size_t getInitialAddress() const { |
| 90 return InitialAddress; | 90 return InitialAddress; |
| 91 } | 91 } |
| 92 | 92 |
| 93 /// Returns the Bit as a Byte:BitInByte string. MinByteWidth is the |
| 94 /// minimum number of characters to print out the Byte value (blank |
| 95 /// fills). |
| 96 static std::string getBitAddress(uint64_t Bit, unsigned MinByteWidth=1); |
| 97 |
| 93 //===--------------------------------------------------------------------===// | 98 //===--------------------------------------------------------------------===// |
| 94 // Block Manipulation | 99 // Block Manipulation |
| 95 //===--------------------------------------------------------------------===// | 100 //===--------------------------------------------------------------------===// |
| 96 | 101 |
| 97 /// hasBlockInfoRecords - Return true if we've already read and processed the | 102 /// hasBlockInfoRecords - Return true if we've already read and processed the |
| 98 /// block info block for this Bitstream. We only process it for the first | 103 /// block info block for this Bitstream. We only process it for the first |
| 99 /// cursor that walks over it. | 104 /// cursor that walks over it. |
| 100 bool hasBlockInfoRecords() const { return !BlockInfoRecords.empty(); } | 105 bool hasBlockInfoRecords() const { return !BlockInfoRecords.empty(); } |
| 101 | 106 |
| 102 /// getBlockInfo - If there is block info for the specified ID, return it, | 107 /// getBlockInfo - If there is block info for the specified ID, return it, |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 uint64_t StartBit; | 207 uint64_t StartBit; |
| 203 }; | 208 }; |
| 204 | 209 |
| 205 /// NaClBitstreamCursor - This represents a position within a bitcode | 210 /// NaClBitstreamCursor - This represents a position within a bitcode |
| 206 /// file. There may be multiple independent cursors reading within | 211 /// file. There may be multiple independent cursors reading within |
| 207 /// one bitstream, each maintaining their own local state. | 212 /// one bitstream, each maintaining their own local state. |
| 208 /// | 213 /// |
| 209 /// Unlike iterators, NaClBitstreamCursors are heavy-weight objects | 214 /// Unlike iterators, NaClBitstreamCursors are heavy-weight objects |
| 210 /// that should not be passed by value. | 215 /// that should not be passed by value. |
| 211 class NaClBitstreamCursor { | 216 class NaClBitstreamCursor { |
| 217 public: |
| 218 /// This class handles errors in the bitstream reader. Redirects |
| 219 /// fatal error messages to virtual method Fatal. |
| 220 class ErrorHandler { |
| 221 ErrorHandler(const ErrorHandler &) = delete; |
| 222 ErrorHandler &operator=(const ErrorHandler &) = delete; |
| 223 public: |
| 224 explicit ErrorHandler(NaClBitstreamCursor &Cursor) : Cursor(Cursor) {} |
| 225 LLVM_ATTRIBUTE_NORETURN |
| 226 virtual void Fatal(const std::string &ErrorMessage) const; |
| 227 virtual ~ErrorHandler() {} |
| 228 uint64_t getCurrentBitNo() const { |
| 229 return Cursor.GetCurrentBitNo(); |
| 230 } |
| 231 private: |
| 232 NaClBitstreamCursor &Cursor; |
| 233 }; |
| 234 |
| 235 private: |
| 212 friend class Deserializer; | 236 friend class Deserializer; |
| 213 NaClBitstreamReader *BitStream; | 237 NaClBitstreamReader *BitStream; |
| 214 size_t NextChar; | 238 size_t NextChar; |
| 239 // The current error handler for the bitstream reader. |
| 240 std::unique_ptr<ErrorHandler> ErrHandler; |
| 215 | 241 |
| 216 /// CurWord/word_t - This is the current data we have pulled from the stream | 242 /// CurWord/word_t - This is the current data we have pulled from the stream |
| 217 /// but have not returned to the client. This is specifically and | 243 /// but have not returned to the client. This is specifically and |
| 218 /// intentionally defined to follow the word size of the host machine for | 244 /// intentionally defined to follow the word size of the host machine for |
| 219 /// efficiency. We use word_t in places that are aware of this to make it | 245 /// efficiency. We use word_t in places that are aware of this to make it |
| 220 /// perfectly explicit what is going on. | 246 /// perfectly explicit what is going on. |
| 221 typedef uint32_t word_t; | 247 typedef uint32_t word_t; |
| 222 word_t CurWord; | 248 word_t CurWord; |
| 223 | 249 |
| 224 /// BitsInCurWord - This is the number of bits in CurWord that are valid. This | 250 /// BitsInCurWord - This is the number of bits in CurWord that are valid. This |
| (...skipping 16 matching lines...) Expand all Loading... |
| 241 }; | 267 }; |
| 242 | 268 |
| 243 /// BlockScope - This tracks the codesize of parent blocks. | 269 /// BlockScope - This tracks the codesize of parent blocks. |
| 244 SmallVector<Block, 8> BlockScope; | 270 SmallVector<Block, 8> BlockScope; |
| 245 | 271 |
| 246 NaClBitstreamCursor(const NaClBitstreamCursor &) LLVM_DELETED_FUNCTION; | 272 NaClBitstreamCursor(const NaClBitstreamCursor &) LLVM_DELETED_FUNCTION; |
| 247 NaClBitstreamCursor &operator=(const NaClBitstreamCursor &) LLVM_DELETED_FUNCT
ION; | 273 NaClBitstreamCursor &operator=(const NaClBitstreamCursor &) LLVM_DELETED_FUNCT
ION; |
| 248 | 274 |
| 249 public: | 275 public: |
| 250 | 276 |
| 251 NaClBitstreamCursor() { | 277 NaClBitstreamCursor() : ErrHandler(new ErrorHandler(*this)) { |
| 252 init(nullptr); | 278 init(nullptr); |
| 253 } | 279 } |
| 254 | 280 |
| 255 explicit NaClBitstreamCursor(NaClBitstreamReader &R) { init(&R); } | 281 explicit NaClBitstreamCursor(NaClBitstreamReader &R) |
| 282 : ErrHandler(new ErrorHandler(*this)) { init(&R); } |
| 256 | 283 |
| 257 void init(NaClBitstreamReader *R) { | 284 void init(NaClBitstreamReader *R) { |
| 258 freeState(); | 285 freeState(); |
| 259 BitStream = R; | 286 BitStream = R; |
| 260 NextChar = (BitStream == nullptr) ? 0 : BitStream->getInitialAddress(); | 287 NextChar = (BitStream == nullptr) ? 0 : BitStream->getInitialAddress(); |
| 261 CurWord = 0; | 288 CurWord = 0; |
| 262 BitsInCurWord = 0; | 289 BitsInCurWord = 0; |
| 263 } | 290 } |
| 264 | 291 |
| 265 ~NaClBitstreamCursor() { | 292 ~NaClBitstreamCursor() { |
| 266 freeState(); | 293 freeState(); |
| 267 } | 294 } |
| 268 | 295 |
| 269 void freeState(); | 296 void freeState(); |
| 270 | 297 |
| 298 // Replaces the current bitstream error handler with the new |
| 299 // handler. Takes ownership of the new handler and deletes it when |
| 300 // it is no longer needed. |
| 301 void setErrorHandler(std::unique_ptr<ErrorHandler> &NewHandler) { |
| 302 ErrHandler = std::move(NewHandler); |
| 303 } |
| 304 |
| 271 bool isEndPos(size_t pos) { | 305 bool isEndPos(size_t pos) { |
| 272 return BitStream->getBitcodeBytes().isObjectEnd(static_cast<uint64_t>(pos)); | 306 return BitStream->getBitcodeBytes().isObjectEnd(static_cast<uint64_t>(pos)); |
| 273 } | 307 } |
| 274 | 308 |
| 275 bool canSkipToPos(size_t pos) const { | 309 bool canSkipToPos(size_t pos) const { |
| 276 // pos can be skipped to if it is a valid address or one byte past the end. | 310 // pos can be skipped to if it is a valid address or one byte past the end. |
| 277 return pos == 0 || BitStream->getBitcodeBytes().isValidAddress( | 311 return pos == 0 || BitStream->getBitcodeBytes().isValidAddress( |
| 278 static_cast<uint64_t>(pos - 1)); | 312 static_cast<uint64_t>(pos - 1)); |
| 279 } | 313 } |
| 280 | 314 |
| 281 bool AtEndOfStream() { | 315 bool AtEndOfStream() { |
| 282 return BitsInCurWord == 0 && isEndPos(NextChar); | 316 return BitsInCurWord == 0 && isEndPos(NextChar); |
| 283 } | 317 } |
| 284 | 318 |
| 285 /// getAbbrevIDWidth - Return the number of bits used to encode an abbrev #. | 319 /// getAbbrevIDWidth - Return the number of bits used to encode an abbrev #. |
| 286 unsigned getAbbrevIDWidth() const { return CurCodeSize.NumBits; } | 320 unsigned getAbbrevIDWidth() const { return CurCodeSize.NumBits; } |
| 287 | 321 |
| 288 /// GetCurrentBitNo - Return the bit # of the bit we are reading. | 322 /// GetCurrentBitNo - Return the bit # of the bit we are reading. |
| 289 uint64_t GetCurrentBitNo() const { | 323 uint64_t GetCurrentBitNo() const { |
| 290 return NextChar*CHAR_BIT - BitsInCurWord; | 324 return NextChar*CHAR_BIT - BitsInCurWord; |
| 291 } | 325 } |
| 292 | 326 |
| 293 NaClBitstreamReader *getBitStreamReader() { | 327 NaClBitstreamReader *getBitStreamReader() { |
| 294 return BitStream; | 328 return BitStream; |
| 295 } | 329 } |
| 296 const NaClBitstreamReader *getBitStreamReader() const { | 330 const NaClBitstreamReader *getBitStreamReader() const { |
| 297 return BitStream; | 331 return BitStream; |
| 298 } | 332 } |
| 299 | 333 |
| 334 /// Returns the current bit address (string) of the bit cursor. |
| 335 /// MinByteWidth is the minimum number of characters to print out |
| 336 /// the Byte value (blank fills). |
| 337 std::string getCurrentBitAddress(unsigned MinByteWidth=1) const { |
| 338 return BitStream->getBitAddress(GetCurrentBitNo(), MinByteWidth); |
| 339 } |
| 340 |
| 300 /// Flags that modify the behavior of advance(). | 341 /// Flags that modify the behavior of advance(). |
| 301 enum { | 342 enum { |
| 302 /// AF_DontPopBlockAtEnd - If this flag is used, the advance() method does | 343 /// AF_DontPopBlockAtEnd - If this flag is used, the advance() method does |
| 303 /// not automatically pop the block scope when the end of a block is | 344 /// not automatically pop the block scope when the end of a block is |
| 304 /// reached. | 345 /// reached. |
| 305 AF_DontPopBlockAtEnd = 1, | 346 AF_DontPopBlockAtEnd = 1, |
| 306 | 347 |
| 307 /// AF_DontAutoprocessAbbrevs - If this flag is used, abbrev entries are | 348 /// AF_DontAutoprocessAbbrevs - If this flag is used, abbrev entries are |
| 308 /// returned just like normal records. | 349 /// returned just like normal records. |
| 309 AF_DontAutoprocessAbbrevs = 2 | 350 AF_DontAutoprocessAbbrevs = 2 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 // If we found a sub-block, just skip over it and check the next entry. | 389 // If we found a sub-block, just skip over it and check the next entry. |
| 349 if (SkipBlock()) | 390 if (SkipBlock()) |
| 350 return NaClBitstreamEntry::getError(); | 391 return NaClBitstreamEntry::getError(); |
| 351 } | 392 } |
| 352 } | 393 } |
| 353 | 394 |
| 354 /// JumpToBit - Reset the stream to the specified bit number. | 395 /// JumpToBit - Reset the stream to the specified bit number. |
| 355 void JumpToBit(uint64_t BitNo) { | 396 void JumpToBit(uint64_t BitNo) { |
| 356 uintptr_t ByteNo = uintptr_t(BitNo/8) & ~(sizeof(word_t)-1); | 397 uintptr_t ByteNo = uintptr_t(BitNo/8) & ~(sizeof(word_t)-1); |
| 357 unsigned WordBitNo = unsigned(BitNo & (sizeof(word_t)*8-1)); | 398 unsigned WordBitNo = unsigned(BitNo & (sizeof(word_t)*8-1)); |
| 358 assert(canSkipToPos(ByteNo) && "Invalid location"); | 399 if (!canSkipToPos(ByteNo)) |
| 400 reportInvalidJumpToBit(BitNo); |
| 359 | 401 |
| 360 // Move the cursor to the right word. | 402 // Move the cursor to the right word. |
| 361 NextChar = ByteNo; | 403 NextChar = ByteNo; |
| 362 BitsInCurWord = 0; | 404 BitsInCurWord = 0; |
| 363 CurWord = 0; | 405 CurWord = 0; |
| 364 | 406 |
| 365 // Skip over any bits that are already consumed. | 407 // Skip over any bits that are already consumed. |
| 366 if (WordBitNo) { | 408 if (WordBitNo) { |
| 367 if (sizeof(word_t) > 4) | 409 if (sizeof(word_t) > 4) |
| 368 Read64(WordBitNo); | 410 Read64(WordBitNo); |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 546 | 588 |
| 547 BlockScope.back().PrevAbbrevs.swap(CurAbbrevs); | 589 BlockScope.back().PrevAbbrevs.swap(CurAbbrevs); |
| 548 BlockScope.pop_back(); | 590 BlockScope.pop_back(); |
| 549 } | 591 } |
| 550 | 592 |
| 551 //===--------------------------------------------------------------------===// | 593 //===--------------------------------------------------------------------===// |
| 552 // Record Processing | 594 // Record Processing |
| 553 //===--------------------------------------------------------------------===// | 595 //===--------------------------------------------------------------------===// |
| 554 | 596 |
| 555 private: | 597 private: |
| 598 // Returns abbreviation encoding associated with Value. |
| 599 NaClBitCodeAbbrevOp::Encoding getEncoding(uint64_t Value); |
| 600 |
| 556 void skipAbbreviatedField(const NaClBitCodeAbbrevOp &Op); | 601 void skipAbbreviatedField(const NaClBitCodeAbbrevOp &Op); |
| 557 | 602 |
| 558 // Reads the next Value using the abbreviation Op. Returns true only | 603 // Reads the next Value using the abbreviation Op. Returns true only |
| 559 // if Op is an array (and sets Value to the number of elements in the | 604 // if Op is an array (and sets Value to the number of elements in the |
| 560 // array). | 605 // array). |
| 561 inline bool readRecordAbbrevField(const NaClBitCodeAbbrevOp &Op, | 606 inline bool readRecordAbbrevField(const NaClBitCodeAbbrevOp &Op, |
| 562 uint64_t &Value); | 607 uint64_t &Value); |
| 563 | 608 |
| 564 // Reads and returns the next value using the abbreviation Op, | 609 // Reads and returns the next value using the abbreviation Op, |
| 565 // assuming Op appears after an array abbreviation. | 610 // assuming Op appears after an array abbreviation. |
| 566 inline uint64_t readArrayAbbreviatedField(const NaClBitCodeAbbrevOp &Op); | 611 inline uint64_t readArrayAbbreviatedField(const NaClBitCodeAbbrevOp &Op); |
| 567 | 612 |
| 568 // Reads the array abbreviation Op, NumArrayElements times, putting | 613 // Reads the array abbreviation Op, NumArrayElements times, putting |
| 569 // the read values in Vals. | 614 // the read values in Vals. |
| 570 inline void readArrayAbbrev(const NaClBitCodeAbbrevOp &Op, | 615 inline void readArrayAbbrev(const NaClBitCodeAbbrevOp &Op, |
| 571 unsigned NumArrayElements, | 616 unsigned NumArrayElements, |
| 572 SmallVectorImpl<uint64_t> &Vals); | 617 SmallVectorImpl<uint64_t> &Vals); |
| 573 | 618 |
| 619 // Reports that that abbreviation Index is not valid. |
| 620 void reportInvalidAbbrevNumber(unsigned Index) const; |
| 621 |
| 622 // Reports that jumping to Bit is not valid. |
| 623 void reportInvalidJumpToBit(uint64_t Bit) const; |
| 624 |
| 574 public: | 625 public: |
| 575 | 626 |
| 576 /// getAbbrev - Return the abbreviation for the specified AbbrevId. | 627 /// getAbbrev - Return the abbreviation for the specified AbbrevId. |
| 577 const NaClBitCodeAbbrev *getAbbrev(unsigned AbbrevID) const { | 628 const NaClBitCodeAbbrev *getAbbrev(unsigned AbbrevID) const { |
| 578 unsigned AbbrevNo = AbbrevID-naclbitc::FIRST_APPLICATION_ABBREV; | 629 unsigned AbbrevNo = AbbrevID-naclbitc::FIRST_APPLICATION_ABBREV; |
| 579 assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!"); | 630 if (AbbrevNo >= CurAbbrevs.size()) |
| 631 reportInvalidAbbrevNumber(AbbrevID); |
| 580 return CurAbbrevs[AbbrevNo]; | 632 return CurAbbrevs[AbbrevNo]; |
| 581 } | 633 } |
| 582 | 634 |
| 583 /// skipRecord - Read the current record and discard it. | 635 /// skipRecord - Read the current record and discard it. |
| 584 void skipRecord(unsigned AbbrevID); | 636 void skipRecord(unsigned AbbrevID); |
| 585 | 637 |
| 586 unsigned readRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals); | 638 unsigned readRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals); |
| 587 | 639 |
| 588 //===--------------------------------------------------------------------===// | 640 //===--------------------------------------------------------------------===// |
| 589 // Abbrev Processing | 641 // Abbrev Processing |
| 590 //===--------------------------------------------------------------------===// | 642 //===--------------------------------------------------------------------===// |
| 591 // IsLocal indicates where the abbreviation occurs. If it is in the | 643 // IsLocal indicates where the abbreviation occurs. If it is in the |
| 592 // BlockInfo block, IsLocal is false. In all other cases, IsLocal is | 644 // BlockInfo block, IsLocal is false. In all other cases, IsLocal is |
| 593 // true. | 645 // true. |
| 594 void ReadAbbrevRecord(bool IsLocal, | 646 void ReadAbbrevRecord(bool IsLocal, |
| 595 NaClAbbrevListener *Listener); | 647 NaClAbbrevListener *Listener); |
| 596 | 648 |
| 597 // Skips over an abbreviation record. Duplicates code of ReadAbbrevRecord, | 649 // Skips over an abbreviation record. Duplicates code of ReadAbbrevRecord, |
| 598 // except that no abbreviation is built. | 650 // except that no abbreviation is built. |
| 599 void SkipAbbrevRecord(); | 651 void SkipAbbrevRecord(); |
| 600 | 652 |
| 601 bool ReadBlockInfoBlock(NaClAbbrevListener *Listener); | 653 bool ReadBlockInfoBlock(NaClAbbrevListener *Listener); |
| 602 }; | 654 }; |
| 603 | 655 |
| 604 } // End llvm namespace | 656 } // End llvm namespace |
| 605 | 657 |
| 606 #endif | 658 #endif |
| OLD | NEW |