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

Unified Diff: include/llvm/Bitcode/NaCl/NaClBitstreamReader.h

Issue 940243003: PNaCl localmod mods in LLVM to 223109 (local files only) (Closed)
Patch Set: 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 side-by-side diff with in-line comments
Download patch
Index: include/llvm/Bitcode/NaCl/NaClBitstreamReader.h
diff --git a/include/llvm/Bitcode/NaCl/NaClBitstreamReader.h b/include/llvm/Bitcode/NaCl/NaClBitstreamReader.h
index 97e216441939906f33f1c2d1f48585005bf51e8f..d56018d065421ec82f69fae5001aafd7275343e8 100644
--- a/include/llvm/Bitcode/NaCl/NaClBitstreamReader.h
+++ b/include/llvm/Bitcode/NaCl/NaClBitstreamReader.h
@@ -19,13 +19,13 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/Bitcode/NaCl/NaClLLVMBitCodes.h"
#include "llvm/Support/Endian.h"
-#include "llvm/Support/StreamableMemoryObject.h"
+#include "llvm/Support/StreamingMemoryObject.h"
#include <climits>
#include <vector>
namespace llvm {
- class Deserializer;
+class Deserializer;
/// NaClBitstreamReader - This class is used to read from a NaCl
/// bitcode wire format stream, maintaining information that is global
@@ -41,7 +41,7 @@ public:
std::vector<NaClBitCodeAbbrev*> Abbrevs;
};
private:
- std::unique_ptr<StreamableMemoryObject> BitcodeBytes;
+ std::unique_ptr<MemoryObject> BitcodeBytes;
std::vector<BlockInfo> BlockInfoRecords;
@@ -59,10 +59,8 @@ public:
init(Start, End);
}
- NaClBitstreamReader(StreamableMemoryObject *Bytes,
- size_t MyInitialAddress=0)
- : InitialAddress(MyInitialAddress)
- {
+ NaClBitstreamReader(MemoryObject *Bytes, size_t MyInitialAddress=0)
+ : InitialAddress(MyInitialAddress) {
BitcodeBytes.reset(Bytes);
}
@@ -71,7 +69,7 @@ public:
BitcodeBytes.reset(getNonStreamedMemoryObject(Start, End));
}
- StreamableMemoryObject &getBitcodeBytes() { return *BitcodeBytes; }
+ MemoryObject &getBitcodeBytes() { return *BitcodeBytes; }
~NaClBitstreamReader() {
// Free the BlockInfoRecords.
@@ -124,7 +122,7 @@ public:
}
};
-
+
/// NaClBitstreamEntry - When advancing through a bitstream cursor,
/// each advance can discover a few different kinds of entries:
/// Error - Malformed bitcode was found.
@@ -140,7 +138,7 @@ struct NaClBitstreamEntry {
SubBlock,
Record
} Kind;
-
+
unsigned ID;
static NaClBitstreamEntry getError() {
@@ -213,6 +211,9 @@ class NaClBitstreamCursor {
NaClBitstreamReader *BitStream;
size_t NextChar;
+ // The size of the bitcode. 0 if we don't know it yet.
+ size_t Size;
+
/// CurWord/word_t - This is the current data we have pulled from the stream
/// but have not returned to the client. This is specifically and
/// intentionally defined to follow the word size of the host machine for
@@ -235,7 +236,7 @@ class NaClBitstreamCursor {
struct Block {
NaClBitcodeSelectorAbbrev PrevCodeSize;
std::vector<NaClBitCodeAbbrev*> PrevAbbrevs;
- explicit Block() : PrevCodeSize() {}
+ Block() : PrevCodeSize() {}
explicit Block(const NaClBitcodeSelectorAbbrev& PCS)
: PrevCodeSize(PCS) {}
};
@@ -247,7 +248,6 @@ class NaClBitstreamCursor {
NaClBitstreamCursor &operator=(const NaClBitstreamCursor &) LLVM_DELETED_FUNCTION;
public:
-
NaClBitstreamCursor() {
init(nullptr);
}
@@ -258,7 +258,7 @@ public:
freeState();
BitStream = R;
NextChar = (BitStream == nullptr) ? 0 : BitStream->getInitialAddress();
- CurWord = 0;
+ Size = 0;
BitsInCurWord = 0;
}
@@ -268,10 +268,6 @@ public:
void freeState();
- bool isEndPos(size_t pos) {
- return BitStream->getBitcodeBytes().isObjectEnd(static_cast<uint64_t>(pos));
- }
-
bool canSkipToPos(size_t pos) const {
// pos can be skipped to if it is a valid address or one byte past the end.
return pos == 0 || BitStream->getBitcodeBytes().isValidAddress(
@@ -279,7 +275,12 @@ public:
}
bool AtEndOfStream() {
- return BitsInCurWord == 0 && isEndPos(NextChar);
+ if (BitsInCurWord != 0)
+ return false;
+ if (Size != 0 && Size == NextChar)
+ return true;
+ fillCurWord();
+ return BitsInCurWord == 0;
}
/// getAbbrevIDWidth - Return the number of bits used to encode an abbrev #.
@@ -308,7 +309,7 @@ public:
/// returned just like normal records.
AF_DontAutoprocessAbbrevs = 2
};
-
+
/// advance - Advance the current bitstream, returning the next entry in the
/// stream. Use the given abbreviation listener (if provided).
NaClBitstreamEntry advance(unsigned Flags, NaClAbbrevListener *Listener) {
@@ -320,10 +321,10 @@ public:
return NaClBitstreamEntry::getError();
return NaClBitstreamEntry::getEndBlock();
}
-
+
if (Code == naclbitc::ENTER_SUBBLOCK)
return NaClBitstreamEntry::getSubBlock(ReadSubBlockID());
-
+
if (Code == naclbitc::DEFINE_ABBREV &&
!(Flags & AF_DontAutoprocessAbbrevs)) {
// We read and accumulate abbrev's, the client can't do anything with
@@ -344,7 +345,7 @@ public:
NaClBitstreamEntry Entry = advance(Flags, 0);
if (Entry.Kind != NaClBitstreamEntry::SubBlock)
return Entry;
-
+
// If we found a sub-block, just skip over it and check the next entry.
if (SkipBlock())
return NaClBitstreamEntry::getError();
@@ -360,7 +361,6 @@ public:
// Move the cursor to the right word.
NextChar = ByteNo;
BitsInCurWord = 0;
- CurWord = 0;
// Skip over any bits that are already consumed.
if (WordBitNo) {
@@ -371,55 +371,65 @@ public:
}
}
+ void fillCurWord() {
+ assert(Size == 0 || NextChar < (unsigned)Size);
+
+ // Read the next word from the stream.
+ uint8_t Array[sizeof(word_t)] = {0};
+
+ uint64_t BytesRead =
+ BitStream->getBitcodeBytes().readBytes(Array, sizeof(Array), NextChar);
+
+ // If we run out of data, stop at the end of the stream.
+ if (BytesRead == 0) {
+ Size = NextChar;
+ return;
+ }
+ assert(BytesRead == sizeof(Array));
Karl 2015/02/20 17:07:02 Should this be an assert (i.e. has the length been
jvoung (off chromium) 2015/02/20 17:38:21 Hmm looks like the assert is gone in the new Bitst
+
+ // Handle big-endian byte-swapping if necessary.
+ support::detail::packed_endian_specific_integral<
+ word_t, support::little, support::unaligned> EndianValue;
+ memcpy(&EndianValue, Array, sizeof(Array));
+
+ CurWord = EndianValue;
+ NextChar += sizeof(word_t);
+ BitsInCurWord = sizeof(word_t) * 8;
+ }
+
uint32_t Read(unsigned NumBits) {
assert(NumBits && NumBits <= 32 &&
"Cannot return zero or more than 32 bits!");
-
+
// If the field is fully contained by CurWord, return it quickly.
if (BitsInCurWord >= NumBits) {
uint32_t R = uint32_t(CurWord) & (~0U >> (32-NumBits));
- CurWord >>= NumBits;
+
+ // Use a mask to avoid undefined behavior.
+ CurWord >>= (NumBits & 0x1f);
Karl 2015/02/20 17:07:02 Is the mask necessary? Doesn't the assert above gu
jvoung (off chromium) 2015/02/20 17:38:21 Yes, in case asserts are turned off. Otherwise it
+
BitsInCurWord -= NumBits;
return R;
}
+ uint32_t R = BitsInCurWord ? uint32_t(CurWord) : 0;
+ unsigned BitsLeft = NumBits - BitsInCurWord;
+
+ fillCurWord();
+
// If we run out of data, stop at the end of the stream.
- if (isEndPos(NextChar)) {
- CurWord = 0;
- BitsInCurWord = 0;
+ if (BitsLeft > BitsInCurWord)
return 0;
- }
- uint32_t R = uint32_t(CurWord);
+ uint32_t R2 = uint32_t(CurWord) & (~0U >> (sizeof(word_t) * 8 - BitsLeft));
- // Read the next word from the stream.
- uint8_t Array[sizeof(word_t)] = {0};
-
- BitStream->getBitcodeBytes().readBytes(NextChar, sizeof(Array), Array);
-
- // Handle big-endian byte-swapping if necessary.
- support::detail::packed_endian_specific_integral
- <word_t, support::little, support::unaligned> EndianValue;
- memcpy(&EndianValue, Array, sizeof(Array));
-
- CurWord = EndianValue;
+ // Use a mask to avoid undefined behavior.
+ CurWord >>= (BitsLeft & 0x1f);
- NextChar += sizeof(word_t);
-
- // Extract NumBits-BitsInCurWord from what we just read.
- unsigned BitsLeft = NumBits-BitsInCurWord;
+ BitsInCurWord -= BitsLeft;
- // Be careful here, BitsLeft is in the range [1..32]/[1..64] inclusive.
- R |= uint32_t((CurWord & (word_t(~0ULL) >> (sizeof(word_t)*8-BitsLeft)))
- << BitsInCurWord);
+ R |= uint32_t(R2 << (NumBits - BitsLeft));
- // BitsLeft bits have just been used up from CurWord. BitsLeft is in the
- // range [1..32]/[1..64] so be careful how we shift.
- if (BitsLeft != sizeof(word_t)*8)
- CurWord >>= BitsLeft;
- else
- CurWord = 0;
- BitsInCurWord = sizeof(word_t)*8-BitsLeft;
return R;
}
@@ -478,9 +488,8 @@ private:
BitsInCurWord = 32;
return;
}
-
+
BitsInCurWord = 0;
- CurWord = 0;
}
public:
@@ -522,7 +531,7 @@ public:
/// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter
/// the block, and return true if the block has an error.
bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = 0);
-
+
bool ReadBlockEnd() {
if (BlockScope.empty()) return true;

Powered by Google App Engine
This is Rietveld 408576698