| 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/NaClLLVMBitCodes.h" | 20 #include "llvm/Bitcode/NaCl/NaClLLVMBitCodes.h" |
| 21 #include "llvm/Support/Endian.h" | 21 #include "llvm/Support/Endian.h" |
| 22 #include "llvm/Support/StreamableMemoryObject.h" | 22 #include "llvm/Support/StreamingMemoryObject.h" |
| 23 #include <climits> | 23 #include <climits> |
| 24 #include <vector> | 24 #include <vector> |
| 25 | 25 |
| 26 namespace llvm { | 26 namespace llvm { |
| 27 | 27 |
| 28 class Deserializer; | 28 class Deserializer; |
| 29 | 29 |
| 30 /// NaClBitstreamReader - This class is used to read from a NaCl | 30 /// This class is used to read from a NaCl bitcode wire format stream, |
| 31 /// bitcode wire format stream, maintaining information that is global | 31 /// maintaining information that is global to decoding the entire file. |
| 32 /// to decoding the entire file. While a file is being read, multiple | 32 /// While a file is being read, multiple cursors can be independently |
| 33 /// cursors can be independently advanced or skipped around within the | 33 /// advanced or skipped around within the file. These are represented by |
| 34 /// file. These are represented by the NaClBitstreamCursor class. | 34 /// the NaClBitstreamCursor class. |
| 35 class NaClBitstreamReader { | 35 class NaClBitstreamReader { |
| 36 public: | 36 public: |
| 37 /// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks. | 37 /// This contains information emitted to BLOCKINFO_BLOCK blocks. These |
| 38 /// These describe abbreviations that all blocks of the specified ID inherit. | 38 /// describe abbreviations that all blocks of the specified ID inherit. |
| 39 struct BlockInfo { | 39 struct BlockInfo { |
| 40 unsigned BlockID; | 40 unsigned BlockID; |
| 41 std::vector<NaClBitCodeAbbrev*> Abbrevs; | 41 std::vector<NaClBitCodeAbbrev*> Abbrevs; |
| 42 }; | 42 }; |
| 43 private: | 43 private: |
| 44 std::unique_ptr<StreamableMemoryObject> BitcodeBytes; | 44 std::unique_ptr<MemoryObject> BitcodeBytes; |
| 45 | 45 |
| 46 std::vector<BlockInfo> BlockInfoRecords; | 46 std::vector<BlockInfo> BlockInfoRecords; |
| 47 | 47 |
| 48 /// \brief Holds the offset of the first byte after the header. | 48 /// \brief Holds the offset of the first byte after the header. |
| 49 size_t InitialAddress; | 49 size_t InitialAddress; |
| 50 | 50 |
| 51 NaClBitstreamReader(const NaClBitstreamReader&) LLVM_DELETED_FUNCTION; | 51 NaClBitstreamReader(const NaClBitstreamReader&) LLVM_DELETED_FUNCTION; |
| 52 void operator=(const NaClBitstreamReader&) LLVM_DELETED_FUNCTION; | 52 void operator=(const NaClBitstreamReader&) LLVM_DELETED_FUNCTION; |
| 53 public: | 53 public: |
| 54 NaClBitstreamReader() : InitialAddress(0) {} | 54 NaClBitstreamReader() : InitialAddress(0) {} |
| 55 | 55 |
| 56 NaClBitstreamReader(const unsigned char *Start, const unsigned char *End, | 56 NaClBitstreamReader(const unsigned char *Start, const unsigned char *End, |
| 57 size_t MyInitialAddress=0) { | 57 size_t MyInitialAddress=0) { |
| 58 InitialAddress = MyInitialAddress; | 58 InitialAddress = MyInitialAddress; |
| 59 init(Start, End); | 59 init(Start, End); |
| 60 } | 60 } |
| 61 | 61 |
| 62 NaClBitstreamReader(StreamableMemoryObject *Bytes, | 62 NaClBitstreamReader(MemoryObject *Bytes, size_t MyInitialAddress=0) |
| 63 size_t MyInitialAddress=0) | 63 : InitialAddress(MyInitialAddress) { |
| 64 : InitialAddress(MyInitialAddress) | |
| 65 { | |
| 66 BitcodeBytes.reset(Bytes); | 64 BitcodeBytes.reset(Bytes); |
| 67 } | 65 } |
| 68 | 66 |
| 69 void init(const unsigned char *Start, const unsigned char *End) { | 67 void init(const unsigned char *Start, const unsigned char *End) { |
| 70 assert(((End-Start) & 3) == 0 &&"Bitcode stream not a multiple of 4 bytes"); | 68 assert(((End-Start) & 3) == 0 &&"Bitcode stream not a multiple of 4 bytes"); |
| 71 BitcodeBytes.reset(getNonStreamedMemoryObject(Start, End)); | 69 BitcodeBytes.reset(getNonStreamedMemoryObject(Start, End)); |
| 72 } | 70 } |
| 73 | 71 |
| 74 StreamableMemoryObject &getBitcodeBytes() { return *BitcodeBytes; } | 72 MemoryObject &getBitcodeBytes() { return *BitcodeBytes; } |
| 75 | 73 |
| 76 ~NaClBitstreamReader() { | 74 ~NaClBitstreamReader() { |
| 77 // Free the BlockInfoRecords. | 75 // Free the BlockInfoRecords. |
| 78 while (!BlockInfoRecords.empty()) { | 76 while (!BlockInfoRecords.empty()) { |
| 79 BlockInfo &Info = BlockInfoRecords.back(); | 77 BlockInfo &Info = BlockInfoRecords.back(); |
| 80 // Free blockinfo abbrev info. | 78 // Free blockinfo abbrev info. |
| 81 for (unsigned i = 0, e = static_cast<unsigned>(Info.Abbrevs.size()); | 79 for (unsigned i = 0, e = static_cast<unsigned>(Info.Abbrevs.size()); |
| 82 i != e; ++i) | 80 i != e; ++i) |
| 83 Info.Abbrevs[i]->dropRef(); | 81 Info.Abbrevs[i]->dropRef(); |
| 84 BlockInfoRecords.pop_back(); | 82 BlockInfoRecords.pop_back(); |
| 85 } | 83 } |
| 86 } | 84 } |
| 87 | 85 |
| 88 /// \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. |
| 89 size_t getInitialAddress() const { | 87 size_t getInitialAddress() const { |
| 90 return InitialAddress; | 88 return InitialAddress; |
| 91 } | 89 } |
| 92 | 90 |
| 93 //===--------------------------------------------------------------------===// | 91 //===--------------------------------------------------------------------===// |
| 94 // Block Manipulation | 92 // Block Manipulation |
| 95 //===--------------------------------------------------------------------===// | 93 //===--------------------------------------------------------------------===// |
| 96 | 94 |
| 97 /// hasBlockInfoRecords - Return true if we've already read and processed the | 95 /// Return true if we've already read and processed the block info block for |
| 98 /// block info block for this Bitstream. We only process it for the first | 96 /// this Bitstream. We only process it for the first cursor that walks over |
| 99 /// cursor that walks over it. | 97 /// it. |
| 100 bool hasBlockInfoRecords() const { return !BlockInfoRecords.empty(); } | 98 bool hasBlockInfoRecords() const { return !BlockInfoRecords.empty(); } |
| 101 | 99 |
| 102 /// getBlockInfo - If there is block info for the specified ID, return it, | 100 /// If there is block info for the specified ID, return it, otherwise return |
| 103 /// otherwise return null. | 101 /// null. |
| 104 const BlockInfo *getBlockInfo(unsigned BlockID) const { | 102 const BlockInfo *getBlockInfo(unsigned BlockID) const { |
| 105 // Common case, the most recent entry matches BlockID. | 103 // Common case, the most recent entry matches BlockID. |
| 106 if (!BlockInfoRecords.empty() && BlockInfoRecords.back().BlockID == BlockID) | 104 if (!BlockInfoRecords.empty() && BlockInfoRecords.back().BlockID == BlockID) |
| 107 return &BlockInfoRecords.back(); | 105 return &BlockInfoRecords.back(); |
| 108 | 106 |
| 109 for (unsigned i = 0, e = static_cast<unsigned>(BlockInfoRecords.size()); | 107 for (unsigned i = 0, e = static_cast<unsigned>(BlockInfoRecords.size()); |
| 110 i != e; ++i) | 108 i != e; ++i) |
| 111 if (BlockInfoRecords[i].BlockID == BlockID) | 109 if (BlockInfoRecords[i].BlockID == BlockID) |
| 112 return &BlockInfoRecords[i]; | 110 return &BlockInfoRecords[i]; |
| 113 return 0; | 111 return nullptr; |
| 114 } | 112 } |
| 115 | 113 |
| 116 BlockInfo &getOrCreateBlockInfo(unsigned BlockID) { | 114 BlockInfo &getOrCreateBlockInfo(unsigned BlockID) { |
| 117 if (const BlockInfo *BI = getBlockInfo(BlockID)) | 115 if (const BlockInfo *BI = getBlockInfo(BlockID)) |
| 118 return *const_cast<BlockInfo*>(BI); | 116 return *const_cast<BlockInfo*>(BI); |
| 119 | 117 |
| 120 // Otherwise, add a new record. | 118 // Otherwise, add a new record. |
| 121 BlockInfoRecords.push_back(BlockInfo()); | 119 BlockInfoRecords.push_back(BlockInfo()); |
| 122 BlockInfoRecords.back().BlockID = BlockID; | 120 BlockInfoRecords.back().BlockID = BlockID; |
| 123 return BlockInfoRecords.back(); | 121 return BlockInfoRecords.back(); |
| 124 } | 122 } |
| 125 }; | 123 }; |
| 126 | 124 |
| 127 | 125 /// When advancing through a bitstream cursor, each advance can discover a few |
| 128 /// NaClBitstreamEntry - When advancing through a bitstream cursor, | 126 /// different kinds of entries: |
| 129 /// each advance can discover a few different kinds of entries: | |
| 130 /// Error - Malformed bitcode was found. | |
| 131 /// EndBlock - We've reached the end of the current block, (or the end of the | |
| 132 /// file, which is treated like a series of EndBlock records. | |
| 133 /// SubBlock - This is the start of a new subblock of a specific ID. | |
| 134 /// Record - This is a record with a specific AbbrevID. | |
| 135 /// | |
| 136 struct NaClBitstreamEntry { | 127 struct NaClBitstreamEntry { |
| 137 enum { | 128 enum { |
| 138 Error, | 129 Error, // Malformed bitcode was found. |
| 139 EndBlock, | 130 EndBlock, // We've reached the end of the current block, (or the end of the |
| 140 SubBlock, | 131 // file, which is treated like a series of EndBlock records. |
| 141 Record | 132 SubBlock, // This is the start of a new subblock of a specific ID. |
| 133 Record // This is a record with a specific AbbrevID. |
| 142 } Kind; | 134 } Kind; |
| 143 | 135 |
| 144 unsigned ID; | 136 unsigned ID; |
| 145 | 137 |
| 146 static NaClBitstreamEntry getError() { | 138 static NaClBitstreamEntry getError() { |
| 147 NaClBitstreamEntry E; E.Kind = Error; return E; | 139 NaClBitstreamEntry E; E.Kind = Error; return E; |
| 148 } | 140 } |
| 149 static NaClBitstreamEntry getEndBlock() { | 141 static NaClBitstreamEntry getEndBlock() { |
| 150 NaClBitstreamEntry E; E.Kind = EndBlock; return E; | 142 NaClBitstreamEntry E; E.Kind = EndBlock; return E; |
| 151 } | 143 } |
| 152 static NaClBitstreamEntry getSubBlock(unsigned ID) { | 144 static NaClBitstreamEntry getSubBlock(unsigned ID) { |
| 153 NaClBitstreamEntry E; E.Kind = SubBlock; E.ID = ID; return E; | 145 NaClBitstreamEntry E; E.Kind = SubBlock; E.ID = ID; return E; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 | 187 |
| 196 /// The values of the bitcode record associated with the called | 188 /// The values of the bitcode record associated with the called |
| 197 /// virtual function. | 189 /// virtual function. |
| 198 NaClBitcodeRecordVector Values; | 190 NaClBitcodeRecordVector Values; |
| 199 | 191 |
| 200 /// Start bit for current record being processed in | 192 /// Start bit for current record being processed in |
| 201 /// NaClBitstreamCursor::ReadBlockInfoBlock. | 193 /// NaClBitstreamCursor::ReadBlockInfoBlock. |
| 202 uint64_t StartBit; | 194 uint64_t StartBit; |
| 203 }; | 195 }; |
| 204 | 196 |
| 205 /// NaClBitstreamCursor - This represents a position within a bitcode | 197 /// This represents a position within a bitcode file. There may be multiple |
| 206 /// file. There may be multiple independent cursors reading within | 198 /// independent cursors reading within one bitstream, each maintaining their |
| 207 /// one bitstream, each maintaining their own local state. | 199 /// own local state. |
| 208 /// | 200 /// |
| 209 /// Unlike iterators, NaClBitstreamCursors are heavy-weight objects | 201 /// Unlike iterators, NaClBitstreamCursors are heavy-weight objects |
| 210 /// that should not be passed by value. | 202 /// that should not be passed by value. |
| 211 class NaClBitstreamCursor { | 203 class NaClBitstreamCursor { |
| 212 friend class Deserializer; | 204 friend class Deserializer; |
| 213 NaClBitstreamReader *BitStream; | 205 NaClBitstreamReader *BitStream; |
| 214 size_t NextChar; | 206 size_t NextChar; |
| 215 | 207 |
| 216 /// CurWord/word_t - This is the current data we have pulled from the stream | 208 // The size of the bitcode. 0 if we don't know it yet. |
| 217 /// but have not returned to the client. This is specifically and | 209 size_t Size; |
| 218 /// intentionally defined to follow the word size of the host machine for | 210 |
| 219 /// efficiency. We use word_t in places that are aware of this to make it | 211 /// This is the current data we have pulled from the stream but have not |
| 220 /// perfectly explicit what is going on. | 212 /// returned to the client. This is specifically and intentionally defined to |
| 221 typedef uint32_t word_t; | 213 /// 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 |
| 215 /// on. |
| 216 typedef size_t word_t; |
| 222 word_t CurWord; | 217 word_t CurWord; |
| 223 | 218 |
| 224 /// BitsInCurWord - This is the number of bits in CurWord that are valid. This | 219 /// This is the number of bits in CurWord that are valid. This |
| 225 /// is always from [0...31/63] inclusive (depending on word size). | 220 /// is always from [0...bits_of(word_t)-1] inclusive. |
| 226 unsigned BitsInCurWord; | 221 unsigned BitsInCurWord; |
| 227 | 222 |
| 228 // CurCodeSize - This is the declared size of code values used for the current | 223 /// This is the declared size of code values used for the current |
| 229 // block, in bits. | 224 /// block, in bits. |
| 230 NaClBitcodeSelectorAbbrev CurCodeSize; | 225 NaClBitcodeSelectorAbbrev CurCodeSize; |
| 231 | 226 |
| 232 /// CurAbbrevs - Abbrevs installed at in this block. | 227 /// Abbrevs installed in this block. |
| 233 std::vector<NaClBitCodeAbbrev*> CurAbbrevs; | 228 std::vector<NaClBitCodeAbbrev*> CurAbbrevs; |
| 234 | 229 |
| 235 struct Block { | 230 struct Block { |
| 236 NaClBitcodeSelectorAbbrev PrevCodeSize; | 231 NaClBitcodeSelectorAbbrev PrevCodeSize; |
| 237 std::vector<NaClBitCodeAbbrev*> PrevAbbrevs; | 232 std::vector<NaClBitCodeAbbrev*> PrevAbbrevs; |
| 238 explicit Block() : PrevCodeSize() {} | 233 Block() : PrevCodeSize() {} |
| 239 explicit Block(const NaClBitcodeSelectorAbbrev& PCS) | 234 explicit Block(const NaClBitcodeSelectorAbbrev& PCS) |
| 240 : PrevCodeSize(PCS) {} | 235 : PrevCodeSize(PCS) {} |
| 241 }; | 236 }; |
| 242 | 237 |
| 243 /// BlockScope - This tracks the codesize of parent blocks. | 238 /// This tracks the codesize of parent blocks. |
| 244 SmallVector<Block, 8> BlockScope; | 239 SmallVector<Block, 8> BlockScope; |
| 245 | 240 |
| 246 NaClBitstreamCursor(const NaClBitstreamCursor &) LLVM_DELETED_FUNCTION; | 241 NaClBitstreamCursor(const NaClBitstreamCursor &) LLVM_DELETED_FUNCTION; |
| 247 NaClBitstreamCursor &operator=(const NaClBitstreamCursor &) LLVM_DELETED_FUNCT
ION; | 242 NaClBitstreamCursor &operator=(const NaClBitstreamCursor &) LLVM_DELETED_FUNCT
ION; |
| 248 | 243 |
| 249 public: | 244 public: |
| 250 | 245 NaClBitstreamCursor() { init(nullptr); } |
| 251 NaClBitstreamCursor() { | |
| 252 init(nullptr); | |
| 253 } | |
| 254 | 246 |
| 255 explicit NaClBitstreamCursor(NaClBitstreamReader &R) { init(&R); } | 247 explicit NaClBitstreamCursor(NaClBitstreamReader &R) { init(&R); } |
| 256 | 248 |
| 257 void init(NaClBitstreamReader *R) { | 249 void init(NaClBitstreamReader *R) { |
| 258 freeState(); | 250 freeState(); |
| 259 BitStream = R; | 251 BitStream = R; |
| 260 NextChar = (BitStream == nullptr) ? 0 : BitStream->getInitialAddress(); | 252 NextChar = (BitStream == nullptr) ? 0 : BitStream->getInitialAddress(); |
| 261 CurWord = 0; | 253 Size = 0; |
| 262 BitsInCurWord = 0; | 254 BitsInCurWord = 0; |
| 263 } | 255 } |
| 264 | 256 |
| 265 ~NaClBitstreamCursor() { | 257 ~NaClBitstreamCursor() { |
| 266 freeState(); | 258 freeState(); |
| 267 } | 259 } |
| 268 | 260 |
| 269 void freeState(); | 261 void freeState(); |
| 270 | 262 |
| 271 bool isEndPos(size_t pos) { | |
| 272 return BitStream->getBitcodeBytes().isObjectEnd(static_cast<uint64_t>(pos)); | |
| 273 } | |
| 274 | |
| 275 bool canSkipToPos(size_t pos) const { | 263 bool canSkipToPos(size_t pos) const { |
| 276 // pos can be skipped to if it is a valid address or one byte past the end. | 264 // pos can be skipped to if it is a valid address or one byte past the end. |
| 277 return pos == 0 || BitStream->getBitcodeBytes().isValidAddress( | 265 return pos == 0 || BitStream->getBitcodeBytes().isValidAddress( |
| 278 static_cast<uint64_t>(pos - 1)); | 266 static_cast<uint64_t>(pos - 1)); |
| 279 } | 267 } |
| 280 | 268 |
| 281 bool AtEndOfStream() { | 269 bool AtEndOfStream() { |
| 282 return BitsInCurWord == 0 && isEndPos(NextChar); | 270 if (BitsInCurWord != 0) |
| 271 return false; |
| 272 if (Size != 0) |
| 273 return Size == NextChar; |
| 274 fillCurWord(); |
| 275 return BitsInCurWord == 0; |
| 283 } | 276 } |
| 284 | 277 |
| 285 /// getAbbrevIDWidth - Return the number of bits used to encode an abbrev #. | 278 /// Return the number of bits used to encode an abbrev #. |
| 286 unsigned getAbbrevIDWidth() const { return CurCodeSize.NumBits; } | 279 unsigned getAbbrevIDWidth() const { return CurCodeSize.NumBits; } |
| 287 | 280 |
| 288 /// GetCurrentBitNo - Return the bit # of the bit we are reading. | 281 /// Return the bit # of the bit we are reading. |
| 289 uint64_t GetCurrentBitNo() const { | 282 uint64_t GetCurrentBitNo() const { |
| 290 return NextChar*CHAR_BIT - BitsInCurWord; | 283 return NextChar*CHAR_BIT - BitsInCurWord; |
| 291 } | 284 } |
| 292 | 285 |
| 293 NaClBitstreamReader *getBitStreamReader() { | 286 NaClBitstreamReader *getBitStreamReader() { |
| 294 return BitStream; | 287 return BitStream; |
| 295 } | 288 } |
| 296 const NaClBitstreamReader *getBitStreamReader() const { | 289 const NaClBitstreamReader *getBitStreamReader() const { |
| 297 return BitStream; | 290 return BitStream; |
| 298 } | 291 } |
| 299 | 292 |
| 300 /// Flags that modify the behavior of advance(). | 293 /// Flags that modify the behavior of advance(). |
| 301 enum { | 294 enum { |
| 302 /// AF_DontPopBlockAtEnd - If this flag is used, the advance() method does | 295 /// If this flag is used, the advance() method does not automatically pop |
| 303 /// not automatically pop the block scope when the end of a block is | 296 /// the block scope when the end of a block is reached. |
| 304 /// reached. | |
| 305 AF_DontPopBlockAtEnd = 1, | 297 AF_DontPopBlockAtEnd = 1, |
| 306 | 298 |
| 307 /// AF_DontAutoprocessAbbrevs - If this flag is used, abbrev entries are | 299 /// If this flag is used, abbrev entries are returned just like normal |
| 308 /// returned just like normal records. | 300 /// records. |
| 309 AF_DontAutoprocessAbbrevs = 2 | 301 AF_DontAutoprocessAbbrevs = 2 |
| 310 }; | 302 }; |
| 311 | 303 |
| 312 /// advance - Advance the current bitstream, returning the next entry in the | 304 /// Advance the current bitstream, returning the next entry in the stream. |
| 313 /// stream. Use the given abbreviation listener (if provided). | 305 /// Use the given abbreviation listener (if provided). |
| 314 NaClBitstreamEntry advance(unsigned Flags, NaClAbbrevListener *Listener) { | 306 NaClBitstreamEntry advance(unsigned Flags, NaClAbbrevListener *Listener) { |
| 315 while (1) { | 307 while (1) { |
| 316 unsigned Code = ReadCode(); | 308 unsigned Code = ReadCode(); |
| 317 if (Code == naclbitc::END_BLOCK) { | 309 if (Code == naclbitc::END_BLOCK) { |
| 318 // Pop the end of the block unless Flags tells us not to. | 310 // Pop the end of the block unless Flags tells us not to. |
| 319 if (!(Flags & AF_DontPopBlockAtEnd) && ReadBlockEnd()) | 311 if (!(Flags & AF_DontPopBlockAtEnd) && ReadBlockEnd()) |
| 320 return NaClBitstreamEntry::getError(); | 312 return NaClBitstreamEntry::getError(); |
| 321 return NaClBitstreamEntry::getEndBlock(); | 313 return NaClBitstreamEntry::getEndBlock(); |
| 322 } | 314 } |
| 323 | 315 |
| 324 if (Code == naclbitc::ENTER_SUBBLOCK) | 316 if (Code == naclbitc::ENTER_SUBBLOCK) |
| 325 return NaClBitstreamEntry::getSubBlock(ReadSubBlockID()); | 317 return NaClBitstreamEntry::getSubBlock(ReadSubBlockID()); |
| 326 | 318 |
| 327 if (Code == naclbitc::DEFINE_ABBREV && | 319 if (Code == naclbitc::DEFINE_ABBREV && |
| 328 !(Flags & AF_DontAutoprocessAbbrevs)) { | 320 !(Flags & AF_DontAutoprocessAbbrevs)) { |
| 329 // We read and accumulate abbrev's, the client can't do anything with | 321 // We read and accumulate abbrev's, the client can't do anything with |
| 330 // them anyway. | 322 // them anyway. |
| 331 ReadAbbrevRecord(true, Listener); | 323 ReadAbbrevRecord(true, Listener); |
| 332 continue; | 324 continue; |
| 333 } | 325 } |
| 334 | 326 |
| 335 return NaClBitstreamEntry::getRecord(Code); | 327 return NaClBitstreamEntry::getRecord(Code); |
| 336 } | 328 } |
| 337 } | 329 } |
| 338 | 330 |
| 339 /// advanceSkippingSubblocks - This is a convenience function for clients that | 331 /// This is a convenience function for clients that don't expect any |
| 340 /// don't expect any subblocks. This just skips over them automatically. | 332 /// subblocks. This just skips over them automatically. |
| 341 NaClBitstreamEntry advanceSkippingSubblocks(unsigned Flags = 0) { | 333 NaClBitstreamEntry advanceSkippingSubblocks(unsigned Flags = 0) { |
| 342 while (1) { | 334 while (1) { |
| 343 // If we found a normal entry, return it. | 335 // If we found a normal entry, return it. |
| 344 NaClBitstreamEntry Entry = advance(Flags, 0); | 336 NaClBitstreamEntry Entry = advance(Flags, 0); |
| 345 if (Entry.Kind != NaClBitstreamEntry::SubBlock) | 337 if (Entry.Kind != NaClBitstreamEntry::SubBlock) |
| 346 return Entry; | 338 return Entry; |
| 347 | 339 |
| 348 // If we found a sub-block, just skip over it and check the next entry. | 340 // If we found a sub-block, just skip over it and check the next entry. |
| 349 if (SkipBlock()) | 341 if (SkipBlock()) |
| 350 return NaClBitstreamEntry::getError(); | 342 return NaClBitstreamEntry::getError(); |
| 351 } | 343 } |
| 352 } | 344 } |
| 353 | 345 |
| 354 /// JumpToBit - Reset the stream to the specified bit number. | 346 /// Reset the stream to the specified bit number. |
| 355 void JumpToBit(uint64_t BitNo) { | 347 void JumpToBit(uint64_t BitNo) { |
| 356 uintptr_t ByteNo = uintptr_t(BitNo/8) & ~(sizeof(word_t)-1); | 348 uintptr_t ByteNo = uintptr_t(BitNo/8) & ~(sizeof(word_t)-1); |
| 357 unsigned WordBitNo = unsigned(BitNo & (sizeof(word_t)*8-1)); | 349 unsigned WordBitNo = unsigned(BitNo & (sizeof(word_t)*8-1)); |
| 358 assert(canSkipToPos(ByteNo) && "Invalid location"); | 350 assert(canSkipToPos(ByteNo) && "Invalid location"); |
| 359 | 351 |
| 360 // Move the cursor to the right word. | 352 // Move the cursor to the right word. |
| 361 NextChar = ByteNo; | 353 NextChar = ByteNo; |
| 362 BitsInCurWord = 0; | 354 BitsInCurWord = 0; |
| 363 CurWord = 0; | |
| 364 | 355 |
| 365 // Skip over any bits that are already consumed. | 356 // Skip over any bits that are already consumed. |
| 366 if (WordBitNo) { | 357 if (WordBitNo) |
| 367 if (sizeof(word_t) > 4) | 358 Read(WordBitNo); |
| 368 Read64(WordBitNo); | |
| 369 else | |
| 370 Read(WordBitNo); | |
| 371 } | |
| 372 } | 359 } |
| 373 | 360 |
| 374 uint32_t Read(unsigned NumBits) { | 361 void fillCurWord() { |
| 375 assert(NumBits && NumBits <= 32 && | 362 assert(Size == 0 || NextChar < (unsigned)Size); |
| 376 "Cannot return zero or more than 32 bits!"); | 363 |
| 377 | 364 // Read the next word from the stream. |
| 365 uint8_t Array[sizeof(word_t)] = {0}; |
| 366 |
| 367 uint64_t BytesRead = |
| 368 BitStream->getBitcodeBytes().readBytes(Array, sizeof(Array), NextChar); |
| 369 |
| 370 // If we run out of data, stop at the end of the stream. |
| 371 if (BytesRead == 0) { |
| 372 Size = NextChar; |
| 373 return; |
| 374 } |
| 375 |
| 376 CurWord = |
| 377 support::endian::read<word_t, support::little, support::unaligned>( |
| 378 Array); |
| 379 NextChar += BytesRead; |
| 380 BitsInCurWord = BytesRead * 8; |
| 381 } |
| 382 |
| 383 word_t Read(unsigned NumBits) { |
| 384 static const unsigned BitsInWord = sizeof(word_t) * 8; |
| 385 |
| 386 assert(NumBits && NumBits <= BitsInWord && |
| 387 "Cannot return zero or more than BitsInWord bits!"); |
| 388 |
| 389 static const unsigned Mask = sizeof(word_t) > 4 ? 0x3f : 0x1f; |
| 390 |
| 378 // If the field is fully contained by CurWord, return it quickly. | 391 // If the field is fully contained by CurWord, return it quickly. |
| 379 if (BitsInCurWord >= NumBits) { | 392 if (BitsInCurWord >= NumBits) { |
| 380 uint32_t R = uint32_t(CurWord) & (~0U >> (32-NumBits)); | 393 word_t R = CurWord & (~word_t(0) >> (BitsInWord - NumBits)); |
| 381 CurWord >>= NumBits; | 394 |
| 395 // Use a mask to avoid undefined behavior. |
| 396 CurWord >>= (NumBits & Mask); |
| 397 |
| 382 BitsInCurWord -= NumBits; | 398 BitsInCurWord -= NumBits; |
| 383 return R; | 399 return R; |
| 384 } | 400 } |
| 385 | 401 |
| 402 word_t R = BitsInCurWord ? CurWord : 0; |
| 403 unsigned BitsLeft = NumBits - BitsInCurWord; |
| 404 |
| 405 fillCurWord(); |
| 406 |
| 386 // If we run out of data, stop at the end of the stream. | 407 // If we run out of data, stop at the end of the stream. |
| 387 if (isEndPos(NextChar)) { | 408 if (BitsLeft > BitsInCurWord) |
| 388 CurWord = 0; | |
| 389 BitsInCurWord = 0; | |
| 390 return 0; | 409 return 0; |
| 391 } | |
| 392 | 410 |
| 393 uint32_t R = uint32_t(CurWord); | 411 word_t R2 = CurWord & (~word_t(0) >> (BitsInWord - BitsLeft)); |
| 394 | 412 |
| 395 // Read the next word from the stream. | 413 // Use a mask to avoid undefined behavior. |
| 396 uint8_t Array[sizeof(word_t)] = {0}; | 414 CurWord >>= (BitsLeft & Mask); |
| 397 | |
| 398 BitStream->getBitcodeBytes().readBytes(NextChar, sizeof(Array), Array); | |
| 399 | |
| 400 // Handle big-endian byte-swapping if necessary. | |
| 401 support::detail::packed_endian_specific_integral | |
| 402 <word_t, support::little, support::unaligned> EndianValue; | |
| 403 memcpy(&EndianValue, Array, sizeof(Array)); | |
| 404 | |
| 405 CurWord = EndianValue; | |
| 406 | 415 |
| 407 NextChar += sizeof(word_t); | 416 BitsInCurWord -= BitsLeft; |
| 408 | 417 |
| 409 // Extract NumBits-BitsInCurWord from what we just read. | 418 R |= R2 << (NumBits - BitsLeft); |
| 410 unsigned BitsLeft = NumBits-BitsInCurWord; | |
| 411 | 419 |
| 412 // Be careful here, BitsLeft is in the range [1..32]/[1..64] inclusive. | |
| 413 R |= uint32_t((CurWord & (word_t(~0ULL) >> (sizeof(word_t)*8-BitsLeft))) | |
| 414 << BitsInCurWord); | |
| 415 | |
| 416 // BitsLeft bits have just been used up from CurWord. BitsLeft is in the | |
| 417 // range [1..32]/[1..64] so be careful how we shift. | |
| 418 if (BitsLeft != sizeof(word_t)*8) | |
| 419 CurWord >>= BitsLeft; | |
| 420 else | |
| 421 CurWord = 0; | |
| 422 BitsInCurWord = sizeof(word_t)*8-BitsLeft; | |
| 423 return R; | 420 return R; |
| 424 } | 421 } |
| 425 | 422 |
| 426 uint64_t Read64(unsigned NumBits) { | |
| 427 if (NumBits <= 32) return Read(NumBits); | |
| 428 | |
| 429 uint64_t V = Read(32); | |
| 430 return V | (uint64_t)Read(NumBits-32) << 32; | |
| 431 } | |
| 432 | |
| 433 uint32_t ReadVBR(unsigned NumBits) { | 423 uint32_t ReadVBR(unsigned NumBits) { |
| 434 uint32_t Piece = Read(NumBits); | 424 uint32_t Piece = Read(NumBits); |
| 435 if ((Piece & (1U << (NumBits-1))) == 0) | 425 if ((Piece & (1U << (NumBits-1))) == 0) |
| 436 return Piece; | 426 return Piece; |
| 437 | 427 |
| 438 uint32_t Result = 0; | 428 uint32_t Result = 0; |
| 439 unsigned NextBit = 0; | 429 unsigned NextBit = 0; |
| 440 while (1) { | 430 while (1) { |
| 441 Result |= (Piece & ((1U << (NumBits-1))-1)) << NextBit; | 431 Result |= (Piece & ((1U << (NumBits-1))-1)) << NextBit; |
| 442 | 432 |
| 443 if ((Piece & (1U << (NumBits-1))) == 0) | 433 if ((Piece & (1U << (NumBits-1))) == 0) |
| 444 return Result; | 434 return Result; |
| 445 | 435 |
| 446 NextBit += NumBits-1; | 436 NextBit += NumBits-1; |
| 447 Piece = Read(NumBits); | 437 Piece = Read(NumBits); |
| 448 } | 438 } |
| 449 } | 439 } |
| 450 | 440 |
| 451 // ReadVBR64 - Read a VBR that may have a value up to 64-bits in size. The | 441 // Read a VBR that may have a value up to 64-bits in size. The chunk size of |
| 452 // chunk size of the VBR must still be <= 32 bits though. | 442 // the VBR must still be <= 32 bits though. |
| 453 uint64_t ReadVBR64(unsigned NumBits) { | 443 uint64_t ReadVBR64(unsigned NumBits) { |
| 454 uint32_t Piece = Read(NumBits); | 444 uint32_t Piece = Read(NumBits); |
| 455 if ((Piece & (1U << (NumBits-1))) == 0) | 445 if ((Piece & (1U << (NumBits-1))) == 0) |
| 456 return uint64_t(Piece); | 446 return uint64_t(Piece); |
| 457 | 447 |
| 458 uint64_t Result = 0; | 448 uint64_t Result = 0; |
| 459 unsigned NextBit = 0; | 449 unsigned NextBit = 0; |
| 460 while (1) { | 450 while (1) { |
| 461 Result |= uint64_t(Piece & ((1U << (NumBits-1))-1)) << NextBit; | 451 Result |= uint64_t(Piece & ((1U << (NumBits-1))-1)) << NextBit; |
| 462 | 452 |
| 463 if ((Piece & (1U << (NumBits-1))) == 0) | 453 if ((Piece & (1U << (NumBits-1))) == 0) |
| 464 return Result; | 454 return Result; |
| 465 | 455 |
| 466 NextBit += NumBits-1; | 456 NextBit += NumBits-1; |
| 467 Piece = Read(NumBits); | 457 Piece = Read(NumBits); |
| 468 } | 458 } |
| 469 } | 459 } |
| 470 | 460 |
| 471 private: | 461 private: |
| 472 void SkipToFourByteBoundary() { | 462 void SkipToFourByteBoundary() { |
| 473 // If word_t is 64-bits and if we've read less than 32 bits, just dump | 463 // If word_t is 64-bits and if we've read less than 32 bits, just dump |
| 474 // the bits we have up to the next 32-bit boundary. | 464 // the bits we have up to the next 32-bit boundary. |
| 475 if (sizeof(word_t) > 4 && | 465 if (sizeof(word_t) > 4 && |
| 476 BitsInCurWord >= 32) { | 466 BitsInCurWord >= 32) { |
| 477 CurWord >>= BitsInCurWord-32; | 467 CurWord >>= BitsInCurWord-32; |
| 478 BitsInCurWord = 32; | 468 BitsInCurWord = 32; |
| 479 return; | 469 return; |
| 480 } | 470 } |
| 481 | 471 |
| 482 BitsInCurWord = 0; | 472 BitsInCurWord = 0; |
| 483 CurWord = 0; | |
| 484 } | 473 } |
| 485 public: | 474 public: |
| 486 | 475 |
| 487 unsigned ReadCode() { | 476 unsigned ReadCode() { |
| 488 return CurCodeSize.IsFixed | 477 return CurCodeSize.IsFixed |
| 489 ? Read(CurCodeSize.NumBits) | 478 ? Read(CurCodeSize.NumBits) |
| 490 : ReadVBR(CurCodeSize.NumBits); | 479 : ReadVBR(CurCodeSize.NumBits); |
| 491 } | 480 } |
| 492 | 481 |
| 493 // Block header: | 482 // Block header: |
| 494 // [ENTER_SUBBLOCK, blockid, newcodelen, <align4bytes>, blocklen] | 483 // [ENTER_SUBBLOCK, blockid, newcodelen, <align4bytes>, blocklen] |
| 495 | 484 |
| 496 /// ReadSubBlockID - Having read the ENTER_SUBBLOCK code, read the BlockID for | 485 /// Having read the ENTER_SUBBLOCK code, read the BlockID for the block. |
| 497 /// the block. | |
| 498 unsigned ReadSubBlockID() { | 486 unsigned ReadSubBlockID() { |
| 499 return ReadVBR(naclbitc::BlockIDWidth); | 487 return ReadVBR(naclbitc::BlockIDWidth); |
| 500 } | 488 } |
| 501 | 489 |
| 502 /// SkipBlock - Having read the ENTER_SUBBLOCK abbrevid and a BlockID, skip | 490 /// Having read the ENTER_SUBBLOCK abbrevid and a BlockID, skip over the body |
| 503 /// over the body of this block. If the block record is malformed, return | 491 /// of this block. If the block record is malformed, return true. |
| 504 /// true. | |
| 505 bool SkipBlock() { | 492 bool SkipBlock() { |
| 506 // Read and ignore the codelen value. Since we are skipping this block, we | 493 // Read and ignore the codelen value. Since we are skipping this block, we |
| 507 // don't care what code widths are used inside of it. | 494 // don't care what code widths are used inside of it. |
| 508 ReadVBR(naclbitc::CodeLenWidth); | 495 ReadVBR(naclbitc::CodeLenWidth); |
| 509 SkipToFourByteBoundary(); | 496 SkipToFourByteBoundary(); |
| 510 unsigned NumFourBytes = Read(naclbitc::BlockSizeWidth); | 497 unsigned NumFourBytes = Read(naclbitc::BlockSizeWidth); |
| 511 | 498 |
| 512 // Check that the block wasn't partially defined, and that the offset isn't | 499 // Check that the block wasn't partially defined, and that the offset isn't |
| 513 // bogus. | 500 // bogus. |
| 514 size_t SkipTo = GetCurrentBitNo() + NumFourBytes*4*8; | 501 size_t SkipTo = GetCurrentBitNo() + NumFourBytes*4*8; |
| 515 if (AtEndOfStream() || !canSkipToPos(SkipTo/8)) | 502 if (AtEndOfStream() || !canSkipToPos(SkipTo/8)) |
| 516 return true; | 503 return true; |
| 517 | 504 |
| 518 JumpToBit(SkipTo); | 505 JumpToBit(SkipTo); |
| 519 return false; | 506 return false; |
| 520 } | 507 } |
| 521 | 508 |
| 522 /// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter | 509 /// Having read the ENTER_SUBBLOCK abbrevid, enter the block, and return true |
| 523 /// the block, and return true if the block has an error. | 510 /// if the block has an error. |
| 524 bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = 0); | 511 bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = nullptr); |
| 525 | 512 |
| 526 bool ReadBlockEnd() { | 513 bool ReadBlockEnd() { |
| 527 if (BlockScope.empty()) return true; | 514 if (BlockScope.empty()) return true; |
| 528 | 515 |
| 529 // Block tail: | 516 // Block tail: |
| 530 // [END_BLOCK, <align4bytes>] | 517 // [END_BLOCK, <align4bytes>] |
| 531 SkipToFourByteBoundary(); | 518 SkipToFourByteBoundary(); |
| 532 | 519 |
| 533 popBlockScope(); | 520 popBlockScope(); |
| 534 return false; | 521 return false; |
| 535 } | 522 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 566 inline uint64_t readArrayAbbreviatedField(const NaClBitCodeAbbrevOp &Op); | 553 inline uint64_t readArrayAbbreviatedField(const NaClBitCodeAbbrevOp &Op); |
| 567 | 554 |
| 568 // Reads the array abbreviation Op, NumArrayElements times, putting | 555 // Reads the array abbreviation Op, NumArrayElements times, putting |
| 569 // the read values in Vals. | 556 // the read values in Vals. |
| 570 inline void readArrayAbbrev(const NaClBitCodeAbbrevOp &Op, | 557 inline void readArrayAbbrev(const NaClBitCodeAbbrevOp &Op, |
| 571 unsigned NumArrayElements, | 558 unsigned NumArrayElements, |
| 572 SmallVectorImpl<uint64_t> &Vals); | 559 SmallVectorImpl<uint64_t> &Vals); |
| 573 | 560 |
| 574 public: | 561 public: |
| 575 | 562 |
| 576 /// getAbbrev - Return the abbreviation for the specified AbbrevId. | 563 /// Return the abbreviation for the specified AbbrevId. |
| 577 const NaClBitCodeAbbrev *getAbbrev(unsigned AbbrevID) const { | 564 const NaClBitCodeAbbrev *getAbbrev(unsigned AbbrevID) const { |
| 578 unsigned AbbrevNo = AbbrevID-naclbitc::FIRST_APPLICATION_ABBREV; | 565 unsigned AbbrevNo = AbbrevID-naclbitc::FIRST_APPLICATION_ABBREV; |
| 579 assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!"); | 566 assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!"); |
| 580 return CurAbbrevs[AbbrevNo]; | 567 return CurAbbrevs[AbbrevNo]; |
| 581 } | 568 } |
| 582 | 569 |
| 583 /// skipRecord - Read the current record and discard it. | 570 /// Read the current record and discard it. |
| 584 void skipRecord(unsigned AbbrevID); | 571 void skipRecord(unsigned AbbrevID); |
| 585 | 572 |
| 586 unsigned readRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals); | 573 unsigned readRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals); |
| 587 | 574 |
| 588 //===--------------------------------------------------------------------===// | 575 //===--------------------------------------------------------------------===// |
| 589 // Abbrev Processing | 576 // Abbrev Processing |
| 590 //===--------------------------------------------------------------------===// | 577 //===--------------------------------------------------------------------===// |
| 591 // IsLocal indicates where the abbreviation occurs. If it is in the | 578 // IsLocal indicates where the abbreviation occurs. If it is in the |
| 592 // BlockInfo block, IsLocal is false. In all other cases, IsLocal is | 579 // BlockInfo block, IsLocal is false. In all other cases, IsLocal is |
| 593 // true. | 580 // true. |
| 594 void ReadAbbrevRecord(bool IsLocal, | 581 void ReadAbbrevRecord(bool IsLocal, |
| 595 NaClAbbrevListener *Listener); | 582 NaClAbbrevListener *Listener); |
| 596 | 583 |
| 597 // Skips over an abbreviation record. Duplicates code of ReadAbbrevRecord, | 584 // Skips over an abbreviation record. Duplicates code of ReadAbbrevRecord, |
| 598 // except that no abbreviation is built. | 585 // except that no abbreviation is built. |
| 599 void SkipAbbrevRecord(); | 586 void SkipAbbrevRecord(); |
| 600 | 587 |
| 601 bool ReadBlockInfoBlock(NaClAbbrevListener *Listener); | 588 bool ReadBlockInfoBlock(NaClAbbrevListener *Listener); |
| 602 }; | 589 }; |
| 603 | 590 |
| 604 } // End llvm namespace | 591 } // End llvm namespace |
| 605 | 592 |
| 606 #endif | 593 #endif |
| OLD | NEW |