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