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