Chromium Code Reviews| 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 // |
| 11 // This header defines the BitstreamReader class. This class can be used to | 11 // This header defines the BitstreamReader class. This class can be used to |
| 12 // read an arbitrary bitstream, regardless of its contents. | 12 // read an arbitrary bitstream, regardless of its contents. |
| 13 // | 13 // |
| 14 //===----------------------------------------------------------------------===// | 14 //===----------------------------------------------------------------------===// |
| 15 | 15 |
| 16 #ifndef LLVM_BITCODE_NACL_NACLBITSTREAMREADER_H | 16 #ifndef LLVM_BITCODE_NACL_NACLBITSTREAMREADER_H |
| 17 #define LLVM_BITCODE_NACL_NACLBITSTREAMREADER_H | 17 #define LLVM_BITCODE_NACL_NACLBITSTREAMREADER_H |
| 18 | 18 |
| 19 #include "llvm/ADT/SmallVector.h" | 19 #include "llvm/ADT/SmallVector.h" |
| 20 #include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h" | 20 #include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h" |
| 21 #include "llvm/Bitcode/NaCl/NaClLLVMBitCodes.h" | 21 #include "llvm/Bitcode/NaCl/NaClLLVMBitCodes.h" |
| 22 #include "llvm/Support/Endian.h" | 22 #include "llvm/Support/Endian.h" |
| 23 #include "llvm/Support/StreamingMemoryObject.h" | 23 #include "llvm/Support/StreamingMemoryObject.h" |
| 24 #include <climits> | 24 #include <climits> |
| 25 #include <vector> | 25 #include <vector> |
| 26 | 26 |
| 27 namespace llvm { | 27 namespace llvm { |
| 28 | 28 |
| 29 class Deserializer; | 29 class Deserializer; |
| 30 class NaClBitstreamCursor; | |
| 30 | 31 |
| 31 namespace naclbitc { | 32 namespace naclbitc { |
| 32 | 33 |
| 33 /// Returns the Bit as a Byte:BitInByte string. | 34 /// Returns the Bit as a Byte:BitInByte string. |
| 34 std::string getBitAddress(uint64_t Bit); | 35 std::string getBitAddress(uint64_t Bit); |
| 35 | 36 |
| 36 /// Severity levels for reporting errors. | 37 /// Severity levels for reporting errors. |
| 37 enum ErrorLevel { | 38 enum ErrorLevel { |
| 38 Warning, | 39 Warning, |
| 39 Error, | 40 Error, |
| 40 Fatal | 41 Fatal |
| 41 }; | 42 }; |
| 42 | 43 |
| 43 // Basic printing routine to generate the beginning of an error | 44 // Basic printing routine to generate the beginning of an error |
| 44 // message. BitPosition is the bit position the error was found. | 45 // message. BitPosition is the bit position the error was found. |
| 45 // Level is the severity of the error. | 46 // Level is the severity of the error. |
| 46 raw_ostream &ErrorAt(raw_ostream &Out, ErrorLevel Level, | 47 raw_ostream &ErrorAt(raw_ostream &Out, ErrorLevel Level, |
| 47 uint64_t BitPosition); | 48 uint64_t BitPosition); |
| 48 | 49 |
| 49 } // End namespace naclbitc. | 50 } // End namespace naclbitc. |
| 50 | 51 |
| 51 /// This class is used to read from a NaCl bitcode wire format stream, | 52 /// This class is used to read from a NaCl bitcode wire format stream, |
| 52 /// maintaining information that is global to decoding the entire file. | 53 /// maintaining information that is global to decoding the entire file. |
| 53 /// While a file is being read, multiple cursors can be independently | 54 /// While a file is being read, multiple cursors can be independently |
| 54 /// advanced or skipped around within the file. These are represented by | 55 /// advanced or skipped around within the file. These are represented by |
| 55 /// the NaClBitstreamCursor class. | 56 /// the NaClBitstreamCursor class. |
| 56 class NaClBitstreamReader { | 57 class NaClBitstreamReader { |
| 57 public: | 58 public: |
| 58 /// This contains information emitted to BLOCKINFO_BLOCK blocks. These | 59 // Models a raw list of abbreviations. |
| 59 /// describe abbreviations that all blocks of the specified ID inherit. | 60 static const size_t DefaultAbbrevListSize = 12; |
| 60 struct BlockInfo { | 61 using AbbrevListVector = SmallVector<NaClBitCodeAbbrev *, |
| 62 DefaultAbbrevListSize>; | |
| 63 | |
| 64 // Models and maintains a list of abbreviations. In particular, it maintains | |
| 65 // updating reference counts of abbreviation operators within the abbreviation | |
| 66 // list. | |
| 67 class AbbrevList { | |
| 68 public: | |
| 69 AbbrevList() = default; | |
| 70 explicit AbbrevList(const AbbrevList &NewAbbrevs) { | |
| 71 appendList(NewAbbrevs); | |
| 72 } | |
| 73 AbbrevList &operator=(const AbbrevList &Rhs) { | |
| 74 clear(); | |
| 75 appendList(Rhs); | |
| 76 return *this; | |
| 77 } | |
| 78 // appends Abbrev assuming that Abbv is not shared (i.e. already has the | |
| 79 // refernce count incremented). Takes ownership of Abbv. | |
| 80 void appendUnique(NaClBitCodeAbbrev *Abbv) { | |
|
Derek Schuff
2016/03/17 16:20:17
Does appendUnique mean that nothing else will ever
Karl
2016/03/17 18:37:08
Simplified the class by adding a "appendCreate" me
| |
| 81 Abbrevs.push_back(Abbv); | |
| 82 } | |
| 83 // appends Abbrev assuming that that Abbv is shared elsewhere (i.e. has not | |
| 84 // yet had the reference count incremented for sharing). | |
| 85 void appendShare(NaClBitCodeAbbrev *Abbrv) { | |
| 86 Abbrv->addRef(); | |
| 87 Abbrevs.push_back(Abbrv); | |
| 88 } | |
| 89 // Returns last abbreviation on list, and returns an unique reference (i.e. | |
| 90 // the reference count has been incremented before returning). | |
| 91 NaClBitCodeAbbrev *lastUnique() { | |
| 92 NaClBitCodeAbbrev *Abbrv = Abbrevs.back(); | |
| 93 Abbrv->addRef(); | |
| 94 return Abbrv; | |
| 95 } | |
| 96 // Removes the last element of the list. | |
| 97 void popLast() { | |
| 98 Abbrevs.back()->dropRef(); | |
| 99 Abbrevs.pop_back(); | |
| 100 } | |
| 101 // Copies contents of NewAbbrevs and appends to this. | |
| 102 void appendList(const AbbrevList &NewAbbrevs) { | |
| 103 for (NaClBitCodeAbbrev *Abbrv : NewAbbrevs.Abbrevs) | |
| 104 appendShare(Abbrv); | |
| 105 } | |
| 106 // Empties abbreviation list. | |
| 107 void clear() { | |
| 108 while(!Abbrevs.empty()) | |
| 109 popLast(); | |
| 110 } | |
| 111 // Allow read access to vector defining list. | |
| 112 const AbbrevListVector &getVector() const { return Abbrevs; } | |
| 113 ~AbbrevList() { clear(); } | |
| 114 private: | |
| 115 AbbrevListVector Abbrevs; | |
| 116 }; | |
| 117 | |
| 118 /// This contains information about abbreviations in blocks defined in the | |
| 119 /// BLOCKINFO_BLOCK block. These describe global abbreviations that apply to | |
| 120 /// all succeeding blocks of the specified ID. | |
| 121 class BlockInfo { | |
| 122 BlockInfo &operator=(const BlockInfo&) = delete; | |
| 123 public: | |
| 124 BlockInfo() = default; | |
| 125 explicit BlockInfo(unsigned BlockID) | |
| 126 : BlockID(BlockID), Abbrevs() {} | |
| 127 BlockInfo(const BlockInfo&) = default; | |
| 128 unsigned getBlockID() const { return BlockID; } | |
| 129 void setBlockID(unsigned ID) { BlockID = ID; } | |
| 130 AbbrevList &getAbbrevs() { return Abbrevs; } | |
| 131 // Allow read access to vector defining abbreviation list. | |
| 132 const AbbrevListVector &getVector() const { | |
| 133 return Abbrevs.getVector(); | |
| 134 } | |
| 135 // appends Abbrev assuming that Abbv is not shared (i.e. already has the | |
| 136 // refernce count incremented). Takes ownership of Abbv. | |
| 137 void appendUnique(NaClBitCodeAbbrev *Abbv) { | |
| 138 Abbrevs.appendUnique(Abbv); | |
| 139 } | |
| 140 ~BlockInfo() {} | |
| 141 private: | |
| 61 unsigned BlockID; | 142 unsigned BlockID; |
| 62 std::vector<NaClBitCodeAbbrev*> Abbrevs; | 143 AbbrevList Abbrevs; |
| 63 }; | 144 }; |
| 145 | |
| 64 private: | 146 private: |
| 65 friend class NaClBitstreamCursor; | 147 friend class NaClBitstreamCursor; |
| 66 | 148 |
| 67 std::unique_ptr<MemoryObject> BitcodeBytes; | 149 std::unique_ptr<MemoryObject> BitcodeBytes; |
| 68 | 150 |
| 69 std::vector<BlockInfo> BlockInfoRecords; | 151 std::vector<BlockInfo> BlockInfoRecords; |
| 70 | 152 |
| 153 // True if the BlockInfo block has been read. | |
| 154 bool HasReadBlockInfoBlock = false; | |
| 155 | |
| 71 /// \brief Holds the offset of the first byte after the header. | 156 /// \brief Holds the offset of the first byte after the header. |
| 72 size_t InitialAddress; | 157 size_t InitialAddress; |
| 73 | 158 |
| 74 // True if filler should be added to byte align records. | 159 // True if filler should be added to byte align records. |
| 75 bool AlignBitcodeRecords = false; | 160 bool AlignBitcodeRecords = false; |
| 76 NaClBitstreamReader(const NaClBitstreamReader&) = delete; | 161 NaClBitstreamReader(const NaClBitstreamReader&) = delete; |
| 77 void operator=(const NaClBitstreamReader&) = delete; | 162 void operator=(const NaClBitstreamReader&) = delete; |
| 78 | 163 |
| 79 | 164 |
| 80 void initFromHeader(NaClBitcodeHeader &Header) { | 165 void initFromHeader(NaClBitcodeHeader &Header) { |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 99 | 184 |
| 100 /// Read stream from bytes, starting at the given initial address. | 185 /// Read stream from bytes, starting at the given initial address. |
| 101 /// Provides simple API for unit testing. | 186 /// Provides simple API for unit testing. |
| 102 NaClBitstreamReader(MemoryObject *Bytes, size_t InitialAddress) | 187 NaClBitstreamReader(MemoryObject *Bytes, size_t InitialAddress) |
| 103 : BitcodeBytes(Bytes), InitialAddress(InitialAddress) { | 188 : BitcodeBytes(Bytes), InitialAddress(InitialAddress) { |
| 104 } | 189 } |
| 105 | 190 |
| 106 // Returns the memory object that is being read. | 191 // Returns the memory object that is being read. |
| 107 MemoryObject &getBitcodeBytes() { return *BitcodeBytes; } | 192 MemoryObject &getBitcodeBytes() { return *BitcodeBytes; } |
| 108 | 193 |
| 109 ~NaClBitstreamReader() { | 194 ~NaClBitstreamReader() {} |
| 110 // Free the BlockInfoRecords. | |
| 111 while (!BlockInfoRecords.empty()) { | |
| 112 BlockInfo &Info = BlockInfoRecords.back(); | |
| 113 // Free blockinfo abbrev info. | |
| 114 for (unsigned i = 0, e = static_cast<unsigned>(Info.Abbrevs.size()); | |
| 115 i != e; ++i) | |
| 116 Info.Abbrevs[i]->dropRef(); | |
| 117 BlockInfoRecords.pop_back(); | |
| 118 } | |
| 119 } | |
| 120 | 195 |
| 121 /// \brief Returns the initial address (after the header) of the input stream. | 196 /// \brief Returns the initial address (after the header) of the input stream. |
| 122 size_t getInitialAddress() const { | 197 size_t getInitialAddress() const { |
| 123 return InitialAddress; | 198 return InitialAddress; |
| 124 } | 199 } |
| 125 | 200 |
| 126 //===--------------------------------------------------------------------===// | 201 //===--------------------------------------------------------------------===// |
| 127 // Block Manipulation | 202 // Block Manipulation |
| 128 //===--------------------------------------------------------------------===// | 203 //===--------------------------------------------------------------------===// |
| 129 | 204 |
| 130 /// Return true if we've already read and processed the block info block for | |
| 131 /// this Bitstream. We only process it for the first cursor that walks over | |
| 132 /// it. | |
| 133 bool hasBlockInfoRecords() const { return !BlockInfoRecords.empty(); } | |
| 134 | |
| 135 /// If there is block info for the specified ID, return it, otherwise return | 205 /// If there is block info for the specified ID, return it, otherwise return |
| 136 /// null. | 206 /// null. |
| 137 const BlockInfo *getBlockInfo(unsigned BlockID) const { | 207 const BlockInfo *getBlockInfo(unsigned BlockID) const { |
| 138 // Common case, the most recent entry matches BlockID. | 208 // Common case, the most recent entry matches BlockID. |
| 139 if (!BlockInfoRecords.empty() && BlockInfoRecords.back().BlockID == BlockID) | 209 if (!BlockInfoRecords.empty() && |
| 210 BlockInfoRecords.back().getBlockID() == BlockID) | |
| 140 return &BlockInfoRecords.back(); | 211 return &BlockInfoRecords.back(); |
| 141 | 212 |
| 142 for (unsigned i = 0, e = static_cast<unsigned>(BlockInfoRecords.size()); | 213 for (unsigned i = 0, e = static_cast<unsigned>(BlockInfoRecords.size()); |
| 143 i != e; ++i) | 214 i != e; ++i) |
| 144 if (BlockInfoRecords[i].BlockID == BlockID) | 215 if (BlockInfoRecords[i].getBlockID() == BlockID) |
| 145 return &BlockInfoRecords[i]; | 216 return &BlockInfoRecords[i]; |
| 146 return nullptr; | 217 return nullptr; |
| 147 } | 218 } |
| 148 | 219 |
| 149 BlockInfo &getOrCreateBlockInfo(unsigned BlockID) { | 220 BlockInfo &getOrCreateBlockInfo(unsigned BlockID) { |
| 150 if (const BlockInfo *BI = getBlockInfo(BlockID)) | 221 if (const BlockInfo *BI = getBlockInfo(BlockID)) |
| 151 return *const_cast<BlockInfo*>(BI); | 222 return *const_cast<BlockInfo*>(BI); |
| 152 | 223 |
| 153 // Otherwise, add a new record. | 224 // Otherwise, add a new record. |
| 154 BlockInfoRecords.push_back(BlockInfo()); | 225 BlockInfoRecords.push_back(BlockInfo(BlockID)); |
| 155 BlockInfoRecords.back().BlockID = BlockID; | |
| 156 return BlockInfoRecords.back(); | 226 return BlockInfoRecords.back(); |
| 157 } | 227 } |
| 158 }; | 228 }; |
| 159 | 229 |
| 160 /// When advancing through a bitstream cursor, each advance can discover a few | 230 /// When advancing through a bitstream cursor, each advance can discover a few |
| 161 /// different kinds of entries: | 231 /// different kinds of entries: |
| 162 struct NaClBitstreamEntry { | 232 struct NaClBitstreamEntry { |
| 163 enum { | 233 enum { |
| 164 Error, // Malformed bitcode was found. | 234 Error, // Malformed bitcode was found. |
| 165 EndBlock, // We've reached the end of the current block, (or the end of the | 235 EndBlock, // We've reached the end of the current block, (or the end of the |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 198 /// to allow the readers to update internals of the bit stream reader | 268 /// to allow the readers to update internals of the bit stream reader |
| 199 /// appropriately. | 269 /// appropriately. |
| 200 class NaClAbbrevListener { | 270 class NaClAbbrevListener { |
| 201 NaClAbbrevListener(const NaClAbbrevListener&) = delete; | 271 NaClAbbrevListener(const NaClAbbrevListener&) = delete; |
| 202 void operator=(const NaClAbbrevListener&) = delete; | 272 void operator=(const NaClAbbrevListener&) = delete; |
| 203 public: | 273 public: |
| 204 NaClAbbrevListener() {} | 274 NaClAbbrevListener() {} |
| 205 virtual ~NaClAbbrevListener() {} | 275 virtual ~NaClAbbrevListener() {} |
| 206 | 276 |
| 207 /// Called to process the read abbreviation. | 277 /// Called to process the read abbreviation. |
| 208 virtual void ProcessAbbreviation(NaClBitCodeAbbrev *Abbrev, | 278 virtual void ProcessAbbreviation(NaClBitCodeAbbrev *Abbrv, |
| 209 bool IsLocal) = 0; | 279 bool IsLocal) = 0; |
| 210 | 280 |
| 211 /// Called after entering block. NumWords is the number of words | 281 /// Called after entering block. NumWords is the number of words |
| 212 /// in the block. | 282 /// in the block. |
| 213 virtual void BeginBlockInfoBlock(unsigned NumWords) = 0; | 283 virtual void BeginBlockInfoBlock(unsigned NumWords) = 0; |
| 214 | 284 |
| 215 /// Called if a naclbitc::BLOCKINFO_CODE_SETBID record is found in | 285 /// Called if a naclbitc::BLOCKINFO_CODE_SETBID record is found in |
| 216 /// NaClBitstreamCursor::ReadBlockInfoBlock. | 286 /// NaClBitstreamCursor::ReadBlockInfoBlock. |
| 217 virtual void SetBID() = 0; | 287 virtual void SetBID() = 0; |
| 218 | 288 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 269 /// follow the word size of the host machine for efficiency. We use word_t in | 339 /// follow the word size of the host machine for efficiency. We use word_t in |
| 270 /// places that are aware of this to make it perfectly explicit what is going | 340 /// places that are aware of this to make it perfectly explicit what is going |
| 271 /// on. | 341 /// on. |
| 272 typedef size_t word_t; | 342 typedef size_t word_t; |
| 273 word_t CurWord; | 343 word_t CurWord; |
| 274 | 344 |
| 275 /// This is the number of bits in CurWord that are valid. This | 345 /// This is the number of bits in CurWord that are valid. This |
| 276 /// is always from [0...bits_of(word_t)-1] inclusive. | 346 /// is always from [0...bits_of(word_t)-1] inclusive. |
| 277 unsigned BitsInCurWord; | 347 unsigned BitsInCurWord; |
| 278 | 348 |
| 279 /// This is the declared size of code values used for the current | 349 // Data specific to a block being scanned. |
| 280 /// block, in bits. | 350 class Block { |
| 281 NaClBitcodeSelectorAbbrev CurCodeSize; | 351 public: |
| 282 | 352 Block() = delete; |
| 283 /// Abbrevs installed in this block. | 353 Block &operator=(const Block &Rhs) { |
| 284 std::vector<NaClBitCodeAbbrev*> CurAbbrevs; | 354 GlobalAbbrevs = Rhs.GlobalAbbrevs; |
| 285 | 355 NumGlobalAbbrevs = Rhs.NumGlobalAbbrevs; |
| 286 struct Block { | 356 LocalAbbrevs = Rhs.LocalAbbrevs; |
| 287 NaClBitcodeSelectorAbbrev PrevCodeSize; | 357 CodeAbbrev = Rhs.CodeAbbrev; |
| 288 std::vector<NaClBitCodeAbbrev*> PrevAbbrevs; | 358 return *this; |
| 289 Block() : PrevCodeSize() {} | 359 } |
| 290 explicit Block(const NaClBitcodeSelectorAbbrev& PCS) | 360 Block(NaClBitstreamReader::BlockInfo *GlobalAbbrevs, |
| 291 : PrevCodeSize(PCS) {} | 361 NaClBitcodeSelectorAbbrev& CodeAbbrev) |
| 362 : GlobalAbbrevs(GlobalAbbrevs), | |
| 363 NumGlobalAbbrevs(GlobalAbbrevs->getVector().size()), | |
| 364 LocalAbbrevs(), CodeAbbrev(CodeAbbrev) {} | |
| 365 Block(NaClBitstreamReader::BlockInfo *GlobalAbbrevs) | |
| 366 : GlobalAbbrevs(GlobalAbbrevs), | |
| 367 NumGlobalAbbrevs(GlobalAbbrevs->getVector().size()), | |
| 368 LocalAbbrevs(), CodeAbbrev() {} | |
| 369 ~Block() = default; | |
| 370 const NaClBitstreamReader::AbbrevList &getGlobalAbbrevs() const { | |
| 371 return GlobalAbbrevs->getAbbrevs(); | |
| 372 } | |
| 373 unsigned getNumGlobalAbbrevs() const { return NumGlobalAbbrevs; } | |
| 374 const NaClBitstreamReader::AbbrevList &getLocalAbbrevs() const { | |
| 375 return LocalAbbrevs; | |
| 376 } | |
| 377 const NaClBitcodeSelectorAbbrev &getCodeAbbrev() const { | |
| 378 return CodeAbbrev; | |
| 379 } | |
| 380 void setCodeAbbrev(NaClBitcodeSelectorAbbrev &Abbrev) { | |
| 381 CodeAbbrev = Abbrev; | |
| 382 } | |
| 383 // Appends Abbrev to local abbreviations assuming that Abbv is not shared | |
| 384 // (i.e. already has the refernce count incremented). Takes ownship of Abbv. | |
| 385 void appendUniqueLocalAbbrev(NaClBitCodeAbbrev *Abbv) { | |
| 386 LocalAbbrevs.appendUnique(Abbv); | |
| 387 } | |
| 388 /// removes the last added local abbreviation and moves it to the given | |
| 389 /// abbreviation list. | |
| 390 void moveLocalAbbrevToAbbrevList(NaClBitstreamReader::AbbrevList *List) { | |
| 391 NaClBitCodeAbbrev *Abbv = LocalAbbrevs.lastUnique(); | |
| 392 LocalAbbrevs.popLast(); | |
| 393 List->appendUnique(Abbv); | |
| 394 } | |
| 395 private: | |
| 396 friend class NaClBitstreamCursor; | |
| 397 // The global abbreviations associated with this scope. | |
| 398 NaClBitstreamReader::BlockInfo *GlobalAbbrevs; | |
| 399 // Number of abbreviations when block was entered. Used to limit scope of | |
| 400 // CurBlockInfo, since any abbreviation added inside a BlockInfo block | |
| 401 // (within this block) must not effect global abbreviations. | |
| 402 unsigned NumGlobalAbbrevs; | |
| 403 NaClBitstreamReader::AbbrevList LocalAbbrevs; | |
| 404 // This is the declared size of code values used for the current block, in | |
| 405 // bits. | |
| 406 NaClBitcodeSelectorAbbrev CodeAbbrev; | |
| 292 }; | 407 }; |
| 293 | 408 |
| 294 /// This tracks the codesize of parent blocks. | 409 /// This tracks the Block-specific information for each nested block. |
| 295 SmallVector<Block, 8> BlockScope; | 410 SmallVector<Block, 8> BlockScope; |
| 296 | 411 |
| 297 NaClBitstreamCursor(const NaClBitstreamCursor &) = delete; | 412 NaClBitstreamCursor(const NaClBitstreamCursor &) = delete; |
| 298 NaClBitstreamCursor &operator=(const NaClBitstreamCursor &) = delete; | 413 NaClBitstreamCursor &operator=(const NaClBitstreamCursor &) = delete; |
| 299 | 414 |
| 300 public: | 415 public: |
| 301 NaClBitstreamCursor() : ErrHandler(new ErrorHandler(*this)) { | 416 NaClBitstreamCursor() : ErrHandler(new ErrorHandler(*this)) { |
| 302 init(nullptr); | 417 init(nullptr); |
| 303 } | 418 } |
| 304 | 419 |
| 305 explicit NaClBitstreamCursor(NaClBitstreamReader &R) | 420 explicit NaClBitstreamCursor(NaClBitstreamReader &R) |
| 306 : ErrHandler(new ErrorHandler(*this)) { init(&R); } | 421 : ErrHandler(new ErrorHandler(*this)) { init(&R); } |
| 307 | 422 |
| 308 void init(NaClBitstreamReader *R) { | 423 void init(NaClBitstreamReader *R) { |
| 309 freeState(); | 424 freeState(); |
| 310 BitStream = R; | 425 BitStream = R; |
| 311 NextChar = (BitStream == nullptr) ? 0 : BitStream->getInitialAddress(); | 426 NextChar = (BitStream == nullptr) ? 0 : BitStream->getInitialAddress(); |
| 312 Size = 0; | 427 Size = 0; |
| 313 BitsInCurWord = 0; | 428 BitsInCurWord = 0; |
| 429 if (BitStream) { | |
| 430 BlockScope.push_back( | |
| 431 Block(&BitStream->getOrCreateBlockInfo(naclbitc::TOP_LEVEL_BLOCKID))); | |
| 432 } | |
| 314 } | 433 } |
| 315 | 434 |
| 316 ~NaClBitstreamCursor() { | 435 ~NaClBitstreamCursor() { |
| 317 freeState(); | 436 freeState(); |
| 318 } | 437 } |
| 319 | 438 |
| 320 void freeState(); | 439 void freeState() { |
| 440 while (!BlockScope.empty()) | |
| 441 BlockScope.pop_back(); | |
| 442 } | |
| 321 | 443 |
| 322 // Replaces the current bitstream error handler with the new | 444 // Replaces the current bitstream error handler with the new |
| 323 // handler. Takes ownership of the new handler and deletes it when | 445 // handler. Takes ownership of the new handler and deletes it when |
| 324 // it is no longer needed. | 446 // it is no longer needed. |
| 325 void setErrorHandler(std::unique_ptr<ErrorHandler> &NewHandler) { | 447 void setErrorHandler(std::unique_ptr<ErrorHandler> &NewHandler) { |
| 326 ErrHandler = std::move(NewHandler); | 448 ErrHandler = std::move(NewHandler); |
| 327 } | 449 } |
| 328 | 450 |
| 329 bool canSkipToPos(size_t pos) const { | 451 bool canSkipToPos(size_t pos) const { |
| 330 // pos can be skipped to if it is a valid address or one byte past the end. | 452 // pos can be skipped to if it is a valid address or one byte past the end. |
| 331 return pos == 0 || BitStream->getBitcodeBytes().isValidAddress( | 453 return pos == 0 || BitStream->getBitcodeBytes().isValidAddress( |
| 332 static_cast<uint64_t>(pos - 1)); | 454 static_cast<uint64_t>(pos - 1)); |
| 333 } | 455 } |
| 334 | 456 |
| 335 bool AtEndOfStream() { | 457 bool AtEndOfStream() { |
| 336 if (BitsInCurWord != 0) | 458 if (BitsInCurWord != 0) |
| 337 return false; | 459 return false; |
| 338 if (Size != 0) | 460 if (Size != 0) |
| 339 return Size == NextChar; | 461 return Size == NextChar; |
| 340 fillCurWord(); | 462 fillCurWord(); |
| 341 return BitsInCurWord == 0; | 463 return BitsInCurWord == 0; |
| 342 } | 464 } |
| 343 | 465 |
| 344 /// Return the number of bits used to encode an abbrev #. | 466 /// Return the number of bits used to encode an abbrev #. |
| 345 unsigned getAbbrevIDWidth() const { return CurCodeSize.NumBits; } | 467 unsigned getAbbrevIDWidth() const { |
| 468 return BlockScope.back().getCodeAbbrev().NumBits; | |
| 469 } | |
| 346 | 470 |
| 347 /// Return the bit # of the bit we are reading. | 471 /// Return the bit # of the bit we are reading. |
| 348 uint64_t GetCurrentBitNo() const { | 472 uint64_t GetCurrentBitNo() const { |
| 349 return NextChar*CHAR_BIT - BitsInCurWord; | 473 return NextChar*CHAR_BIT - BitsInCurWord; |
| 350 } | 474 } |
| 351 | 475 |
| 352 NaClBitstreamReader *getBitStreamReader() { | 476 NaClBitstreamReader *getBitStreamReader() { |
| 353 return BitStream; | 477 return BitStream; |
| 354 } | 478 } |
| 355 const NaClBitstreamReader *getBitStreamReader() const { | 479 const NaClBitstreamReader *getBitStreamReader() const { |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 552 CurWord >>= BitsInCurWord-32; | 676 CurWord >>= BitsInCurWord-32; |
| 553 BitsInCurWord = 32; | 677 BitsInCurWord = 32; |
| 554 return; | 678 return; |
| 555 } | 679 } |
| 556 | 680 |
| 557 BitsInCurWord = 0; | 681 BitsInCurWord = 0; |
| 558 } | 682 } |
| 559 public: | 683 public: |
| 560 | 684 |
| 561 unsigned ReadCode() { | 685 unsigned ReadCode() { |
| 562 return CurCodeSize.IsFixed | 686 const NaClBitcodeSelectorAbbrev &CodeAbbrev = |
| 563 ? Read(CurCodeSize.NumBits) | 687 BlockScope.back().getCodeAbbrev(); |
| 564 : ReadVBR(CurCodeSize.NumBits); | 688 return CodeAbbrev.IsFixed |
| 689 ? Read(CodeAbbrev.NumBits) | |
| 690 : ReadVBR(CodeAbbrev.NumBits); | |
| 565 } | 691 } |
| 566 | 692 |
| 567 // Block header: | 693 // Block header: |
| 568 // [ENTER_SUBBLOCK, blockid, newcodelen, <align4bytes>, blocklen] | 694 // [ENTER_SUBBLOCK, blockid, newcodelen, <align4bytes>, blocklen] |
| 569 | 695 |
| 570 /// Having read the ENTER_SUBBLOCK code, read the BlockID for the block. | 696 /// Having read the ENTER_SUBBLOCK code, read the BlockID for the block. |
| 571 unsigned ReadSubBlockID() { | 697 unsigned ReadSubBlockID() { |
| 572 return ReadVBR(naclbitc::BlockIDWidth); | 698 return ReadVBR(naclbitc::BlockIDWidth); |
| 573 } | 699 } |
| 574 | 700 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 595 /// if the block has an error. | 721 /// if the block has an error. |
| 596 bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = nullptr); | 722 bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = nullptr); |
| 597 | 723 |
| 598 bool ReadBlockEnd() { | 724 bool ReadBlockEnd() { |
| 599 if (BlockScope.empty()) return true; | 725 if (BlockScope.empty()) return true; |
| 600 | 726 |
| 601 // Block tail: | 727 // Block tail: |
| 602 // [END_BLOCK, <align4bytes>] | 728 // [END_BLOCK, <align4bytes>] |
| 603 SkipToFourByteBoundary(); | 729 SkipToFourByteBoundary(); |
| 604 | 730 |
| 605 popBlockScope(); | 731 BlockScope.pop_back(); |
| 606 return false; | 732 return false; |
| 607 } | 733 } |
| 608 | 734 |
| 609 private: | 735 private: |
| 610 | 736 |
| 611 void popBlockScope() { | |
| 612 CurCodeSize = BlockScope.back().PrevCodeSize; | |
| 613 | |
| 614 // Delete abbrevs from popped scope. | |
| 615 for (unsigned i = 0, e = static_cast<unsigned>(CurAbbrevs.size()); | |
| 616 i != e; ++i) | |
| 617 CurAbbrevs[i]->dropRef(); | |
| 618 | |
| 619 BlockScope.back().PrevAbbrevs.swap(CurAbbrevs); | |
| 620 BlockScope.pop_back(); | |
| 621 } | |
| 622 | |
| 623 //===--------------------------------------------------------------------===// | 737 //===--------------------------------------------------------------------===// |
| 624 // Record Processing | 738 // Record Processing |
| 625 //===--------------------------------------------------------------------===// | 739 //===--------------------------------------------------------------------===// |
| 626 | 740 |
| 627 private: | 741 private: |
| 628 // Returns abbreviation encoding associated with Value. | 742 // Returns abbreviation encoding associated with Value. |
| 629 NaClBitCodeAbbrevOp::Encoding getEncoding(uint64_t Value); | 743 NaClBitCodeAbbrevOp::Encoding getEncoding(uint64_t Value); |
| 630 | 744 |
| 631 void skipAbbreviatedField(const NaClBitCodeAbbrevOp &Op); | 745 void skipAbbreviatedField(const NaClBitCodeAbbrevOp &Op); |
| 632 | 746 |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 650 void reportInvalidAbbrevNumber(unsigned Index) const; | 764 void reportInvalidAbbrevNumber(unsigned Index) const; |
| 651 | 765 |
| 652 // Reports that jumping to Bit is not valid. | 766 // Reports that jumping to Bit is not valid. |
| 653 void reportInvalidJumpToBit(uint64_t Bit) const; | 767 void reportInvalidJumpToBit(uint64_t Bit) const; |
| 654 | 768 |
| 655 public: | 769 public: |
| 656 | 770 |
| 657 /// Return the abbreviation for the specified AbbrevId. | 771 /// Return the abbreviation for the specified AbbrevId. |
| 658 const NaClBitCodeAbbrev *getAbbrev(unsigned AbbrevID) const { | 772 const NaClBitCodeAbbrev *getAbbrev(unsigned AbbrevID) const { |
| 659 unsigned AbbrevNo = AbbrevID-naclbitc::FIRST_APPLICATION_ABBREV; | 773 unsigned AbbrevNo = AbbrevID-naclbitc::FIRST_APPLICATION_ABBREV; |
| 660 if (AbbrevNo >= CurAbbrevs.size()) | 774 const Block &CurBlock = BlockScope.back(); |
| 775 const unsigned NumGlobalAbbrevs = CurBlock.getNumGlobalAbbrevs(); | |
| 776 if (AbbrevNo < NumGlobalAbbrevs) | |
| 777 return CurBlock.getGlobalAbbrevs().getVector()[AbbrevNo]; | |
| 778 unsigned LocalAbbrevNo = AbbrevNo - NumGlobalAbbrevs; | |
| 779 NaClBitstreamReader::AbbrevListVector | |
| 780 LocalAbbrevs = CurBlock.getLocalAbbrevs().getVector(); | |
| 781 if (LocalAbbrevNo >= LocalAbbrevs.size()) | |
| 661 reportInvalidAbbrevNumber(AbbrevID); | 782 reportInvalidAbbrevNumber(AbbrevID); |
| 662 return CurAbbrevs[AbbrevNo]; | 783 return LocalAbbrevs[LocalAbbrevNo]; |
| 663 } | 784 } |
| 664 | 785 |
| 665 /// Read the current record and discard it. | 786 /// Read the current record and discard it. |
| 666 void skipRecord(unsigned AbbrevID); | 787 void skipRecord(unsigned AbbrevID); |
| 667 | 788 |
| 668 unsigned readRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals); | 789 unsigned readRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals); |
| 669 | 790 |
| 670 //===--------------------------------------------------------------------===// | 791 //===--------------------------------------------------------------------===// |
| 671 // Abbrev Processing | 792 // Abbrev Processing |
| 672 //===--------------------------------------------------------------------===// | 793 //===--------------------------------------------------------------------===// |
| 673 // IsLocal indicates where the abbreviation occurs. If it is in the | 794 // IsLocal indicates where the abbreviation occurs. If it is in the |
| 674 // BlockInfo block, IsLocal is false. In all other cases, IsLocal is | 795 // BlockInfo block, IsLocal is false. In all other cases, IsLocal is |
| 675 // true. | 796 // true. |
| 676 void ReadAbbrevRecord(bool IsLocal, | 797 void ReadAbbrevRecord(bool IsLocal, |
| 677 NaClAbbrevListener *Listener); | 798 NaClAbbrevListener *Listener); |
| 678 | 799 |
| 679 // Skips over an abbreviation record. Duplicates code of ReadAbbrevRecord, | 800 // Skips over an abbreviation record. Duplicates code of ReadAbbrevRecord, |
| 680 // except that no abbreviation is built. | 801 // except that no abbreviation is built. |
| 681 void SkipAbbrevRecord(); | 802 void SkipAbbrevRecord(); |
| 682 | 803 |
| 683 bool ReadBlockInfoBlock(NaClAbbrevListener *Listener); | 804 bool ReadBlockInfoBlock(NaClAbbrevListener *Listener); |
| 684 }; | 805 }; |
| 685 | 806 |
| 686 } // End llvm namespace | 807 } // End llvm namespace |
| 687 | 808 |
| 688 #endif | 809 #endif |
| OLD | NEW |