Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- BitstreamReader.h - Low-level bitstream reader interface -*- C++ -*-===// | 1 //===- NaClBitstreamReader.h -----------------------------------*- C++ -*-===// |
| 2 // Low-level bitstream reader interface | |
| 2 // | 3 // |
| 3 // The LLVM Compiler Infrastructure | 4 // The LLVM Compiler Infrastructure |
| 4 // | 5 // |
| 5 // This file is distributed under the University of Illinois Open Source | 6 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 7 // License. See LICENSE.TXT for details. |
| 7 // | 8 // |
| 8 //===----------------------------------------------------------------------===// | 9 //===----------------------------------------------------------------------===// |
| 9 // | 10 // |
| 10 // 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 |
| 11 // read an arbitrary bitstream, regardless of its contents. | 12 // read an arbitrary bitstream, regardless of its contents. |
| 12 // | 13 // |
| 13 //===----------------------------------------------------------------------===// | 14 //===----------------------------------------------------------------------===// |
| 14 | 15 |
| 15 #ifndef LLVM_BITCODE_BITSTREAMREADER_H | 16 #ifndef LLVM_BITCODE_NACL_NACLBITSTREAMREADER_H |
| 16 #define LLVM_BITCODE_BITSTREAMREADER_H | 17 #define LLVM_BITCODE_NACL_NACLBITSTREAMREADER_H |
| 17 | 18 |
| 18 #include "llvm/ADT/OwningPtr.h" | 19 #include "llvm/ADT/OwningPtr.h" |
| 19 #include "llvm/Bitcode/BitCodes.h" | 20 #include "llvm/Bitcode/BitCodes.h" |
| 20 #include "llvm/Support/Endian.h" | 21 #include "llvm/Support/Endian.h" |
| 21 #include "llvm/Support/StreamableMemoryObject.h" | 22 #include "llvm/Support/StreamableMemoryObject.h" |
| 22 #include <climits> | 23 #include <climits> |
| 23 #include <string> | 24 #include <string> |
| 24 #include <vector> | 25 #include <vector> |
| 25 | 26 |
| 26 namespace llvm { | 27 namespace llvm { |
| 27 | 28 |
| 28 class Deserializer; | 29 class Deserializer; |
| 29 | 30 |
| 30 /// BitstreamReader - This class is used to read from an LLVM bitcode stream, | 31 /// NaClBitstreamReader - This class is used to read from an LLVM bitcode stream , |
| 31 /// maintaining information that is global to decoding the entire file. While | 32 /// maintaining information that is global to decoding the entire file. While |
| 32 /// a file is being read, multiple cursors can be independently advanced or | 33 /// a file is being read, multiple cursors can be independently advanced or |
| 33 /// skipped around within the file. These are represented by the | 34 /// skipped around within the file. These are represented by the |
| 34 /// BitstreamCursor class. | 35 /// NaClBitstreamCursor class. |
| 35 class BitstreamReader { | 36 class NaClBitstreamReader { |
| 36 public: | 37 public: |
| 37 /// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks. | 38 /// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks. |
| 38 /// These describe abbreviations that all blocks of the specified ID inherit. | 39 /// These describe abbreviations that all blocks of the specified ID inherit. |
| 39 struct BlockInfo { | 40 struct BlockInfo { |
| 40 unsigned BlockID; | 41 unsigned BlockID; |
| 41 std::vector<BitCodeAbbrev*> Abbrevs; | 42 std::vector<BitCodeAbbrev*> Abbrevs; |
| 42 std::string Name; | 43 std::string Name; |
| 43 | 44 |
| 44 std::vector<std::pair<unsigned, std::string> > RecordNames; | 45 std::vector<std::pair<unsigned, std::string> > RecordNames; |
| 45 }; | 46 }; |
| 46 private: | 47 private: |
| 47 OwningPtr<StreamableMemoryObject> BitcodeBytes; | 48 OwningPtr<StreamableMemoryObject> BitcodeBytes; |
| 48 | 49 |
| 49 std::vector<BlockInfo> BlockInfoRecords; | 50 std::vector<BlockInfo> BlockInfoRecords; |
| 50 | 51 |
| 51 /// IgnoreBlockInfoNames - This is set to true if we don't care about the | 52 /// IgnoreBlockInfoNames - This is set to true if we don't care about the |
| 52 /// block/record name information in the BlockInfo block. Only llvm-bcanalyzer | 53 /// block/record name information in the BlockInfo block. Only llvm-bcanalyzer |
| 53 /// uses this. | 54 /// uses this. |
| 54 bool IgnoreBlockInfoNames; | 55 bool IgnoreBlockInfoNames; |
| 55 | 56 |
| 56 BitstreamReader(const BitstreamReader&) LLVM_DELETED_FUNCTION; | 57 NaClBitstreamReader(const NaClBitstreamReader&) LLVM_DELETED_FUNCTION; |
| 57 void operator=(const BitstreamReader&) LLVM_DELETED_FUNCTION; | 58 void operator=(const NaClBitstreamReader&) LLVM_DELETED_FUNCTION; |
| 58 public: | 59 public: |
| 59 BitstreamReader() : IgnoreBlockInfoNames(true) { | 60 NaClBitstreamReader() : IgnoreBlockInfoNames(true) { |
| 60 } | 61 } |
| 61 | 62 |
| 62 BitstreamReader(const unsigned char *Start, const unsigned char *End) { | 63 NaClBitstreamReader(const unsigned char *Start, const unsigned char *End) { |
| 63 IgnoreBlockInfoNames = true; | 64 IgnoreBlockInfoNames = true; |
| 64 init(Start, End); | 65 init(Start, End); |
| 65 } | 66 } |
| 66 | 67 |
| 67 BitstreamReader(StreamableMemoryObject *bytes) { | 68 NaClBitstreamReader(StreamableMemoryObject *bytes) { |
| 68 BitcodeBytes.reset(bytes); | 69 BitcodeBytes.reset(bytes); |
| 69 } | 70 } |
| 70 | 71 |
| 71 void init(const unsigned char *Start, const unsigned char *End) { | 72 void init(const unsigned char *Start, const unsigned char *End) { |
| 72 assert(((End-Start) & 3) == 0 &&"Bitcode stream not a multiple of 4 bytes"); | 73 assert(((End-Start) & 3) == 0 &&"Bitcode stream not a multiple of 4 bytes"); |
| 73 BitcodeBytes.reset(getNonStreamedMemoryObject(Start, End)); | 74 BitcodeBytes.reset(getNonStreamedMemoryObject(Start, End)); |
| 74 } | 75 } |
| 75 | 76 |
| 76 StreamableMemoryObject &getBitcodeBytes() { return *BitcodeBytes; } | 77 StreamableMemoryObject &getBitcodeBytes() { return *BitcodeBytes; } |
| 77 | 78 |
| 78 ~BitstreamReader() { | 79 ~NaClBitstreamReader() { |
| 79 // Free the BlockInfoRecords. | 80 // Free the BlockInfoRecords. |
| 80 while (!BlockInfoRecords.empty()) { | 81 while (!BlockInfoRecords.empty()) { |
| 81 BlockInfo &Info = BlockInfoRecords.back(); | 82 BlockInfo &Info = BlockInfoRecords.back(); |
| 82 // Free blockinfo abbrev info. | 83 // Free blockinfo abbrev info. |
| 83 for (unsigned i = 0, e = static_cast<unsigned>(Info.Abbrevs.size()); | 84 for (unsigned i = 0, e = static_cast<unsigned>(Info.Abbrevs.size()); |
| 84 i != e; ++i) | 85 i != e; ++i) |
| 85 Info.Abbrevs[i]->dropRef(); | 86 Info.Abbrevs[i]->dropRef(); |
| 86 BlockInfoRecords.pop_back(); | 87 BlockInfoRecords.pop_back(); |
| 87 } | 88 } |
| 88 } | 89 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 120 return *const_cast<BlockInfo*>(BI); | 121 return *const_cast<BlockInfo*>(BI); |
| 121 | 122 |
| 122 // Otherwise, add a new record. | 123 // Otherwise, add a new record. |
| 123 BlockInfoRecords.push_back(BlockInfo()); | 124 BlockInfoRecords.push_back(BlockInfo()); |
| 124 BlockInfoRecords.back().BlockID = BlockID; | 125 BlockInfoRecords.back().BlockID = BlockID; |
| 125 return BlockInfoRecords.back(); | 126 return BlockInfoRecords.back(); |
| 126 } | 127 } |
| 127 }; | 128 }; |
| 128 | 129 |
| 129 | 130 |
| 130 /// BitstreamEntry - When advancing through a bitstream cursor, each advance can | 131 /// BitstreamEntry - When advancing through a bitstream cursor, each advance can |
|
jvoung (off chromium)
2013/04/29 18:02:08
Should this top-level struct be made NaClBitstream
Karl
2013/04/29 20:44:37
Good point. Renaming.
| |
| 131 /// discover a few different kinds of entries: | 132 /// discover a few different kinds of entries: |
| 132 /// Error - Malformed bitcode was found. | 133 /// Error - Malformed bitcode was found. |
| 133 /// EndBlock - We've reached the end of the current block, (or the end of the | 134 /// EndBlock - We've reached the end of the current block, (or the end of the |
| 134 /// file, which is treated like a series of EndBlock records. | 135 /// file, which is treated like a series of EndBlock records. |
| 135 /// SubBlock - This is the start of a new subblock of a specific ID. | 136 /// SubBlock - This is the start of a new subblock of a specific ID. |
| 136 /// Record - This is a record with a specific AbbrevID. | 137 /// Record - This is a record with a specific AbbrevID. |
| 137 /// | 138 /// |
| 138 struct BitstreamEntry { | 139 struct BitstreamEntry { |
| 139 enum { | 140 enum { |
| 140 Error, | 141 Error, |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 152 BitstreamEntry E; E.Kind = EndBlock; return E; | 153 BitstreamEntry E; E.Kind = EndBlock; return E; |
| 153 } | 154 } |
| 154 static BitstreamEntry getSubBlock(unsigned ID) { | 155 static BitstreamEntry getSubBlock(unsigned ID) { |
| 155 BitstreamEntry E; E.Kind = SubBlock; E.ID = ID; return E; | 156 BitstreamEntry E; E.Kind = SubBlock; E.ID = ID; return E; |
| 156 } | 157 } |
| 157 static BitstreamEntry getRecord(unsigned AbbrevID) { | 158 static BitstreamEntry getRecord(unsigned AbbrevID) { |
| 158 BitstreamEntry E; E.Kind = Record; E.ID = AbbrevID; return E; | 159 BitstreamEntry E; E.Kind = Record; E.ID = AbbrevID; return E; |
| 159 } | 160 } |
| 160 }; | 161 }; |
| 161 | 162 |
| 162 /// BitstreamCursor - This represents a position within a bitcode file. There | 163 /// NaClBitstreamCursor - This represents a position within a bitcode |
| 163 /// may be multiple independent cursors reading within one bitstream, each | 164 /// file. There may be multiple independent cursors reading within |
| 164 /// maintaining their own local state. | 165 /// one bitstream, each maintaining their own local state. |
| 165 /// | 166 /// |
| 166 /// Unlike iterators, BitstreamCursors are heavy-weight objects that should not | 167 /// Unlike iterators, NaClBitstreamCursors are heavy-weight objects |
| 167 /// be passed by value. | 168 /// that should not be passed by value. |
| 168 class BitstreamCursor { | 169 class NaClBitstreamCursor { |
| 169 friend class Deserializer; | 170 friend class Deserializer; |
| 170 BitstreamReader *BitStream; | 171 NaClBitstreamReader *BitStream; |
| 171 size_t NextChar; | 172 size_t NextChar; |
| 172 | 173 |
| 173 | 174 |
| 174 /// CurWord/word_t - This is the current data we have pulled from the stream | 175 /// CurWord/word_t - This is the current data we have pulled from the stream |
| 175 /// but have not returned to the client. This is specifically and | 176 /// but have not returned to the client. This is specifically and |
| 176 /// intentionally defined to follow the word size of the host machine for | 177 /// intentionally defined to follow the word size of the host machine for |
| 177 /// efficiency. We use word_t in places that are aware of this to make it | 178 /// efficiency. We use word_t in places that are aware of this to make it |
| 178 /// perfectly explicit what is going on. | 179 /// perfectly explicit what is going on. |
| 179 typedef uint32_t word_t; | 180 typedef uint32_t word_t; |
| 180 word_t CurWord; | 181 word_t CurWord; |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 194 unsigned PrevCodeSize; | 195 unsigned PrevCodeSize; |
| 195 std::vector<BitCodeAbbrev*> PrevAbbrevs; | 196 std::vector<BitCodeAbbrev*> PrevAbbrevs; |
| 196 explicit Block(unsigned PCS) : PrevCodeSize(PCS) {} | 197 explicit Block(unsigned PCS) : PrevCodeSize(PCS) {} |
| 197 }; | 198 }; |
| 198 | 199 |
| 199 /// BlockScope - This tracks the codesize of parent blocks. | 200 /// BlockScope - This tracks the codesize of parent blocks. |
| 200 SmallVector<Block, 8> BlockScope; | 201 SmallVector<Block, 8> BlockScope; |
| 201 | 202 |
| 202 | 203 |
| 203 public: | 204 public: |
| 204 BitstreamCursor() : BitStream(0), NextChar(0) { | 205 NaClBitstreamCursor() : BitStream(0), NextChar(0) { |
| 205 } | 206 } |
| 206 BitstreamCursor(const BitstreamCursor &RHS) : BitStream(0), NextChar(0) { | 207 NaClBitstreamCursor(const NaClBitstreamCursor &RHS) |
| 208 : BitStream(0), NextChar(0) { | |
| 207 operator=(RHS); | 209 operator=(RHS); |
| 208 } | 210 } |
| 209 | 211 |
| 210 explicit BitstreamCursor(BitstreamReader &R) : BitStream(&R) { | 212 explicit NaClBitstreamCursor(NaClBitstreamReader &R) : BitStream(&R) { |
| 211 NextChar = 0; | 213 NextChar = 0; |
| 212 CurWord = 0; | 214 CurWord = 0; |
| 213 BitsInCurWord = 0; | 215 BitsInCurWord = 0; |
| 214 CurCodeSize = 2; | 216 CurCodeSize = 2; |
| 215 } | 217 } |
| 216 | 218 |
| 217 void init(BitstreamReader &R) { | 219 void init(NaClBitstreamReader &R) { |
| 218 freeState(); | 220 freeState(); |
| 219 | 221 |
| 220 BitStream = &R; | 222 BitStream = &R; |
| 221 NextChar = 0; | 223 NextChar = 0; |
| 222 CurWord = 0; | 224 CurWord = 0; |
| 223 BitsInCurWord = 0; | 225 BitsInCurWord = 0; |
| 224 CurCodeSize = 2; | 226 CurCodeSize = 2; |
| 225 } | 227 } |
| 226 | 228 |
| 227 ~BitstreamCursor() { | 229 ~NaClBitstreamCursor() { |
| 228 freeState(); | 230 freeState(); |
| 229 } | 231 } |
| 230 | 232 |
| 231 void operator=(const BitstreamCursor &RHS); | 233 void operator=(const NaClBitstreamCursor &RHS); |
| 232 | 234 |
| 233 void freeState(); | 235 void freeState(); |
| 234 | 236 |
| 235 bool isEndPos(size_t pos) { | 237 bool isEndPos(size_t pos) { |
| 236 return BitStream->getBitcodeBytes().isObjectEnd(static_cast<uint64_t>(pos)); | 238 return BitStream->getBitcodeBytes().isObjectEnd(static_cast<uint64_t>(pos)); |
| 237 } | 239 } |
| 238 | 240 |
| 239 bool canSkipToPos(size_t pos) const { | 241 bool canSkipToPos(size_t pos) const { |
| 240 // pos can be skipped to if it is a valid address or one byte past the end. | 242 // pos can be skipped to if it is a valid address or one byte past the end. |
| 241 return pos == 0 || BitStream->getBitcodeBytes().isValidAddress( | 243 return pos == 0 || BitStream->getBitcodeBytes().isValidAddress( |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 253 } | 255 } |
| 254 | 256 |
| 255 /// getAbbrevIDWidth - Return the number of bits used to encode an abbrev #. | 257 /// getAbbrevIDWidth - Return the number of bits used to encode an abbrev #. |
| 256 unsigned getAbbrevIDWidth() const { return CurCodeSize; } | 258 unsigned getAbbrevIDWidth() const { return CurCodeSize; } |
| 257 | 259 |
| 258 /// GetCurrentBitNo - Return the bit # of the bit we are reading. | 260 /// GetCurrentBitNo - Return the bit # of the bit we are reading. |
| 259 uint64_t GetCurrentBitNo() const { | 261 uint64_t GetCurrentBitNo() const { |
| 260 return NextChar*CHAR_BIT - BitsInCurWord; | 262 return NextChar*CHAR_BIT - BitsInCurWord; |
| 261 } | 263 } |
| 262 | 264 |
| 263 BitstreamReader *getBitStreamReader() { | 265 NaClBitstreamReader *getBitStreamReader() { |
| 264 return BitStream; | 266 return BitStream; |
| 265 } | 267 } |
| 266 const BitstreamReader *getBitStreamReader() const { | 268 const NaClBitstreamReader *getBitStreamReader() const { |
| 267 return BitStream; | 269 return BitStream; |
| 268 } | 270 } |
| 269 | 271 |
| 270 /// Flags that modify the behavior of advance(). | 272 /// Flags that modify the behavior of advance(). |
| 271 enum { | 273 enum { |
| 272 /// AF_DontPopBlockAtEnd - If this flag is used, the advance() method does | 274 /// AF_DontPopBlockAtEnd - If this flag is used, the advance() method does |
| 273 /// not automatically pop the block scope when the end of a block is | 275 /// not automatically pop the block scope when the end of a block is |
| 274 /// reached. | 276 /// reached. |
| 275 AF_DontPopBlockAtEnd = 1, | 277 AF_DontPopBlockAtEnd = 1, |
| 276 | 278 |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 549 // Abbrev Processing | 551 // Abbrev Processing |
| 550 //===--------------------------------------------------------------------===// | 552 //===--------------------------------------------------------------------===// |
| 551 void ReadAbbrevRecord(); | 553 void ReadAbbrevRecord(); |
| 552 | 554 |
| 553 bool ReadBlockInfoBlock(); | 555 bool ReadBlockInfoBlock(); |
| 554 }; | 556 }; |
| 555 | 557 |
| 556 } // End llvm namespace | 558 } // End llvm namespace |
| 557 | 559 |
| 558 #endif | 560 #endif |
| OLD | NEW |