mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-14 23:48:56 +00:00
Change all of the bytecode reader primitives to throw exceptions instead of
returning error codes. Because they don't return an error code, they can return the value read, which simplifies the code and makes the reader more efficient (yaay!). Also eliminate the special case code for little endian machines. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10871 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c8434e3d71
commit
7969dc2bec
@ -23,8 +23,7 @@ using namespace llvm;
|
|||||||
|
|
||||||
const Type *BytecodeParser::parseTypeConstant(const unsigned char *&Buf,
|
const Type *BytecodeParser::parseTypeConstant(const unsigned char *&Buf,
|
||||||
const unsigned char *EndBuf) {
|
const unsigned char *EndBuf) {
|
||||||
unsigned PrimType;
|
unsigned PrimType = read_vbr_uint(Buf, EndBuf);
|
||||||
if (read_vbr(Buf, EndBuf, PrimType)) throw Error_readvbr;
|
|
||||||
|
|
||||||
const Type *Val = 0;
|
const Type *Val = 0;
|
||||||
if ((Val = Type::getPrimitiveType((Type::PrimitiveID)PrimType)))
|
if ((Val = Type::getPrimitiveType((Type::PrimitiveID)PrimType)))
|
||||||
@ -32,18 +31,13 @@ const Type *BytecodeParser::parseTypeConstant(const unsigned char *&Buf,
|
|||||||
|
|
||||||
switch (PrimType) {
|
switch (PrimType) {
|
||||||
case Type::FunctionTyID: {
|
case Type::FunctionTyID: {
|
||||||
unsigned Typ;
|
const Type *RetType = getType(read_vbr_uint(Buf, EndBuf));
|
||||||
if (read_vbr(Buf, EndBuf, Typ)) return Val;
|
|
||||||
const Type *RetType = getType(Typ);
|
|
||||||
|
|
||||||
unsigned NumParams;
|
unsigned NumParams = read_vbr_uint(Buf, EndBuf);
|
||||||
if (read_vbr(Buf, EndBuf, NumParams)) return Val;
|
|
||||||
|
|
||||||
std::vector<const Type*> Params;
|
std::vector<const Type*> Params;
|
||||||
while (NumParams--) {
|
while (NumParams--)
|
||||||
if (read_vbr(Buf, EndBuf, Typ)) return Val;
|
Params.push_back(getType(read_vbr_uint(Buf, EndBuf)));
|
||||||
Params.push_back(getType(Typ));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
|
bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
|
||||||
if (isVarArg) Params.pop_back();
|
if (isVarArg) Params.pop_back();
|
||||||
@ -51,32 +45,27 @@ const Type *BytecodeParser::parseTypeConstant(const unsigned char *&Buf,
|
|||||||
return FunctionType::get(RetType, Params, isVarArg);
|
return FunctionType::get(RetType, Params, isVarArg);
|
||||||
}
|
}
|
||||||
case Type::ArrayTyID: {
|
case Type::ArrayTyID: {
|
||||||
unsigned ElTyp;
|
unsigned ElTyp = read_vbr_uint(Buf, EndBuf);
|
||||||
if (read_vbr(Buf, EndBuf, ElTyp)) return Val;
|
|
||||||
const Type *ElementType = getType(ElTyp);
|
const Type *ElementType = getType(ElTyp);
|
||||||
|
|
||||||
unsigned NumElements;
|
unsigned NumElements = read_vbr_uint(Buf, EndBuf);
|
||||||
if (read_vbr(Buf, EndBuf, NumElements)) return Val;
|
|
||||||
|
|
||||||
BCR_TRACE(5, "Array Type Constant #" << ElTyp << " size="
|
BCR_TRACE(5, "Array Type Constant #" << ElTyp << " size="
|
||||||
<< NumElements << "\n");
|
<< NumElements << "\n");
|
||||||
return ArrayType::get(ElementType, NumElements);
|
return ArrayType::get(ElementType, NumElements);
|
||||||
}
|
}
|
||||||
case Type::StructTyID: {
|
case Type::StructTyID: {
|
||||||
unsigned Typ;
|
|
||||||
std::vector<const Type*> Elements;
|
std::vector<const Type*> Elements;
|
||||||
|
unsigned Typ = read_vbr_uint(Buf, EndBuf);
|
||||||
if (read_vbr(Buf, EndBuf, Typ)) return Val;
|
|
||||||
while (Typ) { // List is terminated by void/0 typeid
|
while (Typ) { // List is terminated by void/0 typeid
|
||||||
Elements.push_back(getType(Typ));
|
Elements.push_back(getType(Typ));
|
||||||
if (read_vbr(Buf, EndBuf, Typ)) return Val;
|
Typ = read_vbr_uint(Buf, EndBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
return StructType::get(Elements);
|
return StructType::get(Elements);
|
||||||
}
|
}
|
||||||
case Type::PointerTyID: {
|
case Type::PointerTyID: {
|
||||||
unsigned ElTyp;
|
unsigned ElTyp = read_vbr_uint(Buf, EndBuf);
|
||||||
if (read_vbr(Buf, EndBuf, ElTyp)) return Val;
|
|
||||||
BCR_TRACE(5, "Pointer Type Constant #" << ElTyp << "\n");
|
BCR_TRACE(5, "Pointer Type Constant #" << ElTyp << "\n");
|
||||||
return PointerType::get(getType(ElTyp));
|
return PointerType::get(getType(ElTyp));
|
||||||
}
|
}
|
||||||
@ -154,20 +143,19 @@ Constant *BytecodeParser::parseConstantValue(const unsigned char *&Buf,
|
|||||||
// We must check for a ConstantExpr before switching by type because
|
// We must check for a ConstantExpr before switching by type because
|
||||||
// a ConstantExpr can be of any type, and has no explicit value.
|
// a ConstantExpr can be of any type, and has no explicit value.
|
||||||
//
|
//
|
||||||
unsigned isExprNumArgs; // 0 if not expr; numArgs if is expr
|
// 0 if not expr; numArgs if is expr
|
||||||
if (read_vbr(Buf, EndBuf, isExprNumArgs)) throw Error_readvbr;
|
unsigned isExprNumArgs = read_vbr_uint(Buf, EndBuf);
|
||||||
|
|
||||||
if (isExprNumArgs) {
|
if (isExprNumArgs) {
|
||||||
// FIXME: Encoding of constant exprs could be much more compact!
|
// FIXME: Encoding of constant exprs could be much more compact!
|
||||||
unsigned Opcode;
|
|
||||||
std::vector<Constant*> ArgVec;
|
std::vector<Constant*> ArgVec;
|
||||||
ArgVec.reserve(isExprNumArgs);
|
ArgVec.reserve(isExprNumArgs);
|
||||||
if (read_vbr(Buf, EndBuf, Opcode)) throw Error_readvbr;
|
unsigned Opcode = read_vbr_uint(Buf, EndBuf);
|
||||||
|
|
||||||
// Read the slot number and types of each of the arguments
|
// Read the slot number and types of each of the arguments
|
||||||
for (unsigned i = 0; i != isExprNumArgs; ++i) {
|
for (unsigned i = 0; i != isExprNumArgs; ++i) {
|
||||||
unsigned ArgValSlot, ArgTypeSlot;
|
unsigned ArgValSlot = read_vbr_uint(Buf, EndBuf);
|
||||||
if (read_vbr(Buf, EndBuf, ArgValSlot)) throw Error_readvbr;
|
unsigned ArgTypeSlot = read_vbr_uint(Buf, EndBuf);
|
||||||
if (read_vbr(Buf, EndBuf, ArgTypeSlot)) throw Error_readvbr;
|
|
||||||
BCR_TRACE(4, "CE Arg " << i << ": Type: '" << *getType(ArgTypeSlot)
|
BCR_TRACE(4, "CE Arg " << i << ": Type: '" << *getType(ArgTypeSlot)
|
||||||
<< "' slot: " << ArgValSlot << "\n");
|
<< "' slot: " << ArgValSlot << "\n");
|
||||||
|
|
||||||
@ -191,8 +179,7 @@ Constant *BytecodeParser::parseConstantValue(const unsigned char *&Buf,
|
|||||||
const Type *Ty = getType(TypeID);
|
const Type *Ty = getType(TypeID);
|
||||||
switch (Ty->getPrimitiveID()) {
|
switch (Ty->getPrimitiveID()) {
|
||||||
case Type::BoolTyID: {
|
case Type::BoolTyID: {
|
||||||
unsigned Val;
|
unsigned Val = read_vbr_uint(Buf, EndBuf);
|
||||||
if (read_vbr(Buf, EndBuf, Val)) throw Error_readvbr;
|
|
||||||
if (Val != 0 && Val != 1) throw std::string("Invalid boolean value read.");
|
if (Val != 0 && Val != 1) throw std::string("Invalid boolean value read.");
|
||||||
return ConstantBool::get(Val == 1);
|
return ConstantBool::get(Val == 1);
|
||||||
}
|
}
|
||||||
@ -200,25 +187,21 @@ Constant *BytecodeParser::parseConstantValue(const unsigned char *&Buf,
|
|||||||
case Type::UByteTyID: // Unsigned integer types...
|
case Type::UByteTyID: // Unsigned integer types...
|
||||||
case Type::UShortTyID:
|
case Type::UShortTyID:
|
||||||
case Type::UIntTyID: {
|
case Type::UIntTyID: {
|
||||||
unsigned Val;
|
unsigned Val = read_vbr_uint(Buf, EndBuf);
|
||||||
if (read_vbr(Buf, EndBuf, Val)) throw Error_readvbr;
|
|
||||||
if (!ConstantUInt::isValueValidForType(Ty, Val))
|
if (!ConstantUInt::isValueValidForType(Ty, Val))
|
||||||
throw std::string("Invalid unsigned byte/short/int read.");
|
throw std::string("Invalid unsigned byte/short/int read.");
|
||||||
return ConstantUInt::get(Ty, Val);
|
return ConstantUInt::get(Ty, Val);
|
||||||
}
|
}
|
||||||
|
|
||||||
case Type::ULongTyID: {
|
case Type::ULongTyID: {
|
||||||
uint64_t Val;
|
return ConstantUInt::get(Ty, read_vbr_uint64(Buf, EndBuf));
|
||||||
if (read_vbr(Buf, EndBuf, Val)) throw Error_readvbr;
|
|
||||||
return ConstantUInt::get(Ty, Val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case Type::SByteTyID: // Signed integer types...
|
case Type::SByteTyID: // Signed integer types...
|
||||||
case Type::ShortTyID:
|
case Type::ShortTyID:
|
||||||
case Type::IntTyID: {
|
case Type::IntTyID: {
|
||||||
case Type::LongTyID:
|
case Type::LongTyID:
|
||||||
int64_t Val;
|
int64_t Val = read_vbr_int64(Buf, EndBuf);
|
||||||
if (read_vbr(Buf, EndBuf, Val)) throw Error_readvbr;
|
|
||||||
if (!ConstantSInt::isValueValidForType(Ty, Val))
|
if (!ConstantSInt::isValueValidForType(Ty, Val))
|
||||||
throw std::string("Invalid signed byte/short/int/long read.");
|
throw std::string("Invalid signed byte/short/int/long read.");
|
||||||
return ConstantSInt::get(Ty, Val);
|
return ConstantSInt::get(Ty, Val);
|
||||||
@ -226,13 +209,13 @@ Constant *BytecodeParser::parseConstantValue(const unsigned char *&Buf,
|
|||||||
|
|
||||||
case Type::FloatTyID: {
|
case Type::FloatTyID: {
|
||||||
float F;
|
float F;
|
||||||
if (input_data(Buf, EndBuf, &F, &F+1)) throw Error_inputdata;
|
input_data(Buf, EndBuf, &F, &F+1);
|
||||||
return ConstantFP::get(Ty, F);
|
return ConstantFP::get(Ty, F);
|
||||||
}
|
}
|
||||||
|
|
||||||
case Type::DoubleTyID: {
|
case Type::DoubleTyID: {
|
||||||
double Val;
|
double Val;
|
||||||
if (input_data(Buf, EndBuf, &Val, &Val+1)) throw Error_inputdata;
|
input_data(Buf, EndBuf, &Val, &Val+1);
|
||||||
return ConstantFP::get(Ty, Val);
|
return ConstantFP::get(Ty, Val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,11 +227,10 @@ Constant *BytecodeParser::parseConstantValue(const unsigned char *&Buf,
|
|||||||
unsigned NumElements = AT->getNumElements();
|
unsigned NumElements = AT->getNumElements();
|
||||||
unsigned TypeSlot = getTypeSlot(AT->getElementType());
|
unsigned TypeSlot = getTypeSlot(AT->getElementType());
|
||||||
std::vector<Constant*> Elements;
|
std::vector<Constant*> Elements;
|
||||||
while (NumElements--) { // Read all of the elements of the constant.
|
Elements.reserve(NumElements);
|
||||||
unsigned Slot;
|
while (NumElements--) // Read all of the elements of the constant.
|
||||||
if (read_vbr(Buf, EndBuf, Slot)) throw Error_readvbr;
|
Elements.push_back(getConstantValue(TypeSlot,
|
||||||
Elements.push_back(getConstantValue(TypeSlot, Slot));
|
read_vbr_uint(Buf, EndBuf)));
|
||||||
}
|
|
||||||
return ConstantArray::get(AT, Elements);
|
return ConstantArray::get(AT, Elements);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,19 +239,16 @@ Constant *BytecodeParser::parseConstantValue(const unsigned char *&Buf,
|
|||||||
const StructType::ElementTypes &ET = ST->getElementTypes();
|
const StructType::ElementTypes &ET = ST->getElementTypes();
|
||||||
|
|
||||||
std::vector<Constant *> Elements;
|
std::vector<Constant *> Elements;
|
||||||
for (unsigned i = 0; i < ET.size(); ++i) {
|
Elements.reserve(ET.size());
|
||||||
unsigned Slot;
|
for (unsigned i = 0; i != ET.size(); ++i)
|
||||||
if (read_vbr(Buf, EndBuf, Slot)) throw Error_readvbr;
|
Elements.push_back(getConstantValue(ET[i], read_vbr_uint(Buf, EndBuf)));
|
||||||
Elements.push_back(getConstantValue(ET[i], Slot));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ConstantStruct::get(ST, Elements);
|
return ConstantStruct::get(ST, Elements);
|
||||||
}
|
}
|
||||||
|
|
||||||
case Type::PointerTyID: { // ConstantPointerRef value...
|
case Type::PointerTyID: { // ConstantPointerRef value...
|
||||||
const PointerType *PT = cast<PointerType>(Ty);
|
const PointerType *PT = cast<PointerType>(Ty);
|
||||||
unsigned Slot;
|
unsigned Slot = read_vbr_uint(Buf, EndBuf);
|
||||||
if (read_vbr(Buf, EndBuf, Slot)) throw Error_readvbr;
|
|
||||||
BCR_TRACE(4, "CPR: Type: '" << Ty << "' slot: " << Slot << "\n");
|
BCR_TRACE(4, "CPR: Type: '" << Ty << "' slot: " << Slot << "\n");
|
||||||
|
|
||||||
// Check to see if we have already read this global variable...
|
// Check to see if we have already read this global variable...
|
||||||
@ -301,9 +280,8 @@ void BytecodeParser::ParseGlobalTypes(const unsigned char *&Buf,
|
|||||||
void BytecodeParser::parseStringConstants(const unsigned char *&Buf,
|
void BytecodeParser::parseStringConstants(const unsigned char *&Buf,
|
||||||
const unsigned char *EndBuf,
|
const unsigned char *EndBuf,
|
||||||
unsigned NumEntries, ValueTable &Tab){
|
unsigned NumEntries, ValueTable &Tab){
|
||||||
unsigned Typ;
|
|
||||||
for (; NumEntries; --NumEntries) {
|
for (; NumEntries; --NumEntries) {
|
||||||
if (read_vbr(Buf, EndBuf, Typ)) throw Error_readvbr;
|
unsigned Typ = read_vbr_uint(Buf, EndBuf);
|
||||||
const Type *Ty = getType(Typ);
|
const Type *Ty = getType(Typ);
|
||||||
if (!isa<ArrayType>(Ty))
|
if (!isa<ArrayType>(Ty))
|
||||||
throw std::string("String constant data invalid!");
|
throw std::string("String constant data invalid!");
|
||||||
@ -315,8 +293,7 @@ void BytecodeParser::parseStringConstants(const unsigned char *&Buf,
|
|||||||
|
|
||||||
// Read character data. The type tells us how long the string is.
|
// Read character data. The type tells us how long the string is.
|
||||||
char Data[ATy->getNumElements()];
|
char Data[ATy->getNumElements()];
|
||||||
if (input_data(Buf, EndBuf, Data, Data+ATy->getNumElements()))
|
input_data(Buf, EndBuf, Data, Data+ATy->getNumElements());
|
||||||
throw Error_inputdata;
|
|
||||||
|
|
||||||
std::vector<Constant*> Elements(ATy->getNumElements());
|
std::vector<Constant*> Elements(ATy->getNumElements());
|
||||||
if (ATy->getElementType() == Type::SByteTy)
|
if (ATy->getElementType() == Type::SByteTy)
|
||||||
@ -339,10 +316,8 @@ void BytecodeParser::ParseConstantPool(const unsigned char *&Buf,
|
|||||||
ValueTable &Tab,
|
ValueTable &Tab,
|
||||||
TypeValuesListTy &TypeTab) {
|
TypeValuesListTy &TypeTab) {
|
||||||
while (Buf < EndBuf) {
|
while (Buf < EndBuf) {
|
||||||
unsigned NumEntries, Typ;
|
unsigned NumEntries = read_vbr_uint(Buf, EndBuf);
|
||||||
|
unsigned Typ = read_vbr_uint(Buf, EndBuf);
|
||||||
if (read_vbr(Buf, EndBuf, NumEntries) ||
|
|
||||||
read_vbr(Buf, EndBuf, Typ)) throw Error_readvbr;
|
|
||||||
if (Typ == Type::TypeTyID) {
|
if (Typ == Type::TypeTyID) {
|
||||||
BCR_TRACE(3, "Type: 'type' NumEntries: " << NumEntries << "\n");
|
BCR_TRACE(3, "Type: 'type' NumEntries: " << NumEntries << "\n");
|
||||||
parseTypeConstants(Buf, EndBuf, TypeTab, NumEntries);
|
parseTypeConstants(Buf, EndBuf, TypeTab, NumEntries);
|
||||||
|
@ -36,9 +36,7 @@ namespace {
|
|||||||
|
|
||||||
RawInst::RawInst(const unsigned char *&Buf, const unsigned char *EndBuf,
|
RawInst::RawInst(const unsigned char *&Buf, const unsigned char *EndBuf,
|
||||||
std::vector<unsigned> &Args) {
|
std::vector<unsigned> &Args) {
|
||||||
unsigned Op, Typ;
|
unsigned Op = read(Buf, EndBuf);
|
||||||
if (read(Buf, EndBuf, Op))
|
|
||||||
throw std::string("Error reading from buffer.");
|
|
||||||
|
|
||||||
// bits Instruction format: Common to all formats
|
// bits Instruction format: Common to all formats
|
||||||
// --------------------------
|
// --------------------------
|
||||||
@ -85,25 +83,19 @@ RawInst::RawInst(const unsigned char *&Buf, const unsigned char *EndBuf,
|
|||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
Buf -= 4; // Hrm, try this again...
|
Buf -= 4; // Hrm, try this again...
|
||||||
if (read_vbr(Buf, EndBuf, Opcode))
|
Opcode = read_vbr_uint(Buf, EndBuf);
|
||||||
throw std::string("Error reading from buffer.");
|
|
||||||
Opcode >>= 2;
|
Opcode >>= 2;
|
||||||
if (read_vbr(Buf, EndBuf, Type))
|
Type = read_vbr_uint(Buf, EndBuf);
|
||||||
throw std::string("Error reading from buffer.");
|
|
||||||
|
|
||||||
unsigned NumOperands;
|
unsigned NumOperands = read_vbr_uint(Buf, EndBuf);
|
||||||
if (read_vbr(Buf, EndBuf, NumOperands))
|
|
||||||
throw std::string("Error reading from buffer.");
|
|
||||||
Args.resize(NumOperands);
|
Args.resize(NumOperands);
|
||||||
|
|
||||||
if (NumOperands == 0)
|
if (NumOperands == 0)
|
||||||
throw std::string("Zero-argument instruction found; this is invalid.");
|
throw std::string("Zero-argument instruction found; this is invalid.");
|
||||||
|
|
||||||
for (unsigned i = 0; i != NumOperands; ++i)
|
for (unsigned i = 0; i != NumOperands; ++i)
|
||||||
if (read_vbr(Buf, EndBuf, Args[i]))
|
Args[i] = read_vbr_uint(Buf, EndBuf);
|
||||||
throw std::string("Error reading from buffer");
|
align32(Buf, EndBuf);
|
||||||
if (align32(Buf, EndBuf))
|
|
||||||
throw std::string("Unaligned bytecode buffer.");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,12 +23,6 @@
|
|||||||
#include "Support/StringExtras.h"
|
#include "Support/StringExtras.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
static inline void ALIGN32(const unsigned char *&begin,
|
|
||||||
const unsigned char *end) {
|
|
||||||
if (align32(begin, end))
|
|
||||||
throw std::string("Alignment error in buffer: read past end of block.");
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned BytecodeParser::getTypeSlot(const Type *Ty) {
|
unsigned BytecodeParser::getTypeSlot(const Type *Ty) {
|
||||||
if (Ty->isPrimitiveType())
|
if (Ty->isPrimitiveType())
|
||||||
return Ty->getPrimitiveID();
|
return Ty->getPrimitiveID();
|
||||||
@ -244,20 +238,16 @@ void BytecodeParser::ParseSymbolTable(const unsigned char *&Buf,
|
|||||||
|
|
||||||
while (Buf < EndBuf) {
|
while (Buf < EndBuf) {
|
||||||
// Symtab block header: [num entries][type id number]
|
// Symtab block header: [num entries][type id number]
|
||||||
unsigned NumEntries, Typ;
|
unsigned NumEntries = read_vbr_uint(Buf, EndBuf);
|
||||||
if (read_vbr(Buf, EndBuf, NumEntries) ||
|
unsigned Typ = read_vbr_uint(Buf, EndBuf);
|
||||||
read_vbr(Buf, EndBuf, Typ)) throw Error_readvbr;
|
|
||||||
const Type *Ty = getType(Typ);
|
const Type *Ty = getType(Typ);
|
||||||
BCR_TRACE(3, "Plane Type: '" << *Ty << "' with " << NumEntries <<
|
BCR_TRACE(3, "Plane Type: '" << *Ty << "' with " << NumEntries <<
|
||||||
" entries\n");
|
" entries\n");
|
||||||
|
|
||||||
for (unsigned i = 0; i != NumEntries; ++i) {
|
for (unsigned i = 0; i != NumEntries; ++i) {
|
||||||
// Symtab entry: [def slot #][name]
|
// Symtab entry: [def slot #][name]
|
||||||
unsigned slot;
|
unsigned slot = read_vbr_uint(Buf, EndBuf);
|
||||||
if (read_vbr(Buf, EndBuf, slot)) throw Error_readvbr;
|
std::string Name = read_str(Buf, EndBuf);
|
||||||
std::string Name;
|
|
||||||
if (read(Buf, EndBuf, Name, false)) // Not aligned...
|
|
||||||
throw std::string("Failed reading symbol name.");
|
|
||||||
|
|
||||||
Value *V = 0;
|
Value *V = 0;
|
||||||
if (Typ == Type::TypeTyID)
|
if (Typ == Type::TypeTyID)
|
||||||
@ -317,9 +307,7 @@ void BytecodeParser::materializeFunction(Function* F) {
|
|||||||
|
|
||||||
GlobalValue::LinkageTypes Linkage = GlobalValue::ExternalLinkage;
|
GlobalValue::LinkageTypes Linkage = GlobalValue::ExternalLinkage;
|
||||||
|
|
||||||
unsigned LinkageType;
|
unsigned LinkageType = read_vbr_uint(Buf, EndBuf);
|
||||||
if (read_vbr(Buf, EndBuf, LinkageType))
|
|
||||||
throw std::string("ParseFunction: Error reading from buffer.");
|
|
||||||
if ((!hasExtendedLinkageSpecs && LinkageType > 3) ||
|
if ((!hasExtendedLinkageSpecs && LinkageType > 3) ||
|
||||||
( hasExtendedLinkageSpecs && LinkageType > 4))
|
( hasExtendedLinkageSpecs && LinkageType > 4))
|
||||||
throw std::string("Invalid linkage type for Function.");
|
throw std::string("Invalid linkage type for Function.");
|
||||||
@ -382,7 +370,7 @@ void BytecodeParser::materializeFunction(Function* F) {
|
|||||||
BCR_TRACE(2, "} end block\n");
|
BCR_TRACE(2, "} end block\n");
|
||||||
|
|
||||||
// Malformed bc file if read past end of block.
|
// Malformed bc file if read past end of block.
|
||||||
ALIGN32(Buf, EndBuf);
|
align32(Buf, EndBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure there were no references to non-existant basic blocks.
|
// Make sure there were no references to non-existant basic blocks.
|
||||||
@ -436,8 +424,7 @@ void BytecodeParser::ParseModuleGlobalInfo(const unsigned char *&Buf,
|
|||||||
throw std::string("Two ModuleGlobalInfo packets found!");
|
throw std::string("Two ModuleGlobalInfo packets found!");
|
||||||
|
|
||||||
// Read global variables...
|
// Read global variables...
|
||||||
unsigned VarType;
|
unsigned VarType = read_vbr_uint(Buf, End);
|
||||||
if (read_vbr(Buf, End, VarType)) throw Error_readvbr;
|
|
||||||
while (VarType != Type::VoidTyID) { // List is terminated by Void
|
while (VarType != Type::VoidTyID) { // List is terminated by Void
|
||||||
unsigned SlotNo;
|
unsigned SlotNo;
|
||||||
GlobalValue::LinkageTypes Linkage;
|
GlobalValue::LinkageTypes Linkage;
|
||||||
@ -476,17 +463,13 @@ void BytecodeParser::ParseModuleGlobalInfo(const unsigned char *&Buf,
|
|||||||
BCR_TRACE(2, "Global Variable of type: " << *Ty << "\n");
|
BCR_TRACE(2, "Global Variable of type: " << *Ty << "\n");
|
||||||
insertValue(GV, SlotNo, ModuleValues);
|
insertValue(GV, SlotNo, ModuleValues);
|
||||||
|
|
||||||
if (VarType & 2) { // Does it have an initializer?
|
if (VarType & 2) // Does it have an initializer?
|
||||||
unsigned InitSlot;
|
GlobalInits.push_back(std::make_pair(GV, read_vbr_uint(Buf, End)));
|
||||||
if (read_vbr(Buf, End, InitSlot)) throw Error_readvbr;
|
VarType = read_vbr_uint(Buf, End);
|
||||||
GlobalInits.push_back(std::make_pair(GV, InitSlot));
|
|
||||||
}
|
|
||||||
if (read_vbr(Buf, End, VarType)) throw Error_readvbr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the function objects for all of the functions that are coming
|
// Read the function objects for all of the functions that are coming
|
||||||
unsigned FnSignature;
|
unsigned FnSignature = read_vbr_uint(Buf, End);
|
||||||
if (read_vbr(Buf, End, FnSignature)) throw Error_readvbr;
|
|
||||||
while (FnSignature != Type::VoidTyID) { // List is terminated by Void
|
while (FnSignature != Type::VoidTyID) { // List is terminated by Void
|
||||||
const Type *Ty = getType(FnSignature);
|
const Type *Ty = getType(FnSignature);
|
||||||
if (!isa<PointerType>(Ty) ||
|
if (!isa<PointerType>(Ty) ||
|
||||||
@ -512,11 +495,11 @@ void BytecodeParser::ParseModuleGlobalInfo(const unsigned char *&Buf,
|
|||||||
//
|
//
|
||||||
FunctionSignatureList.push_back(Func);
|
FunctionSignatureList.push_back(Func);
|
||||||
|
|
||||||
if (read_vbr(Buf, End, FnSignature)) throw Error_readvbr;
|
FnSignature = read_vbr_uint(Buf, End);
|
||||||
BCR_TRACE(2, "Function of type: " << Ty << "\n");
|
BCR_TRACE(2, "Function of type: " << Ty << "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
ALIGN32(Buf, End);
|
align32(Buf, End);
|
||||||
|
|
||||||
// Now that the function signature list is set up, reverse it so that we can
|
// Now that the function signature list is set up, reverse it so that we can
|
||||||
// remove elements efficiently from the back of the vector.
|
// remove elements efficiently from the back of the vector.
|
||||||
@ -530,8 +513,7 @@ void BytecodeParser::ParseModuleGlobalInfo(const unsigned char *&Buf,
|
|||||||
|
|
||||||
void BytecodeParser::ParseVersionInfo(const unsigned char *&Buf,
|
void BytecodeParser::ParseVersionInfo(const unsigned char *&Buf,
|
||||||
const unsigned char *EndBuf) {
|
const unsigned char *EndBuf) {
|
||||||
unsigned Version;
|
unsigned Version = read_vbr_uint(Buf, EndBuf);
|
||||||
if (read_vbr(Buf, EndBuf, Version)) throw Error_readvbr;
|
|
||||||
|
|
||||||
// Unpack version number: low four bits are for flags, top bits = version
|
// Unpack version number: low four bits are for flags, top bits = version
|
||||||
Module::Endianness Endianness;
|
Module::Endianness Endianness;
|
||||||
@ -596,7 +578,7 @@ void BytecodeParser::ParseModule(const unsigned char *Buf,
|
|||||||
|
|
||||||
// Read into instance variables...
|
// Read into instance variables...
|
||||||
ParseVersionInfo(Buf, EndBuf);
|
ParseVersionInfo(Buf, EndBuf);
|
||||||
ALIGN32(Buf, EndBuf);
|
align32(Buf, EndBuf);
|
||||||
|
|
||||||
while (Buf < EndBuf) {
|
while (Buf < EndBuf) {
|
||||||
const unsigned char *OldBuf = Buf;
|
const unsigned char *OldBuf = Buf;
|
||||||
@ -633,7 +615,7 @@ void BytecodeParser::ParseModule(const unsigned char *Buf,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
BCR_TRACE(1, "} end block\n");
|
BCR_TRACE(1, "} end block\n");
|
||||||
ALIGN32(Buf, EndBuf);
|
align32(Buf, EndBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// After the module constant pool has been read, we can safely initialize
|
// After the module constant pool has been read, we can safely initialize
|
||||||
@ -666,9 +648,8 @@ void BytecodeParser::ParseBytecode(const unsigned char *Buf, unsigned Length,
|
|||||||
unsigned char *EndBuf = (unsigned char*)(Buf + Length);
|
unsigned char *EndBuf = (unsigned char*)(Buf + Length);
|
||||||
|
|
||||||
// Read and check signature...
|
// Read and check signature...
|
||||||
unsigned Sig;
|
unsigned Sig = read(Buf, EndBuf);
|
||||||
if (read(Buf, EndBuf, Sig) ||
|
if (Sig != ('l' | ('l' << 8) | ('v' << 16) | ('m' << 24)))
|
||||||
Sig != ('l' | ('l' << 8) | ('v' << 16) | ('m' << 24)))
|
|
||||||
throw std::string("Invalid bytecode signature!");
|
throw std::string("Invalid bytecode signature!");
|
||||||
|
|
||||||
TheModule = new Module(ModuleID);
|
TheModule = new Module(ModuleID);
|
||||||
|
@ -214,23 +214,11 @@ struct ConstantPlaceHolderHelper : public ConstantExpr {
|
|||||||
|
|
||||||
typedef PlaceholderDef<ConstantPlaceHolderHelper> ConstPHolder;
|
typedef PlaceholderDef<ConstantPlaceHolderHelper> ConstPHolder;
|
||||||
|
|
||||||
// Some common errors we find
|
|
||||||
static const std::string Error_readvbr = "read_vbr(): error reading.";
|
|
||||||
static const std::string Error_read = "read(): error reading.";
|
|
||||||
static const std::string Error_inputdata = "input_data(): error reading.";
|
|
||||||
static const std::string Error_DestSlot = "No destination slot found.";
|
|
||||||
|
|
||||||
static inline void readBlock(const unsigned char *&Buf,
|
static inline void readBlock(const unsigned char *&Buf,
|
||||||
const unsigned char *EndBuf,
|
const unsigned char *EndBuf,
|
||||||
unsigned &Type, unsigned &Size) {
|
unsigned &Type, unsigned &Size) {
|
||||||
#ifdef DEBUG_OUTPUT
|
Type = read(Buf, EndBuf);
|
||||||
bool Result = read(Buf, EndBuf, Type) || read(Buf, EndBuf, Size);
|
Size = read(Buf, EndBuf);
|
||||||
std::cerr << "StartLoc = " << ((unsigned)Buf & 4095)
|
|
||||||
<< " Type = " << Type << " Size = " << Size << "\n";
|
|
||||||
if (Result) throw Error_read;
|
|
||||||
#else
|
|
||||||
if (read(Buf, EndBuf, Type) || read(Buf, EndBuf, Size)) throw Error_read;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
@ -20,127 +20,78 @@
|
|||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
static inline bool read(const unsigned char *&Buf, const unsigned char *EndBuf,
|
static inline unsigned read(const unsigned char *&Buf,
|
||||||
unsigned &Result) {
|
const unsigned char *EndBuf) {
|
||||||
if (Buf+4 > EndBuf) return true;
|
if (Buf+4 > EndBuf) throw std::string("Ran out of data!");
|
||||||
#ifdef ENDIAN_LITTLE
|
Buf += 4;
|
||||||
Result = *(unsigned*)Buf;
|
return Buf[-4] | (Buf[-3] << 8) | (Buf[-2] << 16) | (Buf[-1] << 24);
|
||||||
#else
|
}
|
||||||
Result = Buf[0] | (Buf[1] << 8) | (Buf[2] << 16) | (Buf[3] << 24);
|
|
||||||
#endif
|
|
||||||
Buf += 4;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool read(const unsigned char *&Buf, const unsigned char *EndBuf,
|
|
||||||
uint64_t &Result) {
|
|
||||||
if (Buf+8 > EndBuf) return true;
|
|
||||||
|
|
||||||
#ifdef ENDIAN_LITTLE
|
|
||||||
Result = *(uint64_t*)Buf;
|
|
||||||
#else
|
|
||||||
Result = Buf[0] | (Buf[1] << 8) | (Buf[2] << 16) | (Buf[3] << 24) |
|
|
||||||
((uint64_t)(Buf[4] | (Buf[5] << 8) | (Buf[6] << 16) | (Buf[7] << 24)) <<32);
|
|
||||||
#endif
|
|
||||||
Buf += 8;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool read(const unsigned char *&Buf, const unsigned char *EndBuf,
|
|
||||||
int &Result) {
|
|
||||||
return read(Buf, EndBuf, (unsigned &)Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool read(const unsigned char *&Buf, const unsigned char *EndBuf,
|
|
||||||
int64_t &Result) {
|
|
||||||
return read(Buf, EndBuf, (uint64_t &)Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// read_vbr - Read an unsigned integer encoded in variable bitrate format.
|
// read_vbr - Read an unsigned integer encoded in variable bitrate format.
|
||||||
//
|
//
|
||||||
static inline bool read_vbr(const unsigned char *&Buf,
|
static inline unsigned read_vbr_uint(const unsigned char *&Buf,
|
||||||
const unsigned char *EndBuf, unsigned &Result) {
|
const unsigned char *EndBuf) {
|
||||||
unsigned Shift = Result = 0;
|
unsigned Shift = 0;
|
||||||
|
unsigned Result = 0;
|
||||||
do {
|
|
||||||
Result |= (unsigned)((*Buf++) & 0x7F) << Shift;
|
do {
|
||||||
Shift += 7;
|
if (Buf == EndBuf) throw std::string("Ran out of data!");
|
||||||
} while (Buf[-1] & 0x80 && Buf < EndBuf);
|
Result |= (unsigned)((*Buf++) & 0x7F) << Shift;
|
||||||
|
Shift += 7;
|
||||||
return Buf > EndBuf;
|
} while (Buf[-1] & 0x80);
|
||||||
}
|
return Result;
|
||||||
|
}
|
||||||
static inline bool read_vbr(const unsigned char *&Buf,
|
|
||||||
const unsigned char *EndBuf, uint64_t &Result) {
|
|
||||||
unsigned Shift = 0; Result = 0;
|
|
||||||
|
|
||||||
do {
|
|
||||||
Result |= (uint64_t)((*Buf++) & 0x7F) << Shift;
|
|
||||||
Shift += 7;
|
|
||||||
} while (Buf[-1] & 0x80 && Buf < EndBuf);
|
|
||||||
return Buf > EndBuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
// read_vbr (signed) - Read a signed number stored in sign-magnitude format
|
|
||||||
static inline bool read_vbr(const unsigned char *&Buf,
|
|
||||||
const unsigned char *EndBuf, int &Result) {
|
|
||||||
unsigned R;
|
|
||||||
if (read_vbr(Buf, EndBuf, R)) return true;
|
|
||||||
if (R & 1)
|
|
||||||
Result = -(int)(R >> 1);
|
|
||||||
else
|
|
||||||
Result = (int)(R >> 1);
|
|
||||||
|
|
||||||
return false;
|
static inline uint64_t read_vbr_uint64(const unsigned char *&Buf,
|
||||||
}
|
const unsigned char *EndBuf) {
|
||||||
|
unsigned Shift = 0;
|
||||||
|
uint64_t Result = 0;
|
||||||
static inline bool read_vbr(const unsigned char *&Buf,
|
|
||||||
const unsigned char *EndBuf, int64_t &Result) {
|
do {
|
||||||
uint64_t R;
|
if (Buf == EndBuf) throw std::string("Ran out of data!");
|
||||||
if (read_vbr(Buf, EndBuf, R)) return true;
|
Result |= (uint64_t)((*Buf++) & 0x7F) << Shift;
|
||||||
if (R & 1)
|
Shift += 7;
|
||||||
Result = -(int64_t)(R >> 1);
|
} while (Buf[-1] & 0x80);
|
||||||
else
|
return Result;
|
||||||
Result = (int64_t)(R >> 1);
|
}
|
||||||
|
|
||||||
|
static inline int64_t read_vbr_int64(const unsigned char *&Buf,
|
||||||
|
const unsigned char *EndBuf) {
|
||||||
|
uint64_t R = read_vbr_uint64(Buf, EndBuf);
|
||||||
|
if (R & 1)
|
||||||
|
return -(int64_t)(R >> 1);
|
||||||
|
else
|
||||||
|
return (int64_t)(R >> 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// align32 - Round up to multiple of 32 bits...
|
||||||
|
static inline void align32(const unsigned char *&Buf,
|
||||||
|
const unsigned char *EndBuf) {
|
||||||
|
Buf = (const unsigned char *)((unsigned long)(Buf+3) & (~3UL));
|
||||||
|
if (Buf > EndBuf) throw std::string("Ran out of data!");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline std::string read_str(const unsigned char *&Buf,
|
||||||
|
const unsigned char *EndBuf) {
|
||||||
|
unsigned Size = read_vbr_uint(Buf, EndBuf);
|
||||||
|
const unsigned char *OldBuf = Buf;
|
||||||
|
Buf += Size;
|
||||||
|
if (Buf > EndBuf) // Size invalid?
|
||||||
|
throw std::string("Ran out of data reading a string!");
|
||||||
|
return std::string((char*)OldBuf, Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void input_data(const unsigned char *&Buf,
|
||||||
|
const unsigned char *EndBuf,
|
||||||
|
void *Ptr, void *End) {
|
||||||
|
unsigned char *Start = (unsigned char *)Ptr;
|
||||||
|
unsigned Amount = (unsigned char *)End - Start;
|
||||||
|
if (Buf+Amount > EndBuf) throw std::string("Ran out of data!");
|
||||||
|
std::copy(Buf, Buf+Amount, Start);
|
||||||
|
Buf += Amount;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// align32 - Round up to multiple of 32 bits...
|
|
||||||
static inline bool align32(const unsigned char *&Buf,
|
|
||||||
const unsigned char *EndBuf) {
|
|
||||||
Buf = (const unsigned char *)((unsigned long)(Buf+3) & (~3UL));
|
|
||||||
return Buf > EndBuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool read(const unsigned char *&Buf, const unsigned char *EndBuf,
|
|
||||||
std::string &Result, bool Aligned = true) {
|
|
||||||
unsigned Size;
|
|
||||||
if (read_vbr(Buf, EndBuf, Size)) return true; // Failure reading size?
|
|
||||||
if (Buf+Size > EndBuf) return true; // Size invalid?
|
|
||||||
|
|
||||||
Result = std::string((char*)Buf, Size);
|
|
||||||
Buf += Size;
|
|
||||||
|
|
||||||
if (Aligned) // If we should stay aligned do so...
|
|
||||||
if (align32(Buf, EndBuf)) return true; // Failure aligning?
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool input_data(const unsigned char *&Buf,
|
|
||||||
const unsigned char *EndBuf,
|
|
||||||
void *Ptr, void *End) {
|
|
||||||
unsigned char *Start = (unsigned char *)Ptr;
|
|
||||||
unsigned Amount = (unsigned char *)End - Start;
|
|
||||||
if (Buf+Amount > EndBuf) return true;
|
|
||||||
std::copy(Buf, Buf+Amount, Start);
|
|
||||||
Buf += Amount;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user