blob: 9caef6dae1e54db47ead44c85c68156b70e77cb9 [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 Kremenekfe2a0122007-10-25 00:10:21 +000025
Ted Kremenek5973ef42007-10-28 21:17:59 +000026 assert (FreeList == NULL && "Some pointers were not backpatched.");
Ted Kremenekfe2a0122007-10-25 00:10:21 +000027}
28
29
30bool 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;
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000040}
41
42void Deserializer::ReadRecord() {
43 // FIXME: Check if we haven't run off the edge of the stream.
44 // FIXME: Handle abbreviations.
Ted Kremenek6e9b4962007-10-24 19:06:40 +000045
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000046 // FIXME: Check for the correct code.
Ted Kremenek6e9b4962007-10-24 19:06:40 +000047 unsigned Code = Stream.ReadCode();
48
49 assert (Record.size() == 0);
50 Stream.ReadRecord(Code,Record);
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000051 assert (Record.size() > 0);
52}
53
Ted Kremenek6e9b4962007-10-24 19:06:40 +000054uint64_t Deserializer::ReadInt() {
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000055 // FIXME: Any error recovery/handling with incomplete or bad files?
56 if (!inRecord())
57 ReadRecord();
58
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000059 return Record[RecIdx++];
60}
61
Ted Kremenek6e9b4962007-10-24 19:06:40 +000062char* Deserializer::ReadCStr(char* cstr, unsigned MaxLen, bool isNullTerm) {
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000063 if (cstr == NULL)
64 MaxLen = 0; // Zero this just in case someone does something funny.
65
Ted Kremenek6e9b4962007-10-24 19:06:40 +000066 unsigned len = ReadInt();
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000067
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000068 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)
Ted Kremenek6e9b4962007-10-24 19:06:40 +000076 cstr[i] = (char) ReadInt();
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000077
78 if (isNullTerm)
79 cstr[len+1] = '\0';
80
81 return cstr;
82}
83
Ted Kremenek6e9b4962007-10-24 19:06:40 +000084void Deserializer::ReadCStr(std::vector<char>& buff, bool isNullTerm) {
85 unsigned len = ReadInt();
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000086
Ted Kremenek6e9b4962007-10-24 19:06:40 +000087 buff.clear();
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000088 buff.reserve(len);
89
90 for (unsigned i = 0; i < len; ++i)
Ted Kremenek6e9b4962007-10-24 19:06:40 +000091 buff.push_back((char) ReadInt());
Ted Kremenek0b2d7aa2007-10-23 21:29:33 +000092
93 if (isNullTerm)
94 buff.push_back('\0');
95}
Ted Kremenek6e9b4962007-10-24 19:06:40 +000096
Ted Kremenekfe2a0122007-10-25 00:10:21 +000097void Deserializer::RegisterPtr(unsigned PtrId,void* Ptr) {
98 BPatchEntry& E = BPatchMap[PtrId];
Ted Kremenek5973ef42007-10-28 21:17:59 +000099 assert (E.hasFinalPtr() && "Pointer already registered.");
100 E.setFinalPtr(FreeList,Ptr);
Ted Kremenekfe2a0122007-10-25 00:10:21 +0000101}
102
Ted Kremenek5973ef42007-10-28 21:17:59 +0000103void Deserializer::ReadUIntPtr(uintptr_t& PtrRef) {
Ted Kremenekfe2a0122007-10-25 00:10:21 +0000104 unsigned PtrId = ReadInt();
105
Ted Kremenek2423e032007-10-25 18:42:52 +0000106 if (PtrId == 0) {
107 PtrRef = NULL;
108 return;
109 }
110
Ted Kremenekfe2a0122007-10-25 00:10:21 +0000111 BPatchEntry& E = BPatchMap[PtrId];
112
Ted Kremenek5973ef42007-10-28 21:17:59 +0000113 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);
Ted Kremenekfe2a0122007-10-25 00:10:21 +0000128 }
Ted Kremenekfe2a0122007-10-25 00:10:21 +0000129}
130
Ted Kremenek5973ef42007-10-28 21:17:59 +0000131
132void 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);
Ted Kremenekfe2a0122007-10-25 00:10:21 +0000142 }
143
Ted Kremenek5973ef42007-10-28 21:17:59 +0000144 if (Last) {
145 Last->Next = FreeList;
146 FreeList = getBPNode();
147 }
148
149 Ptr = reinterpret_cast<uintptr_t>(P);
Ted Kremenekfe2a0122007-10-25 00:10:21 +0000150}
Ted Kremenek6e9b4962007-10-24 19:06:40 +0000151
Ted Kremenek5973ef42007-10-28 21:17:59 +0000152
Ted Kremenek6e9b4962007-10-24 19:06:40 +0000153#define INT_READ(TYPE)\
154void SerializeTrait<TYPE>::Read(Deserializer& D, TYPE& X) {\
Ted Kremenekfe2a0122007-10-25 00:10:21 +0000155 X = (TYPE) D.ReadInt(); }\
156TYPE SerializeTrait<TYPE>::ReadVal(Deserializer& D) {\
157 return (TYPE) D.ReadInt(); }
Ted Kremenek6e9b4962007-10-24 19:06:40 +0000158
159INT_READ(bool)
160INT_READ(unsigned char)
161INT_READ(unsigned short)
162INT_READ(unsigned int)
163INT_READ(unsigned long)