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 // 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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |