Add support for extern varargs methods & varargs method calls
[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 "ReaderInternals.h"
16
17 bool 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
36     MethodType::ParamTypes Params;
37
38     if (read_vbr(Buf, EndBuf, Typ)) return true;
39     while (Typ) {
40       const Type *Ty = getType(Typ);
41       if (Ty == 0) return true;
42       Params.push_back(Ty);
43       
44       if (read_vbr(Buf, EndBuf, Typ)) return true;
45     }
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
96 bool 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
142   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
156   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);
173       if (!V || !V->isConstant())
174         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);
190       if (!V || !V->isConstant())
191         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
208 bool 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 }