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"
16 #ifdef DEBUG_BACKPATCH
17 #include "llvm/Support/Streams.h"
22 Deserializer::Deserializer(BitstreamReader& stream)
23 : Stream(stream), RecIdx(0), FreeList(NULL) {
26 Deserializer::~Deserializer() {
27 assert (RecIdx >= Record.size() &&
28 "Still scanning bitcode record when deserialization completed.");
31 for (MapTy::iterator I=BPatchMap.begin(), E=BPatchMap.end(); I!=E; ++I)
32 assert (I->first.hasFinalPtr() &&
33 "Some pointers were not backpatched.");
38 bool Deserializer::inRecord() {
39 if (Record.size() > 0) {
40 if (RecIdx >= Record.size()) {
50 void Deserializer::ReadRecord() {
51 // FIXME: Check if we haven't run off the edge of the stream.
52 // FIXME: Handle abbreviations.
54 assert (Record.size() == 0);
60 if (Stream.AtEndOfStream())
63 Code = Stream.ReadCode();
65 if (Code == bitc::ENTER_SUBBLOCK) {
66 // No known subblocks, always skip them.
67 unsigned id = Stream.ReadSubBlockID();
68 Stream.EnterSubBlock(id);
72 if (Code == bitc::END_BLOCK) {
73 bool x = Stream.ReadBlockEnd();
74 assert (!x && "Error at block end.");
78 if (Code == bitc::DEFINE_ABBREV) {
79 Stream.ReadAbbrevRecord();
86 assert (Record.size() == 0);
87 Stream.ReadRecord(Code,Record);
88 assert (Record.size() > 0 || Stream.AtEndOfStream());
91 bool Deserializer::AtEnd() {
97 return Stream.AtEndOfStream();
100 uint64_t Deserializer::ReadInt() {
101 // FIXME: Any error recovery/handling with incomplete or bad files?
105 return Record[RecIdx++];
108 char* Deserializer::ReadCStr(char* cstr, unsigned MaxLen, bool isNullTerm) {
110 MaxLen = 0; // Zero this just in case someone does something funny.
112 unsigned len = ReadInt();
114 assert (MaxLen == 0 || (len + (isNullTerm ? 1 : 0)) <= MaxLen);
117 cstr = new char[len + (isNullTerm ? 1 : 0)];
119 assert (cstr != NULL);
121 for (unsigned i = 0; i < len; ++i)
122 cstr[i] = (char) ReadInt();
130 void Deserializer::ReadCStr(std::vector<char>& buff, bool isNullTerm) {
131 unsigned len = ReadInt();
136 for (unsigned i = 0; i < len; ++i)
137 buff.push_back((char) ReadInt());
140 buff.push_back('\0');
143 void Deserializer::RegisterPtr(unsigned PtrId, const void* Ptr) {
144 MapTy::value_type& E = BPatchMap.FindAndConstruct(BPKey(PtrId));
146 assert (!HasFinalPtr(E) && "Pointer already registered.");
148 #ifdef DEBUG_BACKPATCH
149 llvm::cerr << "RegisterPtr: " << PtrId << " => " << Ptr << "\n";
155 void Deserializer::ReadUIntPtr(uintptr_t& PtrRef) {
156 unsigned PtrId = ReadInt();
163 #ifdef DEBUG_BACKPATCH
164 llvm::cerr << "ReadUintPtr: " << PtrId << "\n";
167 MapTy::value_type& E = BPatchMap.FindAndConstruct(BPKey(PtrId));
170 PtrRef = GetFinalPtr(E);
172 // Register backpatch. Check the freelist for a BPNode.
177 FreeList = FreeList->Next;
179 else // No available BPNode. Allocate one.
180 N = (BPNode*) Allocator.Allocate<BPNode>();
182 new (N) BPNode(GetBPNode(E),PtrRef);
187 uintptr_t Deserializer::ReadInternalRefPtr() {
188 unsigned PtrId = ReadInt();
190 assert (PtrId != 0 && "References cannot refer the NULL address.");
192 MapTy::value_type& E = BPatchMap.FindAndConstruct(BPKey(PtrId));
194 assert (HasFinalPtr(E) &&
195 "Cannot backpatch references. Object must be already deserialized.");
197 return GetFinalPtr(E);
200 void Deserializer::BPEntry::SetPtr(BPNode*& FreeList, void* P) {
203 for (BPNode* N = Head; N != NULL; N=N->Next) {
205 N->PtrRef |= reinterpret_cast<uintptr_t>(P);
209 Last->Next = FreeList;
213 Ptr = const_cast<void*>(P);
217 #define INT_READ(TYPE)\
218 void SerializeTrait<TYPE>::Read(Deserializer& D, TYPE& X) {\
219 X = (TYPE) D.ReadInt(); }
222 INT_READ(unsigned char)
223 INT_READ(unsigned short)
224 INT_READ(unsigned int)
225 INT_READ(unsigned long)