blob: ec841cfbbe1fd3c3bfa10504c08e9273778175b3 [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;
Chris Lattner3d3f2892001-07-28 17:50:18 +000022 if (read_vbr(Buf, EndBuf, PrimType)) return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +000023
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;
Chris Lattner3d3f2892001-07-28 17:50:18 +000032 if (read_vbr(Buf, EndBuf, Typ)) return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +000033 const Type *RetType = getType(Typ);
Chris Lattner3d3f2892001-07-28 17:50:18 +000034 if (RetType == 0) return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +000035
Chris Lattnere5a57ee2001-07-25 22:47:55 +000036 unsigned NumParams;
Chris Lattner3d3f2892001-07-28 17:50:18 +000037 if (read_vbr(Buf, EndBuf, NumParams)) return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +000038
Chris Lattnere5a57ee2001-07-25 22:47:55 +000039 MethodType::ParamTypes Params;
40 while (NumParams--) {
Chris Lattner3d3f2892001-07-28 17:50:18 +000041 if (read_vbr(Buf, EndBuf, Typ)) return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +000042 const Type *Ty = getType(Typ);
Chris Lattner3d3f2892001-07-28 17:50:18 +000043 if (Ty == 0) return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +000044 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;
Chris Lattner3d3f2892001-07-28 17:50:18 +000052 if (read_vbr(Buf, EndBuf, ElTyp)) return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +000053 const Type *ElementType = getType(ElTyp);
Chris Lattner3d3f2892001-07-28 17:50:18 +000054 if (ElementType == 0) return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +000055
56 int NumElements;
Chris Lattner3d3f2892001-07-28 17:50:18 +000057 if (read_vbr(Buf, EndBuf, NumElements)) return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +000058 Val = ArrayType::getArrayType(ElementType, NumElements);
59 break;
60 }
61 case Type::StructTyID: {
62 unsigned Typ;
63 StructType::ElementTypes Elements;
64
Chris Lattner3d3f2892001-07-28 17:50:18 +000065 if (read_vbr(Buf, EndBuf, Typ)) return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +000066 while (Typ) { // List is terminated by void/0 typeid
67 const Type *Ty = getType(Typ);
Chris Lattner3d3f2892001-07-28 17:50:18 +000068 if (Ty == 0) return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +000069 Elements.push_back(Ty);
70
Chris Lattner3d3f2892001-07-28 17:50:18 +000071 if (read_vbr(Buf, EndBuf, Typ)) return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +000072 }
73
74 Val = StructType::getStructType(Elements);
75 break;
76 }
77 case Type::PointerTyID: {
78 unsigned ElTyp;
Chris Lattner3d3f2892001-07-28 17:50:18 +000079 if (read_vbr(Buf, EndBuf, ElTyp)) return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +000080 const Type *ElementType = getType(ElTyp);
Chris Lattner3d3f2892001-07-28 17:50:18 +000081 if (ElementType == 0) return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +000082 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";
Chris Lattner3d3f2892001-07-28 17:50:18 +000089 return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +000090 }
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;
Chris Lattner3d3f2892001-07-28 17:50:18 +0000102 if (read_vbr(Buf, EndBuf, Val)) return failure(true);
103 if (Val != 0 && Val != 1) return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +0000104 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;
Chris Lattner3d3f2892001-07-28 17:50:18 +0000112 if (read_vbr(Buf, EndBuf, Val)) return failure(true);
113 if (!ConstPoolUInt::isValueValidForType(Ty, Val)) return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +0000114 V = new ConstPoolUInt(Ty, Val);
115 break;
116 }
117
118 case Type::ULongTyID: {
119 uint64_t Val;
Chris Lattner3d3f2892001-07-28 17:50:18 +0000120 if (read_vbr(Buf, EndBuf, Val)) return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +0000121 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;
Chris Lattner3d3f2892001-07-28 17:50:18 +0000129 if (read_vbr(Buf, EndBuf, Val)) return failure(true);
130 if (!ConstPoolSInt::isValueValidForType(Ty, Val)) return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +0000131 V = new ConstPoolSInt(Ty, Val);
132 break;
133 }
134
135 case Type::LongTyID: {
136 int64_t Val;
Chris Lattner3d3f2892001-07-28 17:50:18 +0000137 if (read_vbr(Buf, EndBuf, Val)) return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +0000138 V = new ConstPoolSInt(Ty, Val);
139 break;
140 }
141
Chris Lattnera1375302001-07-15 00:17:18 +0000142 case Type::FloatTyID: {
143 float F;
Chris Lattner3d3f2892001-07-28 17:50:18 +0000144 if (input_data(Buf, EndBuf, &F, &F+1)) return failure(true);
Chris Lattnera1375302001-07-15 00:17:18 +0000145 V = new ConstPoolFP(Ty, F);
146 break;
147 }
148
149 case Type::DoubleTyID: {
150 double Val;
Chris Lattner3d3f2892001-07-28 17:50:18 +0000151 if (input_data(Buf, EndBuf, &Val, &Val+1)) return failure(true);
Chris Lattnera1375302001-07-15 00:17:18 +0000152 V = new ConstPoolFP(Ty, Val);
153 break;
154 }
155
Chris Lattner00950542001-06-06 20:29:01 +0000156 case Type::TypeTyID:
Chris Lattner3d3f2892001-07-28 17:50:18 +0000157 if (parseTypeConstant(Buf, EndBuf, V)) return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +0000158 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!
Chris Lattner3d3f2892001-07-28 17:50:18 +0000166 if (read_vbr(Buf, EndBuf, NumElements)) return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +0000167
168 vector<ConstPoolVal *> Elements;
169 while (NumElements--) { // Read all of the elements of the constant.
170 unsigned Slot;
Chris Lattner3d3f2892001-07-28 17:50:18 +0000171 if (read_vbr(Buf, EndBuf, Slot)) return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +0000172 Value *V = getValue(AT->getElementType(), Slot, false);
Chris Lattner3d3f2892001-07-28 17:50:18 +0000173 if (!V || !V->isConstant()) return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +0000174 Elements.push_back((ConstPoolVal*)V);
175 }
176 V = new ConstPoolArray(AT, Elements);
177 break;
178 }
179
180 case Type::StructTyID: {
181 const StructType *ST = (const StructType*)Ty;
182 const StructType::ElementTypes &ET = ST->getElementTypes();
183
184 vector<ConstPoolVal *> Elements;
185 for (unsigned i = 0; i < ET.size(); ++i) {
186 unsigned Slot;
Chris Lattner3d3f2892001-07-28 17:50:18 +0000187 if (read_vbr(Buf, EndBuf, Slot)) return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +0000188 Value *V = getValue(ET[i], Slot, false);
Chris Lattner7fc9fe32001-06-27 23:41:11 +0000189 if (!V || !V->isConstant())
Chris Lattner3d3f2892001-07-28 17:50:18 +0000190 return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +0000191 Elements.push_back((ConstPoolVal*)V);
192 }
193
194 V = new ConstPoolStruct(ST, Elements);
195 break;
196 }
197
198 default:
199 cerr << __FILE__ << ":" << __LINE__
200 << ": Don't know how to deserialize constant value of type '"
201 << Ty->getName() << "'\n";
Chris Lattner3d3f2892001-07-28 17:50:18 +0000202 return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +0000203 }
204 return false;
205}
206
207bool BytecodeParser::ParseConstantPool(const uchar *&Buf, const uchar *EndBuf,
208 SymTabValue::ConstantPoolType &CP,
209 ValueTable &Tab) {
210 while (Buf < EndBuf) {
211 unsigned NumEntries, Typ;
212
213 if (read_vbr(Buf, EndBuf, NumEntries) ||
Chris Lattner3d3f2892001-07-28 17:50:18 +0000214 read_vbr(Buf, EndBuf, Typ)) return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +0000215 const Type *Ty = getType(Typ);
Chris Lattner3d3f2892001-07-28 17:50:18 +0000216 if (Ty == 0) return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +0000217
218 for (unsigned i = 0; i < NumEntries; i++) {
219 ConstPoolVal *I;
Chris Lattner3d3f2892001-07-28 17:50:18 +0000220 if (parseConstPoolValue(Buf, EndBuf, Ty, I)) return failure(true);
Chris Lattner00950542001-06-06 20:29:01 +0000221#if 0
222 cerr << " Read const value: <" << I->getType()->getName()
223 << ">: " << I->getStrValue() << endl;
224#endif
225 insertValue(I, Tab);
226 CP.insert(I);
227 }
228 }
229
Chris Lattner3d3f2892001-07-28 17:50:18 +0000230 if (Buf > EndBuf) return failure(true);
231 return false;
Chris Lattner00950542001-06-06 20:29:01 +0000232}