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 Bit as a Byte::BitInByte string. MinByteWidth is the | |
335 /// minimum number of characters to print out the Byte value (blank | |
336 /// fills). | |
337 std::string getBitAddress(uint64_t Bit, unsigned MinByteWidth=1) const { | |
338 return BitStream->getBitAddress(Bit, MinByteWidth); | |
jvoung (off chromium)
2015/02/23 18:58:56
Is it useful to have this wrapper or can the bitst
Karl
2015/02/23 20:46:22
Removed.
| |
339 } | |
340 | |
341 /// Returns the current bit address (string) of the bit cursor. | |
342 /// MinByteWidth is the minimum number of characters to print out | |
343 /// the Byte value (blank fills). | |
344 std::string getCurrentBitAddress(unsigned MinByteWidth=1) const { | |
345 return BitStream->getBitAddress(GetCurrentBitNo(), MinByteWidth); | |
346 } | |
347 | |
300 /// Flags that modify the behavior of advance(). | 348 /// Flags that modify the behavior of advance(). |
301 enum { | 349 enum { |
302 /// AF_DontPopBlockAtEnd - If this flag is used, the advance() method does | 350 /// 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 | 351 /// not automatically pop the block scope when the end of a block is |
304 /// reached. | 352 /// reached. |
305 AF_DontPopBlockAtEnd = 1, | 353 AF_DontPopBlockAtEnd = 1, |
306 | 354 |
307 /// AF_DontAutoprocessAbbrevs - If this flag is used, abbrev entries are | 355 /// AF_DontAutoprocessAbbrevs - If this flag is used, abbrev entries are |
308 /// returned just like normal records. | 356 /// returned just like normal records. |
309 AF_DontAutoprocessAbbrevs = 2 | 357 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. | 396 // If we found a sub-block, just skip over it and check the next entry. |
349 if (SkipBlock()) | 397 if (SkipBlock()) |
350 return NaClBitstreamEntry::getError(); | 398 return NaClBitstreamEntry::getError(); |
351 } | 399 } |
352 } | 400 } |
353 | 401 |
354 /// JumpToBit - Reset the stream to the specified bit number. | 402 /// JumpToBit - Reset the stream to the specified bit number. |
355 void JumpToBit(uint64_t BitNo) { | 403 void JumpToBit(uint64_t BitNo) { |
356 uintptr_t ByteNo = uintptr_t(BitNo/8) & ~(sizeof(word_t)-1); | 404 uintptr_t ByteNo = uintptr_t(BitNo/8) & ~(sizeof(word_t)-1); |
357 unsigned WordBitNo = unsigned(BitNo & (sizeof(word_t)*8-1)); | 405 unsigned WordBitNo = unsigned(BitNo & (sizeof(word_t)*8-1)); |
358 assert(canSkipToPos(ByteNo) && "Invalid location"); | 406 if (!canSkipToPos(ByteNo)) |
407 reportInvalidJumpToBit(BitNo); | |
359 | 408 |
360 // Move the cursor to the right word. | 409 // Move the cursor to the right word. |
361 NextChar = ByteNo; | 410 NextChar = ByteNo; |
362 BitsInCurWord = 0; | 411 BitsInCurWord = 0; |
363 CurWord = 0; | 412 CurWord = 0; |
364 | 413 |
365 // Skip over any bits that are already consumed. | 414 // Skip over any bits that are already consumed. |
366 if (WordBitNo) { | 415 if (WordBitNo) { |
367 if (sizeof(word_t) > 4) | 416 if (sizeof(word_t) > 4) |
368 Read64(WordBitNo); | 417 Read64(WordBitNo); |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
546 | 595 |
547 BlockScope.back().PrevAbbrevs.swap(CurAbbrevs); | 596 BlockScope.back().PrevAbbrevs.swap(CurAbbrevs); |
548 BlockScope.pop_back(); | 597 BlockScope.pop_back(); |
549 } | 598 } |
550 | 599 |
551 //===--------------------------------------------------------------------===// | 600 //===--------------------------------------------------------------------===// |
552 // Record Processing | 601 // Record Processing |
553 //===--------------------------------------------------------------------===// | 602 //===--------------------------------------------------------------------===// |
554 | 603 |
555 private: | 604 private: |
605 // Returns abbreviation encoding associated with Value. | |
606 NaClBitCodeAbbrevOp::Encoding getEncoding(uint64_t Value); | |
607 | |
556 void skipAbbreviatedField(const NaClBitCodeAbbrevOp &Op); | 608 void skipAbbreviatedField(const NaClBitCodeAbbrevOp &Op); |
557 | 609 |
558 // Reads the next Value using the abbreviation Op. Returns true only | 610 // 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 | 611 // if Op is an array (and sets Value to the number of elements in the |
560 // array). | 612 // array). |
561 inline bool readRecordAbbrevField(const NaClBitCodeAbbrevOp &Op, | 613 inline bool readRecordAbbrevField(const NaClBitCodeAbbrevOp &Op, |
562 uint64_t &Value); | 614 uint64_t &Value); |
563 | 615 |
564 // Reads and returns the next value using the abbreviation Op, | 616 // Reads and returns the next value using the abbreviation Op, |
565 // assuming Op appears after an array abbreviation. | 617 // assuming Op appears after an array abbreviation. |
566 inline uint64_t readArrayAbbreviatedField(const NaClBitCodeAbbrevOp &Op); | 618 inline uint64_t readArrayAbbreviatedField(const NaClBitCodeAbbrevOp &Op); |
567 | 619 |
568 // Reads the array abbreviation Op, NumArrayElements times, putting | 620 // Reads the array abbreviation Op, NumArrayElements times, putting |
569 // the read values in Vals. | 621 // the read values in Vals. |
570 inline void readArrayAbbrev(const NaClBitCodeAbbrevOp &Op, | 622 inline void readArrayAbbrev(const NaClBitCodeAbbrevOp &Op, |
571 unsigned NumArrayElements, | 623 unsigned NumArrayElements, |
572 SmallVectorImpl<uint64_t> &Vals); | 624 SmallVectorImpl<uint64_t> &Vals); |
573 | 625 |
626 // Reports that that abbreviation Index is not valid. | |
627 void reportInvalidAbbrevNumber(unsigned Index) const; | |
628 | |
629 // Reports that jumping to Bit is not valid. | |
630 void reportInvalidJumpToBit(uint64_t Bit) const; | |
631 | |
574 public: | 632 public: |
575 | 633 |
576 /// getAbbrev - Return the abbreviation for the specified AbbrevId. | 634 /// getAbbrev - Return the abbreviation for the specified AbbrevId. |
577 const NaClBitCodeAbbrev *getAbbrev(unsigned AbbrevID) const { | 635 const NaClBitCodeAbbrev *getAbbrev(unsigned AbbrevID) const { |
578 unsigned AbbrevNo = AbbrevID-naclbitc::FIRST_APPLICATION_ABBREV; | 636 unsigned AbbrevNo = AbbrevID-naclbitc::FIRST_APPLICATION_ABBREV; |
579 assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!"); | 637 if (AbbrevNo >= CurAbbrevs.size()) |
638 reportInvalidAbbrevNumber(AbbrevID); | |
580 return CurAbbrevs[AbbrevNo]; | 639 return CurAbbrevs[AbbrevNo]; |
581 } | 640 } |
582 | 641 |
583 /// skipRecord - Read the current record and discard it. | 642 /// skipRecord - Read the current record and discard it. |
584 void skipRecord(unsigned AbbrevID); | 643 void skipRecord(unsigned AbbrevID); |
585 | 644 |
586 unsigned readRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals); | 645 unsigned readRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals); |
587 | 646 |
588 //===--------------------------------------------------------------------===// | 647 //===--------------------------------------------------------------------===// |
589 // Abbrev Processing | 648 // Abbrev Processing |
590 //===--------------------------------------------------------------------===// | 649 //===--------------------------------------------------------------------===// |
591 // IsLocal indicates where the abbreviation occurs. If it is in the | 650 // IsLocal indicates where the abbreviation occurs. If it is in the |
592 // BlockInfo block, IsLocal is false. In all other cases, IsLocal is | 651 // BlockInfo block, IsLocal is false. In all other cases, IsLocal is |
593 // true. | 652 // true. |
594 void ReadAbbrevRecord(bool IsLocal, | 653 void ReadAbbrevRecord(bool IsLocal, |
595 NaClAbbrevListener *Listener); | 654 NaClAbbrevListener *Listener); |
596 | 655 |
597 // Skips over an abbreviation record. Duplicates code of ReadAbbrevRecord, | 656 // Skips over an abbreviation record. Duplicates code of ReadAbbrevRecord, |
598 // except that no abbreviation is built. | 657 // except that no abbreviation is built. |
599 void SkipAbbrevRecord(); | 658 void SkipAbbrevRecord(); |
600 | 659 |
601 bool ReadBlockInfoBlock(NaClAbbrevListener *Listener); | 660 bool ReadBlockInfoBlock(NaClAbbrevListener *Listener); |
602 }; | 661 }; |
603 | 662 |
604 } // End llvm namespace | 663 } // End llvm namespace |
605 | 664 |
606 #endif | 665 #endif |
OLD | NEW |