1 //===- BitstreamReaderTest.cpp - Tests for BitstreamReader ----------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/Bitcode/BitstreamReader.h"
12 #include "llvm/Bitcode/BitstreamWriter.h"
13 #include "llvm/Support/StreamingMemoryObject.h"
14 #include "gtest/gtest.h"
15
16 using namespace llvm;
17
18 namespace {
19
20 class BufferStreamer : public DataStreamer {
21 StringRef Buffer;
22
23 public:
BufferStreamer(StringRef Buffer)24 BufferStreamer(StringRef Buffer) : Buffer(Buffer) {}
GetBytes(unsigned char * OutBuffer,size_t Length)25 size_t GetBytes(unsigned char *OutBuffer, size_t Length) override {
26 if (Length >= Buffer.size())
27 Length = Buffer.size();
28
29 std::copy(Buffer.begin(), Buffer.begin() + Length, OutBuffer);
30 Buffer = Buffer.drop_front(Length);
31 return Length;
32 }
33 };
34
TEST(BitstreamReaderTest,AtEndOfStream)35 TEST(BitstreamReaderTest, AtEndOfStream) {
36 uint8_t Bytes[4] = {
37 0x00, 0x01, 0x02, 0x03
38 };
39 BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
40 BitstreamCursor Cursor(Reader);
41
42 EXPECT_FALSE(Cursor.AtEndOfStream());
43 (void)Cursor.Read(8);
44 EXPECT_FALSE(Cursor.AtEndOfStream());
45 (void)Cursor.Read(24);
46 EXPECT_TRUE(Cursor.AtEndOfStream());
47
48 Cursor.JumpToBit(0);
49 EXPECT_FALSE(Cursor.AtEndOfStream());
50
51 Cursor.JumpToBit(32);
52 EXPECT_TRUE(Cursor.AtEndOfStream());
53 }
54
TEST(BitstreamReaderTest,AtEndOfStreamJump)55 TEST(BitstreamReaderTest, AtEndOfStreamJump) {
56 uint8_t Bytes[4] = {
57 0x00, 0x01, 0x02, 0x03
58 };
59 BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
60 BitstreamCursor Cursor(Reader);
61
62 Cursor.JumpToBit(32);
63 EXPECT_TRUE(Cursor.AtEndOfStream());
64 }
65
TEST(BitstreamReaderTest,AtEndOfStreamEmpty)66 TEST(BitstreamReaderTest, AtEndOfStreamEmpty) {
67 uint8_t Dummy = 0xFF;
68 BitstreamReader Reader(&Dummy, &Dummy);
69 BitstreamCursor Cursor(Reader);
70
71 EXPECT_TRUE(Cursor.AtEndOfStream());
72 }
73
TEST(BitstreamReaderTest,getCurrentByteNo)74 TEST(BitstreamReaderTest, getCurrentByteNo) {
75 uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03};
76 BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
77 SimpleBitstreamCursor Cursor(Reader);
78
79 for (unsigned I = 0, E = 33; I != E; ++I) {
80 EXPECT_EQ(I / 8, Cursor.getCurrentByteNo());
81 (void)Cursor.Read(1);
82 }
83 EXPECT_EQ(4u, Cursor.getCurrentByteNo());
84 }
85
TEST(BitstreamReaderTest,getPointerToByte)86 TEST(BitstreamReaderTest, getPointerToByte) {
87 uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
88 BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
89 SimpleBitstreamCursor Cursor(Reader);
90
91 for (unsigned I = 0, E = 8; I != E; ++I) {
92 EXPECT_EQ(Bytes + I, Cursor.getPointerToByte(I, 1));
93 }
94 }
95
TEST(BitstreamReaderTest,getPointerToBit)96 TEST(BitstreamReaderTest, getPointerToBit) {
97 uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
98 BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
99 SimpleBitstreamCursor Cursor(Reader);
100
101 for (unsigned I = 0, E = 8; I != E; ++I) {
102 EXPECT_EQ(Bytes + I, Cursor.getPointerToBit(I * 8, 1));
103 }
104 }
105
TEST(BitstreamReaderTest,jumpToPointer)106 TEST(BitstreamReaderTest, jumpToPointer) {
107 uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
108 BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
109 SimpleBitstreamCursor Cursor(Reader);
110
111 for (unsigned I : {0, 6, 2, 7}) {
112 Cursor.jumpToPointer(Bytes + I);
113 EXPECT_EQ(I, Cursor.getCurrentByteNo());
114 }
115 }
116
TEST(BitstreamReaderTest,setArtificialByteLimit)117 TEST(BitstreamReaderTest, setArtificialByteLimit) {
118 uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
119 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
120 BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
121 SimpleBitstreamCursor Cursor(Reader);
122
123 Cursor.setArtificialByteLimit(8);
124 EXPECT_EQ(8u, Cursor.getSizeIfKnown());
125 while (!Cursor.AtEndOfStream())
126 (void)Cursor.Read(1);
127
128 EXPECT_EQ(8u, Cursor.getCurrentByteNo());
129 }
130
TEST(BitstreamReaderTest,setArtificialByteLimitNotWordBoundary)131 TEST(BitstreamReaderTest, setArtificialByteLimitNotWordBoundary) {
132 uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
133 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
134 BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
135 SimpleBitstreamCursor Cursor(Reader);
136
137 Cursor.setArtificialByteLimit(5);
138 EXPECT_EQ(8u, Cursor.getSizeIfKnown());
139 while (!Cursor.AtEndOfStream())
140 (void)Cursor.Read(1);
141
142 EXPECT_EQ(8u, Cursor.getCurrentByteNo());
143 }
144
TEST(BitstreamReaderTest,setArtificialByteLimitPastTheEnd)145 TEST(BitstreamReaderTest, setArtificialByteLimitPastTheEnd) {
146 uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
147 0x08, 0x09, 0x0a, 0x0b};
148 BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
149 SimpleBitstreamCursor Cursor(Reader);
150
151 // The size of the memory object isn't known yet. Set it too high and
152 // confirm that we don't read too far.
153 Cursor.setArtificialByteLimit(24);
154 EXPECT_EQ(24u, Cursor.getSizeIfKnown());
155 while (!Cursor.AtEndOfStream())
156 (void)Cursor.Read(1);
157
158 EXPECT_EQ(12u, Cursor.getCurrentByteNo());
159 EXPECT_EQ(12u, Cursor.getSizeIfKnown());
160 }
161
TEST(BitstreamReaderTest,setArtificialByteLimitPastTheEndKnown)162 TEST(BitstreamReaderTest, setArtificialByteLimitPastTheEndKnown) {
163 uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
164 0x08, 0x09, 0x0a, 0x0b};
165 BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
166 SimpleBitstreamCursor Cursor(Reader);
167
168 // Save the size of the memory object in the cursor.
169 while (!Cursor.AtEndOfStream())
170 (void)Cursor.Read(1);
171 EXPECT_EQ(12u, Cursor.getCurrentByteNo());
172 EXPECT_EQ(12u, Cursor.getSizeIfKnown());
173
174 Cursor.setArtificialByteLimit(20);
175 EXPECT_TRUE(Cursor.AtEndOfStream());
176 EXPECT_EQ(12u, Cursor.getSizeIfKnown());
177 }
178
TEST(BitstreamReaderTest,readRecordWithBlobWhileStreaming)179 TEST(BitstreamReaderTest, readRecordWithBlobWhileStreaming) {
180 SmallVector<uint8_t, 1> BlobData;
181 for (unsigned I = 0, E = 1024; I != E; ++I)
182 BlobData.push_back(I);
183
184 // Try a bunch of different sizes.
185 const unsigned Magic = 0x12345678;
186 const unsigned BlockID = bitc::FIRST_APPLICATION_BLOCKID;
187 const unsigned RecordID = 1;
188 for (unsigned I = 0, BlobSize = 0, E = BlobData.size(); BlobSize < E;
189 BlobSize += ++I) {
190 StringRef BlobIn((const char *)BlobData.begin(), BlobSize);
191
192 // Write the bitcode.
193 SmallVector<char, 1> Buffer;
194 unsigned AbbrevID;
195 {
196 BitstreamWriter Stream(Buffer);
197 Stream.Emit(Magic, 32);
198 Stream.EnterSubblock(BlockID, 3);
199
200 BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
201 Abbrev->Add(BitCodeAbbrevOp(RecordID));
202 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
203 AbbrevID = Stream.EmitAbbrev(Abbrev);
204 unsigned Record[] = {RecordID};
205 Stream.EmitRecordWithBlob(AbbrevID, makeArrayRef(Record), BlobIn);
206
207 Stream.ExitBlock();
208 }
209
210 // Stream the buffer into the reader.
211 BitstreamReader R(llvm::make_unique<StreamingMemoryObject>(
212 llvm::make_unique<BufferStreamer>(
213 StringRef(Buffer.begin(), Buffer.size()))));
214 BitstreamCursor Stream(R);
215
216 // Header. Included in test so that we can run llvm-bcanalyzer to debug
217 // when there are problems.
218 ASSERT_EQ(Magic, Stream.Read(32));
219
220 // Block.
221 BitstreamEntry Entry =
222 Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs);
223 ASSERT_EQ(BitstreamEntry::SubBlock, Entry.Kind);
224 ASSERT_EQ(BlockID, Entry.ID);
225 ASSERT_FALSE(Stream.EnterSubBlock(BlockID));
226
227 // Abbreviation.
228 Entry = Stream.advance();
229 ASSERT_EQ(BitstreamEntry::Record, Entry.Kind);
230 ASSERT_EQ(AbbrevID, Entry.ID);
231
232 // Record.
233 StringRef BlobOut;
234 SmallVector<uint64_t, 1> Record;
235 ASSERT_EQ(RecordID, Stream.readRecord(Entry.ID, Record, &BlobOut));
236 EXPECT_TRUE(Record.empty());
237 EXPECT_EQ(BlobIn, BlobOut);
238 }
239 }
240
241 } // end anonymous namespace
242