X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FBitcode%2FBitstreamReader.h;h=eac9ab0b607ad82f5bdbca5cc4e4e6c5dd3d25e6;hb=a727d5502c8e23c090da658bf14c5ebc1169a070;hp=f41c4f0ec3b91ef3b31ffc4efa2dcc3f27ea2a90;hpb=bd40a6d3ee9658f9bfd6ab74893fca5fa75c6de0;p=oota-llvm.git diff --git a/include/llvm/Bitcode/BitstreamReader.h b/include/llvm/Bitcode/BitstreamReader.h index f41c4f0ec3b..eac9ab0b607 100644 --- a/include/llvm/Bitcode/BitstreamReader.h +++ b/include/llvm/Bitcode/BitstreamReader.h @@ -48,9 +48,23 @@ class BitstreamReader { /// BlockScope - This tracks the codesize of parent blocks. SmallVector BlockScope; + /// FirstChar - This remembers the first byte of the stream. + const unsigned char *FirstChar; public: - BitstreamReader(const unsigned char *Start, const unsigned char *End) - : NextChar(Start), LastChar(End) { + BitstreamReader() { + NextChar = FirstChar = LastChar = 0; + CurWord = 0; + BitsInCurWord = 0; + CurCodeSize = 0; + } + + BitstreamReader(const unsigned char *Start, const unsigned char *End) { + init(Start, End); + } + + void init(const unsigned char *Start, const unsigned char *End) { + NextChar = FirstChar = Start; + LastChar = End; assert(((End-Start) & 3) == 0 &&"Bitcode stream not a multiple of 4 bytes"); CurWord = 0; BitsInCurWord = 0; @@ -61,12 +75,12 @@ public: // Abbrevs could still exist if the stream was broken. If so, don't leak // them. for (unsigned i = 0, e = CurAbbrevs.size(); i != e; ++i) - delete CurAbbrevs[i]; + CurAbbrevs[i]->dropRef(); for (unsigned S = 0, e = BlockScope.size(); S != e; ++S) { std::vector &Abbrevs = BlockScope[S].PrevAbbrevs; for (unsigned i = 0, e = Abbrevs.size(); i != e; ++i) - delete Abbrevs[i]; + Abbrevs[i]->dropRef(); } } @@ -74,9 +88,28 @@ public: /// GetCurrentBitNo - Return the bit # of the bit we are reading. uint64_t GetCurrentBitNo() const { - return CurWord * 32ULL + (32-CurCodeSize); + return (NextChar-FirstChar)*8 + (32-BitsInCurWord); + } + + /// JumpToBit - Reset the stream to the specified bit number. + void JumpToBit(uint64_t BitNo) { + unsigned ByteNo = (BitNo/8) & ~3; + unsigned WordBitNo = BitNo & 31; + assert(ByteNo < (unsigned)(LastChar-FirstChar) && "Invalid location"); + + // Move the cursor to the right word. + NextChar = FirstChar+ByteNo; + BitsInCurWord = 0; + + // Skip over any bits that are already consumed. + if (WordBitNo) { + NextChar -= 4; + Read(WordBitNo); + } } + /// GetAbbrevIDWidth - Return the number of bits used to encode an abbrev #. + unsigned GetAbbrevIDWidth() const { return CurCodeSize; } uint32_t Read(unsigned NumBits) { // If the field is fully contained by CurWord, return it quickly. @@ -203,7 +236,7 @@ public: /// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, read and enter /// the block, returning the BlockID of the block we just entered. - bool EnterSubBlock() { + bool EnterSubBlock(unsigned *NumWordsP = 0) { BlockScope.push_back(Block(CurCodeSize)); BlockScope.back().PrevAbbrevs.swap(CurAbbrevs); @@ -211,6 +244,7 @@ public: CurCodeSize = ReadVBR(bitc::CodeLenWidth); SkipToWord(); unsigned NumWords = Read(bitc::BlockSizeWidth); + if (NumWordsP) *NumWordsP = NumWords; // Validate that this block is sane. if (CurCodeSize == 0 || AtEndOfStream() || NextChar+NumWords*4 > LastChar) @@ -229,7 +263,7 @@ public: // Delete abbrevs from popped scope. for (unsigned i = 0, e = CurAbbrevs.size(); i != e; ++i) - delete CurAbbrevs[i]; + CurAbbrevs[i]->dropRef(); BlockScope.back().PrevAbbrevs.swap(CurAbbrevs); BlockScope.pop_back(); @@ -249,7 +283,7 @@ public: return Code; } - unsigned AbbrevNo = AbbrevID-bitc::FIRST_ABBREV; + unsigned AbbrevNo = AbbrevID-bitc::FIRST_APPLICATION_ABBREV; assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!"); BitCodeAbbrev *Abbv = CurAbbrevs[AbbrevNo];