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

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

Powered by Google App Engine
This is Rietveld 408576698