[llvm] r264547 - Bitcode: Add SimpleBitstreamCursor::setArtificialByteLimit

Duncan P. N. Exon Smith via llvm-commits llvm-commits at lists.llvm.org
Sun Mar 27 15:49:32 PDT 2016


Author: dexonsmith
Date: Sun Mar 27 17:49:32 2016
New Revision: 264547

URL: http://llvm.org/viewvc/llvm-project?rev=264547&view=rev
Log:
Bitcode: Add SimpleBitstreamCursor::setArtificialByteLimit

Allow users of SimpleBitstreamCursor to limit the number of bytes
available to the cursor.  This is preparation for instantiating a cursor
that isn't allowed to load more bytes from a StreamingMemoryObject (just
move around the ones already-loaded).

Modified:
    llvm/trunk/include/llvm/Bitcode/BitstreamReader.h
    llvm/trunk/unittests/Bitcode/BitstreamReaderTest.cpp

Modified: llvm/trunk/include/llvm/Bitcode/BitstreamReader.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/BitstreamReader.h?rev=264547&r1=264546&r2=264547&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Bitcode/BitstreamReader.h (original)
+++ llvm/trunk/include/llvm/Bitcode/BitstreamReader.h Sun Mar 27 17:49:32 2016
@@ -171,7 +171,7 @@ public:
     if (BitsInCurWord != 0)
       return false;
     if (Size != 0)
-      return Size == NextChar;
+      return Size <= NextChar;
     fillCurWord();
     return BitsInCurWord == 0;
   }
@@ -351,6 +351,28 @@ public:
 
   /// Skip to the end of the file.
   void skipToEnd() { NextChar = R->getBitcodeBytes().getExtent(); }
+
+  /// Prevent the cursor from reading past a byte boundary.
+  ///
+  /// Prevent the cursor from requesting byte reads past \c Limit.  This is
+  /// useful when working with a cursor on a StreamingMemoryObject, when it's
+  /// desirable to avoid invalidating the result of getPointerToByte().
+  ///
+  /// If \c Limit is on a word boundary, AtEndOfStream() will return true if
+  /// the cursor position reaches or exceeds \c Limit, regardless of the true
+  /// number of available bytes.  Otherwise, AtEndOfStream() returns true when
+  /// it reaches or exceeds the next word boundary.
+  void setArtificialByteLimit(uint64_t Limit) {
+    assert(getCurrentByteNo() < Limit && "Move cursor before lowering limit");
+
+    // Round to word boundary.
+    if (Limit & (sizeof(word_t) - 1))
+      Limit += sizeof(word_t) - Limit & (sizeof(word_t) - 1);
+
+    // Only change size if the new one is lower.
+    if (!Size || Size > Limit)
+      Size = Limit;
+  }
 };
 
 /// When advancing through a bitstream cursor, each advance can discover a few

Modified: llvm/trunk/unittests/Bitcode/BitstreamReaderTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Bitcode/BitstreamReaderTest.cpp?rev=264547&r1=264546&r2=264547&view=diff
==============================================================================
--- llvm/trunk/unittests/Bitcode/BitstreamReaderTest.cpp (original)
+++ llvm/trunk/unittests/Bitcode/BitstreamReaderTest.cpp Sun Mar 27 17:49:32 2016
@@ -96,4 +96,73 @@ 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);
+  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);
+  while (!Cursor.AtEndOfStream())
+    (void)Cursor.Read(1);
+
+  EXPECT_EQ(8u, Cursor.getCurrentByteNo());
+}
+
+TEST(BitstreamReaderTest, setArtificialByteLimitNot4ByteBoundary) {
+  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);
+  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(20);
+  while (!Cursor.AtEndOfStream())
+    (void)Cursor.Read(1);
+
+  EXPECT_EQ(12u, Cursor.getCurrentByteNo());
+}
+
+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());
+
+  Cursor.setArtificialByteLimit(20);
+  EXPECT_TRUE(Cursor.AtEndOfStream());
+}
+
 } // end anonymous namespace




More information about the llvm-commits mailing list