Fix another annoying bug that took forever to track down. This one involves abstract...
[oota-llvm.git] / lib / Bytecode / Reader / ConstantReader.cpp
1 //===- 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 "llvm/GlobalVariable.h"
16 #include "ReaderInternals.h"
17 #include <algorithm>
18
19
20
21 const Type *BytecodeParser::parseTypeConstant(const uchar *&Buf,
22                                               const uchar *EndBuf) {
23   unsigned PrimType;
24   if (read_vbr(Buf, EndBuf, PrimType)) return failure<const Type*>(0);
25
26   const Type *Val = 0;
27   if ((Val = Type::getPrimitiveType((Type::PrimitiveID)PrimType)))
28     return Val;
29   
30   switch (PrimType) {
31   case Type::MethodTyID: {
32     unsigned Typ;
33     if (read_vbr(Buf, EndBuf, Typ)) return failure(Val);
34     const Type *RetType = getType(Typ);
35     if (RetType == 0) return failure(Val);
36
37     unsigned NumParams;
38     if (read_vbr(Buf, EndBuf, NumParams)) return failure(Val);
39
40     vector<const Type*> Params;
41     while (NumParams--) {
42       if (read_vbr(Buf, EndBuf, Typ)) return failure(Val);
43       const Type *Ty = getType(Typ);
44       if (Ty == 0) return failure(Val);
45       Params.push_back(Ty);
46     }
47
48     bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
49     if (isVarArg) Params.pop_back();
50
51     Val = MethodType::get(RetType, Params, isVarArg);
52     break;
53   }
54   case Type::ArrayTyID: {
55     unsigned ElTyp;
56     if (read_vbr(Buf, EndBuf, ElTyp)) return failure(Val);
57     const Type *ElementType = getType(ElTyp);
58     if (ElementType == 0) return failure(Val);
59
60     int NumElements;
61     if (read_vbr(Buf, EndBuf, NumElements)) return failure(Val);
62     Val = ArrayType::get(ElementType, NumElements);
63     break;
64   }
65   case Type::StructTyID: {
66     unsigned Typ;
67     vector<const Type*> Elements;
68
69     if (read_vbr(Buf, EndBuf, Typ)) return failure(Val);
70     while (Typ) {         // List is terminated by void/0 typeid
71       const Type *Ty = getType(Typ);
72       if (Ty == 0) return failure(Val);
73       Elements.push_back(Ty);
74       
75       if (read_vbr(Buf, EndBuf, Typ)) return failure(Val);
76     }
77
78     Val = StructType::get(Elements);
79     break;
80   }
81   case Type::PointerTyID: {
82     unsigned ElTyp;
83     if (read_vbr(Buf, EndBuf, ElTyp)) return failure(Val);
84     const Type *ElementType = getType(ElTyp);
85     if (ElementType == 0) return failure(Val);
86     Val = PointerType::get(ElementType);
87     break;
88   }
89
90   case Type::OpaqueTyID: {
91     Val = OpaqueType::get();
92     break;
93   }
94
95   default:
96     cerr << __FILE__ << ":" << __LINE__ << ": Don't know how to deserialize"
97          << " primitive Type " << PrimType << "\n";
98     return failure(Val);
99   }
100
101   return Val;
102 }
103
104 // refineAbstractType - The callback method is invoked when one of the
105 // elements of TypeValues becomes more concrete...
106 //
107 void BytecodeParser::refineAbstractType(const DerivedType *OldType, 
108                                         const Type *NewType) {
109   if (OldType == NewType) return;  // Type is modified, but same
110
111   TypeValuesListTy::iterator I = find(MethodTypeValues.begin(), 
112                                       MethodTypeValues.end(), OldType);
113   if (I == MethodTypeValues.end()) {
114     I = find(ModuleTypeValues.begin(), ModuleTypeValues.end(), OldType);
115     assert(I != ModuleTypeValues.end() && 
116            "Can't refine a type I don't know about!");
117   }
118
119   *I = NewType;  // Update to point to new, more refined type.
120 }
121
122
123
124 // parseTypeConstants - We have to use this wierd code to handle recursive
125 // types.  We know that recursive types will only reference the current slab of
126 // values in the type plane, but they can forward reference types before they
127 // have been read.  For example, Type #0 might be '{ Ty#1 }' and Type #1 might
128 // be 'Ty#0*'.  When reading Type #0, type number one doesn't exist.  To fix
129 // this ugly problem, we pesimistically insert an opaque type for each type we
130 // are about to read.  This means that forward references will resolve to
131 // something and when we reread the type later, we can replace the opaque type
132 // with a new resolved concrete type.
133 //
134 bool BytecodeParser::parseTypeConstants(const uchar *&Buf, const uchar *EndBuf,
135                                         TypeValuesListTy &Tab,
136                                         unsigned NumEntries) {
137   assert(Tab.size() == 0 && "should not have read type constants in before!");
138
139   // Insert a bunch of opaque types to be resolved later...
140   for (unsigned i = 0; i < NumEntries; i++)
141     Tab.push_back(PATypeHandle<Type>(OpaqueType::get(), this));
142
143   // Loop through reading all of the types.  Forward types will make use of the
144   // opaque types just inserted.
145   //
146   for (unsigned i = 0; i < NumEntries; i++) {
147     const Type *NewTy = parseTypeConstant(Buf, EndBuf), *OldTy = Tab[i].get();
148     if (NewTy == 0) return failure(true);
149     BCR_TRACE(4, "Read Type Constant: '" << NewTy << "'\n");
150
151     // Don't insertValue the new type... instead we want to replace the opaque
152     // type with the new concrete value...
153     //
154
155     // Refine the abstract type to the new type.  This causes all uses of the
156     // abstract type to use the newty.  This also will cause the opaque type
157     // to be deleted...
158     //
159     cast<DerivedType>(Tab[i].get())->refineAbstractTypeTo(NewTy);
160
161     // This should have replace the old opaque type with the new type in the
162     // value table... or with a preexisting type that was already in the system
163     assert(Tab[i] != OldTy && "refineAbstractType didn't work!");
164   }
165
166   BCR_TRACE(5, "Resulting types:\n");
167   for (unsigned i = 0; i < NumEntries; i++) {
168     BCR_TRACE(5, cast<const Type>(Tab[i]) << "\n");
169   }
170   return false;
171 }
172
173
174 bool BytecodeParser::parseConstPoolValue(const uchar *&Buf, 
175                                          const uchar *EndBuf,
176                                          const Type *Ty, ConstPoolVal *&V) {
177   switch (Ty->getPrimitiveID()) {
178   case Type::BoolTyID: {
179     unsigned Val;
180     if (read_vbr(Buf, EndBuf, Val)) return failure(true);
181     if (Val != 0 && Val != 1) return failure(true);
182     V = ConstPoolBool::get(Val == 1);
183     break;
184   }
185
186   case Type::UByteTyID:   // Unsigned integer types...
187   case Type::UShortTyID:
188   case Type::UIntTyID: {
189     unsigned Val;
190     if (read_vbr(Buf, EndBuf, Val)) return failure(true);
191     if (!ConstPoolUInt::isValueValidForType(Ty, Val)) return failure(true);
192     V = ConstPoolUInt::get(Ty, Val);
193     break;
194   }
195
196   case Type::ULongTyID: {
197     uint64_t Val;
198     if (read_vbr(Buf, EndBuf, Val)) return failure(true);
199     V = ConstPoolUInt::get(Ty, Val);
200     break;
201   }
202
203   case Type::SByteTyID:   // Unsigned integer types...
204   case Type::ShortTyID:
205   case Type::IntTyID: {
206     int Val;
207     if (read_vbr(Buf, EndBuf, Val)) return failure(true);
208     if (!ConstPoolSInt::isValueValidForType(Ty, Val)) return failure(true);
209     V = ConstPoolSInt::get(Ty, Val);
210     break;
211   }
212
213   case Type::LongTyID: {
214     int64_t Val;
215     if (read_vbr(Buf, EndBuf, Val)) return failure(true);
216     V = ConstPoolSInt::get(Ty, Val);
217     break;
218   }
219
220   case Type::FloatTyID: {
221     float F;
222     if (input_data(Buf, EndBuf, &F, &F+1)) return failure(true);
223     V = ConstPoolFP::get(Ty, F);
224     break;
225   }
226
227   case Type::DoubleTyID: {
228     double Val;
229     if (input_data(Buf, EndBuf, &Val, &Val+1)) return failure(true);
230     V = ConstPoolFP::get(Ty, Val);
231     break;
232   }
233
234   case Type::TypeTyID:
235     assert(0 && "Type constants should be handled seperately!!!");
236     abort();
237
238   case Type::ArrayTyID: {
239     const ArrayType *AT = cast<const ArrayType>(Ty);
240     unsigned NumElements;
241     if (AT->isSized())          // Sized array, # elements stored in type!
242       NumElements = (unsigned)AT->getNumElements();
243     else                        // Unsized array, # elements stored in stream!
244       if (read_vbr(Buf, EndBuf, NumElements)) return failure(true);
245
246     vector<ConstPoolVal *> Elements;
247     while (NumElements--) {   // Read all of the elements of the constant.
248       unsigned Slot;
249       if (read_vbr(Buf, EndBuf, Slot)) return failure(true);
250       Value *V = getValue(AT->getElementType(), Slot, false);
251       if (!V || !isa<ConstPoolVal>(V)) return failure(true);
252       Elements.push_back(cast<ConstPoolVal>(V));
253     }
254     V = ConstPoolArray::get(AT, Elements);
255     break;
256   }
257
258   case Type::StructTyID: {
259     const StructType *ST = cast<StructType>(Ty);
260     const StructType::ElementTypes &ET = ST->getElementTypes();
261
262     vector<ConstPoolVal *> Elements;
263     for (unsigned i = 0; i < ET.size(); ++i) {
264       unsigned Slot;
265       if (read_vbr(Buf, EndBuf, Slot)) return failure(true);
266       Value *V = getValue(ET[i], Slot, false);
267       if (!V || !isa<ConstPoolVal>(V))
268         return failure(true);
269       Elements.push_back(cast<ConstPoolVal>(V));      
270     }
271
272     V = ConstPoolStruct::get(ST, Elements);
273     break;
274   }    
275
276   case Type::PointerTyID: {
277     const PointerType *PT = cast<const PointerType>(Ty);
278     unsigned SubClass;
279     if (read_vbr(Buf, EndBuf, SubClass)) return failure(true);
280     switch (SubClass) {
281     case 0:    // ConstPoolPointerNull value...
282       V = ConstPoolPointerNull::get(PT);
283       break;
284
285     case 1: {  // ConstPoolPointerRef value...
286       unsigned Slot;
287       if (read_vbr(Buf, EndBuf, Slot)) return failure(true);
288       BCR_TRACE(4, "CPPR: Type: '" << Ty << "'  slot: " << Slot << "\n");
289
290       // Check to see if we have already read this global variable yet...
291       Value *Val = getValue(PT, Slot, false);
292       GlobalValue *GV;
293       if (Val) {
294         if (!(GV = dyn_cast<GlobalValue>(Val))) return failure(true);
295         BCR_TRACE(5, "Value Found in ValueTable!\n");
296       } else {         // Nope... see if we have previously forward ref'd it
297         GlobalRefsType::iterator I = GlobalRefs.find(make_pair(PT, Slot));
298         if (I != GlobalRefs.end()) {
299           BCR_TRACE(5, "Previous forward ref found!\n");
300           GV = I->second;
301         } else {
302           BCR_TRACE(5, "Creating new forward ref variable!\n");
303
304           // Create a placeholder for the global variable reference...
305           GlobalVariable *GVar = new GlobalVariable(PT->getValueType(), false);
306
307           // Keep track of the fact that we have a forward ref to recycle it
308           GlobalRefs.insert(make_pair(make_pair(PT, Slot), GVar));
309
310           // Must temporarily push this value into the module table...
311           TheModule->getGlobalList().push_back(GVar);
312           GV = GVar;
313         }
314       }
315       
316       V = ConstPoolPointerRef::get(GV);
317       break;
318     }
319     default:
320       return failure(true);
321     }
322     break;
323   }
324
325   default:
326     cerr << __FILE__ << ":" << __LINE__ 
327          << ": Don't know how to deserialize constant value of type '"
328          << Ty->getName() << "'\n";
329     return failure(true);
330   }
331
332   return false;
333 }
334
335 bool BytecodeParser::ParseConstantPool(const uchar *&Buf, const uchar *EndBuf,
336                                        ValueTable &Tab, 
337                                        TypeValuesListTy &TypeTab) {
338   while (Buf < EndBuf) {
339     unsigned NumEntries, Typ;
340
341     if (read_vbr(Buf, EndBuf, NumEntries) ||
342         read_vbr(Buf, EndBuf, Typ)) return failure(true);
343     const Type *Ty = getType(Typ);
344     if (Ty == 0) return failure(true);
345     BCR_TRACE(3, "Type: '" << Ty << "'  NumEntries: " << NumEntries << "\n");
346
347     if (Typ == Type::TypeTyID) {
348       if (parseTypeConstants(Buf, EndBuf, TypeTab, NumEntries)) return true;
349     } else {
350       for (unsigned i = 0; i < NumEntries; i++) {
351         ConstPoolVal *I;
352         if (parseConstPoolValue(Buf, EndBuf, Ty, I)) return failure(true);
353         BCR_TRACE(4, "Read Constant: '" << I << "'\n");
354         if (insertValue(I, Tab) == -1) return failure(true);
355       }
356     }
357   }
358   
359   if (Buf > EndBuf) return failure(true);
360   return false;
361 }