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 constexpr size_t DefaultAbbrevListSize = 12; |
Jim Stichnoth
2016/03/14 22:46:49
same comment about constexpr
Karl
2016/03/15 20:29:41
changed to "const".
| |
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 push_back(NewAbbrevs); | |
72 } | |
73 AbbrevList &operator=(const AbbrevList &Rhs) { | |
74 clear(); | |
75 push_back(Rhs); | |
76 return *this; | |
77 } | |
78 void push_back(NaClBitCodeAbbrev *Abbv) { | |
79 Abbrevs.push_back(Abbv); | |
Derek Schuff
2016/03/15 17:47:04
I don't really understand why you have to call add
Karl
2016/03/15 20:29:41
This is part of the confusing usage of reference c
| |
80 } | |
81 void push_back(const AbbrevList &NewAbbrevs) { | |
Derek Schuff
2016/03/15 17:47:04
It seems a little weird that this is also called p
Karl
2016/03/15 20:29:41
Changed to appendList, to better clarify.
| |
82 for (NaClBitCodeAbbrev *Abbrev : NewAbbrevs.Abbrevs) { | |
83 Abbrev->addRef(); | |
84 Abbrevs.push_back(Abbrev); | |
85 } | |
86 } | |
87 // Empties abbreviation list. | |
88 void clear() { | |
89 while(!Abbrevs.empty()) { | |
90 Abbrevs.back()->dropRef(); | |
91 Abbrevs.pop_back(); | |
92 } | |
93 } | |
94 const AbbrevListVector &getVector() const { return Abbrevs; } | |
95 ~AbbrevList() { clear(); } | |
96 private: | |
97 AbbrevListVector Abbrevs; | |
98 // Allow NaClBitstreamCursor to update, so that it can install abbreviations | |
99 // as they are read. | |
100 friend class NaClBitstreamCursor; | |
101 }; | |
102 | |
103 /// This contains information about abbreviations in blocks defined in the | |
104 /// BLOCKINFO_BLOCK block. These describe global abbreviations that apply to | |
105 /// all succeeding blocks of the specified ID. | |
106 class BlockInfo { | |
Derek Schuff
2016/03/15 17:47:04
does a BLOCKINFO_BLOCK have information other than
Karl
2016/03/15 20:29:41
For LLVM, there is more information. for PNaCl bit
| |
107 BlockInfo &operator=(const BlockInfo&) = delete; | |
108 public: | |
109 BlockInfo() = default; | |
110 explicit BlockInfo(unsigned BlockID) | |
111 : BlockID(BlockID), Abbrevs() {} | |
112 BlockInfo(const BlockInfo&) = default; | |
113 unsigned getBlockID() const { return BlockID; } | |
114 void setBlockID(unsigned ID) { BlockID = ID; } | |
115 AbbrevList &getAbbrevs() { return Abbrevs; } | |
116 const AbbrevListVector &getVector() const { | |
117 return Abbrevs.getVector(); | |
118 } | |
119 void push_back(NaClBitCodeAbbrev *Abbv) { | |
120 Abbrevs.push_back(Abbv); | |
121 } | |
122 void destroy() { Abbrevs.clear(); } | |
Derek Schuff
2016/03/15 17:47:04
Is destroy() used anywhere?
Karl
2016/03/15 20:29:41
Good catch. This clear has already been moved to A
| |
123 ~BlockInfo() { destroy(); } | |
124 private: | |
61 unsigned BlockID; | 125 unsigned BlockID; |
62 std::vector<NaClBitCodeAbbrev*> Abbrevs; | 126 AbbrevList Abbrevs; |
127 // Allow NaClBitstreamCursor to update, so that it can install | |
Jim Stichnoth
2016/03/14 22:46:49
reflow comment (I think)
here and below
Karl
2016/03/15 20:29:41
Done by removing need for friend class.
| |
128 // abbreviations within a BlockInfo, as they are read. | |
129 friend NaClBitstreamCursor; | |
63 }; | 130 }; |
131 | |
64 private: | 132 private: |
65 friend class NaClBitstreamCursor; | 133 friend class NaClBitstreamCursor; |
66 | 134 |
67 std::unique_ptr<MemoryObject> BitcodeBytes; | 135 std::unique_ptr<MemoryObject> BitcodeBytes; |
68 | 136 |
69 std::vector<BlockInfo> BlockInfoRecords; | 137 std::vector<BlockInfo> BlockInfoRecords; |
70 | 138 |
139 // True if ReadBlockInfoBlock has been called. | |
Derek Schuff
2016/03/15 17:47:04
Please fix the bug in English that the past and pr
Karl
2016/03/15 20:29:41
On 2016/03/15 17:47:04, Derek Schuff wrote:
> Plea
| |
140 bool HasReadBlockInfoBlock = false; | |
141 | |
71 /// \brief Holds the offset of the first byte after the header. | 142 /// \brief Holds the offset of the first byte after the header. |
72 size_t InitialAddress; | 143 size_t InitialAddress; |
73 | 144 |
74 // True if filler should be added to byte align records. | 145 // True if filler should be added to byte align records. |
75 bool AlignBitcodeRecords = false; | 146 bool AlignBitcodeRecords = false; |
76 NaClBitstreamReader(const NaClBitstreamReader&) = delete; | 147 NaClBitstreamReader(const NaClBitstreamReader&) = delete; |
77 void operator=(const NaClBitstreamReader&) = delete; | 148 void operator=(const NaClBitstreamReader&) = delete; |
78 | 149 |
79 | 150 |
80 void initFromHeader(NaClBitcodeHeader &Header) { | 151 void initFromHeader(NaClBitcodeHeader &Header) { |
(...skipping 18 matching lines...) Expand all Loading... | |
99 | 170 |
100 /// Read stream from bytes, starting at the given initial address. | 171 /// Read stream from bytes, starting at the given initial address. |
101 /// Provides simple API for unit testing. | 172 /// Provides simple API for unit testing. |
102 NaClBitstreamReader(MemoryObject *Bytes, size_t InitialAddress) | 173 NaClBitstreamReader(MemoryObject *Bytes, size_t InitialAddress) |
103 : BitcodeBytes(Bytes), InitialAddress(InitialAddress) { | 174 : BitcodeBytes(Bytes), InitialAddress(InitialAddress) { |
104 } | 175 } |
105 | 176 |
106 // Returns the memory object that is being read. | 177 // Returns the memory object that is being read. |
107 MemoryObject &getBitcodeBytes() { return *BitcodeBytes; } | 178 MemoryObject &getBitcodeBytes() { return *BitcodeBytes; } |
108 | 179 |
109 ~NaClBitstreamReader() { | 180 ~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 | 181 |
121 /// \brief Returns the initial address (after the header) of the input stream. | 182 /// \brief Returns the initial address (after the header) of the input stream. |
122 size_t getInitialAddress() const { | 183 size_t getInitialAddress() const { |
123 return InitialAddress; | 184 return InitialAddress; |
124 } | 185 } |
125 | 186 |
126 //===--------------------------------------------------------------------===// | 187 //===--------------------------------------------------------------------===// |
127 // Block Manipulation | 188 // Block Manipulation |
128 //===--------------------------------------------------------------------===// | 189 //===--------------------------------------------------------------------===// |
129 | 190 |
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 | 191 /// If there is block info for the specified ID, return it, otherwise return |
136 /// null. | 192 /// null. |
137 const BlockInfo *getBlockInfo(unsigned BlockID) const { | 193 const BlockInfo *getBlockInfo(unsigned BlockID) const { |
138 // Common case, the most recent entry matches BlockID. | 194 // Common case, the most recent entry matches BlockID. |
139 if (!BlockInfoRecords.empty() && BlockInfoRecords.back().BlockID == BlockID) | 195 if (!BlockInfoRecords.empty() && |
196 BlockInfoRecords.back().getBlockID() == BlockID) | |
140 return &BlockInfoRecords.back(); | 197 return &BlockInfoRecords.back(); |
141 | 198 |
142 for (unsigned i = 0, e = static_cast<unsigned>(BlockInfoRecords.size()); | 199 for (unsigned i = 0, e = static_cast<unsigned>(BlockInfoRecords.size()); |
143 i != e; ++i) | 200 i != e; ++i) |
144 if (BlockInfoRecords[i].BlockID == BlockID) | 201 if (BlockInfoRecords[i].getBlockID() == BlockID) |
145 return &BlockInfoRecords[i]; | 202 return &BlockInfoRecords[i]; |
146 return nullptr; | 203 return nullptr; |
147 } | 204 } |
148 | 205 |
149 BlockInfo &getOrCreateBlockInfo(unsigned BlockID) { | 206 BlockInfo &getOrCreateBlockInfo(unsigned BlockID) { |
150 if (const BlockInfo *BI = getBlockInfo(BlockID)) | 207 if (const BlockInfo *BI = getBlockInfo(BlockID)) |
151 return *const_cast<BlockInfo*>(BI); | 208 return *const_cast<BlockInfo*>(BI); |
152 | 209 |
153 // Otherwise, add a new record. | 210 // Otherwise, add a new record. |
154 BlockInfoRecords.push_back(BlockInfo()); | 211 BlockInfoRecords.push_back(BlockInfo(BlockID)); |
155 BlockInfoRecords.back().BlockID = BlockID; | |
156 return BlockInfoRecords.back(); | 212 return BlockInfoRecords.back(); |
157 } | 213 } |
158 }; | 214 }; |
159 | 215 |
160 /// When advancing through a bitstream cursor, each advance can discover a few | 216 /// When advancing through a bitstream cursor, each advance can discover a few |
161 /// different kinds of entries: | 217 /// different kinds of entries: |
162 struct NaClBitstreamEntry { | 218 struct NaClBitstreamEntry { |
163 enum { | 219 enum { |
164 Error, // Malformed bitcode was found. | 220 Error, // Malformed bitcode was found. |
165 EndBlock, // We've reached the end of the current block, (or the end of the | 221 EndBlock, // We've reached the end of the current block, (or the end of the |
(...skipping 103 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 | 325 /// 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 | 326 /// places that are aware of this to make it perfectly explicit what is going |
271 /// on. | 327 /// on. |
272 typedef size_t word_t; | 328 typedef size_t word_t; |
273 word_t CurWord; | 329 word_t CurWord; |
274 | 330 |
275 /// This is the number of bits in CurWord that are valid. This | 331 /// This is the number of bits in CurWord that are valid. This |
276 /// is always from [0...bits_of(word_t)-1] inclusive. | 332 /// is always from [0...bits_of(word_t)-1] inclusive. |
277 unsigned BitsInCurWord; | 333 unsigned BitsInCurWord; |
278 | 334 |
279 /// This is the declared size of code values used for the current | 335 // Data specific to a block being scanned. |
280 /// block, in bits. | 336 class Block { |
281 NaClBitcodeSelectorAbbrev CurCodeSize; | 337 public: |
282 | 338 Block() = delete; |
283 /// Abbrevs installed in this block. | 339 Block &operator=(const Block &Rhs) { |
284 std::vector<NaClBitCodeAbbrev*> CurAbbrevs; | 340 GlobalAbbrevs = Rhs.GlobalAbbrevs; |
285 | 341 NumGlobalAbbrevs = Rhs.NumGlobalAbbrevs; |
286 struct Block { | 342 LocalAbbrevs = Rhs.LocalAbbrevs; |
287 NaClBitcodeSelectorAbbrev PrevCodeSize; | 343 CodeAbbrev = Rhs.CodeAbbrev; |
288 std::vector<NaClBitCodeAbbrev*> PrevAbbrevs; | 344 return *this; |
289 Block() : PrevCodeSize() {} | 345 } |
290 explicit Block(const NaClBitcodeSelectorAbbrev& PCS) | 346 Block(NaClBitstreamReader::BlockInfo *GlobalAbbrevs, |
291 : PrevCodeSize(PCS) {} | 347 NaClBitcodeSelectorAbbrev& CodeAbbrev) |
348 : GlobalAbbrevs(GlobalAbbrevs), | |
349 NumGlobalAbbrevs(GlobalAbbrevs->getVector().size()), | |
350 LocalAbbrevs(), CodeAbbrev(CodeAbbrev) {} | |
351 Block(NaClBitstreamReader::BlockInfo *GlobalAbbrevs) | |
352 : GlobalAbbrevs(GlobalAbbrevs), | |
353 NumGlobalAbbrevs(GlobalAbbrevs->getVector().size()), | |
354 LocalAbbrevs(), CodeAbbrev() {} | |
355 ~Block() = default; | |
356 const NaClBitstreamReader::AbbrevList &getGlobalAbbrevs() const { | |
357 return GlobalAbbrevs->getAbbrevs(); | |
358 } | |
359 unsigned getNumGlobalAbbrevs() const { return NumGlobalAbbrevs; } | |
360 const NaClBitstreamReader::AbbrevList &getLocalAbbrevs() const { | |
361 return LocalAbbrevs; | |
362 } | |
363 const NaClBitcodeSelectorAbbrev &getCodeAbbrev() const { | |
364 return CodeAbbrev; | |
365 } | |
366 void setCodeAbbrev(NaClBitcodeSelectorAbbrev &Abbrev) { | |
367 CodeAbbrev = Abbrev; | |
368 } | |
369 void addNewLocalAbbrev(NaClBitCodeAbbrev *Abbv) { | |
370 LocalAbbrevs.push_back(Abbv); | |
371 } | |
372 private: | |
373 friend class NaClBitstreamCursor; | |
374 // The global abbreviations associated with this scope. | |
375 NaClBitstreamReader::BlockInfo *GlobalAbbrevs; | |
376 // Number of abbreviations when block was entered. Used to limit scope | |
377 // of CurBlockInfo, since any abbreviation added inside a BlockInfo block | |
378 // (within this block) must not effect global abbreviations. | |
379 unsigned NumGlobalAbbrevs; | |
380 NaClBitstreamReader::AbbrevList LocalAbbrevs; | |
381 // This is the declared size of code values used for the current block, | |
382 // in bits. | |
383 NaClBitcodeSelectorAbbrev CodeAbbrev; | |
292 }; | 384 }; |
293 | 385 |
294 /// This tracks the codesize of parent blocks. | 386 /// This tracks the Block-specific information for each nested block. |
295 SmallVector<Block, 8> BlockScope; | 387 SmallVector<Block, 8> BlockScope; |
296 | 388 |
297 NaClBitstreamCursor(const NaClBitstreamCursor &) = delete; | 389 NaClBitstreamCursor(const NaClBitstreamCursor &) = delete; |
298 NaClBitstreamCursor &operator=(const NaClBitstreamCursor &) = delete; | 390 NaClBitstreamCursor &operator=(const NaClBitstreamCursor &) = delete; |
299 | 391 |
300 public: | 392 public: |
301 NaClBitstreamCursor() : ErrHandler(new ErrorHandler(*this)) { | 393 NaClBitstreamCursor() : ErrHandler(new ErrorHandler(*this)) { |
302 init(nullptr); | 394 init(nullptr); |
303 } | 395 } |
304 | 396 |
305 explicit NaClBitstreamCursor(NaClBitstreamReader &R) | 397 explicit NaClBitstreamCursor(NaClBitstreamReader &R) |
306 : ErrHandler(new ErrorHandler(*this)) { init(&R); } | 398 : ErrHandler(new ErrorHandler(*this)) { init(&R); } |
307 | 399 |
308 void init(NaClBitstreamReader *R) { | 400 void init(NaClBitstreamReader *R) { |
309 freeState(); | 401 freeState(); |
310 BitStream = R; | 402 BitStream = R; |
311 NextChar = (BitStream == nullptr) ? 0 : BitStream->getInitialAddress(); | 403 NextChar = (BitStream == nullptr) ? 0 : BitStream->getInitialAddress(); |
312 Size = 0; | 404 Size = 0; |
313 BitsInCurWord = 0; | 405 BitsInCurWord = 0; |
406 if (BitStream) { | |
407 BlockScope.push_back( | |
408 Block(&BitStream->getOrCreateBlockInfo(naclbitc::TOP_LEVEL_BLOCKID))); | |
409 } | |
314 } | 410 } |
315 | 411 |
316 ~NaClBitstreamCursor() { | 412 ~NaClBitstreamCursor() { |
317 freeState(); | 413 freeState(); |
318 } | 414 } |
319 | 415 |
320 void freeState(); | 416 void freeState() { |
417 while (!BlockScope.empty()) | |
418 BlockScope.pop_back(); | |
419 } | |
321 | 420 |
322 // Replaces the current bitstream error handler with the new | 421 // Replaces the current bitstream error handler with the new |
323 // handler. Takes ownership of the new handler and deletes it when | 422 // handler. Takes ownership of the new handler and deletes it when |
324 // it is no longer needed. | 423 // it is no longer needed. |
325 void setErrorHandler(std::unique_ptr<ErrorHandler> &NewHandler) { | 424 void setErrorHandler(std::unique_ptr<ErrorHandler> &NewHandler) { |
326 ErrHandler = std::move(NewHandler); | 425 ErrHandler = std::move(NewHandler); |
327 } | 426 } |
328 | 427 |
329 bool canSkipToPos(size_t pos) const { | 428 bool canSkipToPos(size_t pos) const { |
330 // pos can be skipped to if it is a valid address or one byte past the end. | 429 // pos can be skipped to if it is a valid address or one byte past the end. |
331 return pos == 0 || BitStream->getBitcodeBytes().isValidAddress( | 430 return pos == 0 || BitStream->getBitcodeBytes().isValidAddress( |
332 static_cast<uint64_t>(pos - 1)); | 431 static_cast<uint64_t>(pos - 1)); |
333 } | 432 } |
334 | 433 |
335 bool AtEndOfStream() { | 434 bool AtEndOfStream() { |
336 if (BitsInCurWord != 0) | 435 if (BitsInCurWord != 0) |
337 return false; | 436 return false; |
338 if (Size != 0) | 437 if (Size != 0) |
339 return Size == NextChar; | 438 return Size == NextChar; |
340 fillCurWord(); | 439 fillCurWord(); |
341 return BitsInCurWord == 0; | 440 return BitsInCurWord == 0; |
342 } | 441 } |
343 | 442 |
344 /// Return the number of bits used to encode an abbrev #. | 443 /// Return the number of bits used to encode an abbrev #. |
345 unsigned getAbbrevIDWidth() const { return CurCodeSize.NumBits; } | 444 unsigned getAbbrevIDWidth() const { |
445 return BlockScope.back().getCodeAbbrev().NumBits; | |
446 } | |
346 | 447 |
347 /// Return the bit # of the bit we are reading. | 448 /// Return the bit # of the bit we are reading. |
348 uint64_t GetCurrentBitNo() const { | 449 uint64_t GetCurrentBitNo() const { |
349 return NextChar*CHAR_BIT - BitsInCurWord; | 450 return NextChar*CHAR_BIT - BitsInCurWord; |
350 } | 451 } |
351 | 452 |
352 NaClBitstreamReader *getBitStreamReader() { | 453 NaClBitstreamReader *getBitStreamReader() { |
353 return BitStream; | 454 return BitStream; |
354 } | 455 } |
355 const NaClBitstreamReader *getBitStreamReader() const { | 456 const NaClBitstreamReader *getBitStreamReader() const { |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
552 CurWord >>= BitsInCurWord-32; | 653 CurWord >>= BitsInCurWord-32; |
553 BitsInCurWord = 32; | 654 BitsInCurWord = 32; |
554 return; | 655 return; |
555 } | 656 } |
556 | 657 |
557 BitsInCurWord = 0; | 658 BitsInCurWord = 0; |
558 } | 659 } |
559 public: | 660 public: |
560 | 661 |
561 unsigned ReadCode() { | 662 unsigned ReadCode() { |
562 return CurCodeSize.IsFixed | 663 const NaClBitcodeSelectorAbbrev &CodeAbbrev = |
563 ? Read(CurCodeSize.NumBits) | 664 BlockScope.back().getCodeAbbrev(); |
564 : ReadVBR(CurCodeSize.NumBits); | 665 return CodeAbbrev.IsFixed |
666 ? Read(CodeAbbrev.NumBits) | |
667 : ReadVBR(CodeAbbrev.NumBits); | |
565 } | 668 } |
566 | 669 |
567 // Block header: | 670 // Block header: |
568 // [ENTER_SUBBLOCK, blockid, newcodelen, <align4bytes>, blocklen] | 671 // [ENTER_SUBBLOCK, blockid, newcodelen, <align4bytes>, blocklen] |
569 | 672 |
570 /// Having read the ENTER_SUBBLOCK code, read the BlockID for the block. | 673 /// Having read the ENTER_SUBBLOCK code, read the BlockID for the block. |
571 unsigned ReadSubBlockID() { | 674 unsigned ReadSubBlockID() { |
572 return ReadVBR(naclbitc::BlockIDWidth); | 675 return ReadVBR(naclbitc::BlockIDWidth); |
573 } | 676 } |
574 | 677 |
(...skipping 14 matching lines...) Expand all Loading... | |
589 | 692 |
590 JumpToBit(SkipTo); | 693 JumpToBit(SkipTo); |
591 return false; | 694 return false; |
592 } | 695 } |
593 | 696 |
594 /// Having read the ENTER_SUBBLOCK abbrevid, enter the block, and return true | 697 /// Having read the ENTER_SUBBLOCK abbrevid, enter the block, and return true |
595 /// if the block has an error. | 698 /// if the block has an error. |
596 bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = nullptr); | 699 bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = nullptr); |
597 | 700 |
598 bool ReadBlockEnd() { | 701 bool ReadBlockEnd() { |
599 if (BlockScope.empty()) return true; | 702 if (BlockScope.empty()) return true; |
Derek Schuff
2016/03/15 17:47:04
extra space?
Karl
2016/03/15 20:29:41
Done.
| |
600 | 703 |
601 // Block tail: | 704 // Block tail: |
602 // [END_BLOCK, <align4bytes>] | 705 // [END_BLOCK, <align4bytes>] |
603 SkipToFourByteBoundary(); | 706 SkipToFourByteBoundary(); |
604 | 707 |
605 popBlockScope(); | 708 BlockScope.pop_back(); |
606 return false; | 709 return false; |
607 } | 710 } |
608 | 711 |
609 private: | 712 private: |
610 | 713 |
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 //===--------------------------------------------------------------------===// | 714 //===--------------------------------------------------------------------===// |
624 // Record Processing | 715 // Record Processing |
625 //===--------------------------------------------------------------------===// | 716 //===--------------------------------------------------------------------===// |
626 | 717 |
627 private: | 718 private: |
628 // Returns abbreviation encoding associated with Value. | 719 // Returns abbreviation encoding associated with Value. |
629 NaClBitCodeAbbrevOp::Encoding getEncoding(uint64_t Value); | 720 NaClBitCodeAbbrevOp::Encoding getEncoding(uint64_t Value); |
630 | 721 |
631 void skipAbbreviatedField(const NaClBitCodeAbbrevOp &Op); | 722 void skipAbbreviatedField(const NaClBitCodeAbbrevOp &Op); |
632 | 723 |
(...skipping 17 matching lines...) Expand all Loading... | |
650 void reportInvalidAbbrevNumber(unsigned Index) const; | 741 void reportInvalidAbbrevNumber(unsigned Index) const; |
651 | 742 |
652 // Reports that jumping to Bit is not valid. | 743 // Reports that jumping to Bit is not valid. |
653 void reportInvalidJumpToBit(uint64_t Bit) const; | 744 void reportInvalidJumpToBit(uint64_t Bit) const; |
654 | 745 |
655 public: | 746 public: |
656 | 747 |
657 /// Return the abbreviation for the specified AbbrevId. | 748 /// Return the abbreviation for the specified AbbrevId. |
658 const NaClBitCodeAbbrev *getAbbrev(unsigned AbbrevID) const { | 749 const NaClBitCodeAbbrev *getAbbrev(unsigned AbbrevID) const { |
659 unsigned AbbrevNo = AbbrevID-naclbitc::FIRST_APPLICATION_ABBREV; | 750 unsigned AbbrevNo = AbbrevID-naclbitc::FIRST_APPLICATION_ABBREV; |
660 if (AbbrevNo >= CurAbbrevs.size()) | 751 const Block &CurBlock = BlockScope.back(); |
752 const unsigned NumGlobalAbbrevs = CurBlock.getNumGlobalAbbrevs(); | |
753 if (AbbrevNo < NumGlobalAbbrevs) | |
754 return CurBlock.getGlobalAbbrevs().getVector()[AbbrevNo]; | |
755 unsigned LocalAbbrevNo = AbbrevNo - NumGlobalAbbrevs; | |
756 NaClBitstreamReader::AbbrevListVector | |
757 LocalAbbrevs = CurBlock.getLocalAbbrevs().getVector(); | |
758 if (LocalAbbrevNo >= LocalAbbrevs.size()) | |
661 reportInvalidAbbrevNumber(AbbrevID); | 759 reportInvalidAbbrevNumber(AbbrevID); |
662 return CurAbbrevs[AbbrevNo]; | 760 return LocalAbbrevs[LocalAbbrevNo]; |
663 } | 761 } |
664 | 762 |
665 /// Read the current record and discard it. | 763 /// Read the current record and discard it. |
666 void skipRecord(unsigned AbbrevID); | 764 void skipRecord(unsigned AbbrevID); |
667 | 765 |
668 unsigned readRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals); | 766 unsigned readRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals); |
669 | 767 |
670 //===--------------------------------------------------------------------===// | 768 //===--------------------------------------------------------------------===// |
671 // Abbrev Processing | 769 // Abbrev Processing |
672 //===--------------------------------------------------------------------===// | 770 //===--------------------------------------------------------------------===// |
673 // IsLocal indicates where the abbreviation occurs. If it is in the | 771 // IsLocal indicates where the abbreviation occurs. If it is in the |
674 // BlockInfo block, IsLocal is false. In all other cases, IsLocal is | 772 // BlockInfo block, IsLocal is false. In all other cases, IsLocal is |
675 // true. | 773 // true. |
676 void ReadAbbrevRecord(bool IsLocal, | 774 void ReadAbbrevRecord(bool IsLocal, |
677 NaClAbbrevListener *Listener); | 775 NaClAbbrevListener *Listener); |
678 | 776 |
679 // Skips over an abbreviation record. Duplicates code of ReadAbbrevRecord, | 777 // Skips over an abbreviation record. Duplicates code of ReadAbbrevRecord, |
680 // except that no abbreviation is built. | 778 // except that no abbreviation is built. |
681 void SkipAbbrevRecord(); | 779 void SkipAbbrevRecord(); |
682 | 780 |
683 bool ReadBlockInfoBlock(NaClAbbrevListener *Listener); | 781 bool ReadBlockInfoBlock(NaClAbbrevListener *Listener); |
684 }; | 782 }; |
685 | 783 |
686 } // End llvm namespace | 784 } // End llvm namespace |
687 | 785 |
688 #endif | 786 #endif |
OLD | NEW |