blob: 9bc0f1578e797b6dc57408cabf8faadb62965c0b [file] [log] [blame]
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +00001//==- 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
Ted Kremenek6e9b4962007-10-24 19:06:40 +000014#include "llvm/Bitcode/Deserialize.h"
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000015
16using namespace llvm;
17
18Deserializer::Deserializer(BitstreamReader& stream)
Ted Kremenek5973ef42007-10-28 21:17:59 +000019 : Stream(stream), RecIdx(0), FreeList(NULL) {
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000020}
21
22Deserializer::~Deserializer() {
23 assert (RecIdx >= Record.size() &&
24 "Still scanning bitcode record when deserialization completed.");
Ted Kremenekadc9b9c2007-10-28 23:38:38 +000025
26#ifdef NDEBUG
27 for (MapTy::iterator I=BPatchMap.begin(), E=BPatchMap.end(); I!=E; ++I)
28 assert (I->second.hasFinalPtr() &&
29 "Some pointers were not backpatched.");
30#endif
Ted Kremenekfe2a0122007-10-25 00:10:21 +000031}
32
33
34bool Deserializer::inRecord() {
35 if (Record.size() > 0) {
36 if (RecIdx >= Record.size()) {
37 RecIdx = 0;
38 Record.clear();
39 return false;
40 }
41 else return true;
42 }
43 else return false;
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000044}
45
46void Deserializer::ReadRecord() {
47 // FIXME: Check if we haven't run off the edge of the stream.
48 // FIXME: Handle abbreviations.
Ted Kremenek6e9b4962007-10-24 19:06:40 +000049
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000050 // FIXME: Check for the correct code.
Ted Kremenek6e9b4962007-10-24 19:06:40 +000051 unsigned Code = Stream.ReadCode();
52
53 assert (Record.size() == 0);
54 Stream.ReadRecord(Code,Record);
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000055 assert (Record.size() > 0);
56}
57
Ted Kremenek6e9b4962007-10-24 19:06:40 +000058uint64_t Deserializer::ReadInt() {
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000059 // FIXME: Any error recovery/handling with incomplete or bad files?
60 if (!inRecord())
61 ReadRecord();
62
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000063 return Record[RecIdx++];
64}
65
Ted Kremenek6e9b4962007-10-24 19:06:40 +000066char* Deserializer::ReadCStr(char* cstr, unsigned MaxLen, bool isNullTerm) {
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000067 if (cstr == NULL)
68 MaxLen = 0; // Zero this just in case someone does something funny.
69
Ted Kremenek6e9b4962007-10-24 19:06:40 +000070 unsigned len = ReadInt();
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000071
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000072 assert (MaxLen == 0 || (len + (isNullTerm ? 1 : 0)) <= MaxLen);
73
74 if (!cstr)
75 cstr = new char[len + (isNullTerm ? 1 : 0)];
76
77 assert (cstr != NULL);
78
79 for (unsigned i = 0; i < len; ++i)
Ted Kremenek6e9b4962007-10-24 19:06:40 +000080 cstr[i] = (char) ReadInt();
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000081
82 if (isNullTerm)
83 cstr[len+1] = '\0';
84
85 return cstr;
86}
87
Ted Kremenek6e9b4962007-10-24 19:06:40 +000088void Deserializer::ReadCStr(std::vector<char>& buff, bool isNullTerm) {
89 unsigned len = ReadInt();
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000090
Ted Kremenek6e9b4962007-10-24 19:06:40 +000091 buff.clear();
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000092 buff.reserve(len);
93
94 for (unsigned i = 0; i < len; ++i)
Ted Kremenek6e9b4962007-10-24 19:06:40 +000095 buff.push_back((char) ReadInt());
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000096
97 if (isNullTerm)
98 buff.push_back('\0');
99}
Ted Kremenek6e9b4962007-10-24 19:06:40 +0000100
Ted Kremeneka7963a52007-10-31 22:42:03 +0000101void Deserializer::RegisterPtr(unsigned PtrId, const void* Ptr) {
Ted Kremenekfe2a0122007-10-25 00:10:21 +0000102 BPatchEntry& E = BPatchMap[PtrId];
Ted Kremeneka7963a52007-10-31 22:42:03 +0000103 assert (!E.hasFinalPtr() && "Pointer already registered.");
Ted Kremenek5973ef42007-10-28 21:17:59 +0000104 E.setFinalPtr(FreeList,Ptr);
Ted Kremenekfe2a0122007-10-25 00:10:21 +0000105}
106
Ted Kremenek5973ef42007-10-28 21:17:59 +0000107void Deserializer::ReadUIntPtr(uintptr_t& PtrRef) {
Ted Kremenekfe2a0122007-10-25 00:10:21 +0000108 unsigned PtrId = ReadInt();
109
Ted Kremenek2423e032007-10-25 18:42:52 +0000110 if (PtrId == 0) {
Ted Kremenek8308a482007-10-29 18:43:39 +0000111 PtrRef = 0;
Ted Kremenek2423e032007-10-25 18:42:52 +0000112 return;
113 }
114
Ted Kremenekfe2a0122007-10-25 00:10:21 +0000115 BPatchEntry& E = BPatchMap[PtrId];
116
Ted Kremenek5973ef42007-10-28 21:17:59 +0000117 if (E.hasFinalPtr())
Ted Kremenekeb9409d2007-10-31 19:58:32 +0000118 PtrRef = E.getFinalPtr();
Ted Kremenek5973ef42007-10-28 21:17:59 +0000119 else {
120 // Register backpatch. Check the freelist for a BPNode.
121 BPNode* N;
122
123 if (FreeList) {
124 N = FreeList;
125 FreeList = FreeList->Next;
126 }
127 else // No available BPNode. Allocate one.
128 N = (BPNode*) Allocator.Allocate<BPNode>();
129
130 new (N) BPNode(E.getBPNode(),PtrRef);
131 E.setBPNode(N);
Ted Kremenekfe2a0122007-10-25 00:10:21 +0000132 }
Ted Kremenekfe2a0122007-10-25 00:10:21 +0000133}
134
Ted Kremenekeb9409d2007-10-31 19:58:32 +0000135uintptr_t Deserializer::ReadInternalRefPtr() {
136 unsigned PtrId = ReadInt();
137
138 assert (PtrId != 0 && "References cannot refer the NULL address.");
139
140 BPatchEntry& E = BPatchMap[PtrId];
141
142 assert (E.hasFinalPtr() &&
143 "Cannot backpatch references. Object must be already deserialized.");
144
145 return E.getFinalPtr();
146}
Ted Kremenek5973ef42007-10-28 21:17:59 +0000147
Ted Kremeneka7963a52007-10-31 22:42:03 +0000148void Deserializer::BPatchEntry::setFinalPtr(BPNode*& FreeList, const void* P) {
Ted Kremenek5973ef42007-10-28 21:17:59 +0000149 assert (!hasFinalPtr());
150
151 // Perform backpatching.
152
153 BPNode* Last = NULL;
154
155 for (BPNode* N = getBPNode() ; N != NULL; N = N->Next) {
156 Last = N;
157 N->PtrRef |= reinterpret_cast<uintptr_t>(P);
Ted Kremenekfe2a0122007-10-25 00:10:21 +0000158 }
159
Ted Kremenek5973ef42007-10-28 21:17:59 +0000160 if (Last) {
161 Last->Next = FreeList;
162 FreeList = getBPNode();
163 }
164
165 Ptr = reinterpret_cast<uintptr_t>(P);
Ted Kremenekfe2a0122007-10-25 00:10:21 +0000166}
Ted Kremenek6e9b4962007-10-24 19:06:40 +0000167
Ted Kremenek5973ef42007-10-28 21:17:59 +0000168
Ted Kremenek6e9b4962007-10-24 19:06:40 +0000169#define INT_READ(TYPE)\
170void SerializeTrait<TYPE>::Read(Deserializer& D, TYPE& X) {\
Ted Kremenekfe2a0122007-10-25 00:10:21 +0000171 X = (TYPE) D.ReadInt(); }\
172TYPE SerializeTrait<TYPE>::ReadVal(Deserializer& D) {\
173 return (TYPE) D.ReadInt(); }
Ted Kremenek6e9b4962007-10-24 19:06:40 +0000174
175INT_READ(bool)
176INT_READ(unsigned char)
177INT_READ(unsigned short)
178INT_READ(unsigned int)
179INT_READ(unsigned long)