1 //===- ReadConst.cpp - Code to constants and constant pools -----------------===
3 // This file implements functionality to deserialize constants and entire
6 // Note that this library should be as fast as possible, reentrant, and
9 //===------------------------------------------------------------------------===
11 #include "llvm/Module.h"
12 #include "llvm/BasicBlock.h"
13 #include "llvm/ConstPoolVals.h"
14 #include "llvm/DerivedTypes.h"
15 #include "ReaderInternals.h"
17 bool BytecodeParser::parseTypeConstant(const uchar *&Buf, const uchar *EndBuf,
22 if (read_vbr(Buf, EndBuf, PrimType)) return true;
24 if ((Val = Type::getPrimitiveType((Type::PrimitiveID)PrimType))) {
25 V = new ConstPoolType(Val); // It's just a primitive ID.
30 case Type::MethodTyID: {
32 if (read_vbr(Buf, EndBuf, Typ)) return true;
33 const Type *RetType = getType(Typ);
34 if (RetType == 0) return true;
36 MethodType::ParamTypes Params;
38 if (read_vbr(Buf, EndBuf, Typ)) return true;
40 const Type *Ty = getType(Typ);
41 if (Ty == 0) return true;
44 if (read_vbr(Buf, EndBuf, Typ)) return true;
47 Val = MethodType::getMethodType(RetType, Params);
50 case Type::ArrayTyID: {
52 if (read_vbr(Buf, EndBuf, ElTyp)) return true;
53 const Type *ElementType = getType(ElTyp);
54 if (ElementType == 0) return true;
57 if (read_vbr(Buf, EndBuf, NumElements)) return true;
58 Val = ArrayType::getArrayType(ElementType, NumElements);
61 case Type::StructTyID: {
63 StructType::ElementTypes Elements;
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);
71 if (read_vbr(Buf, EndBuf, Typ)) return true;
74 Val = StructType::getStructType(Elements);
77 case Type::PointerTyID: {
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);
87 cerr << __FILE__ << ":" << __LINE__ << ": Don't know how to deserialize"
88 << " primitive Type " << PrimType << "\n";
92 V = new ConstPoolType(Val);
96 bool BytecodeParser::parseConstPoolValue(const uchar *&Buf,
98 const Type *Ty, ConstPoolVal *&V) {
99 switch (Ty->getPrimitiveID()) {
100 case Type::BoolTyID: {
102 if (read_vbr(Buf, EndBuf, Val)) return true;
103 if (Val != 0 && Val != 1) return true;
104 V = new ConstPoolBool(Val == 1);
108 case Type::UByteTyID: // Unsigned integer types...
109 case Type::UShortTyID:
110 case Type::UIntTyID: {
112 if (read_vbr(Buf, EndBuf, Val)) return true;
113 if (!ConstPoolUInt::isValueValidForType(Ty, Val)) return true;
114 V = new ConstPoolUInt(Ty, Val);
118 case Type::ULongTyID: {
120 if (read_vbr(Buf, EndBuf, Val)) return true;
121 V = new ConstPoolUInt(Ty, Val);
125 case Type::SByteTyID: // Unsigned integer types...
126 case Type::ShortTyID:
127 case Type::IntTyID: {
129 if (read_vbr(Buf, EndBuf, Val)) return true;
130 if (!ConstPoolSInt::isValueValidForType(Ty, Val)) return 0;
131 V = new ConstPoolSInt(Ty, Val);
135 case Type::LongTyID: {
137 if (read_vbr(Buf, EndBuf, Val)) return true;
138 V = new ConstPoolSInt(Ty, Val);
142 case Type::FloatTyID: {
144 if (input_data(Buf, EndBuf, &F, &F+1)) return true;
145 V = new ConstPoolFP(Ty, F);
149 case Type::DoubleTyID: {
151 if (input_data(Buf, EndBuf, &Val, &Val+1)) return true;
152 V = new ConstPoolFP(Ty, Val);
157 if (parseTypeConstant(Buf, EndBuf, V)) return true;
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;
168 vector<ConstPoolVal *> Elements;
169 while (NumElements--) { // Read all of the elements of the constant.
171 if (read_vbr(Buf, EndBuf, Slot)) return true;
172 Value *V = getValue(AT->getElementType(), Slot, false);
173 if (!V || !V->isConstant())
175 Elements.push_back((ConstPoolVal*)V);
177 V = new ConstPoolArray(AT, Elements);
181 case Type::StructTyID: {
182 const StructType *ST = (const StructType*)Ty;
183 const StructType::ElementTypes &ET = ST->getElementTypes();
185 vector<ConstPoolVal *> Elements;
186 for (unsigned i = 0; i < ET.size(); ++i) {
188 if (read_vbr(Buf, EndBuf, Slot)) return true;
189 Value *V = getValue(ET[i], Slot, false);
190 if (!V || !V->isConstant())
192 Elements.push_back((ConstPoolVal*)V);
195 V = new ConstPoolStruct(ST, Elements);
200 cerr << __FILE__ << ":" << __LINE__
201 << ": Don't know how to deserialize constant value of type '"
202 << Ty->getName() << "'\n";
208 bool BytecodeParser::ParseConstantPool(const uchar *&Buf, const uchar *EndBuf,
209 SymTabValue::ConstantPoolType &CP,
211 while (Buf < EndBuf) {
212 unsigned NumEntries, Typ;
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;
219 for (unsigned i = 0; i < NumEntries; i++) {
221 if (parseConstPoolValue(Buf, EndBuf, Ty, I)) return true;
223 cerr << " Read const value: <" << I->getType()->getName()
224 << ">: " << I->getStrValue() << endl;