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 |