diff options
author | Chris Lattner <sabre@nondot.org> | 2001-06-06 20:29:01 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2001-06-06 20:29:01 +0000 |
commit | 009505452b713ed2e3a8e99c5545a6e721c65495 (patch) | |
tree | 136a71c5b87bdf534d1f20a67558b49226b5a4d6 /lib/Bytecode/Reader/ConstantReader.cpp | |
parent | 8d0afd3d32d1d67f9aa5df250a1d6955aa8f1ac9 (diff) |
Initial revision
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Bytecode/Reader/ConstantReader.cpp')
-rw-r--r-- | lib/Bytecode/Reader/ConstantReader.cpp | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/lib/Bytecode/Reader/ConstantReader.cpp b/lib/Bytecode/Reader/ConstantReader.cpp new file mode 100644 index 0000000000..b85bd887ef --- /dev/null +++ b/lib/Bytecode/Reader/ConstantReader.cpp @@ -0,0 +1,218 @@ +//===- ReadConst.cpp - Code to constants and constant pools -----------------=== +// +// This file implements functionality to deserialize constants and entire +// constant pools. +// +// Note that this library should be as fast as possible, reentrant, and +// threadsafe!! +// +//===------------------------------------------------------------------------=== + +#include "llvm/Module.h" +#include "llvm/BasicBlock.h" +#include "llvm/ConstPoolVals.h" +#include "llvm/DerivedTypes.h" +#include "ReaderInternals.h" + +bool BytecodeParser::parseTypeConstant(const uchar *&Buf, const uchar *EndBuf, + ConstPoolVal *&V) { + const Type *Val = 0; + + unsigned PrimType; + if (read_vbr(Buf, EndBuf, PrimType)) return true; + + if ((Val = Type::getPrimitiveType((Type::PrimitiveID)PrimType))) { + V = new ConstPoolType(Val); // It's just a primitive ID. + return false; + } + + switch (PrimType) { + case Type::MethodTyID: { + unsigned Typ; + if (read_vbr(Buf, EndBuf, Typ)) return true; + const Type *RetType = getType(Typ); + if (RetType == 0) return true; + + MethodType::ParamTypes Params; + + if (read_vbr(Buf, EndBuf, Typ)) return true; + while (Typ) { + const Type *Ty = getType(Typ); + if (Ty == 0) return true; + Params.push_back(Ty); + + if (read_vbr(Buf, EndBuf, Typ)) return true; + } + + Val = MethodType::getMethodType(RetType, Params); + break; + } + case Type::ArrayTyID: { + unsigned ElTyp; + if (read_vbr(Buf, EndBuf, ElTyp)) return true; + const Type *ElementType = getType(ElTyp); + if (ElementType == 0) return true; + + int NumElements; + if (read_vbr(Buf, EndBuf, NumElements)) return true; + Val = ArrayType::getArrayType(ElementType, NumElements); + break; + } + case Type::StructTyID: { + unsigned Typ; + StructType::ElementTypes Elements; + + if (read_vbr(Buf, EndBuf, Typ)) return true; + while (Typ) { // List is terminated by void/0 typeid + const Type *Ty = getType(Typ); + if (Ty == 0) return true; + Elements.push_back(Ty); + + if (read_vbr(Buf, EndBuf, Typ)) return true; + } + + Val = StructType::getStructType(Elements); + break; + } + case Type::PointerTyID: { + unsigned ElTyp; + if (read_vbr(Buf, EndBuf, ElTyp)) return true; + const Type *ElementType = getType(ElTyp); + if (ElementType == 0) return true; + Val = PointerType::getPointerType(ElementType); + break; + } + + default: + cerr << __FILE__ << ":" << __LINE__ << ": Don't know how to deserialize" + << " primitive Type " << PrimType << "\n"; + return true; + } + + V = new ConstPoolType(Val); + return false; +} + +bool BytecodeParser::parseConstPoolValue(const uchar *&Buf, + const uchar *EndBuf, + const Type *Ty, ConstPoolVal *&V) { + switch (Ty->getPrimitiveID()) { + case Type::BoolTyID: { + unsigned Val; + if (read_vbr(Buf, EndBuf, Val)) return true; + if (Val != 0 && Val != 1) return true; + V = new ConstPoolBool(Val == 1); + break; + } + + case Type::UByteTyID: // Unsigned integer types... + case Type::UShortTyID: + case Type::UIntTyID: { + unsigned Val; + if (read_vbr(Buf, EndBuf, Val)) return true; + if (!ConstPoolUInt::isValueValidForType(Ty, Val)) return true; + V = new ConstPoolUInt(Ty, Val); + break; + } + + case Type::ULongTyID: { + uint64_t Val; + if (read_vbr(Buf, EndBuf, Val)) return true; + V = new ConstPoolUInt(Ty, Val); + break; + } + + case Type::SByteTyID: // Unsigned integer types... + case Type::ShortTyID: + case Type::IntTyID: { + int Val; + if (read_vbr(Buf, EndBuf, Val)) return true; + if (!ConstPoolSInt::isValueValidForType(Ty, Val)) return 0; + V = new ConstPoolSInt(Ty, Val); + break; + } + + case Type::LongTyID: { + int64_t Val; + if (read_vbr(Buf, EndBuf, Val)) return true; + V = new ConstPoolSInt(Ty, Val); + break; + } + + case Type::TypeTyID: + if (parseTypeConstant(Buf, EndBuf, V)) return true; + break; + + case Type::ArrayTyID: { + const ArrayType *AT = (const ArrayType*)Ty; + unsigned NumElements; + if (AT->isSized()) // Sized array, # elements stored in type! + NumElements = (unsigned)AT->getNumElements(); + else // Unsized array, # elements stored in stream! + if (read_vbr(Buf, EndBuf, NumElements)) return true; + + vector<ConstPoolVal *> Elements; + while (NumElements--) { // Read all of the elements of the constant. + unsigned Slot; + if (read_vbr(Buf, EndBuf, Slot)) return true; + Value *V = getValue(AT->getElementType(), Slot, false); + if (!V || V->getValueType() != Value::ConstantVal) + return true; + Elements.push_back((ConstPoolVal*)V); + } + V = new ConstPoolArray(AT, Elements); + break; + } + + case Type::StructTyID: { + const StructType *ST = (const StructType*)Ty; + const StructType::ElementTypes &ET = ST->getElementTypes(); + + vector<ConstPoolVal *> Elements; + for (unsigned i = 0; i < ET.size(); ++i) { + unsigned Slot; + if (read_vbr(Buf, EndBuf, Slot)) return true; + Value *V = getValue(ET[i], Slot, false); + if (!V || V->getValueType() != Value::ConstantVal) + return true; + Elements.push_back((ConstPoolVal*)V); + } + + V = new ConstPoolStruct(ST, Elements); + break; + } + + default: + cerr << __FILE__ << ":" << __LINE__ + << ": Don't know how to deserialize constant value of type '" + << Ty->getName() << "'\n"; + return true; + } + return false; +} + +bool BytecodeParser::ParseConstantPool(const uchar *&Buf, const uchar *EndBuf, + SymTabValue::ConstantPoolType &CP, + ValueTable &Tab) { + while (Buf < EndBuf) { + unsigned NumEntries, Typ; + + if (read_vbr(Buf, EndBuf, NumEntries) || + read_vbr(Buf, EndBuf, Typ)) return true; + const Type *Ty = getType(Typ); + if (Ty == 0) return true; + + for (unsigned i = 0; i < NumEntries; i++) { + ConstPoolVal *I; + if (parseConstPoolValue(Buf, EndBuf, Ty, I)) return true; +#if 0 + cerr << " Read const value: <" << I->getType()->getName() + << ">: " << I->getStrValue() << endl; +#endif + insertValue(I, Tab); + CP.insert(I); + } + } + + return Buf > EndBuf; +} |