blob: dd47d1c2cfb6668995ddbc48e0ae2d5e02ac73d7 [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
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
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
142 case Type::TypeTyID:
143 if (parseTypeConstant(Buf, EndBuf, V)) return true;
144 break;
145
146 case Type::ArrayTyID: {
147 const ArrayType *AT = (const ArrayType*)Ty;
148 unsigned NumElements;
149 if (AT->isSized()) // Sized array, # elements stored in type!
150 NumElements = (unsigned)AT->getNumElements();
151 else // Unsized array, # elements stored in stream!
152 if (read_vbr(Buf, EndBuf, NumElements)) return true;
153
154 vector<ConstPoolVal *> Elements;
155 while (NumElements--) { // Read all of the elements of the constant.
156 unsigned Slot;
157 if (read_vbr(Buf, EndBuf, Slot)) return true;
158 Value *V = getValue(AT->getElementType(), Slot, false);
Chris Lattner7fc9fe32001-06-27 23:41:11 +0000159 if (!V || !V->isConstant())
Chris Lattner00950542001-06-06 20:29:01 +0000160 return true;
161 Elements.push_back((ConstPoolVal*)V);
162 }
163 V = new ConstPoolArray(AT, Elements);
164 break;
165 }
166
167 case Type::StructTyID: {
168 const StructType *ST = (const StructType*)Ty;
169 const StructType::ElementTypes &ET = ST->getElementTypes();
170
171 vector<ConstPoolVal *> Elements;
172 for (unsigned i = 0; i < ET.size(); ++i) {
173 unsigned Slot;
174 if (read_vbr(Buf, EndBuf, Slot)) return true;
175 Value *V = getValue(ET[i], Slot, false);
Chris Lattner7fc9fe32001-06-27 23:41:11 +0000176 if (!V || !V->isConstant())
Chris Lattner00950542001-06-06 20:29:01 +0000177 return true;
178 Elements.push_back((ConstPoolVal*)V);
179 }
180
181 V = new ConstPoolStruct(ST, Elements);
182 break;
183 }
184
185 default:
186 cerr << __FILE__ << ":" << __LINE__
187 << ": Don't know how to deserialize constant value of type '"
188 << Ty->getName() << "'\n";
189 return true;
190 }
191 return false;
192}
193
194bool BytecodeParser::ParseConstantPool(const uchar *&Buf, const uchar *EndBuf,
195 SymTabValue::ConstantPoolType &CP,
196 ValueTable &Tab) {
197 while (Buf < EndBuf) {
198 unsigned NumEntries, Typ;
199
200 if (read_vbr(Buf, EndBuf, NumEntries) ||
201 read_vbr(Buf, EndBuf, Typ)) return true;
202 const Type *Ty = getType(Typ);
203 if (Ty == 0) return true;
204
205 for (unsigned i = 0; i < NumEntries; i++) {
206 ConstPoolVal *I;
207 if (parseConstPoolValue(Buf, EndBuf, Ty, I)) return true;
208#if 0
209 cerr << " Read const value: <" << I->getType()->getName()
210 << ">: " << I->getStrValue() << endl;
211#endif
212 insertValue(I, Tab);
213 CP.insert(I);
214 }
215 }
216
217 return Buf > EndBuf;
218}