9caef6dae1e54db47ead44c85c68156b70e77cb9
[oota-llvm.git] / lib / Bitcode / Reader / Deserialize.cpp
1 //==- Deserialize.cpp - Generic Object Serialization to Bitcode --*- C++ -*-==//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
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.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the internal methods used for object serialization.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/Bitcode/Deserialize.h"
15
16 using namespace llvm;
17
18 Deserializer::Deserializer(BitstreamReader& stream)
19   : Stream(stream), RecIdx(0), FreeList(NULL) {
20 }
21
22 Deserializer::~Deserializer() {
23   assert (RecIdx >= Record.size() && 
24           "Still scanning bitcode record when deserialization completed.");
25   
26   assert (FreeList == NULL && "Some pointers were not backpatched.");
27 }
28
29
30 bool Deserializer::inRecord() {
31   if (Record.size() > 0) {
32     if (RecIdx >= Record.size()) {
33       RecIdx = 0;
34       Record.clear();
35       return false;
36     }
37     else return true;
38   }
39   else return false;
40 }
41
42 void Deserializer::ReadRecord() {
43   // FIXME: Check if we haven't run off the edge of the stream.
44   // FIXME: Handle abbreviations.
45
46   // FIXME: Check for the correct code.
47   unsigned Code = Stream.ReadCode();
48
49   assert (Record.size() == 0);  
50   Stream.ReadRecord(Code,Record);  
51   assert (Record.size() > 0);
52 }
53
54 uint64_t Deserializer::ReadInt() {
55   // FIXME: Any error recovery/handling with incomplete or bad files?
56   if (!inRecord())
57     ReadRecord();
58
59   return Record[RecIdx++];
60 }
61
62 char* Deserializer::ReadCStr(char* cstr, unsigned MaxLen, bool isNullTerm) {
63   if (cstr == NULL)
64     MaxLen = 0; // Zero this just in case someone does something funny.
65   
66   unsigned len = ReadInt();
67
68   assert (MaxLen == 0 || (len + (isNullTerm ? 1 : 0)) <= MaxLen);
69
70   if (!cstr)
71     cstr = new char[len + (isNullTerm ? 1 : 0)];
72   
73   assert (cstr != NULL);
74   
75   for (unsigned i = 0; i < len; ++i)
76     cstr[i] = (char) ReadInt();
77   
78   if (isNullTerm)
79     cstr[len+1] = '\0';
80   
81   return cstr;
82 }
83
84 void Deserializer::ReadCStr(std::vector<char>& buff, bool isNullTerm) {
85   unsigned len = ReadInt();
86
87   buff.clear();  
88   buff.reserve(len);
89   
90   for (unsigned i = 0; i < len; ++i)
91     buff.push_back((char) ReadInt());
92   
93   if (isNullTerm)
94     buff.push_back('\0');
95 }
96
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);
101 }
102
103 void Deserializer::ReadUIntPtr(uintptr_t& PtrRef) {
104   unsigned PtrId = ReadInt();
105   
106   if (PtrId == 0) {
107     PtrRef = NULL;
108     return;
109   }  
110   
111   BPatchEntry& E = BPatchMap[PtrId];
112   
113   if (E.hasFinalPtr())
114     PtrRef = E.getRawPtr();
115   else {
116     // Register backpatch.  Check the freelist for a BPNode.
117     BPNode* N;
118
119     if (FreeList) {
120       N = FreeList;
121       FreeList = FreeList->Next;
122     }
123     else // No available BPNode.  Allocate one.
124       N = (BPNode*) Allocator.Allocate<BPNode>();
125     
126     new (N) BPNode(E.getBPNode(),PtrRef);
127     E.setBPNode(N);
128   }
129 }
130
131
132 void Deserializer::BPatchEntry::setFinalPtr(BPNode*& FreeList, void* P) {
133   assert (!hasFinalPtr());
134   
135   // Perform backpatching.
136   
137   BPNode* Last = NULL;
138   
139   for (BPNode* N = getBPNode() ; N != NULL; N = N->Next) {
140     Last = N;
141     N->PtrRef |= reinterpret_cast<uintptr_t>(P);
142   }
143   
144   if (Last) {
145     Last->Next = FreeList;
146     FreeList = getBPNode();    
147   }
148   
149   Ptr = reinterpret_cast<uintptr_t>(P);
150 }
151
152
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(); }
158
159 INT_READ(bool)
160 INT_READ(unsigned char)
161 INT_READ(unsigned short)
162 INT_READ(unsigned int)
163 INT_READ(unsigned long)