Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(167)

Side by Side Diff: include/llvm/Bitcode/NaCl/NaClBitstreamReader.h

Issue 1798243002: Fix the block stack used by the bitstream cursor. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-llvm.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698