blob: e367d02e7cfc2a4b0299c46dbc0c6d40d98c16c5 [file] [log] [blame]
Chris Lattner00950542001-06-06 20:29:01 +00001//===- ReadConst.cpp - Code to constants and constant pools -----------------===
2//
3// This file implements functionality to deserialize constants and entire
4// constant pools.
5//
6// Note that this library should be as fast as possible, reentrant, and
7// threadsafe!!
8//
9//===------------------------------------------------------------------------===
10
11#include "llvm/Module.h"
12#include "llvm/BasicBlock.h"
13#include "llvm/ConstPoolVals.h"
14#include "llvm/DerivedTypes.h"
15#include "ReaderInternals.h"
16
17bool BytecodeParser::parseTypeConstant(const uchar *&Buf, const uchar *EndBuf,
18 ConstPoolVal *&V) {
19 const Type *Val = 0;
20
21 unsigned PrimType;
22 if (read_vbr(Buf, EndBuf, PrimType)) return true;
23
24 if ((Val = Type::getPrimitiveType((Type::PrimitiveID)PrimType))) {
25 V = new ConstPoolType(Val); // It's just a primitive ID.
26 return false;
27 }
28
29 switch (PrimType) {
30 case Type::MethodTyID: {
31 unsigned Typ;
32 if (read_vbr(Buf, EndBuf, Typ)) return true;
33 const Type *RetType = getType(Typ);
34 if (RetType == 0) return true;
35
Chris Lattnere5a57ee2001-07-25 22:47:55 +000036 unsigned NumParams;
37 if (read_vbr(Buf, EndBuf, NumParams)) return true;
Chris Lattner00950542001-06-06 20:29:01 +000038
Chris Lattnere5a57ee2001-07-25 22:47:55 +000039 MethodType::ParamTypes Params;
40 while (NumParams--) {
41 if (read_vbr(Buf, EndBuf, Typ)) return true;
Chris Lattner00950542001-06-06 20:29:01 +000042 const Type *Ty = getType(Typ);
43 if (Ty == 0) return true;
44 Params.push_back(Ty);
Chris Lattner00950542001-06-06 20:29:01 +000045 }
46
47 Val = MethodType::getMethodType(RetType, Params);
48 break;
49 }
50 case Type::ArrayTyID: {
51 unsigned ElTyp;
52 if (read_vbr(Buf, EndBuf, ElTyp)) return true;
53 const Type *ElementType = getType(ElTyp);
54 if (ElementType == 0) return true;
55
56 int NumElements;
57 if (read_vbr(Buf, EndBuf, NumElements)) return true;
58 Val = ArrayType::getArrayType(ElementType, NumElements);
59 break;
60 }
61 case Type::StructTyID: {
62 unsigned Typ;
63 StructType::ElementTypes Elements;
64
65 if (read_vbr(Buf, EndBuf, Typ)) return true;
66 while (Typ) { // List is terminated by void/0 typeid
67 const Type *Ty = getType(Typ);
68 if (Ty == 0) return true;
69 Elements.push_back(Ty);
70
71 if (read_vbr(Buf, EndBuf, Typ)) return true;
72 }
73
74 Val = StructType::getStructType(Elements);
75 break;
76 }
77 case Type::PointerTyID: {
78 unsigned ElTyp;
79 if (read_vbr(Buf, EndBuf, ElTyp)) return true;
80 const Type *ElementType = getType(ElTyp);
81 if (ElementType == 0) return true;
82 Val = PointerType::getPointerType(ElementType);
83 break;
84 }
85
86 default:
87 cerr << __FILE__ << ":" << __LINE__ << ": Don't know how to deserialize"
88 << " primitive Type " << PrimType << "\n";
89 return true;
90 }
91
92 V = new ConstPoolType(Val);
93 return false;
94}
95
96bool BytecodeParser::parseConstPoolValue(const uchar *&Buf,
97 const uchar *EndBuf,
98 const Type *Ty, ConstPoolVal *&V) {
99 switch (Ty->getPrimitiveID()) {
100 case Type::BoolTyID: {
101 unsigned Val;
102 if (read_vbr(Buf, EndBuf, Val)) return true;
103 if (Val != 0 && Val != 1) return true;
104 V = new ConstPoolBool(Val == 1);
105 break;
106 }
107
108 case Type::UByteTyID: // Unsigned integer types...
109 case Type::UShortTyID:
110 case Type::UIntTyID: {
111 unsigned Val;
112 if (read_vbr(Buf, EndBuf, Val)) return true;
113 if (!ConstPoolUInt::isValueValidForType(Ty, Val)) return true;
114 V = new ConstPoolUInt(Ty, Val);
115 break;
116 }
117
118 case Type::ULongTyID: {
119 uint64_t Val;
120 if (read_vbr(Buf, EndBuf, Val)) return true;
121 V = new ConstPoolUInt(Ty, Val);
122 break;
123 }
124
125 case Type::SByteTyID: // Unsigned integer types...
126 case Type::ShortTyID:
127 case Type::IntTyID: {
128 int Val;
129 if (read_vbr(Buf, EndBuf, Val)) return true;
130 if (!ConstPoolSInt::isValueValidForType(Ty, Val)) return 0;
131 V = new ConstPoolSInt(Ty, Val);
132 break;
133 }
134
135 case Type::LongTyID: {
136 int64_t Val;
137 if (read_vbr(Buf, EndBuf, Val)) return true;
138 V = new ConstPoolSInt(Ty, Val);
139 break;
140 }
141
Chris Lattnera1375302001-07-15 00:17:18 +0000142 case Type::FloatTyID: {
143 float F;
144 if (input_data(Buf, EndBuf, &F, &F+1)) return true;
145 V = new ConstPoolFP(Ty, F);
146 break;
147 }
148
149 case Type::DoubleTyID: {
150 double Val;
151 if (input_data(Buf, EndBuf, &Val, &Val+1)) return true;
152 V = new ConstPoolFP(Ty, Val);
153 break;
154 }
155
Chris Lattner00950542001-06-06 20:29:01 +0000156 case Type::TypeTyID:
157 if (parseTypeConstant(Buf, EndBuf, V)) return true;
158 break;
159
160 case Type::ArrayTyID: {
161 const ArrayType *AT = (const ArrayType*)Ty;
162 unsigned NumElements;
163 if (AT->isSized()) // Sized array, # elements stored in type!
164 NumElements = (unsigned)AT->getNumElements();
165 else // Unsized array, # elements stored in stream!
166 if (read_vbr(Buf, EndBuf, NumElements)) return true;
167
168 vector<ConstPoolVal *> Elements;
169 while (NumElements--) { // Read all of the elements of the constant.
170 unsigned Slot;
171 if (read_vbr(Buf, EndBuf, Slot)) return true;
172 Value *V = getValue(AT->getElementType(), Slot, false);
Chris Lattner7fc9fe32001-06-27 23:41:11 +0000173 if (!V || !V->isConstant())
Chris Lattner00950542001-06-06 20:29:01 +0000174 return true;
175 Elements.push_back((ConstPoolVal*)V);
176 }
177 V = new ConstPoolArray(AT, Elements);
178 break;
179 }
180
181 case Type::StructTyID: {
182 const StructType *ST = (const StructType*)Ty;
183 const StructType::ElementTypes &ET = ST->getElementTypes();
184
185 vector<ConstPoolVal *> Elements;
186 for (unsigned i = 0; i < ET.size(); ++i) {
187 unsigned Slot;
188 if (read_vbr(Buf, EndBuf, Slot)) return true;
189 Value *V = getValue(ET[i], Slot, false);
Chris Lattner7fc9fe32001-06-27 23:41:11 +0000190 if (!V || !V->isConstant())
Chris Lattner00950542001-06-06 20:29:01 +0000191 return true;
192 Elements.push_back((ConstPoolVal*)V);
193 }
194
195 V = new ConstPoolStruct(ST, Elements);
196 break;
197 }
198
199 default:
200 cerr << __FILE__ << ":" << __LINE__
201 << ": Don't know how to deserialize constant value of type '"
202 << Ty->getName() << "'\n";
203 return true;
204 }
205 return false;
206}
207
208bool BytecodeParser::ParseConstantPool(const uchar *&Buf, const uchar *EndBuf,
209 SymTabValue::ConstantPoolType &CP,
210 ValueTable &Tab) {
211 while (Buf < EndBuf) {
212 unsigned NumEntries, Typ;
213
214 if (read_vbr(Buf, EndBuf, NumEntries) ||
215 read_vbr(Buf, EndBuf, Typ)) return true;
216 const Type *Ty = getType(Typ);
217 if (Ty == 0) return true;
218
219 for (unsigned i = 0; i < NumEntries; i++) {
220 ConstPoolVal *I;
221 if (parseConstPoolValue(Buf, EndBuf, Ty, I)) return true;
222#if 0
223 cerr << " Read const value: <" << I->getType()->getName()
224 << ">: " << I->getStrValue() << endl;
225#endif
226 insertValue(I, Tab);
227 CP.insert(I);
228 }
229 }
230
231 return Buf > EndBuf;
232}