#include "ReaderInternals.h"
#include "llvm/Module.h"
-#include "llvm/Constants.h"
-#include "llvm/GlobalVariable.h"
#include <algorithm>
-#include <iostream>
using std::make_pair;
const Type *BytecodeParser::parseTypeConstant(const uchar *&Buf,
const uchar *EndBuf) {
unsigned PrimType;
- if (read_vbr(Buf, EndBuf, PrimType)) return failure<const Type*>(0);
+ if (read_vbr(Buf, EndBuf, PrimType)) return 0;
const Type *Val = 0;
if ((Val = Type::getPrimitiveType((Type::PrimitiveID)PrimType)))
switch (PrimType) {
case Type::FunctionTyID: {
unsigned Typ;
- if (read_vbr(Buf, EndBuf, Typ)) return failure(Val);
+ if (read_vbr(Buf, EndBuf, Typ)) return Val;
const Type *RetType = getType(Typ);
- if (RetType == 0) return failure(Val);
+ if (RetType == 0) return Val;
unsigned NumParams;
- if (read_vbr(Buf, EndBuf, NumParams)) return failure(Val);
+ if (read_vbr(Buf, EndBuf, NumParams)) return Val;
std::vector<const Type*> Params;
while (NumParams--) {
- if (read_vbr(Buf, EndBuf, Typ)) return failure(Val);
+ if (read_vbr(Buf, EndBuf, Typ)) return Val;
const Type *Ty = getType(Typ);
- if (Ty == 0) return failure(Val);
+ if (Ty == 0) return Val;
Params.push_back(Ty);
}
}
case Type::ArrayTyID: {
unsigned ElTyp;
- if (read_vbr(Buf, EndBuf, ElTyp)) return failure(Val);
+ if (read_vbr(Buf, EndBuf, ElTyp)) return Val;
const Type *ElementType = getType(ElTyp);
- if (ElementType == 0) return failure(Val);
+ if (ElementType == 0) return Val;
unsigned NumElements;
- if (read_vbr(Buf, EndBuf, NumElements)) return failure(Val);
+ if (read_vbr(Buf, EndBuf, NumElements)) return Val;
BCR_TRACE(5, "Array Type Constant #" << ElTyp << " size="
<< NumElements << "\n");
unsigned Typ;
std::vector<const Type*> Elements;
- if (read_vbr(Buf, EndBuf, Typ)) return failure(Val);
+ if (read_vbr(Buf, EndBuf, Typ)) return Val;
while (Typ) { // List is terminated by void/0 typeid
const Type *Ty = getType(Typ);
- if (Ty == 0) return failure(Val);
+ if (Ty == 0) return Val;
Elements.push_back(Ty);
- if (read_vbr(Buf, EndBuf, Typ)) return failure(Val);
+ if (read_vbr(Buf, EndBuf, Typ)) return Val;
}
return StructType::get(Elements);
}
case Type::PointerTyID: {
unsigned ElTyp;
- if (read_vbr(Buf, EndBuf, ElTyp)) return failure(Val);
+ if (read_vbr(Buf, EndBuf, ElTyp)) return Val;
BCR_TRACE(5, "Pointer Type Constant #" << (ElTyp-14) << "\n");
const Type *ElementType = getType(ElTyp);
- if (ElementType == 0) return failure(Val);
+ if (ElementType == 0) return Val;
return PointerType::get(ElementType);
}
std::cerr << __FILE__ << ":" << __LINE__
<< ": Don't know how to deserialize"
<< " primitive Type " << PrimType << "\n";
- return failure(Val);
+ return Val;
}
}
//
for (unsigned i = 0; i < NumEntries; ++i) {
const Type *NewTy = parseTypeConstant(Buf, EndBuf), *OldTy = Tab[i].get();
- if (NewTy == 0) return failure(true);
+ if (NewTy == 0) return true;
BCR_TRACE(4, "#" << i << ": Read Type Constant: '" << NewTy <<
"' Replacing: " << OldTy << "\n");
// a ConstantExpr can be of any type, and has no explicit value.
//
unsigned isExprNumArgs; // 0 if not expr; numArgs if is expr
- if (read_vbr(Buf, EndBuf, isExprNumArgs)) return failure(true);
+ if (read_vbr(Buf, EndBuf, isExprNumArgs)) return true;
if (isExprNumArgs) {
// FIXME: Encoding of constant exprs could be much more compact!
unsigned Opcode;
std::vector<Constant*> ArgVec;
ArgVec.reserve(isExprNumArgs);
- if (read_vbr(Buf, EndBuf, Opcode)) return failure(true);
+ if (read_vbr(Buf, EndBuf, Opcode)) return true;
// Read the slot number and types of each of the arguments
for (unsigned i = 0; i != isExprNumArgs; ++i) {
unsigned ArgValSlot, ArgTypeSlot;
- if (read_vbr(Buf, EndBuf, ArgValSlot)) return failure(true);
- if (read_vbr(Buf, EndBuf, ArgTypeSlot)) return failure(true);
+ if (read_vbr(Buf, EndBuf, ArgValSlot)) return true;
+ if (read_vbr(Buf, EndBuf, ArgTypeSlot)) return true;
const Type *ArgTy = getType(ArgTypeSlot);
- if (ArgTy == 0) return failure(true);
+ if (ArgTy == 0) return true;
BCR_TRACE(4, "CE Arg " << i << ": Type: '" << ArgTy << "' slot: "
<< ArgValSlot << "\n");
Value *Val = getValue(ArgTy, ArgValSlot, false);
Constant *C;
if (Val) {
- if (!(C = dyn_cast<Constant>(Val))) return failure(true);
+ if (!(C = dyn_cast<Constant>(Val))) return true;
BCR_TRACE(5, "Constant Found in ValueTable!\n");
} else { // Nope... find or create a forward ref. for it
- C = fwdRefs.GetFwdRefToConstant(ArgTy, ArgValSlot);
+ GlobalRefsType::iterator I = GlobalRefs.find(make_pair(Ty, ArgValSlot));
+
+ if (I != GlobalRefs.end()) {
+ BCR_TRACE(5, "Previous forward ref found!\n");
+ C = cast<Constant>(I->second);
+ } else {
+ // Create a placeholder for the constant reference and
+ // keep track of the fact that we have a forward ref to recycle it
+ BCR_TRACE(5, "Creating new forward ref to a constant!\n");
+ C = new ConstPHolder(ArgTy, ArgValSlot);
+
+ // Keep track of the fact that we have a forward ref to recycle it
+ GlobalRefs.insert(make_pair(make_pair(ArgTy, ArgValSlot), C));
+ }
}
ArgVec.push_back(C);
}
switch (Ty->getPrimitiveID()) {
case Type::BoolTyID: {
unsigned Val;
- if (read_vbr(Buf, EndBuf, Val)) return failure(true);
- if (Val != 0 && Val != 1) return failure(true);
+ if (read_vbr(Buf, EndBuf, Val)) return true;
+ if (Val != 0 && Val != 1) return true;
V = ConstantBool::get(Val == 1);
break;
}
case Type::UShortTyID:
case Type::UIntTyID: {
unsigned Val;
- if (read_vbr(Buf, EndBuf, Val)) return failure(true);
- if (!ConstantUInt::isValueValidForType(Ty, Val)) return failure(true);
+ if (read_vbr(Buf, EndBuf, Val)) return true;
+ if (!ConstantUInt::isValueValidForType(Ty, Val)) return true;
V = ConstantUInt::get(Ty, Val);
break;
}
case Type::ULongTyID: {
uint64_t Val;
- if (read_vbr(Buf, EndBuf, Val)) return failure(true);
+ if (read_vbr(Buf, EndBuf, Val)) return true;
V = ConstantUInt::get(Ty, Val);
break;
}
case Type::ShortTyID:
case Type::IntTyID: {
int Val;
- if (read_vbr(Buf, EndBuf, Val)) return failure(true);
- if (!ConstantSInt::isValueValidForType(Ty, Val)) return failure(true);
+ if (read_vbr(Buf, EndBuf, Val)) return true;
+ if (!ConstantSInt::isValueValidForType(Ty, Val)) return true;
V = ConstantSInt::get(Ty, Val);
break;
}
case Type::LongTyID: {
int64_t Val;
- if (read_vbr(Buf, EndBuf, Val)) return failure(true);
+ if (read_vbr(Buf, EndBuf, Val)) return true;
V = ConstantSInt::get(Ty, Val);
break;
}
case Type::FloatTyID: {
float F;
- if (input_data(Buf, EndBuf, &F, &F+1)) return failure(true);
+ if (input_data(Buf, EndBuf, &F, &F+1)) return true;
V = ConstantFP::get(Ty, F);
break;
}
case Type::DoubleTyID: {
double Val;
- if (input_data(Buf, EndBuf, &Val, &Val+1)) return failure(true);
+ if (input_data(Buf, EndBuf, &Val, &Val+1)) return true;
V = ConstantFP::get(Ty, Val);
break;
}
std::vector<Constant*> Elements;
while (NumElements--) { // Read all of the elements of the constant.
unsigned Slot;
- if (read_vbr(Buf, EndBuf, Slot)) return failure(true);
+ if (read_vbr(Buf, EndBuf, Slot)) return true;
Value *V = getValue(AT->getElementType(), Slot, false);
- if (!V || !isa<Constant>(V)) return failure(true);
+ if (!V || !isa<Constant>(V)) return true;
Elements.push_back(cast<Constant>(V));
}
V = ConstantArray::get(AT, Elements);
std::vector<Constant *> Elements;
for (unsigned i = 0; i < ET.size(); ++i) {
unsigned Slot;
- if (read_vbr(Buf, EndBuf, Slot)) return failure(true);
+ if (read_vbr(Buf, EndBuf, Slot)) return true;
Value *V = getValue(ET[i], Slot, false);
if (!V || !isa<Constant>(V))
- return failure(true);
+ return true;
Elements.push_back(cast<Constant>(V));
}
case Type::PointerTyID: {
const PointerType *PT = cast<const PointerType>(Ty);
unsigned SubClass;
- if (read_vbr(Buf, EndBuf, SubClass)) return failure(true);
+ if (read_vbr(Buf, EndBuf, SubClass)) return true;
switch (SubClass) {
case 0: // ConstantPointerNull value...
V = ConstantPointerNull::get(PT);
case 1: { // ConstantPointerRef value...
unsigned Slot;
- if (read_vbr(Buf, EndBuf, Slot)) return failure(true);
+ if (read_vbr(Buf, EndBuf, Slot)) return true;
BCR_TRACE(4, "CPR: Type: '" << Ty << "' slot: " << Slot << "\n");
- // Check to see if we have already read this global variable yet...
+ // Check to see if we have already read this global variable...
Value *Val = getValue(PT, Slot, false);
- GlobalValue* GV;
+ GlobalValue *GV;
if (Val) {
- if (!(GV = dyn_cast<GlobalValue>(Val))) return failure(true);
+ if (!(GV = dyn_cast<GlobalValue>(Val))) return true;
BCR_TRACE(5, "Value Found in ValueTable!\n");
} else { // Nope... find or create a forward ref. for it
- GV = fwdRefs.GetFwdRefToGlobal(PT, Slot);
+ GlobalRefsType::iterator I = GlobalRefs.find(make_pair(PT, Slot));
+
+ if (I != GlobalRefs.end()) {
+ BCR_TRACE(5, "Previous forward ref found!\n");
+ GV = cast<GlobalValue>(I->second);
+ } else {
+ BCR_TRACE(5, "Creating new forward ref to a global variable!\n");
+
+ // Create a placeholder for the global variable reference...
+ GlobalVariable *GVar =
+ new GlobalVariable(PT->getElementType(), false, true);
+
+ // Keep track of the fact that we have a forward ref to recycle it
+ GlobalRefs.insert(make_pair(make_pair(PT, Slot), GVar));
+
+ // Must temporarily push this value into the module table...
+ TheModule->getGlobalList().push_back(GVar);
+ GV = GVar;
+ }
}
V = ConstantPointerRef::get(GV);
break;
default:
BCR_TRACE(5, "UNKNOWN Pointer Constant Type!\n");
- return failure(true);
+ return true;
}
break;
}
std::cerr << __FILE__ << ":" << __LINE__
<< ": Don't know how to deserialize constant value of type '"
<< Ty->getName() << "'\n";
- return failure(true);
+ return true;
}
return false;
unsigned NumEntries, Typ;
if (read_vbr(Buf, EndBuf, NumEntries) ||
- read_vbr(Buf, EndBuf, Typ)) return failure(true);
+ read_vbr(Buf, EndBuf, Typ)) return true;
const Type *Ty = getType(Typ);
- if (Ty == 0) return failure(true);
+ if (Ty == 0) return true;
BCR_TRACE(3, "Type: '" << Ty << "' NumEntries: " << NumEntries << "\n");
if (Typ == Type::TypeTyID) {
for (unsigned i = 0; i < NumEntries; ++i) {
Constant *I;
int Slot;
- if (parseConstantValue(Buf, EndBuf, Ty, I)) return failure(true);
- assert(I && "parseConstantValue returned `!failure' and NULL result");
+ if (parseConstantValue(Buf, EndBuf, Ty, I)) return true;
+ assert(I && "parseConstantValue returned NULL!");
BCR_TRACE(4, "Read Constant: '" << I << "'\n");
- if ((Slot = insertValue(I, Tab)) < 0) return failure(true);
- resolveRefsToConstant(I, (unsigned) Slot);
+ if ((Slot = insertValue(I, Tab)) < 0) return true;
+
+ // If we are reading a function constant table, make sure that we adjust
+ // the slot number to be the real global constant number.
+ //
+ if (&Tab != &ModuleValues)
+ Slot += ModuleValues[Typ].size();
+
+ ResolveReferencesToValue(I, (unsigned)Slot);
}
}
}
- if (Buf > EndBuf) return failure(true);
+ if (Buf > EndBuf) return true;
return false;
}
#include "llvm/iMemory.h"
#include "llvm/iPHINode.h"
#include "llvm/iOther.h"
-#include <iostream>
using std::vector;
using std::cerr;
bool BytecodeParser::ParseRawInst(const uchar *&Buf, const uchar *EndBuf,
RawInst &Result) {
unsigned Op, Typ;
- if (read(Buf, EndBuf, Op)) return failure(true);
+ if (read(Buf, EndBuf, Op)) return true;
// bits Instruction format: Common to all formats
// --------------------------
break;
case 0:
Buf -= 4; // Hrm, try this again...
- if (read_vbr(Buf, EndBuf, Result.Opcode)) return failure(true);
+ if (read_vbr(Buf, EndBuf, Result.Opcode)) return true;
Result.Opcode >>= 2;
- if (read_vbr(Buf, EndBuf, Typ)) return failure(true);
+ if (read_vbr(Buf, EndBuf, Typ)) return true;
Result.Ty = getType(Typ);
- if (Result.Ty == 0) return failure(true);
- if (read_vbr(Buf, EndBuf, Result.NumOperands)) return failure(true);
+ if (Result.Ty == 0) return true;
+ if (read_vbr(Buf, EndBuf, Result.NumOperands)) return true;
switch (Result.NumOperands) {
case 0:
cerr << "Zero Arg instr found!\n";
- return failure(true); // This encoding is invalid!
+ return true; // This encoding is invalid!
case 1:
- if (read_vbr(Buf, EndBuf, Result.Arg1)) return failure(true);
+ if (read_vbr(Buf, EndBuf, Result.Arg1)) return true;
break;
case 2:
if (read_vbr(Buf, EndBuf, Result.Arg1) ||
- read_vbr(Buf, EndBuf, Result.Arg2)) return failure(true);
+ read_vbr(Buf, EndBuf, Result.Arg2)) return true;
break;
case 3:
if (read_vbr(Buf, EndBuf, Result.Arg1) ||
read_vbr(Buf, EndBuf, Result.Arg2) ||
- read_vbr(Buf, EndBuf, Result.Arg3)) return failure(true);
+ read_vbr(Buf, EndBuf, Result.Arg3)) return true;
break;
default:
if (read_vbr(Buf, EndBuf, Result.Arg1) ||
- read_vbr(Buf, EndBuf, Result.Arg2)) return failure(true);
+ read_vbr(Buf, EndBuf, Result.Arg2)) return true;
// Allocate a vector to hold arguments 3, 4, 5, 6 ...
Result.VarArgs = new vector<unsigned>(Result.NumOperands-2);
for (unsigned a = 0; a < Result.NumOperands-2; a++)
- if (read_vbr(Buf, EndBuf, (*Result.VarArgs)[a])) return failure(true);
+ if (read_vbr(Buf, EndBuf, (*Result.VarArgs)[a])) return true;
break;
}
- if (align32(Buf, EndBuf)) return failure(true);
+ if (align32(Buf, EndBuf)) return true;
break;
}
Instruction *&Res) {
RawInst Raw;
if (ParseRawInst(Buf, EndBuf, Raw))
- return failure(true);
+ return true;
if (Raw.Opcode >= Instruction::FirstBinaryOp &&
Raw.Opcode < Instruction::NumBinaryOps && Raw.NumOperands == 2) {
case 1:
case 3: cerr << "Invalid phi node encountered!\n";
delete PN;
- return failure(true);
+ return true;
case 2: PN->addIncoming(getValue(Raw.Ty, Raw.Arg1),
cast<BasicBlock>(getValue(Type::LabelTy,Raw.Arg2)));
break;
if (Raw.VarArgs->size() & 1) {
cerr << "PHI Node with ODD number of arguments!\n";
delete PN;
- return failure(true);
+ return true;
} else {
vector<unsigned> &args = *Raw.VarArgs;
for (unsigned i = 0; i < args.size(); i+=2)
if (Raw.NumOperands == 3 || Raw.VarArgs->size() & 1) {
cerr << "Switch statement with odd number of arguments!\n";
delete I;
- return failure(true);
+ return true;
}
vector<unsigned> &args = *Raw.VarArgs;
case Instruction::Call: {
Value *M = getValue(Raw.Ty, Raw.Arg1);
- if (M == 0) return failure(true);
+ if (M == 0) return true;
// Check to make sure we have a pointer to method type
const PointerType *PTy = dyn_cast<PointerType>(M->getType());
- if (PTy == 0) return failure(true);
+ if (PTy == 0) return true;
const FunctionType *MTy = dyn_cast<FunctionType>(PTy->getElementType());
- if (MTy == 0) return failure(true);
+ if (MTy == 0) return true;
vector<Value *> Params;
const FunctionType::ParamTypes &PL = MTy->getParamTypes();
switch (Raw.NumOperands) {
case 0: cerr << "Invalid call instruction encountered!\n";
- return failure(true);
+ return true;
case 1: break;
case 2: Params.push_back(getValue(*It++, Raw.Arg2)); break;
case 3: Params.push_back(getValue(*It++, Raw.Arg2));
- if (It == PL.end()) return failure(true);
+ if (It == PL.end()) return true;
Params.push_back(getValue(*It++, Raw.Arg3)); break;
default:
Params.push_back(getValue(*It++, Raw.Arg2));
{
vector<unsigned> &args = *Raw.VarArgs;
for (unsigned i = 0; i < args.size(); i++) {
- if (It == PL.end()) return failure(true);
+ if (It == PL.end()) return true;
// TODO: Check getValue for null!
Params.push_back(getValue(*It++, args[i]));
}
}
delete Raw.VarArgs;
}
- if (It != PL.end()) return failure(true);
+ if (It != PL.end()) return true;
} else {
if (Raw.NumOperands > 2) {
vector<unsigned> &args = *Raw.VarArgs;
- if (args.size() < 1) return failure(true);
+ if (args.size() < 1) return true;
if ((args.size() & 1) != 0)
- return failure(true); // Must be pairs of type/value
+ return true; // Must be pairs of type/value
for (unsigned i = 0; i < args.size(); i+=2) {
const Type *Ty = getType(args[i]);
if (Ty == 0)
- return failure(true);
+ return true;
Value *V = getValue(Ty, args[i+1]);
- if (V == 0) return failure(true);
+ if (V == 0) return true;
Params.push_back(V);
}
delete Raw.VarArgs;
}
case Instruction::Invoke: {
Value *M = getValue(Raw.Ty, Raw.Arg1);
- if (M == 0) return failure(true);
+ if (M == 0) return true;
// Check to make sure we have a pointer to method type
const PointerType *PTy = dyn_cast<PointerType>(M->getType());
- if (PTy == 0) return failure(true);
+ if (PTy == 0) return true;
const FunctionType *MTy = dyn_cast<FunctionType>(PTy->getElementType());
- if (MTy == 0) return failure(true);
+ if (MTy == 0) return true;
vector<Value *> Params;
const FunctionType::ParamTypes &PL = MTy->getParamTypes();
BasicBlock *Normal, *Except;
if (!MTy->isVarArg()) {
- if (Raw.NumOperands < 3) return failure(true);
+ if (Raw.NumOperands < 3) return true;
Normal = cast<BasicBlock>(getValue(Type::LabelTy, Raw.Arg2));
Except = cast<BasicBlock>(getValue(Type::LabelTy, args[0]));
FunctionType::ParamTypes::const_iterator It = PL.begin();
for (unsigned i = 1; i < args.size(); i++) {
- if (It == PL.end()) return failure(true);
+ if (It == PL.end()) return true;
// TODO: Check getValue for null!
Params.push_back(getValue(*It++, args[i]));
}
- if (It != PL.end()) return failure(true);
+ if (It != PL.end()) return true;
} else {
- if (args.size() < 4) return failure(true);
+ if (args.size() < 4) return true;
Normal = cast<BasicBlock>(getValue(Type::LabelTy, args[0]));
Except = cast<BasicBlock>(getValue(Type::LabelTy, args[2]));
if ((args.size() & 1) != 0)
- return failure(true); // Must be pairs of type/value
+ return true; // Must be pairs of type/value
for (unsigned i = 4; i < args.size(); i+=2) {
// TODO: Check getValue for null!
Params.push_back(getValue(getType(args[i]), args[i+1]));
return false;
}
case Instruction::Malloc:
- if (Raw.NumOperands > 2) return failure(true);
+ if (Raw.NumOperands > 2) return true;
V = Raw.NumOperands ? getValue(Type::UIntTy, Raw.Arg1) : 0;
Res = new MallocInst(Raw.Ty, V);
return false;
case Instruction::Alloca:
- if (Raw.NumOperands > 2) return failure(true);
+ if (Raw.NumOperands > 2) return true;
V = Raw.NumOperands ? getValue(Type::UIntTy, Raw.Arg1) : 0;
Res = new AllocaInst(Raw.Ty, V);
return false;
case Instruction::Free:
V = getValue(Raw.Ty, Raw.Arg1);
- if (!isa<PointerType>(V->getType())) return failure(true);
+ if (!isa<PointerType>(V->getType())) return true;
Res = new FreeInst(V);
return false;
case Instruction::Load:
case Instruction::GetElementPtr: {
vector<Value*> Idx;
- if (!isa<PointerType>(Raw.Ty)) return failure(true);
+ if (!isa<PointerType>(Raw.Ty)) return true;
const CompositeType *TopTy = dyn_cast<CompositeType>(Raw.Ty);
switch (Raw.NumOperands) {
- case 0: cerr << "Invalid load encountered!\n"; return failure(true);
+ case 0: cerr << "Invalid load encountered!\n"; return true;
case 1: break;
case 2:
- if (!TopTy) return failure(true);
+ if (!TopTy) return true;
Idx.push_back(V = getValue(TopTy->getIndexType(), Raw.Arg2));
- if (!V) return failure(true);
+ if (!V) return true;
break;
case 3: {
- if (!TopTy) return failure(true);
+ if (!TopTy) return true;
Idx.push_back(V = getValue(TopTy->getIndexType(), Raw.Arg2));
- if (!V) return failure(true);
+ if (!V) return true;
const Type *ETy = MemAccessInst::getIndexedType(TopTy, Idx, true);
const CompositeType *ElTy = dyn_cast_or_null<CompositeType>(ETy);
- if (!ElTy) return failure(true);
+ if (!ElTy) return true;
Idx.push_back(V = getValue(ElTy->getIndexType(), Raw.Arg3));
- if (!V) return failure(true);
+ if (!V) return true;
break;
}
default:
- if (!TopTy) return failure(true);
+ if (!TopTy) return true;
Idx.push_back(V = getValue(TopTy->getIndexType(), Raw.Arg2));
- if (!V) return failure(true);
+ if (!V) return true;
vector<unsigned> &args = *Raw.VarArgs;
for (unsigned i = 0, E = args.size(); i != E; ++i) {
const Type *ETy = MemAccessInst::getIndexedType(Raw.Ty, Idx, true);
const CompositeType *ElTy = dyn_cast_or_null<CompositeType>(ETy);
- if (!ElTy) return failure(true);
+ if (!ElTy) return true;
Idx.push_back(V = getValue(ElTy->getIndexType(), args[i]));
- if (!V) return failure(true);
+ if (!V) return true;
}
delete Raw.VarArgs;
break;
}
case Instruction::Store: {
vector<Value*> Idx;
- if (!isa<PointerType>(Raw.Ty)) return failure(true);
+ if (!isa<PointerType>(Raw.Ty)) return true;
const CompositeType *TopTy = dyn_cast<CompositeType>(Raw.Ty);
switch (Raw.NumOperands) {
case 0:
- case 1: cerr << "Invalid store encountered!\n"; return failure(true);
+ case 1: cerr << "Invalid store encountered!\n"; return true;
case 2: break;
case 3:
- if (!TopTy) return failure(true);
+ if (!TopTy) return true;
Idx.push_back(V = getValue(TopTy->getIndexType(), Raw.Arg3));
- if (!V) return failure(true);
+ if (!V) return true;
break;
default:
vector<unsigned> &args = *Raw.VarArgs;
unsigned i, E;
for (i = 0, E = args.size(); ElTy && i != E; ++i) {
Idx.push_back(V = getValue(ElTy->getIndexType(), args[i]));
- if (!V) return failure(true);
+ if (!V) return true;
const Type *ETy = MemAccessInst::getIndexedType(Raw.Ty, Idx, true);
ElTy = dyn_cast_or_null<CompositeType>(ETy);
}
if (i != E)
- return failure(true); // didn't use up all of the indices!
+ return true; // didn't use up all of the indices!
delete Raw.VarArgs;
break;
}
const Type *ElType = StoreInst::getIndexedType(Raw.Ty, Idx);
- if (ElType == 0) return failure(true);
+ if (ElType == 0) return true;
Res = new StoreInst(getValue(ElType, Raw.Arg1), getValue(Raw.Ty, Raw.Arg2),
Idx);
return false;
cerr << "Unrecognized instruction! " << Raw.Opcode
<< " ADDR = 0x" << (void*)Buf << "\n";
- return failure(true);
+ return true;
}
// Note that this library should be as fast as possible, reentrant, and
// threadsafe!!
//
-// TODO: Make error message outputs be configurable depending on an option?
+// TODO: Return error messages to caller instead of printing them out directly.
// TODO: Allow passing in an option to ignore the symbol table
//
//===----------------------------------------------------------------------===//
#include "ReaderInternals.h"
#include "llvm/Bytecode/Reader.h"
#include "llvm/Bytecode/Format.h"
-#include "llvm/GlobalVariable.h"
#include "llvm/Module.h"
#include "llvm/Constants.h"
#include "llvm/iPHINode.h"
#include <fcntl.h>
#include <unistd.h>
#include <algorithm>
-#include <iostream>
using std::cerr;
using std::pair;
using std::make_pair;
//cerr << "Looking up Type ID: " << ID << "\n";
const Value *D = getValue(Type::TypeTy, ID, false);
- if (D == 0) return failure<const Type*>(0);
+ if (D == 0) return 0;
return cast<Type>(D);
}
int BytecodeParser::insertValue(Value *Val, std::vector<ValueList> &ValueTab) {
unsigned type;
- if (getTypeSlot(Val->getType(), type)) return failure<int>(-1);
+ if (getTypeSlot(Val->getType(), type)) return -1;
assert(type != Type::TypeTyID && "Types should never be insertValue'd!");
if (ValueTab.size() <= type)
unsigned Num = oNum;
unsigned type; // The type plane it lives in...
- if (getTypeSlot(Ty, type)) return failure<Value*>(0); // TODO: true
+ if (getTypeSlot(Ty, type)) return 0;
if (type == Type::TypeTyID) { // The 'type' plane has implicit values
assert(Create == false);
if (Values.size() > type && Values[type].size() > Num)
return Values[type][Num];
- if (!Create) return failure<Value*>(0); // Do not create a placeholder?
+ if (!Create) return 0; // Do not create a placeholder?
Value *d = 0;
switch (Ty->getPrimitiveID()) {
- case Type::LabelTyID: d = new BBPHolder(Ty, oNum); break;
case Type::FunctionTyID:
cerr << "Creating method pholder! : " << type << ":" << oNum << " "
<< Ty->getName() << "\n";
- d = new MethPHolder(Ty, oNum);
- if (insertValue(d, LateResolveModuleValues) ==-1) return failure<Value*>(0);
+ d = new FunctionPHolder(Ty, oNum);
+ if (insertValue(d, LateResolveModuleValues) == -1) return 0;
return d;
- default: d = new DefPHolder(Ty, oNum); break;
+ case Type::LabelTyID:
+ d = new BBPHolder(Ty, oNum);
+ break;
+ default:
+ d = new ValPHolder(Ty, oNum);
+ break;
}
assert(d != 0 && "How did we not make something?");
- if (insertValue(d, LateResolveValues) == -1) return failure<Value*>(0);
+ if (insertValue(d, LateResolveValues) == -1) return 0;
return d;
}
Instruction *Inst;
if (ParseInstruction(Buf, EndBuf, Inst)) {
delete BB;
- return failure(true);
+ return true;
}
- if (Inst == 0) { delete BB; return failure(true); }
- if (insertValue(Inst, Values) == -1) { delete BB; return failure(true); }
+ if (Inst == 0) { delete BB; return true; }
+ if (insertValue(Inst, Values) == -1) { delete BB; return true; }
BB->getInstList().push_back(Inst);
// Symtab block header: [num entries][type id number]
unsigned NumEntries, Typ;
if (read_vbr(Buf, EndBuf, NumEntries) ||
- read_vbr(Buf, EndBuf, Typ)) return failure(true);
+ read_vbr(Buf, EndBuf, Typ)) return true;
const Type *Ty = getType(Typ);
- if (Ty == 0) return failure(true);
+ if (Ty == 0) return true;
BCR_TRACE(3, "Plane Type: '" << Ty << "' with " << NumEntries <<
" entries\n");
for (unsigned i = 0; i < NumEntries; ++i) {
// Symtab entry: [def slot #][name]
unsigned slot;
- if (read_vbr(Buf, EndBuf, slot)) return failure(true);
+ if (read_vbr(Buf, EndBuf, slot)) return true;
std::string Name;
if (read(Buf, EndBuf, Name, false)) // Not aligned...
- return failure(true);
+ return true;
Value *D = getValue(Ty, slot, false); // Find mapping...
if (D == 0) {
BCR_TRACE(3, "FAILED LOOKUP: Slot #" << slot << "\n");
- return failure(true);
+ return true;
}
BCR_TRACE(4, "Map: '" << Name << "' to #" << slot << ":" << D;
if (!isa<Instruction>(D)) cerr << "\n");
}
}
- if (Buf > EndBuf) return failure(true);
+ if (Buf > EndBuf) return true;
return false;
}
-Value*
-ConstantFwdRefs::find(const Type* Ty, unsigned Slot) {
- GlobalRefsType::iterator I = GlobalRefs.find(make_pair(Ty, Slot));
- if (I != GlobalRefs.end()) {
- return I->second;
- } else {
- return failure<Value*>(0);
- }
-}
+void BytecodeParser::ResolveReferencesToValue(Value *NewV, unsigned Slot) {
+ GlobalRefsType::iterator I = GlobalRefs.find(make_pair(NewV->getType(),Slot));
+ if (I == GlobalRefs.end()) return; // Never forward referenced?
-void
-ConstantFwdRefs::insert(const Type* Ty, unsigned Slot, Value* V) {
- // Keep track of the fact that we have a forward ref to recycle it
- const pair<GlobalRefsType::iterator, bool>& result =
- GlobalRefs.insert(make_pair(make_pair(Ty, Slot), V));
- assert(result.second == true && "Entry already exists for this slot?");
-}
+ BCR_TRACE(3, "Mutating forward refs!\n");
+ Value *VPH = I->second; // Get the placeholder...
-void
-ConstantFwdRefs::erase(const Type* Ty, unsigned Slot) {
- GlobalRefsType::iterator I = GlobalRefs.find(make_pair(Ty, Slot));
- if (I != GlobalRefs.end())
- GlobalRefs.erase(I);
-}
-
-// GetFwdRefToConstant - Get a forward reference to a constant value.
-// Create a unique one if it does not exist already.
-//
-Constant*
-ConstantFwdRefs::GetFwdRefToConstant(const Type* Ty, unsigned Slot) {
-
- Constant* C = cast_or_null<Constant>(find(Ty, Slot));
-
- if (C) {
- BCR_TRACE(5, "Previous forward ref found!\n");
- } else {
- // Create a placeholder for the constant reference and
- // keep track of the fact that we have a forward ref to recycle it
- BCR_TRACE(5, "Creating new forward ref to a constant!\n");
- C = new ConstPHolder(Ty, Slot);
- insert(Ty, Slot, C);
- }
-
- return C;
-}
-
-
-// GetFwdRefToGlobal - Get a forward reference to a global value.
-// Create a unique one if it does not exist already.
-//
-GlobalValue*
-ConstantFwdRefs::GetFwdRefToGlobal(const PointerType* PT, unsigned Slot) {
-
- GlobalValue* GV = cast_or_null<GlobalValue>(find(PT, Slot));
-
- if (GV) {
- BCR_TRACE(5, "Previous forward ref found!\n");
- } else {
- BCR_TRACE(5, "Creating new forward ref to a global variable!\n");
-
- // Create a placeholder for the global variable reference...
- GlobalVariable *GVar =
- new GlobalVariable(PT->getElementType(), false, true);
-
- // Keep track of the fact that we have a forward ref to recycle it
- insert(PT, Slot, GVar);
-
- // Must temporarily push this value into the module table...
- TheModule->getGlobalList().push_back(GVar);
- GV = GVar;
- }
-
- return GV;
-}
-
-void
-ConstantFwdRefs::ResolveRefsToValue(Value* NewV, unsigned Slot) {
- if (Value* vph = find(NewV->getType(), Slot)) {
- BCR_TRACE(3, "Mutating forward refs!\n");
-
- // Loop over all of the uses of the Value. What they are depends
- // on what NewV is. Replacing a use of the old reference takes the
- // use off the use list, so loop with !use_empty(), not the use_iterator.
- while (!vph->use_empty()) {
- Constant *C = cast<Constant>(vph->use_back());
- unsigned numReplaced = C->mutateReferences(vph, NewV);
- assert(numReplaced > 0 && "Supposed user wasn't really a user?");
+ // Loop over all of the uses of the Value. What they are depends
+ // on what NewV is. Replacing a use of the old reference takes the
+ // use off the use list, so loop with !use_empty(), not the use_iterator.
+ while (!VPH->use_empty()) {
+ Constant *C = cast<Constant>(VPH->use_back());
+ unsigned numReplaced = C->mutateReferences(VPH, NewV);
+ assert(numReplaced > 0 && "Supposed user wasn't really a user?");
- if (GlobalValue* GVal = dyn_cast<GlobalValue>(NewV)) {
- // Remove the placeholder GlobalValue from the module...
- GVal->getParent()->getGlobalList().remove(cast<GlobalVariable>(vph));
- }
+ if (GlobalValue* GVal = dyn_cast<GlobalValue>(NewV)) {
+ // Remove the placeholder GlobalValue from the module...
+ GVal->getParent()->getGlobalList().remove(cast<GlobalVariable>(VPH));
}
-
- delete vph; // Delete the old placeholder
- erase(NewV->getType(), Slot); // Remove the map entry for it
}
-}
-
-// resolveRefsToGlobal - Patch up forward references to global values in the
-// form of ConstantPointerRef.
-//
-void BytecodeParser::resolveRefsToGlobal(GlobalValue *GV, unsigned Slot) {
- fwdRefs.ResolveRefsToValue(GV, Slot);
-}
-// resolveRefsToConstant - Patch up forward references to constants
-//
-void BytecodeParser::resolveRefsToConstant(Constant *C, unsigned Slot) {
- fwdRefs.ResolveRefsToValue(C, Slot);
+ delete VPH; // Delete the old placeholder
+ GlobalRefs.erase(I); // Remove the map entry for it
}
-
bool BytecodeParser::ParseMethod(const uchar *&Buf, const uchar *EndBuf,
Module *C) {
// Clear out the local values table...
Values.clear();
- if (MethodSignatureList.empty()) {
+ if (FunctionSignatureList.empty()) {
Error = "Function found, but FunctionSignatureList empty!";
- return failure(true); // Unexpected method!
+ return true; // Unexpected method!
}
- const PointerType *PMTy = MethodSignatureList.front().first; // PtrMeth
+ const PointerType *PMTy = FunctionSignatureList.back().first; // PtrMeth
const FunctionType *MTy = dyn_cast<FunctionType>(PMTy->getElementType());
- if (MTy == 0) return failure(true); // Not ptr to method!
+ if (MTy == 0) return true; // Not ptr to method!
unsigned isInternal;
- if (read_vbr(Buf, EndBuf, isInternal)) return failure(true);
+ if (read_vbr(Buf, EndBuf, isInternal)) return true;
- unsigned MethSlot = MethodSignatureList.front().second;
- MethodSignatureList.pop_front();
+ unsigned MethSlot = FunctionSignatureList.back().second;
+ FunctionSignatureList.pop_back();
Function *M = new Function(MTy, isInternal != 0);
BCR_TRACE(2, "METHOD TYPE: " << MTy << "\n");
Argument *FA = new Argument(*It);
if (insertValue(FA, Values) == -1) {
Error = "Error reading method arguments!\n";
- delete M; return failure(true);
+ delete M; return true;
}
M->getArgumentList().push_back(FA);
}
const uchar *OldBuf = Buf;
if (readBlock(Buf, EndBuf, Type, Size)) {
Error = "Error reading Function level block!";
- delete M; return failure(true);
+ delete M; return true;
}
switch (Type) {
case BytecodeFormat::ConstantPool:
BCR_TRACE(2, "BLOCK BytecodeFormat::ConstantPool: {\n");
if (ParseConstantPool(Buf, Buf+Size, Values, MethodTypeValues)) {
- delete M; return failure(true);
+ delete M; return true;
}
break;
BasicBlock *BB;
if (ParseBasicBlock(Buf, Buf+Size, BB) ||
insertValue(BB, Values) == -1) {
- delete M; return failure(true); // Parse error... :(
+ delete M; return true; // Parse error... :(
}
M->getBasicBlockList().push_back(BB);
case BytecodeFormat::SymbolTable:
BCR_TRACE(2, "BLOCK BytecodeFormat::SymbolTable: {\n");
if (ParseSymbolTable(Buf, Buf+Size, M->getSymbolTableSure())) {
- delete M; return failure(true);
+ delete M; return true;
}
break;
default:
BCR_TRACE(2, "BLOCK <unknown>:ignored! {\n");
Buf += Size;
- if (OldBuf > Buf) return failure(true); // Wrap around!
+ if (OldBuf > Buf) return true; // Wrap around!
break;
}
BCR_TRACE(2, "} end block\n");
if (align32(Buf, EndBuf)) {
Error = "Error aligning Function level block!";
delete M; // Malformed bc file, read past end of block.
- return failure(true);
+ return true;
}
}
if (postResolveValues(LateResolveValues) ||
postResolveValues(LateResolveModuleValues)) {
Error = "Error resolving method values!";
- delete M; return failure(true); // Unresolvable references!
+ delete M; return true; // Unresolvable references!
}
- Value *MethPHolder = getValue(PMTy, MethSlot, false);
- assert(MethPHolder && "Something is broken no placeholder found!");
- assert(isa<Function>(MethPHolder) && "Not a function?");
+ Value *FunctionPHolder = getValue(PMTy, MethSlot, false);
+ assert(FunctionPHolder && "Something is broken no placeholder found!");
+ assert(isa<Function>(FunctionPHolder) && "Not a function?");
unsigned type; // Type slot
assert(!getTypeSlot(MTy, type) && "How can meth type not exist?");
MethodTypeValues.clear();
// If anyone is using the placeholder make them use the real method instead
- MethPHolder->replaceAllUsesWith(M);
+ FunctionPHolder->replaceAllUsesWith(M);
// We don't need the placeholder anymore!
- delete MethPHolder;
+ delete FunctionPHolder;
// If the method is empty, we don't need the method argument entries...
if (M->isExternal())
M->getArgumentList().clear();
- resolveRefsToGlobal(M, MethSlot);
+ ResolveReferencesToValue(M, MethSlot);
return false;
}
bool BytecodeParser::ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End,
Module *Mod) {
- if (!MethodSignatureList.empty()) {
+ if (!FunctionSignatureList.empty()) {
Error = "Two ModuleGlobalInfo packets found!";
- return failure(true); // Two ModuleGlobal blocks?
+ return true; // Two ModuleGlobal blocks?
}
// Read global variables...
unsigned VarType;
- if (read_vbr(Buf, End, VarType)) return failure(true);
+ if (read_vbr(Buf, End, VarType)) return true;
while (VarType != Type::VoidTyID) { // List is terminated by Void
// VarType Fields: bit0 = isConstant, bit1 = hasInitializer,
// bit2 = isInternal, bit3+ = slot#
const Type *Ty = getType(VarType >> 3);
if (!Ty || !isa<PointerType>(Ty)) {
Error = "Global not pointer type! Ty = " + Ty->getDescription();
- return failure(true);
+ return true;
}
const PointerType *PTy = cast<const PointerType>(Ty);
// which should have been read before now.
//
unsigned InitSlot;
- if (read_vbr(Buf, End, InitSlot)) return failure(true);
+ if (read_vbr(Buf, End, InitSlot)) return true;
Value *V = getValue(ElTy, InitSlot, false);
- if (V == 0) return failure(true);
+ if (V == 0) return true;
Initializer = cast<Constant>(V);
}
GlobalVariable *GV = new GlobalVariable(ElTy, VarType & 1, VarType & 4,
Initializer);
int DestSlot = insertValue(GV, ModuleValues);
- if (DestSlot == -1) return failure(true);
+ if (DestSlot == -1) return true;
Mod->getGlobalList().push_back(GV);
- resolveRefsToGlobal(GV, unsigned(DestSlot));
+ ResolveReferencesToValue(GV, (unsigned)DestSlot);
BCR_TRACE(2, "Global Variable of type: " << PTy->getDescription()
<< " into slot #" << DestSlot << "\n");
- if (read_vbr(Buf, End, VarType)) return failure(true);
+ if (read_vbr(Buf, End, VarType)) return true;
}
// Read the method signatures for all of the methods that are coming, and
// create fillers in the Value tables.
- unsigned MethSignature;
- if (read_vbr(Buf, End, MethSignature)) return failure(true);
- while (MethSignature != Type::VoidTyID) { // List is terminated by Void
- const Type *Ty = getType(MethSignature);
+ unsigned FnSignature;
+ if (read_vbr(Buf, End, FnSignature)) return true;
+ while (FnSignature != Type::VoidTyID) { // List is terminated by Void
+ const Type *Ty = getType(FnSignature);
if (!Ty || !isa<PointerType>(Ty) ||
!isa<FunctionType>(cast<PointerType>(Ty)->getElementType())) {
Error = "Function not ptr to func type! Ty = " + Ty->getDescription();
- return failure(true);
+ return true;
}
// We create methods by passing the underlying FunctionType to create...
// placeholder is replaced.
// Insert the placeholder...
- Value *Val = new MethPHolder(Ty, 0);
- if (insertValue(Val, ModuleValues) == -1) return failure(true);
+ Value *Val = new FunctionPHolder(Ty, 0);
+ if (insertValue(Val, ModuleValues) == -1) return true;
// Figure out which entry of its typeslot it went into...
unsigned TypeSlot;
- if (getTypeSlot(Val->getType(), TypeSlot)) return failure(true);
+ if (getTypeSlot(Val->getType(), TypeSlot)) return true;
unsigned SlotNo = ModuleValues[TypeSlot].size()-1;
// Keep track of this information in a linked list that is emptied as
// methods are loaded...
//
- MethodSignatureList.push_back(
+ FunctionSignatureList.push_back(
make_pair(cast<const PointerType>(Val->getType()), SlotNo));
- if (read_vbr(Buf, End, MethSignature)) return failure(true);
+ if (read_vbr(Buf, End, FnSignature)) return true;
BCR_TRACE(2, "Function of type: " << Ty << "\n");
}
- if (align32(Buf, End)) return failure(true);
+ if (align32(Buf, End)) return true;
+
+ // Now that the function signature list is set up, reverse it so that we can
+ // remove elements efficiently from the back of the vector.
+ std::reverse(FunctionSignatureList.begin(), FunctionSignatureList.end());
// This is for future proofing... in the future extra fields may be added that
// we don't understand, so we transparently ignore them.
}
bool BytecodeParser::ParseModule(const uchar *Buf, const uchar *EndBuf,
- Module *&C) {
+ Module *&Mod) {
unsigned Type, Size;
- if (readBlock(Buf, EndBuf, Type, Size)) return failure(true);
+ if (readBlock(Buf, EndBuf, Type, Size)) return true;
if (Type != BytecodeFormat::Module || Buf+Size != EndBuf) {
Error = "Expected Module packet!";
- return failure(true); // Hrm, not a class?
+ return true; // Hrm, not a class?
}
BCR_TRACE(0, "BLOCK BytecodeFormat::Module: {\n");
- MethodSignatureList.clear(); // Just in case...
+ FunctionSignatureList.clear(); // Just in case...
// Read into instance variables...
- if (read_vbr(Buf, EndBuf, FirstDerivedTyID)) return failure(true);
- if (align32(Buf, EndBuf)) return failure(true);
+ if (read_vbr(Buf, EndBuf, FirstDerivedTyID)) return true;
+ if (align32(Buf, EndBuf)) return true;
BCR_TRACE(1, "FirstDerivedTyID = " << FirstDerivedTyID << "\n");
- TheModule = C = new Module();
- fwdRefs.VisitingModule(TheModule);
+ TheModule = Mod = new Module();
while (Buf < EndBuf) {
const uchar *OldBuf = Buf;
- if (readBlock(Buf, EndBuf, Type, Size)) { delete C; return failure(true); }
+ if (readBlock(Buf, EndBuf, Type, Size)) { delete Mod; return true;}
switch (Type) {
case BytecodeFormat::ConstantPool:
BCR_TRACE(1, "BLOCK BytecodeFormat::ConstantPool: {\n");
if (ParseConstantPool(Buf, Buf+Size, ModuleValues, ModuleTypeValues)) {
- delete C; return failure(true);
+ delete Mod; return true;
}
break;
case BytecodeFormat::ModuleGlobalInfo:
BCR_TRACE(1, "BLOCK BytecodeFormat::ModuleGlobalInfo: {\n");
- if (ParseModuleGlobalInfo(Buf, Buf+Size, C)) {
- delete C; return failure(true);
+ if (ParseModuleGlobalInfo(Buf, Buf+Size, Mod)) {
+ delete Mod; return true;
}
break;
case BytecodeFormat::Function: {
BCR_TRACE(1, "BLOCK BytecodeFormat::Function: {\n");
- if (ParseMethod(Buf, Buf+Size, C)) {
- delete C; return failure(true); // Error parsing method
+ if (ParseMethod(Buf, Buf+Size, Mod)) {
+ delete Mod; return true; // Error parsing function
}
break;
}
case BytecodeFormat::SymbolTable:
BCR_TRACE(1, "BLOCK BytecodeFormat::SymbolTable: {\n");
- if (ParseSymbolTable(Buf, Buf+Size, C->getSymbolTableSure())) {
- delete C; return failure(true);
+ if (ParseSymbolTable(Buf, Buf+Size, Mod->getSymbolTableSure())) {
+ delete Mod; return true;
}
break;
default:
Error = "Expected Module Block!";
Buf += Size;
- if (OldBuf > Buf) return failure(true); // Wrap around!
+ if (OldBuf > Buf) return true; // Wrap around!
break;
}
BCR_TRACE(1, "} end block\n");
- if (align32(Buf, EndBuf)) { delete C; return failure(true); }
+ if (align32(Buf, EndBuf)) { delete Mod; return true; }
}
- if (!MethodSignatureList.empty()) { // Expected more methods!
+ if (!FunctionSignatureList.empty()) { // Expected more methods!
Error = "Function expected, but bytecode stream at end!";
- return failure(true);
+ return true;
}
BCR_TRACE(0, "} end block\n\n");
if (read(Buf, EndBuf, Sig) ||
Sig != ('l' | ('l' << 8) | ('v' << 16) | 'm' << 24)) {
Error = "Invalid bytecode signature!";
- return failure<Module*>(0); // Invalid signature!
+ return 0; // Invalid signature!
}
Module *Result;
int FD = open(Filename.c_str(), O_RDONLY);
if (FD == -1) {
if (ErrorStr) *ErrorStr = "Error opening file!";
- return failure<Module*>(0);
+ return 0;
}
- if (fstat(FD, &StatBuf) == -1) { close(FD); return failure<Module*>(0); }
+ if (fstat(FD, &StatBuf) == -1) { close(FD); return 0; }
int Length = StatBuf.st_size;
if (Length == 0) {
if (ErrorStr) *ErrorStr = "Error stat'ing file!";
- close(FD); return failure<Module*>(0);
+ close(FD); return 0;
}
uchar *Buffer = (uchar*)mmap(0, Length, PROT_READ,
MAP_PRIVATE, FD, 0);
if (Buffer == (uchar*)-1) {
if (ErrorStr) *ErrorStr = "Error mmapping file!";
- close(FD); return failure<Module*>(0);
+ close(FD); return 0;
}
BytecodeParser Parser;
int BlockSize;
uchar Buffer[4096], *FileData = 0;
while ((BlockSize = read(0, Buffer, 4))) {
- if (BlockSize == -1) { free(FileData); return failure<Module*>(0); }
+ if (BlockSize == -1) { free(FileData); return 0; }
FileData = (uchar*)realloc(FileData, FileSize+BlockSize);
memcpy(FileData+FileSize, Buffer, BlockSize);
if (FileSize == 0) {
if (ErrorStr) *ErrorStr = "Standard Input empty!";
- free(FileData); return failure<Module*>(0);
+ free(FileData); return 0;
}
#define ALIGN_PTRS 1
#define READER_INTERNALS_H
#include "llvm/Bytecode/Primitives.h"
-#include "llvm/Function.h"
-#include "llvm/BasicBlock.h"
-#include "llvm/Instruction.h"
#include "llvm/DerivedTypes.h"
+#include "llvm/Function.h"
#include "llvm/Constant.h"
-#include "Support/NonCopyable.h"
-#include <map>
#include <utility>
-#include <list>
-#include <iostream>
+#include <map>
// Enable to trace to figure out what the heck is going on when parsing fails
#define TRACE_LEVEL 0
};
};
-
-class ConstantFwdRefs: public NonCopyable {
- Module* TheModule;
-
- // GlobalRefs - This maintains a mapping between <Type, Slot #>'s and forward
- // references to global values or constants. Such values may be referenced
- // before they are defined, and if so, the temporary object that they
- // represent is held here.
- //
- typedef std::map<std::pair<const Type *, unsigned>,
- Value*> GlobalRefsType;
- GlobalRefsType GlobalRefs;
-
- Value* find (const Type* Ty, unsigned Slot);
- void insert (const Type* Ty, unsigned Slot, Value* V);
- void erase (const Type* Ty, unsigned Slot);
-
-public:
- // sets the current module pointer: needed to insert placeholder globals
- void VisitingModule (Module* M) { TheModule = M; }
-
- // get a forward reference to a global or a constant
- GlobalValue* GetFwdRefToGlobal (const PointerType* PT, unsigned Slot);
- Constant* GetFwdRefToConstant (const Type* Ty, unsigned Slot);
-
- // resolve all references to the placeholder (if any) for the given value
- void ResolveRefsToValue (Value* val, unsigned Slot);
-};
-
-
class BytecodeParser : public AbstractTypeUser {
std::string Error; // Error message string goes here...
+ BytecodeParser(const BytecodeParser &); // DO NOT IMPLEMENT
+ void operator=(const BytecodeParser &); // DO NOT IMPLEMENT
public:
BytecodeParser() {
// Define this in case we don't see a ModuleGlobalInfo block.
ValueTable Values, LateResolveValues;
ValueTable ModuleValues, LateResolveModuleValues;
- // fwdRefs - This manages forward references to global values.
- ConstantFwdRefs fwdRefs;
+ // GlobalRefs - This maintains a mapping between <Type, Slot #>'s and forward
+ // references to global values or constants. Such values may be referenced
+ // before they are defined, and if so, the temporary object that they
+ // represent is held here.
+ //
+ typedef std::map<std::pair<const Type *, unsigned>,
+ Value*> GlobalRefsType;
+ GlobalRefsType GlobalRefs;
// TypesLoaded - This vector mirrors the Values[TypeTyID] plane. It is used
// to deal with forward references to types.
// Information read from the ModuleGlobalInfo section of the file...
unsigned FirstDerivedTyID;
- // When the ModuleGlobalInfo section is read, we load the type of each method
- // and the 'ModuleValues' slot that it lands in. We then load a placeholder
- // into its slot to reserve it. When the method is loaded, this placeholder
- // is replaced.
+ // When the ModuleGlobalInfo section is read, we load the type of each
+ // function and the 'ModuleValues' slot that it lands in. We then load a
+ // placeholder into its slot to reserve it. When the function is loaded, this
+ // placeholder is replaced.
//
- std::list<std::pair<const PointerType *, unsigned> > MethodSignatureList;
+ std::vector<std::pair<const PointerType *, unsigned> > FunctionSignatureList;
private:
bool ParseModule (const uchar * Buf, const uchar *End, Module *&);
bool getTypeSlot(const Type *Ty, unsigned &Slot);
- // resolveRefsToGlobal -- resolve forward references to a global
- // resolveRefsToConstant -- resolve forward references to a constant
- //
- void resolveRefsToGlobal(GlobalValue* GV, unsigned Slot);
- void resolveRefsToConstant(Constant* C, unsigned Slot);
+ // resolve all references to the placeholder (if any) for the given value
+ void ResolveReferencesToValue(Value *Val, unsigned Slot);
+
// refineAbstractType - The callback method is invoked when one of the
// elements of TypeValues becomes more concrete...
template<class SuperType>
class PlaceholderDef : public SuperType {
unsigned ID;
- PlaceholderDef(); // do not implement
+ PlaceholderDef(); // DO NOT IMPLEMENT
+ void operator=(const PlaceholderDef &); // DO NOT IMPLEMENT
public:
PlaceholderDef(const Type *Ty, unsigned id) : SuperType(Ty), ID(id) {}
unsigned getID() { return ID; }
}
};
-struct MethPlaceHolderHelper : public Function {
- MethPlaceHolderHelper(const Type *Ty)
+struct FunctionPlaceHolderHelper : public Function {
+ FunctionPlaceHolderHelper(const Type *Ty)
: Function(cast<const FunctionType>(Ty), true) {
}
};
virtual bool isNullValue() const { return false; }
};
-typedef PlaceholderDef<InstPlaceHolderHelper> DefPHolder;
+typedef PlaceholderDef<InstPlaceHolderHelper> ValPHolder;
typedef PlaceholderDef<BBPlaceHolderHelper> BBPHolder;
-typedef PlaceholderDef<MethPlaceHolderHelper> MethPHolder;
+typedef PlaceholderDef<FunctionPlaceHolderHelper> FunctionPHolder;
typedef PlaceholderDef<ConstantPlaceHolderHelper> ConstPHolder;
-static inline unsigned getValueIDNumberFromPlaceHolder(Value *Def) {
- if (isa<Constant>(Def))
- return ((ConstPHolder*)Def)->getID();
+static inline unsigned getValueIDNumberFromPlaceHolder(Value *Val) {
+ if (isa<Constant>(Val))
+ return ((ConstPHolder*)Val)->getID();
// else discriminate by type
- switch (Def->getType()->getPrimitiveID()) {
- case Type::LabelTyID: return ((BBPHolder*)Def)->getID();
- case Type::FunctionTyID: return ((MethPHolder*)Def)->getID();
- default: return ((DefPHolder*)Def)->getID();
+ switch (Val->getType()->getPrimitiveID()) {
+ case Type::LabelTyID: return ((BBPHolder*)Val)->getID();
+ case Type::FunctionTyID: return ((FunctionPHolder*)Val)->getID();
+ default: return ((ValPHolder*)Val)->getID();
}
}
#endif
}
-
-// failure Template - This template function is used as a place to put
-// breakpoints in to debug failures of the bytecode parser.
-//
-template <typename X>
-static X failure(X Value) {
- return Value;
-}
-
#endif