• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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