1 //==- Deserialize.cpp - Generic Object Serialization to Bitcode --*- C++ -*-==//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by Ted Kremenek and is distributed under the
6 // University of Illinois Open Source License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the internal methods used for object serialization.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/Bitcode/Deserialize.h"
18 Deserializer::Deserializer(BitstreamReader& stream)
19 : Stream(stream), RecIdx(0), FreeList(NULL) {
22 Deserializer::~Deserializer() {
23 assert (RecIdx >= Record.size() &&
24 "Still scanning bitcode record when deserialization completed.");
26 assert (FreeList == NULL && "Some pointers were not backpatched.");
30 bool Deserializer::inRecord() {
31 if (Record.size() > 0) {
32 if (RecIdx >= Record.size()) {
42 void Deserializer::ReadRecord() {
43 // FIXME: Check if we haven't run off the edge of the stream.
44 // FIXME: Handle abbreviations.
46 // FIXME: Check for the correct code.
47 unsigned Code = Stream.ReadCode();
49 assert (Record.size() == 0);
50 Stream.ReadRecord(Code,Record);
51 assert (Record.size() > 0);
54 uint64_t Deserializer::ReadInt() {
55 // FIXME: Any error recovery/handling with incomplete or bad files?
59 return Record[RecIdx++];
62 char* Deserializer::ReadCStr(char* cstr, unsigned MaxLen, bool isNullTerm) {
64 MaxLen = 0; // Zero this just in case someone does something funny.
66 unsigned len = ReadInt();
68 assert (MaxLen == 0 || (len + (isNullTerm ? 1 : 0)) <= MaxLen);
71 cstr = new char[len + (isNullTerm ? 1 : 0)];
73 assert (cstr != NULL);
75 for (unsigned i = 0; i < len; ++i)
76 cstr[i] = (char) ReadInt();
84 void Deserializer::ReadCStr(std::vector<char>& buff, bool isNullTerm) {
85 unsigned len = ReadInt();
90 for (unsigned i = 0; i < len; ++i)
91 buff.push_back((char) ReadInt());
97 void Deserializer::RegisterPtr(unsigned PtrId,void* Ptr) {
98 BPatchEntry& E = BPatchMap[PtrId];
99 assert (E.hasFinalPtr() && "Pointer already registered.");
100 E.setFinalPtr(FreeList,Ptr);
103 void Deserializer::ReadUIntPtr(uintptr_t& PtrRef) {
104 unsigned PtrId = ReadInt();
111 BPatchEntry& E = BPatchMap[PtrId];
114 PtrRef = E.getRawPtr();
116 // Register backpatch. Check the freelist for a BPNode.
121 FreeList = FreeList->Next;
123 else // No available BPNode. Allocate one.
124 N = (BPNode*) Allocator.Allocate<BPNode>();
126 new (N) BPNode(E.getBPNode(),PtrRef);
132 void Deserializer::BPatchEntry::setFinalPtr(BPNode*& FreeList, void* P) {
133 assert (!hasFinalPtr());
135 // Perform backpatching.
139 for (BPNode* N = getBPNode() ; N != NULL; N = N->Next) {
141 N->PtrRef |= reinterpret_cast<uintptr_t>(P);
145 Last->Next = FreeList;
146 FreeList = getBPNode();
149 Ptr = reinterpret_cast<uintptr_t>(P);
153 #define INT_READ(TYPE)\
154 void SerializeTrait<TYPE>::Read(Deserializer& D, TYPE& X) {\
155 X = (TYPE) D.ReadInt(); }\
156 TYPE SerializeTrait<TYPE>::ReadVal(Deserializer& D) {\
157 return (TYPE) D.ReadInt(); }
160 INT_READ(unsigned char)
161 INT_READ(unsigned short)
162 INT_READ(unsigned int)
163 INT_READ(unsigned long)