OLD | NEW |
---|---|
1 //===- NaClBitstreamReader.h -----------------------------------*- C++ -*-===// | 1 //===- NaClBitstreamReader.h -----------------------------------*- C++ -*-===// |
2 // Low-level bitstream reader interface | 2 // Low-level bitstream reader interface |
3 // | 3 // |
4 // The LLVM Compiler Infrastructure | 4 // The LLVM Compiler Infrastructure |
5 // | 5 // |
6 // This file is distributed under the University of Illinois Open Source | 6 // This file is distributed under the University of Illinois Open Source |
7 // License. See LICENSE.TXT for details. | 7 // License. See LICENSE.TXT for details. |
8 // | 8 // |
9 //===----------------------------------------------------------------------===// | 9 //===----------------------------------------------------------------------===// |
10 // | 10 // |
11 // This header defines the BitstreamReader class. This class can be used to | 11 // This header defines the BitstreamReader class. This class can be used to |
12 // read an arbitrary bitstream, regardless of its contents. | 12 // read an arbitrary bitstream, regardless of its contents. |
13 // | 13 // |
14 //===----------------------------------------------------------------------===// | 14 //===----------------------------------------------------------------------===// |
15 | 15 |
16 #ifndef LLVM_BITCODE_NACL_NACLBITSTREAMREADER_H | 16 #ifndef LLVM_BITCODE_NACL_NACLBITSTREAMREADER_H |
17 #define LLVM_BITCODE_NACL_NACLBITSTREAMREADER_H | 17 #define LLVM_BITCODE_NACL_NACLBITSTREAMREADER_H |
18 | 18 |
19 #include "llvm/ADT/SmallVector.h" | 19 #include "llvm/ADT/SmallVector.h" |
20 #include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h" | 20 #include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h" |
21 #include "llvm/Bitcode/NaCl/NaClLLVMBitCodes.h" | 21 #include "llvm/Bitcode/NaCl/NaClLLVMBitCodes.h" |
22 #include "llvm/Support/Endian.h" | 22 #include "llvm/Support/Endian.h" |
23 #include "llvm/Support/StreamingMemoryObject.h" | 23 #include "llvm/Support/StreamingMemoryObject.h" |
24 #include <climits> | 24 #include <climits> |
25 #include <vector> | 25 #include <vector> |
26 | 26 |
27 namespace llvm { | 27 namespace llvm { |
28 | 28 |
29 class Deserializer; | 29 class Deserializer; |
30 class NaClBitstreamCursor; | |
30 | 31 |
31 namespace naclbitc { | 32 namespace naclbitc { |
32 | 33 |
33 /// Returns the Bit as a Byte:BitInByte string. | 34 /// Returns the Bit as a Byte:BitInByte string. |
34 std::string getBitAddress(uint64_t Bit); | 35 std::string getBitAddress(uint64_t Bit); |
35 | 36 |
36 /// Severity levels for reporting errors. | 37 /// Severity levels for reporting errors. |
37 enum ErrorLevel { | 38 enum ErrorLevel { |
38 Warning, | 39 Warning, |
39 Error, | 40 Error, |
40 Fatal | 41 Fatal |
41 }; | 42 }; |
42 | 43 |
43 // Basic printing routine to generate the beginning of an error | 44 // Basic printing routine to generate the beginning of an error |
44 // message. BitPosition is the bit position the error was found. | 45 // message. BitPosition is the bit position the error was found. |
45 // Level is the severity of the error. | 46 // Level is the severity of the error. |
46 raw_ostream &ErrorAt(raw_ostream &Out, ErrorLevel Level, | 47 raw_ostream &ErrorAt(raw_ostream &Out, ErrorLevel Level, |
47 uint64_t BitPosition); | 48 uint64_t BitPosition); |
48 | 49 |
49 } // End namespace naclbitc. | 50 } // End namespace naclbitc. |
50 | 51 |
51 /// This class is used to read from a NaCl bitcode wire format stream, | 52 /// This class is used to read from a NaCl bitcode wire format stream, |
52 /// maintaining information that is global to decoding the entire file. | 53 /// maintaining information that is global to decoding the entire file. |
53 /// While a file is being read, multiple cursors can be independently | 54 /// While a file is being read, multiple cursors can be independently |
54 /// advanced or skipped around within the file. These are represented by | 55 /// advanced or skipped around within the file. These are represented by |
55 /// the NaClBitstreamCursor class. | 56 /// the NaClBitstreamCursor class. |
56 class NaClBitstreamReader { | 57 class NaClBitstreamReader { |
57 public: | 58 public: |
58 /// This contains information emitted to BLOCKINFO_BLOCK blocks. These | 59 // Models a raw list of abbreviations. |
59 /// describe abbreviations that all blocks of the specified ID inherit. | 60 static 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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |