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

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