Chromium Code Reviews| Index: include/llvm/Bitcode/NaCl/NaClBitstreamReader.h |
| diff --git a/include/llvm/Bitcode/NaCl/NaClBitstreamReader.h b/include/llvm/Bitcode/NaCl/NaClBitstreamReader.h |
| index 97e216441939906f33f1c2d1f48585005bf51e8f..76f179430271e5135b615b71e5f01b7b03102cb4 100644 |
| --- a/include/llvm/Bitcode/NaCl/NaClBitstreamReader.h |
| +++ b/include/llvm/Bitcode/NaCl/NaClBitstreamReader.h |
| @@ -90,6 +90,11 @@ public: |
| return InitialAddress; |
| } |
| + /// Returns the Bit as a Byte:BitInByte string. MinByteWidth is the |
| + /// minimum number of characters to print out the Byte value (blank |
| + /// fills). |
| + static std::string getBitAddress(uint64_t Bit, unsigned MinByteWidth=1); |
| + |
| //===--------------------------------------------------------------------===// |
| // Block Manipulation |
| //===--------------------------------------------------------------------===// |
| @@ -209,9 +214,30 @@ public: |
| /// Unlike iterators, NaClBitstreamCursors are heavy-weight objects |
| /// that should not be passed by value. |
| class NaClBitstreamCursor { |
| +public: |
| + /// This class handle mistakes in the bitstream reader. Redirects |
|
jvoung (off chromium)
2015/02/20 00:12:42
"handles mistakes"
Karl
2015/02/20 21:41:17
Done.
|
| + /// fatal error messages to virtual method Fatal. |
| + class ErrorHandler { |
| + ErrorHandler(const ErrorHandler &) = delete; |
| + ErrorHandler &operator=(const ErrorHandler &) = delete; |
| + public: |
| + ErrorHandler(NaClBitstreamCursor &Cursor) : Cursor(Cursor) {} |
|
jvoung (off chromium)
2015/02/20 00:12:42
explicit
Karl
2015/02/20 21:41:17
Done.
|
| + LLVM_ATTRIBUTE_NORETURN |
| + virtual void Fatal(const std::string &ErrorMessage) const; |
| + virtual ~ErrorHandler() {} |
| + uint64_t getCurrentBitNo() const { |
| + return Cursor.GetCurrentBitNo(); |
| + } |
| + private: |
| + NaClBitstreamCursor &Cursor; |
| + }; |
| + |
| +private: |
| friend class Deserializer; |
| NaClBitstreamReader *BitStream; |
| size_t NextChar; |
| + // The current error handler for the bitstream reader. |
| + std::unique_ptr<ErrorHandler> ErrHandler; |
| /// CurWord/word_t - This is the current data we have pulled from the stream |
| /// but have not returned to the client. This is specifically and |
| @@ -248,11 +274,12 @@ class NaClBitstreamCursor { |
| public: |
| - NaClBitstreamCursor() { |
| + NaClBitstreamCursor() : ErrHandler(new ErrorHandler(*this)) { |
| init(nullptr); |
| } |
| - explicit NaClBitstreamCursor(NaClBitstreamReader &R) { init(&R); } |
| + explicit NaClBitstreamCursor(NaClBitstreamReader &R) |
| + : ErrHandler(new ErrorHandler(*this)) { init(&R); } |
| void init(NaClBitstreamReader *R) { |
| freeState(); |
| @@ -268,6 +295,13 @@ public: |
| void freeState(); |
| + // Replaces the current bitstream error handler with the new |
| + // handler. Takes ownership of the new handler and delete's it when |
|
jvoung (off chromium)
2015/02/20 00:12:42
"delete's" -> "deletes"
Karl
2015/02/20 21:41:17
Done.
|
| + // it is no longer needed. |
| + void setErrorHandler(std::unique_ptr<ErrorHandler> &NewHandler) { |
| + ErrHandler = std::move(NewHandler); |
|
jvoung (off chromium)
2015/02/20 00:12:42
Hmm, I'm not too familiar with what exactly std::m
Karl
2015/02/20 21:41:17
That is my understanding. I didn't know about this
|
| + } |
| + |
| bool isEndPos(size_t pos) { |
| return BitStream->getBitcodeBytes().isObjectEnd(static_cast<uint64_t>(pos)); |
| } |
| @@ -297,6 +331,20 @@ public: |
| return BitStream; |
| } |
| + /// Returns Bit as a Byte::BitInByte string. MinByteWidth is the |
| + /// minimum number of characters to print out the Byte value (blank |
| + /// fills). |
| + std::string getBitAddress(uint64_t Bit, unsigned MinByteWidth=1) const { |
| + return BitStream->getBitAddress(Bit, MinByteWidth); |
| + } |
| + |
| + /// Returns the current bit address (string) of the bit cursor. |
| + /// MinByteWidth is the minimum number of characters to print out |
| + /// the Byte value (blank fills). |
| + std::string getCurrentBitAddress(unsigned MinByteWidth=1) const { |
| + return BitStream->getBitAddress(GetCurrentBitNo(), MinByteWidth); |
| + } |
| + |
| /// Flags that modify the behavior of advance(). |
| enum { |
| /// AF_DontPopBlockAtEnd - If this flag is used, the advance() method does |
| @@ -355,7 +403,8 @@ public: |
| void JumpToBit(uint64_t BitNo) { |
| uintptr_t ByteNo = uintptr_t(BitNo/8) & ~(sizeof(word_t)-1); |
| unsigned WordBitNo = unsigned(BitNo & (sizeof(word_t)*8-1)); |
| - assert(canSkipToPos(ByteNo) && "Invalid location"); |
| + if (!canSkipToPos(ByteNo)) |
| + reportInvalidJumpToBit(BitNo); |
| // Move the cursor to the right word. |
| NextChar = ByteNo; |
| @@ -553,6 +602,9 @@ private: |
| //===--------------------------------------------------------------------===// |
| private: |
| + // Returns abbreviation encoding associated with Value. |
| + NaClBitCodeAbbrevOp::Encoding getEncoding(uint64_t Value); |
| + |
| void skipAbbreviatedField(const NaClBitCodeAbbrevOp &Op); |
| // Reads the next Value using the abbreviation Op. Returns true only |
| @@ -571,12 +623,19 @@ private: |
| unsigned NumArrayElements, |
| SmallVectorImpl<uint64_t> &Vals); |
| + // Reports that that abbreviation Index is not valid. |
| + void reportInvalidAbbrevNumber(unsigned Index) const; |
| + |
| + // Reports that jumping to Bit is not valid. |
| + void reportInvalidJumpToBit(uint64_t Bit) const; |
| + |
| public: |
| /// getAbbrev - Return the abbreviation for the specified AbbrevId. |
| const NaClBitCodeAbbrev *getAbbrev(unsigned AbbrevID) const { |
| unsigned AbbrevNo = AbbrevID-naclbitc::FIRST_APPLICATION_ABBREV; |
| - assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!"); |
| + if (AbbrevNo >= CurAbbrevs.size()) |
| + reportInvalidAbbrevNumber(AbbrevID); |
| return CurAbbrevs[AbbrevNo]; |
| } |