Added preliminary implementation of generic object serialization to bitcode.
authorTed Kremenek <kremenek@apple.com>
Tue, 23 Oct 2007 21:29:33 +0000 (21:29 +0000)
committerTed Kremenek <kremenek@apple.com>
Tue, 23 Oct 2007 21:29:33 +0000 (21:29 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43261 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Bitcode/Serialization.h [new file with mode: 0644]
lib/Bitcode/Reader/Deserialize.cpp [new file with mode: 0644]
lib/Bitcode/Writer/Serialize.cpp [new file with mode: 0644]

diff --git a/include/llvm/Bitcode/Serialization.h b/include/llvm/Bitcode/Serialization.h
new file mode 100644 (file)
index 0000000..2d63311
--- /dev/null
@@ -0,0 +1,115 @@
+ //=- Serialization.h - Generic Object Serialization to Bitcode ---*- C++ -*-=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Ted Kremenek and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the interface for generic object serialization to
+// LLVM bitcode.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BITCODE_SERIALIZE
+#define LLVM_BITCODE_SERIALIZE
+
+#include "llvm/Bitcode/BitstreamWriter.h"
+#include "llvm/Bitcode/BitstreamReader.h"
+#include "llvm/ADT/SmallVector.h"
+#include <vector>
+
+namespace llvm {
+
+template <typename T> struct SerializeTrait;
+  
+class Serializer {
+  BitstreamWriter& Stream;
+  SmallVector<uint64_t,10> Record;
+  bool inBlock;
+public:
+  Serializer(BitstreamWriter& stream, unsigned BlockID = 0);
+  ~Serializer();
+  
+  template <typename T>
+  inline void Emit(const T& X) { SerializeTrait<T>::Serialize(*this,X); }
+    
+  void EmitInt(unsigned X, unsigned bits);  
+  void EmitCString(const char* cstr);
+
+  void Flush() { if (inRecord()) EmitRecord(); }
+  
+private:
+  void EmitRecord();
+  inline bool inRecord() { return Record.size() > 0; }  
+};
+  
+  
+class Deserializer {
+  BitstreamReader& Stream;
+  SmallVector<uint64_t,10> Record;
+  unsigned RecIdx;
+public:
+  Deserializer(BitstreamReader& stream);
+  ~Deserializer();
+
+  template <typename T>
+  inline void Read(T& X) { SerializeTrait<T>::Deserialize(*this,X); }
+
+  template <typename T>
+  inline T* Materialize() {
+    T* X = SerializeTrait<T>::Instantiate();
+    Read(*X);
+    return X;
+  }
+  
+  uint64_t ReadInt(unsigned bits = 32);
+  bool ReadBool() { return ReadInt(1); }
+  
+  char* ReadCString(char* cstr = NULL, unsigned MaxLen=0, bool isNullTerm=true);
+  void ReadCString(std::vector<char>& buff, bool isNullTerm=false);
+  
+private:
+  void ReadRecord();
+
+  inline bool inRecord() { 
+    if (Record.size() > 0) {
+      if (RecIdx >= Record.size()) {
+        RecIdx = 0;
+        Record.clear();
+        return false;
+      }
+      else return true;
+    }
+    else return false;
+  }
+};
+
+template <typename uintty, unsigned Bits> 
+struct SerializeIntTrait {
+  static inline void Serialize(Serializer& S, uintty X) {
+    S.EmitInt(X,Bits);
+  }
+  
+  static inline void Deserialize(Deserializer& S, uintty& X) {
+    X = (uintty) S.ReadInt(Bits);
+  }
+};
+
+  
+template <> struct SerializeTrait<bool>
+  : public SerializeIntTrait<bool,1> {};
+
+template <> struct SerializeTrait<char>
+  : public SerializeIntTrait<char,8> {};
+  
+template <> struct SerializeTrait<short>
+  : public SerializeIntTrait<short,16> {};
+
+template <> struct SerializeTrait<unsigned>
+  : public SerializeIntTrait<unsigned,32> {};
+
+} // end namespace llvm
+#endif
diff --git a/lib/Bitcode/Reader/Deserialize.cpp b/lib/Bitcode/Reader/Deserialize.cpp
new file mode 100644 (file)
index 0000000..ccd929a
--- /dev/null
@@ -0,0 +1,83 @@
+//==- Deserialize.cpp - Generic Object Serialization to Bitcode --*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Ted Kremenek and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the internal methods used for object serialization.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Bitcode/Serialization.h"
+
+using namespace llvm;
+
+Deserializer::Deserializer(BitstreamReader& stream)
+  : Stream(stream), RecIdx(0) {
+}
+
+Deserializer::~Deserializer() {
+  assert (RecIdx >= Record.size() && 
+          "Still scanning bitcode record when deserialization completed.");
+}
+
+void Deserializer::ReadRecord() {
+  // FIXME: Check if we haven't run off the edge of the stream.
+  // FIXME: Handle abbreviations.
+  unsigned Code = Stream.ReadCode();
+  // FIXME: Check for the correct code.
+  assert (Record.size() == 0);
+  
+  Stream.ReadRecord(Code,Record);
+  
+  assert (Record.size() > 0);
+}
+
+uint64_t Deserializer::ReadInt(unsigned Bits) {
+  // FIXME: Any error recovery/handling with incomplete or bad files?
+  if (!inRecord())
+    ReadRecord();
+
+  // FIXME: check for loss of precision in read (compare to Bits)
+  return Record[RecIdx++];
+}
+
+char* Deserializer::ReadCString(char* cstr, unsigned MaxLen, bool isNullTerm) {
+  if (cstr == NULL)
+    MaxLen = 0; // Zero this just in case someone does something funny.
+  
+  unsigned len = ReadInt(32);
+
+  // FIXME: perform dynamic checking of lengths?
+  assert (MaxLen == 0 || (len + (isNullTerm ? 1 : 0)) <= MaxLen);
+
+  if (!cstr)
+    cstr = new char[len + (isNullTerm ? 1 : 0)];
+  
+  assert (cstr != NULL);
+  
+  for (unsigned i = 0; i < len; ++i)
+    cstr[i] = ReadInt(8);
+  
+  if (isNullTerm)
+    cstr[len+1] = '\0';
+  
+  return cstr;
+}
+
+void Deserializer::ReadCString(std::vector<char>& buff, bool isNullTerm) {
+  buff.clear();
+
+  unsigned len = ReadInt(32);
+  
+  buff.reserve(len);
+  
+  for (unsigned i = 0; i < len; ++i)
+    buff.push_back(ReadInt(8));
+  
+  if (isNullTerm)
+    buff.push_back('\0');
+}
diff --git a/lib/Bitcode/Writer/Serialize.cpp b/lib/Bitcode/Writer/Serialize.cpp
new file mode 100644 (file)
index 0000000..9fbb97d
--- /dev/null
@@ -0,0 +1,52 @@
+//==- Serialize.cpp - Generic Object Serialization to Bitcode ----*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Ted Kremenek and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the internal methods used for object serialization.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Bitcode/Serialization.h"
+
+using namespace llvm;
+
+Serializer::Serializer(BitstreamWriter& stream, unsigned BlockID)
+  : Stream(stream), inBlock(BlockID >= 8) {
+    
+  if (inBlock) Stream.EnterSubblock(8,3);
+}
+
+Serializer::~Serializer() {
+  if (inRecord())
+    EmitRecord();
+
+  if (inBlock)
+    Stream.ExitBlock();
+  
+  Stream.FlushToWord();
+}
+
+void Serializer::EmitRecord() {
+  assert(Record.size() > 0 && "Cannot emit empty record.");
+  Stream.EmitRecord(8,Record);
+  Record.clear();
+}
+
+void Serializer::EmitInt(unsigned X, unsigned bits) {
+  Record.push_back(X);
+}
+
+void Serializer::EmitCString(const char* cstr) {
+  unsigned l = strlen(cstr);
+  Record.push_back(l);
+  
+  for (unsigned i = 0; i < l; i++)
+    Record.push_back(cstr[i]);
+
+  EmitRecord();
+}