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

Side by Side Diff: include/llvm/Bitcode/NaCl/NaClBitstreamReader.h

Issue 939073008: Rebased PNaCl localmods in LLVM to 223109 (Closed)
Patch Set: undo localmod Created 5 years, 10 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 //===- BitstreamReader.h - Low-level bitstream reader interface -*- C++ -*-===// 1 //===- NaClBitstreamReader.h -----------------------------------*- C++ -*-===//
2 // Low-level bitstream reader interface
2 // 3 //
3 // The LLVM Compiler Infrastructure 4 // The LLVM Compiler Infrastructure
4 // 5 //
5 // This file is distributed under the University of Illinois Open Source 6 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 7 // License. See LICENSE.TXT for details.
7 // 8 //
8 //===----------------------------------------------------------------------===// 9 //===----------------------------------------------------------------------===//
9 // 10 //
10 // 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
11 // read an arbitrary bitstream, regardless of its contents. 12 // read an arbitrary bitstream, regardless of its contents.
12 // 13 //
13 //===----------------------------------------------------------------------===// 14 //===----------------------------------------------------------------------===//
14 15
15 #ifndef LLVM_BITCODE_BITSTREAMREADER_H 16 #ifndef LLVM_BITCODE_NACL_NACLBITSTREAMREADER_H
16 #define LLVM_BITCODE_BITSTREAMREADER_H 17 #define LLVM_BITCODE_NACL_NACLBITSTREAMREADER_H
17 18
18 #include "llvm/Bitcode/BitCodes.h" 19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/Bitcode/NaCl/NaClLLVMBitCodes.h"
19 #include "llvm/Support/Endian.h" 21 #include "llvm/Support/Endian.h"
20 #include "llvm/Support/StreamingMemoryObject.h" 22 #include "llvm/Support/StreamingMemoryObject.h"
21 #include <climits> 23 #include <climits>
22 #include <string>
23 #include <vector> 24 #include <vector>
24 25
25 namespace llvm { 26 namespace llvm {
26 27
27 class Deserializer; 28 class Deserializer;
28 29
29 /// This class is used to read from an LLVM bitcode stream, maintaining 30 /// This class is used to read from a NaCl bitcode wire format stream,
30 /// information that is global to decoding the entire file. While a file is 31 /// maintaining information that is global to decoding the entire file.
31 /// being read, multiple cursors can be independently advanced or skipped around 32 /// While a file is being read, multiple cursors can be independently
32 /// within the file. These are represented by the BitstreamCursor class. 33 /// advanced or skipped around within the file. These are represented by
33 class BitstreamReader { 34 /// the NaClBitstreamCursor class.
35 class NaClBitstreamReader {
34 public: 36 public:
35 /// This contains information emitted to BLOCKINFO_BLOCK blocks. These 37 /// This contains information emitted to BLOCKINFO_BLOCK blocks. These
36 /// describe abbreviations that all blocks of the specified ID inherit. 38 /// describe abbreviations that all blocks of the specified ID inherit.
37 struct BlockInfo { 39 struct BlockInfo {
38 unsigned BlockID; 40 unsigned BlockID;
39 std::vector<IntrusiveRefCntPtr<BitCodeAbbrev>> Abbrevs; 41 std::vector<NaClBitCodeAbbrev*> Abbrevs;
40 std::string Name;
41
42 std::vector<std::pair<unsigned, std::string> > RecordNames;
43 }; 42 };
44 private: 43 private:
45 std::unique_ptr<MemoryObject> BitcodeBytes; 44 std::unique_ptr<MemoryObject> BitcodeBytes;
46 45
47 std::vector<BlockInfo> BlockInfoRecords; 46 std::vector<BlockInfo> BlockInfoRecords;
48 47
49 /// This is set to true if we don't care about the block/record name 48 /// \brief Holds the offset of the first byte after the header.
50 /// information in the BlockInfo block. Only llvm-bcanalyzer uses this. 49 size_t InitialAddress;
51 bool IgnoreBlockInfoNames;
52 50
53 BitstreamReader(const BitstreamReader&) LLVM_DELETED_FUNCTION; 51 NaClBitstreamReader(const NaClBitstreamReader&) LLVM_DELETED_FUNCTION;
54 void operator=(const BitstreamReader&) LLVM_DELETED_FUNCTION; 52 void operator=(const NaClBitstreamReader&) LLVM_DELETED_FUNCTION;
55 public: 53 public:
56 BitstreamReader() : IgnoreBlockInfoNames(true) { 54 NaClBitstreamReader() : InitialAddress(0) {}
57 }
58 55
59 BitstreamReader(const unsigned char *Start, const unsigned char *End) 56 NaClBitstreamReader(const unsigned char *Start, const unsigned char *End,
60 : IgnoreBlockInfoNames(true) { 57 size_t MyInitialAddress=0) {
58 InitialAddress = MyInitialAddress;
61 init(Start, End); 59 init(Start, End);
62 } 60 }
63 61
64 BitstreamReader(MemoryObject *bytes) : IgnoreBlockInfoNames(true) { 62 NaClBitstreamReader(MemoryObject *Bytes, size_t MyInitialAddress=0)
65 BitcodeBytes.reset(bytes); 63 : InitialAddress(MyInitialAddress) {
66 } 64 BitcodeBytes.reset(Bytes);
67
68 BitstreamReader(BitstreamReader &&Other) {
69 *this = std::move(Other);
70 }
71
72 BitstreamReader &operator=(BitstreamReader &&Other) {
73 BitcodeBytes = std::move(Other.BitcodeBytes);
74 // Explicitly swap block info, so that nothing gets destroyed twice.
75 std::swap(BlockInfoRecords, Other.BlockInfoRecords);
76 IgnoreBlockInfoNames = Other.IgnoreBlockInfoNames;
77 return *this;
78 } 65 }
79 66
80 void init(const unsigned char *Start, const unsigned char *End) { 67 void init(const unsigned char *Start, const unsigned char *End) {
81 assert(((End-Start) & 3) == 0 &&"Bitcode stream not a multiple of 4 bytes"); 68 assert(((End-Start) & 3) == 0 &&"Bitcode stream not a multiple of 4 bytes");
82 BitcodeBytes.reset(getNonStreamedMemoryObject(Start, End)); 69 BitcodeBytes.reset(getNonStreamedMemoryObject(Start, End));
83 } 70 }
84 71
85 MemoryObject &getBitcodeBytes() { return *BitcodeBytes; } 72 MemoryObject &getBitcodeBytes() { return *BitcodeBytes; }
86 73
87 /// This is called by clients that want block/record name information. 74 ~NaClBitstreamReader() {
88 void CollectBlockInfoNames() { IgnoreBlockInfoNames = false; } 75 // Free the BlockInfoRecords.
89 bool isIgnoringBlockInfoNames() { return IgnoreBlockInfoNames; } 76 while (!BlockInfoRecords.empty()) {
77 BlockInfo &Info = BlockInfoRecords.back();
78 // Free blockinfo abbrev info.
79 for (unsigned i = 0, e = static_cast<unsigned>(Info.Abbrevs.size());
80 i != e; ++i)
81 Info.Abbrevs[i]->dropRef();
82 BlockInfoRecords.pop_back();
83 }
84 }
85
86 /// \brief Returns the initial address (after the header) of the input stream.
87 size_t getInitialAddress() const {
88 return InitialAddress;
89 }
90 90
91 //===--------------------------------------------------------------------===// 91 //===--------------------------------------------------------------------===//
92 // Block Manipulation 92 // Block Manipulation
93 //===--------------------------------------------------------------------===// 93 //===--------------------------------------------------------------------===//
94 94
95 /// Return true if we've already read and processed the block info block for 95 /// Return true if we've already read and processed the block info block for
96 /// this Bitstream. We only process it for the first cursor that walks over 96 /// this Bitstream. We only process it for the first cursor that walks over
97 /// it. 97 /// it.
98 bool hasBlockInfoRecords() const { return !BlockInfoRecords.empty(); } 98 bool hasBlockInfoRecords() const { return !BlockInfoRecords.empty(); }
99 99
(...skipping 13 matching lines...) Expand all
113 113
114 BlockInfo &getOrCreateBlockInfo(unsigned BlockID) { 114 BlockInfo &getOrCreateBlockInfo(unsigned BlockID) {
115 if (const BlockInfo *BI = getBlockInfo(BlockID)) 115 if (const BlockInfo *BI = getBlockInfo(BlockID))
116 return *const_cast<BlockInfo*>(BI); 116 return *const_cast<BlockInfo*>(BI);
117 117
118 // Otherwise, add a new record. 118 // Otherwise, add a new record.
119 BlockInfoRecords.push_back(BlockInfo()); 119 BlockInfoRecords.push_back(BlockInfo());
120 BlockInfoRecords.back().BlockID = BlockID; 120 BlockInfoRecords.back().BlockID = BlockID;
121 return BlockInfoRecords.back(); 121 return BlockInfoRecords.back();
122 } 122 }
123
124 /// Takes block info from the other bitstream reader.
125 ///
126 /// This is a "take" operation because BlockInfo records are non-trivial, and
127 /// indeed rather expensive.
128 void takeBlockInfo(BitstreamReader &&Other) {
129 assert(!hasBlockInfoRecords());
130 BlockInfoRecords = std::move(Other.BlockInfoRecords);
131 }
132 }; 123 };
133 124
134 /// When advancing through a bitstream cursor, each advance can discover a few 125 /// When advancing through a bitstream cursor, each advance can discover a few
135 /// different kinds of entries: 126 /// different kinds of entries:
136 struct BitstreamEntry { 127 struct NaClBitstreamEntry {
137 enum { 128 enum {
138 Error, // Malformed bitcode was found. 129 Error, // Malformed bitcode was found.
139 EndBlock, // We've reached the end of the current block, (or the end of the 130 EndBlock, // We've reached the end of the current block, (or the end of the
140 // file, which is treated like a series of EndBlock records. 131 // file, which is treated like a series of EndBlock records.
141 SubBlock, // This is the start of a new subblock of a specific ID. 132 SubBlock, // This is the start of a new subblock of a specific ID.
142 Record // This is a record with a specific AbbrevID. 133 Record // This is a record with a specific AbbrevID.
143 } Kind; 134 } Kind;
144 135
145 unsigned ID; 136 unsigned ID;
146 137
147 static BitstreamEntry getError() { 138 static NaClBitstreamEntry getError() {
148 BitstreamEntry E; E.Kind = Error; return E; 139 NaClBitstreamEntry E; E.Kind = Error; return E;
149 } 140 }
150 static BitstreamEntry getEndBlock() { 141 static NaClBitstreamEntry getEndBlock() {
151 BitstreamEntry E; E.Kind = EndBlock; return E; 142 NaClBitstreamEntry E; E.Kind = EndBlock; return E;
152 } 143 }
153 static BitstreamEntry getSubBlock(unsigned ID) { 144 static NaClBitstreamEntry getSubBlock(unsigned ID) {
154 BitstreamEntry E; E.Kind = SubBlock; E.ID = ID; return E; 145 NaClBitstreamEntry E; E.Kind = SubBlock; E.ID = ID; return E;
155 } 146 }
156 static BitstreamEntry getRecord(unsigned AbbrevID) { 147 static NaClBitstreamEntry getRecord(unsigned AbbrevID) {
157 BitstreamEntry E; E.Kind = Record; E.ID = AbbrevID; return E; 148 NaClBitstreamEntry E; E.Kind = Record; E.ID = AbbrevID; return E;
158 } 149 }
159 }; 150 };
160 151
152 /// Models default view of a bitcode record.
153 typedef SmallVector<uint64_t, 8> NaClBitcodeRecordVector;
154
155 /// Class NaClAbbrevListener is used to allow instances of class
156 /// NaClBitcodeParser to listen to record details when processing
157 /// abbreviations. The major reason for using a listener is that the
158 /// NaCl bitcode reader would require a major rewrite (including the
159 /// introduction of more overhead) if we were to lift abbreviations up
160 /// to the bitcode reader. That is, not only would we have to lift the
161 /// block processing up into the readers (i.e. many blocks in
162 /// NaClBitcodeReader and NaClBitcodeParser), but add many new API's
163 /// to allow the readers to update internals of the bit stream reader
164 /// appropriately.
165 class NaClAbbrevListener {
166 NaClAbbrevListener(const NaClAbbrevListener&) LLVM_DELETED_FUNCTION;
167 void operator=(const NaClAbbrevListener&) LLVM_DELETED_FUNCTION;
168 public:
169 NaClAbbrevListener() {}
170 virtual ~NaClAbbrevListener() {}
171
172 /// Called to process the read abbreviation.
173 virtual void ProcessAbbreviation(NaClBitCodeAbbrev *Abbrev,
174 bool IsLocal) = 0;
175
176 /// Called after entering block. NumWords is the number of words
177 /// in the block.
178 virtual void BeginBlockInfoBlock(unsigned NumWords) = 0;
179
180 /// Called if a naclbitc::BLOCKINFO_CODE_SETBID record is found in
181 /// NaClBitstreamCursor::ReadBlockInfoBlock.
182 virtual void SetBID() = 0;
183
184 /// Called just before an EndBlock record is processed by
185 /// NaClBitstreamCursor::ReadBlockInfoBlock
186 virtual void EndBlockInfoBlock() = 0;
187
188 /// The values of the bitcode record associated with the called
189 /// virtual function.
190 NaClBitcodeRecordVector Values;
191
192 /// Start bit for current record being processed in
193 /// NaClBitstreamCursor::ReadBlockInfoBlock.
194 uint64_t StartBit;
195 };
196
161 /// This represents a position within a bitcode file. There may be multiple 197 /// This represents a position within a bitcode file. There may be multiple
162 /// independent cursors reading within one bitstream, each maintaining their own 198 /// independent cursors reading within one bitstream, each maintaining their
163 /// local state. 199 /// own local state.
164 /// 200 ///
165 /// Unlike iterators, BitstreamCursors are heavy-weight objects that should not 201 /// Unlike iterators, NaClBitstreamCursors are heavy-weight objects
166 /// be passed by value. 202 /// that should not be passed by value.
167 class BitstreamCursor { 203 class NaClBitstreamCursor {
168 friend class Deserializer; 204 friend class Deserializer;
169 BitstreamReader *BitStream; 205 NaClBitstreamReader *BitStream;
170 size_t NextChar; 206 size_t NextChar;
171 207
172 // The size of the bicode. 0 if we don't know it yet. 208 // The size of the bitcode. 0 if we don't know it yet.
173 size_t Size; 209 size_t Size;
174 210
175 /// This is the current data we have pulled from the stream but have not 211 /// This is the current data we have pulled from the stream but have not
176 /// returned to the client. This is specifically and intentionally defined to 212 /// returned to the client. This is specifically and intentionally defined to
177 /// follow the word size of the host machine for efficiency. We use word_t in 213 /// follow the word size of the host machine for efficiency. We use word_t in
178 /// places that are aware of this to make it perfectly explicit what is going 214 /// places that are aware of this to make it perfectly explicit what is going
179 /// on. 215 /// on.
180 typedef size_t word_t; 216 typedef size_t word_t;
181 word_t CurWord; 217 word_t CurWord;
182 218
183 /// This is the number of bits in CurWord that are valid. This is always from 219 /// This is the number of bits in CurWord that are valid. This
184 /// [0...bits_of(size_t)-1] inclusive. 220 /// is always from [0...bits_of(word_t)-1] inclusive.
185 unsigned BitsInCurWord; 221 unsigned BitsInCurWord;
186 222
187 // This is the declared size of code values used for the current block, in 223 /// This is the declared size of code values used for the current
188 // bits. 224 /// block, in bits.
189 unsigned CurCodeSize; 225 NaClBitcodeSelectorAbbrev CurCodeSize;
190 226
191 /// Abbrevs installed at in this block. 227 /// Abbrevs installed in this block.
192 std::vector<IntrusiveRefCntPtr<BitCodeAbbrev>> CurAbbrevs; 228 std::vector<NaClBitCodeAbbrev*> CurAbbrevs;
193 229
194 struct Block { 230 struct Block {
195 unsigned PrevCodeSize; 231 NaClBitcodeSelectorAbbrev PrevCodeSize;
196 std::vector<IntrusiveRefCntPtr<BitCodeAbbrev>> PrevAbbrevs; 232 std::vector<NaClBitCodeAbbrev*> PrevAbbrevs;
197 explicit Block(unsigned PCS) : PrevCodeSize(PCS) {} 233 Block() : PrevCodeSize() {}
234 explicit Block(const NaClBitcodeSelectorAbbrev& PCS)
235 : PrevCodeSize(PCS) {}
198 }; 236 };
199 237
200 /// This tracks the codesize of parent blocks. 238 /// This tracks the codesize of parent blocks.
201 SmallVector<Block, 8> BlockScope; 239 SmallVector<Block, 8> BlockScope;
202 240
241 NaClBitstreamCursor(const NaClBitstreamCursor &) LLVM_DELETED_FUNCTION;
242 NaClBitstreamCursor &operator=(const NaClBitstreamCursor &) LLVM_DELETED_FUNCT ION;
203 243
204 public: 244 public:
205 BitstreamCursor() { init(nullptr); } 245 NaClBitstreamCursor() { init(nullptr); }
206 246
207 explicit BitstreamCursor(BitstreamReader &R) { init(&R); } 247 explicit NaClBitstreamCursor(NaClBitstreamReader &R) { init(&R); }
208 248
209 void init(BitstreamReader *R) { 249 void init(NaClBitstreamReader *R) {
210 freeState(); 250 freeState();
211
212 BitStream = R; 251 BitStream = R;
213 NextChar = 0; 252 NextChar = (BitStream == nullptr) ? 0 : BitStream->getInitialAddress();
214 Size = 0; 253 Size = 0;
215 BitsInCurWord = 0; 254 BitsInCurWord = 0;
216 CurCodeSize = 2; 255 }
256
257 ~NaClBitstreamCursor() {
258 freeState();
217 } 259 }
218 260
219 void freeState(); 261 void freeState();
220 262
221 bool canSkipToPos(size_t pos) const { 263 bool canSkipToPos(size_t pos) const {
222 // pos can be skipped to if it is a valid address or one byte past the end. 264 // pos can be skipped to if it is a valid address or one byte past the end.
223 return pos == 0 || BitStream->getBitcodeBytes().isValidAddress( 265 return pos == 0 || BitStream->getBitcodeBytes().isValidAddress(
224 static_cast<uint64_t>(pos - 1)); 266 static_cast<uint64_t>(pos - 1));
225 } 267 }
226 268
227 bool AtEndOfStream() { 269 bool AtEndOfStream() {
228 if (BitsInCurWord != 0) 270 if (BitsInCurWord != 0)
229 return false; 271 return false;
230 if (Size != 0) 272 if (Size != 0)
231 return Size == NextChar; 273 return Size == NextChar;
232 fillCurWord(); 274 fillCurWord();
233 return BitsInCurWord == 0; 275 return BitsInCurWord == 0;
234 } 276 }
235 277
236 /// Return the number of bits used to encode an abbrev #. 278 /// Return the number of bits used to encode an abbrev #.
237 unsigned getAbbrevIDWidth() const { return CurCodeSize; } 279 unsigned getAbbrevIDWidth() const { return CurCodeSize.NumBits; }
238 280
239 /// Return the bit # of the bit we are reading. 281 /// Return the bit # of the bit we are reading.
240 uint64_t GetCurrentBitNo() const { 282 uint64_t GetCurrentBitNo() const {
241 return NextChar*CHAR_BIT - BitsInCurWord; 283 return NextChar*CHAR_BIT - BitsInCurWord;
242 } 284 }
243 285
244 BitstreamReader *getBitStreamReader() { 286 NaClBitstreamReader *getBitStreamReader() {
245 return BitStream; 287 return BitStream;
246 } 288 }
247 const BitstreamReader *getBitStreamReader() const { 289 const NaClBitstreamReader *getBitStreamReader() const {
248 return BitStream; 290 return BitStream;
249 } 291 }
250 292
251 /// Flags that modify the behavior of advance(). 293 /// Flags that modify the behavior of advance().
252 enum { 294 enum {
253 /// If this flag is used, the advance() method does not automatically pop 295 /// If this flag is used, the advance() method does not automatically pop
254 /// the block scope when the end of a block is reached. 296 /// the block scope when the end of a block is reached.
255 AF_DontPopBlockAtEnd = 1, 297 AF_DontPopBlockAtEnd = 1,
256 298
257 /// If this flag is used, abbrev entries are returned just like normal 299 /// If this flag is used, abbrev entries are returned just like normal
258 /// records. 300 /// records.
259 AF_DontAutoprocessAbbrevs = 2 301 AF_DontAutoprocessAbbrevs = 2
260 }; 302 };
261 303
262 /// Advance the current bitstream, returning the next entry in the stream. 304 /// Advance the current bitstream, returning the next entry in the stream.
263 BitstreamEntry advance(unsigned Flags = 0) { 305 /// Use the given abbreviation listener (if provided).
306 NaClBitstreamEntry advance(unsigned Flags, NaClAbbrevListener *Listener) {
264 while (1) { 307 while (1) {
265 unsigned Code = ReadCode(); 308 unsigned Code = ReadCode();
266 if (Code == bitc::END_BLOCK) { 309 if (Code == naclbitc::END_BLOCK) {
267 // Pop the end of the block unless Flags tells us not to. 310 // Pop the end of the block unless Flags tells us not to.
268 if (!(Flags & AF_DontPopBlockAtEnd) && ReadBlockEnd()) 311 if (!(Flags & AF_DontPopBlockAtEnd) && ReadBlockEnd())
269 return BitstreamEntry::getError(); 312 return NaClBitstreamEntry::getError();
270 return BitstreamEntry::getEndBlock(); 313 return NaClBitstreamEntry::getEndBlock();
271 } 314 }
272 315
273 if (Code == bitc::ENTER_SUBBLOCK) 316 if (Code == naclbitc::ENTER_SUBBLOCK)
274 return BitstreamEntry::getSubBlock(ReadSubBlockID()); 317 return NaClBitstreamEntry::getSubBlock(ReadSubBlockID());
275 318
276 if (Code == bitc::DEFINE_ABBREV && 319 if (Code == naclbitc::DEFINE_ABBREV &&
277 !(Flags & AF_DontAutoprocessAbbrevs)) { 320 !(Flags & AF_DontAutoprocessAbbrevs)) {
278 // We read and accumulate abbrev's, the client can't do anything with 321 // We read and accumulate abbrev's, the client can't do anything with
279 // them anyway. 322 // them anyway.
280 ReadAbbrevRecord(); 323 ReadAbbrevRecord(true, Listener);
281 continue; 324 continue;
282 } 325 }
283 326
284 return BitstreamEntry::getRecord(Code); 327 return NaClBitstreamEntry::getRecord(Code);
285 } 328 }
286 } 329 }
287 330
288 /// This is a convenience function for clients that don't expect any 331 /// This is a convenience function for clients that don't expect any
289 /// subblocks. This just skips over them automatically. 332 /// subblocks. This just skips over them automatically.
290 BitstreamEntry advanceSkippingSubblocks(unsigned Flags = 0) { 333 NaClBitstreamEntry advanceSkippingSubblocks(unsigned Flags = 0) {
291 while (1) { 334 while (1) {
292 // If we found a normal entry, return it. 335 // If we found a normal entry, return it.
293 BitstreamEntry Entry = advance(Flags); 336 NaClBitstreamEntry Entry = advance(Flags, 0);
294 if (Entry.Kind != BitstreamEntry::SubBlock) 337 if (Entry.Kind != NaClBitstreamEntry::SubBlock)
295 return Entry; 338 return Entry;
296 339
297 // If we found a sub-block, just skip over it and check the next entry. 340 // If we found a sub-block, just skip over it and check the next entry.
298 if (SkipBlock()) 341 if (SkipBlock())
299 return BitstreamEntry::getError(); 342 return NaClBitstreamEntry::getError();
300 } 343 }
301 } 344 }
302 345
303 /// Reset the stream to the specified bit number. 346 /// Reset the stream to the specified bit number.
304 void JumpToBit(uint64_t BitNo) { 347 void JumpToBit(uint64_t BitNo) {
305 uintptr_t ByteNo = uintptr_t(BitNo/8) & ~(sizeof(word_t)-1); 348 uintptr_t ByteNo = uintptr_t(BitNo/8) & ~(sizeof(word_t)-1);
306 unsigned WordBitNo = unsigned(BitNo & (sizeof(word_t)*8-1)); 349 unsigned WordBitNo = unsigned(BitNo & (sizeof(word_t)*8-1));
307 assert(canSkipToPos(ByteNo) && "Invalid location"); 350 assert(canSkipToPos(ByteNo) && "Invalid location");
308 351
309 // Move the cursor to the right word. 352 // Move the cursor to the right word.
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 CurWord >>= BitsInCurWord-32; 467 CurWord >>= BitsInCurWord-32;
425 BitsInCurWord = 32; 468 BitsInCurWord = 32;
426 return; 469 return;
427 } 470 }
428 471
429 BitsInCurWord = 0; 472 BitsInCurWord = 0;
430 } 473 }
431 public: 474 public:
432 475
433 unsigned ReadCode() { 476 unsigned ReadCode() {
434 return Read(CurCodeSize); 477 return CurCodeSize.IsFixed
478 ? Read(CurCodeSize.NumBits)
479 : ReadVBR(CurCodeSize.NumBits);
435 } 480 }
436 481
437
438 // Block header: 482 // Block header:
439 // [ENTER_SUBBLOCK, blockid, newcodelen, <align4bytes>, blocklen] 483 // [ENTER_SUBBLOCK, blockid, newcodelen, <align4bytes>, blocklen]
440 484
441 /// Having read the ENTER_SUBBLOCK code, read the BlockID for the block. 485 /// Having read the ENTER_SUBBLOCK code, read the BlockID for the block.
442 unsigned ReadSubBlockID() { 486 unsigned ReadSubBlockID() {
443 return ReadVBR(bitc::BlockIDWidth); 487 return ReadVBR(naclbitc::BlockIDWidth);
444 } 488 }
445 489
446 /// Having read the ENTER_SUBBLOCK abbrevid and a BlockID, skip over the body 490 /// Having read the ENTER_SUBBLOCK abbrevid and a BlockID, skip over the body
447 /// of this block. If the block record is malformed, return true. 491 /// of this block. If the block record is malformed, return true.
448 bool SkipBlock() { 492 bool SkipBlock() {
449 // Read and ignore the codelen value. Since we are skipping this block, we 493 // Read and ignore the codelen value. Since we are skipping this block, we
450 // don't care what code widths are used inside of it. 494 // don't care what code widths are used inside of it.
451 ReadVBR(bitc::CodeLenWidth); 495 ReadVBR(naclbitc::CodeLenWidth);
452 SkipToFourByteBoundary(); 496 SkipToFourByteBoundary();
453 unsigned NumFourBytes = Read(bitc::BlockSizeWidth); 497 unsigned NumFourBytes = Read(naclbitc::BlockSizeWidth);
454 498
455 // Check that the block wasn't partially defined, and that the offset isn't 499 // Check that the block wasn't partially defined, and that the offset isn't
456 // bogus. 500 // bogus.
457 size_t SkipTo = GetCurrentBitNo() + NumFourBytes*4*8; 501 size_t SkipTo = GetCurrentBitNo() + NumFourBytes*4*8;
458 if (AtEndOfStream() || !canSkipToPos(SkipTo/8)) 502 if (AtEndOfStream() || !canSkipToPos(SkipTo/8))
459 return true; 503 return true;
460 504
461 JumpToBit(SkipTo); 505 JumpToBit(SkipTo);
462 return false; 506 return false;
463 } 507 }
(...skipping 11 matching lines...) Expand all
475 519
476 popBlockScope(); 520 popBlockScope();
477 return false; 521 return false;
478 } 522 }
479 523
480 private: 524 private:
481 525
482 void popBlockScope() { 526 void popBlockScope() {
483 CurCodeSize = BlockScope.back().PrevCodeSize; 527 CurCodeSize = BlockScope.back().PrevCodeSize;
484 528
485 CurAbbrevs = std::move(BlockScope.back().PrevAbbrevs); 529 // Delete abbrevs from popped scope.
530 for (unsigned i = 0, e = static_cast<unsigned>(CurAbbrevs.size());
531 i != e; ++i)
532 CurAbbrevs[i]->dropRef();
533
534 BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
486 BlockScope.pop_back(); 535 BlockScope.pop_back();
487 } 536 }
488 537
489 //===--------------------------------------------------------------------===// 538 //===--------------------------------------------------------------------===//
490 // Record Processing 539 // Record Processing
491 //===--------------------------------------------------------------------===// 540 //===--------------------------------------------------------------------===//
492 541
542 private:
543 void skipAbbreviatedField(const NaClBitCodeAbbrevOp &Op);
544
545 // Reads the next Value using the abbreviation Op. Returns true only
546 // if Op is an array (and sets Value to the number of elements in the
547 // array).
548 inline bool readRecordAbbrevField(const NaClBitCodeAbbrevOp &Op,
549 uint64_t &Value);
550
551 // Reads and returns the next value using the abbreviation Op,
552 // assuming Op appears after an array abbreviation.
553 inline uint64_t readArrayAbbreviatedField(const NaClBitCodeAbbrevOp &Op);
554
555 // Reads the array abbreviation Op, NumArrayElements times, putting
556 // the read values in Vals.
557 inline void readArrayAbbrev(const NaClBitCodeAbbrevOp &Op,
558 unsigned NumArrayElements,
559 SmallVectorImpl<uint64_t> &Vals);
560
493 public: 561 public:
494 562
495 /// Return the abbreviation for the specified AbbrevId. 563 /// Return the abbreviation for the specified AbbrevId.
496 const BitCodeAbbrev *getAbbrev(unsigned AbbrevID) { 564 const NaClBitCodeAbbrev *getAbbrev(unsigned AbbrevID) const {
497 unsigned AbbrevNo = AbbrevID-bitc::FIRST_APPLICATION_ABBREV; 565 unsigned AbbrevNo = AbbrevID-naclbitc::FIRST_APPLICATION_ABBREV;
498 assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!"); 566 assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!");
499 return CurAbbrevs[AbbrevNo].get(); 567 return CurAbbrevs[AbbrevNo];
500 } 568 }
501 569
502 /// Read the current record and discard it. 570 /// Read the current record and discard it.
503 void skipRecord(unsigned AbbrevID); 571 void skipRecord(unsigned AbbrevID);
504 572
505 unsigned readRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals, 573 unsigned readRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals);
506 StringRef *Blob = nullptr);
507 574
508 //===--------------------------------------------------------------------===// 575 //===--------------------------------------------------------------------===//
509 // Abbrev Processing 576 // Abbrev Processing
510 //===--------------------------------------------------------------------===// 577 //===--------------------------------------------------------------------===//
511 void ReadAbbrevRecord(); 578 // IsLocal indicates where the abbreviation occurs. If it is in the
579 // BlockInfo block, IsLocal is false. In all other cases, IsLocal is
580 // true.
581 void ReadAbbrevRecord(bool IsLocal,
582 NaClAbbrevListener *Listener);
512 583
513 bool ReadBlockInfoBlock(); 584 // Skips over an abbreviation record. Duplicates code of ReadAbbrevRecord,
585 // except that no abbreviation is built.
586 void SkipAbbrevRecord();
587
588 bool ReadBlockInfoBlock(NaClAbbrevListener *Listener);
514 }; 589 };
515 590
516 } // End llvm namespace 591 } // End llvm namespace
517 592
518 #endif 593 #endif
OLDNEW
« no previous file with comments | « include/llvm/Bitcode/NaCl/NaClBitcodeWriterPass.h ('k') | include/llvm/Bitcode/NaCl/NaClBitstreamWriter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698