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

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