Bitcode: Change reader interface to take memory buffers.
As proposed on llvm-dev: http://lists.llvm.org/pipermail/llvm-dev/2016-October/106595.html This change also fixes an API oddity where BitstreamCursor::Read() would return zero for the first read past the end of the bitstream, but would report_fatal_error for subsequent reads. Now we always report_fatal_error for all reads past the end. Updated clients to check for the end of the bitstream before reading from it. I also needed to add padding to the invalid bitcode tests in test/Bitcode/. This is because the streaming interface was not checking that the file size is a multiple of 4. Differential Revision: https://reviews.llvm.org/D26219 llvm-svn: 285773
This commit is contained in:
@@ -10,33 +10,17 @@
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/Bitcode/BitstreamReader.h"
|
||||
#include "llvm/Bitcode/BitstreamWriter.h"
|
||||
#include "llvm/Support/StreamingMemoryObject.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
class BufferStreamer : public DataStreamer {
|
||||
StringRef Buffer;
|
||||
|
||||
public:
|
||||
BufferStreamer(StringRef Buffer) : Buffer(Buffer) {}
|
||||
size_t GetBytes(unsigned char *OutBuffer, size_t Length) override {
|
||||
if (Length >= Buffer.size())
|
||||
Length = Buffer.size();
|
||||
|
||||
std::copy(Buffer.begin(), Buffer.begin() + Length, OutBuffer);
|
||||
Buffer = Buffer.drop_front(Length);
|
||||
return Length;
|
||||
}
|
||||
};
|
||||
|
||||
TEST(BitstreamReaderTest, AtEndOfStream) {
|
||||
uint8_t Bytes[4] = {
|
||||
0x00, 0x01, 0x02, 0x03
|
||||
};
|
||||
BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
|
||||
BitstreamReader Reader(Bytes);
|
||||
BitstreamCursor Cursor(Reader);
|
||||
|
||||
EXPECT_FALSE(Cursor.AtEndOfStream());
|
||||
@@ -56,7 +40,7 @@ TEST(BitstreamReaderTest, AtEndOfStreamJump) {
|
||||
uint8_t Bytes[4] = {
|
||||
0x00, 0x01, 0x02, 0x03
|
||||
};
|
||||
BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
|
||||
BitstreamReader Reader(Bytes);
|
||||
BitstreamCursor Cursor(Reader);
|
||||
|
||||
Cursor.JumpToBit(32);
|
||||
@@ -64,8 +48,7 @@ TEST(BitstreamReaderTest, AtEndOfStreamJump) {
|
||||
}
|
||||
|
||||
TEST(BitstreamReaderTest, AtEndOfStreamEmpty) {
|
||||
uint8_t Dummy = 0xFF;
|
||||
BitstreamReader Reader(&Dummy, &Dummy);
|
||||
BitstreamReader Reader(ArrayRef<uint8_t>{});
|
||||
BitstreamCursor Cursor(Reader);
|
||||
|
||||
EXPECT_TRUE(Cursor.AtEndOfStream());
|
||||
@@ -73,10 +56,10 @@ TEST(BitstreamReaderTest, AtEndOfStreamEmpty) {
|
||||
|
||||
TEST(BitstreamReaderTest, getCurrentByteNo) {
|
||||
uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03};
|
||||
BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
|
||||
BitstreamReader Reader(Bytes);
|
||||
SimpleBitstreamCursor Cursor(Reader);
|
||||
|
||||
for (unsigned I = 0, E = 33; I != E; ++I) {
|
||||
for (unsigned I = 0, E = 32; I != E; ++I) {
|
||||
EXPECT_EQ(I / 8, Cursor.getCurrentByteNo());
|
||||
(void)Cursor.Read(1);
|
||||
}
|
||||
@@ -85,7 +68,7 @@ TEST(BitstreamReaderTest, getCurrentByteNo) {
|
||||
|
||||
TEST(BitstreamReaderTest, getPointerToByte) {
|
||||
uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
|
||||
BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
|
||||
BitstreamReader Reader(Bytes);
|
||||
SimpleBitstreamCursor Cursor(Reader);
|
||||
|
||||
for (unsigned I = 0, E = 8; I != E; ++I) {
|
||||
@@ -95,7 +78,7 @@ TEST(BitstreamReaderTest, getPointerToByte) {
|
||||
|
||||
TEST(BitstreamReaderTest, getPointerToBit) {
|
||||
uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
|
||||
BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
|
||||
BitstreamReader Reader(Bytes);
|
||||
SimpleBitstreamCursor Cursor(Reader);
|
||||
|
||||
for (unsigned I = 0, E = 8; I != E; ++I) {
|
||||
@@ -105,7 +88,7 @@ TEST(BitstreamReaderTest, getPointerToBit) {
|
||||
|
||||
TEST(BitstreamReaderTest, jumpToPointer) {
|
||||
uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
|
||||
BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
|
||||
BitstreamReader Reader(Bytes);
|
||||
SimpleBitstreamCursor Cursor(Reader);
|
||||
|
||||
for (unsigned I : {0, 6, 2, 7}) {
|
||||
@@ -114,68 +97,6 @@ TEST(BitstreamReaderTest, jumpToPointer) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(BitstreamReaderTest, setArtificialByteLimit) {
|
||||
uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
|
||||
BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
|
||||
SimpleBitstreamCursor Cursor(Reader);
|
||||
|
||||
Cursor.setArtificialByteLimit(8);
|
||||
EXPECT_EQ(8u, Cursor.getSizeIfKnown());
|
||||
while (!Cursor.AtEndOfStream())
|
||||
(void)Cursor.Read(1);
|
||||
|
||||
EXPECT_EQ(8u, Cursor.getCurrentByteNo());
|
||||
}
|
||||
|
||||
TEST(BitstreamReaderTest, setArtificialByteLimitNotWordBoundary) {
|
||||
uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
|
||||
BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
|
||||
SimpleBitstreamCursor Cursor(Reader);
|
||||
|
||||
Cursor.setArtificialByteLimit(5);
|
||||
EXPECT_EQ(8u, Cursor.getSizeIfKnown());
|
||||
while (!Cursor.AtEndOfStream())
|
||||
(void)Cursor.Read(1);
|
||||
|
||||
EXPECT_EQ(8u, Cursor.getCurrentByteNo());
|
||||
}
|
||||
|
||||
TEST(BitstreamReaderTest, setArtificialByteLimitPastTheEnd) {
|
||||
uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b};
|
||||
BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
|
||||
SimpleBitstreamCursor Cursor(Reader);
|
||||
|
||||
// The size of the memory object isn't known yet. Set it too high and
|
||||
// confirm that we don't read too far.
|
||||
Cursor.setArtificialByteLimit(24);
|
||||
EXPECT_EQ(24u, Cursor.getSizeIfKnown());
|
||||
while (!Cursor.AtEndOfStream())
|
||||
(void)Cursor.Read(1);
|
||||
|
||||
EXPECT_EQ(12u, Cursor.getCurrentByteNo());
|
||||
EXPECT_EQ(12u, Cursor.getSizeIfKnown());
|
||||
}
|
||||
|
||||
TEST(BitstreamReaderTest, setArtificialByteLimitPastTheEndKnown) {
|
||||
uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b};
|
||||
BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
|
||||
SimpleBitstreamCursor Cursor(Reader);
|
||||
|
||||
// Save the size of the memory object in the cursor.
|
||||
while (!Cursor.AtEndOfStream())
|
||||
(void)Cursor.Read(1);
|
||||
EXPECT_EQ(12u, Cursor.getCurrentByteNo());
|
||||
EXPECT_EQ(12u, Cursor.getSizeIfKnown());
|
||||
|
||||
Cursor.setArtificialByteLimit(20);
|
||||
EXPECT_TRUE(Cursor.AtEndOfStream());
|
||||
EXPECT_EQ(12u, Cursor.getSizeIfKnown());
|
||||
}
|
||||
|
||||
TEST(BitstreamReaderTest, readRecordWithBlobWhileStreaming) {
|
||||
SmallVector<uint8_t, 1> BlobData;
|
||||
for (unsigned I = 0, E = 1024; I != E; ++I)
|
||||
@@ -208,9 +129,8 @@ TEST(BitstreamReaderTest, readRecordWithBlobWhileStreaming) {
|
||||
}
|
||||
|
||||
// Stream the buffer into the reader.
|
||||
BitstreamReader R(llvm::make_unique<StreamingMemoryObject>(
|
||||
llvm::make_unique<BufferStreamer>(
|
||||
StringRef(Buffer.begin(), Buffer.size()))));
|
||||
BitstreamReader R(
|
||||
ArrayRef<uint8_t>((const uint8_t *)Buffer.begin(), Buffer.size()));
|
||||
BitstreamCursor Stream(R);
|
||||
|
||||
// Header. Included in test so that we can run llvm-bcanalyzer to debug
|
||||
|
||||
Reference in New Issue
Block a user