blob: 8fba9d20b5d2312815ccc3d96cd5602fa21d785d [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 Kremenekfe2a0122007-10-25 00:10:21 +0000101void Deserializer::RegisterPtr(unsigned PtrId,void* Ptr) {
102 BPatchEntry& E = BPatchMap[PtrId];
Ted Kremenek5973ef42007-10-28 21:17:59 +0000103 assert (E.hasFinalPtr() && "Pointer already registered.");
104 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) {
111 PtrRef = NULL;
112 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())
118 PtrRef = E.getRawPtr();
119 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 Kremenek5973ef42007-10-28 21:17:59 +0000135
136void Deserializer::BPatchEntry::setFinalPtr(BPNode*& FreeList, void* P) {
137 assert (!hasFinalPtr());
138
139 // Perform backpatching.
140
141 BPNode* Last = NULL;
142
143 for (BPNode* N = getBPNode() ; N != NULL; N = N->Next) {
144 Last = N;
145 N->PtrRef |= reinterpret_cast<uintptr_t>(P);
Ted Kremenekfe2a0122007-10-25 00:10:21 +0000146 }
147
Ted Kremenek5973ef42007-10-28 21:17:59 +0000148 if (Last) {
149 Last->Next = FreeList;
150 FreeList = getBPNode();
151 }
152
153 Ptr = reinterpret_cast<uintptr_t>(P);
Ted Kremenekfe2a0122007-10-25 00:10:21 +0000154}
Ted Kremenek6e9b4962007-10-24 19:06:40 +0000155
Ted Kremenek5973ef42007-10-28 21:17:59 +0000156
Ted Kremenek6e9b4962007-10-24 19:06:40 +0000157#define INT_READ(TYPE)\
158void SerializeTrait<TYPE>::Read(Deserializer& D, TYPE& X) {\
Ted Kremenekfe2a0122007-10-25 00:10:21 +0000159 X = (TYPE) D.ReadInt(); }\
160TYPE SerializeTrait<TYPE>::ReadVal(Deserializer& D) {\
161 return (TYPE) D.ReadInt(); }
Ted Kremenek6e9b4962007-10-24 19:06:40 +0000162
163INT_READ(bool)
164INT_READ(unsigned char)
165INT_READ(unsigned short)
166INT_READ(unsigned int)
167INT_READ(unsigned long)