From 7473413072a92c119cf123c5266b26bc041e0bd5 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 17 Aug 2002 22:01:27 +0000 Subject: [PATCH] - Finally nailed: test/Regression/Assembler/2002-08-16-ConstExprInlined.llx - ParseConstantPool was resolving reference to value using the function slot # instead of the global slot #. - Bytecode reader changes: - Remove the failure<> template from Bytecode Reader - Remove extraneous #includes - s/method/function/ a bit - Eliminate the fwdRefs class that just added abstraction where it was not needed, making things more complex. - Use a vector instead of a list for function signatures. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3366 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Bytecode/Reader/ConstantReader.cpp | 145 ++++++---- lib/Bytecode/Reader/InstructionReader.cpp | 117 ++++----- lib/Bytecode/Reader/Reader.cpp | 305 ++++++++-------------- lib/Bytecode/Reader/ReaderInternals.h | 103 +++----- 4 files changed, 292 insertions(+), 378 deletions(-) diff --git a/lib/Bytecode/Reader/ConstantReader.cpp b/lib/Bytecode/Reader/ConstantReader.cpp index 37e201f2807..88bfa3444a2 100644 --- a/lib/Bytecode/Reader/ConstantReader.cpp +++ b/lib/Bytecode/Reader/ConstantReader.cpp @@ -10,17 +10,14 @@ #include "ReaderInternals.h" #include "llvm/Module.h" -#include "llvm/Constants.h" -#include "llvm/GlobalVariable.h" #include -#include using std::make_pair; const Type *BytecodeParser::parseTypeConstant(const uchar *&Buf, const uchar *EndBuf) { unsigned PrimType; - if (read_vbr(Buf, EndBuf, PrimType)) return failure(0); + if (read_vbr(Buf, EndBuf, PrimType)) return 0; const Type *Val = 0; if ((Val = Type::getPrimitiveType((Type::PrimitiveID)PrimType))) @@ -29,18 +26,18 @@ const Type *BytecodeParser::parseTypeConstant(const uchar *&Buf, 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 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); } @@ -51,12 +48,12 @@ const Type *BytecodeParser::parseTypeConstant(const uchar *&Buf, } 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"); @@ -66,23 +63,23 @@ const Type *BytecodeParser::parseTypeConstant(const uchar *&Buf, unsigned Typ; std::vector 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); } @@ -94,7 +91,7 @@ const Type *BytecodeParser::parseTypeConstant(const uchar *&Buf, std::cerr << __FILE__ << ":" << __LINE__ << ": Don't know how to deserialize" << " primitive Type " << PrimType << "\n"; - return failure(Val); + return Val; } } @@ -149,7 +146,7 @@ bool BytecodeParser::parseTypeConstants(const uchar *&Buf, const uchar *EndBuf, // 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"); @@ -184,21 +181,21 @@ bool BytecodeParser::parseConstantValue(const uchar *&Buf, const uchar *EndBuf, // 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 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"); @@ -207,10 +204,23 @@ bool BytecodeParser::parseConstantValue(const uchar *&Buf, const uchar *EndBuf, Value *Val = getValue(ArgTy, ArgValSlot, false); Constant *C; if (Val) { - if (!(C = dyn_cast(Val))) return failure(true); + if (!(C = dyn_cast(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(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); } @@ -232,8 +242,8 @@ bool BytecodeParser::parseConstantValue(const uchar *&Buf, const uchar *EndBuf, 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; } @@ -242,15 +252,15 @@ bool BytecodeParser::parseConstantValue(const uchar *&Buf, const uchar *EndBuf, 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; } @@ -259,29 +269,29 @@ bool BytecodeParser::parseConstantValue(const uchar *&Buf, const uchar *EndBuf, 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; } @@ -297,9 +307,9 @@ bool BytecodeParser::parseConstantValue(const uchar *&Buf, const uchar *EndBuf, std::vector 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(V)) return failure(true); + if (!V || !isa(V)) return true; Elements.push_back(cast(V)); } V = ConstantArray::get(AT, Elements); @@ -313,10 +323,10 @@ bool BytecodeParser::parseConstantValue(const uchar *&Buf, const uchar *EndBuf, std::vector 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(V)) - return failure(true); + return true; Elements.push_back(cast(V)); } @@ -327,7 +337,7 @@ bool BytecodeParser::parseConstantValue(const uchar *&Buf, const uchar *EndBuf, case Type::PointerTyID: { const PointerType *PT = cast(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); @@ -335,17 +345,35 @@ bool BytecodeParser::parseConstantValue(const uchar *&Buf, const uchar *EndBuf, 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(Val))) return failure(true); + if (!(GV = dyn_cast(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(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; @@ -353,7 +381,7 @@ bool BytecodeParser::parseConstantValue(const uchar *&Buf, const uchar *EndBuf, default: BCR_TRACE(5, "UNKNOWN Pointer Constant Type!\n"); - return failure(true); + return true; } break; } @@ -362,7 +390,7 @@ bool BytecodeParser::parseConstantValue(const uchar *&Buf, const uchar *EndBuf, std::cerr << __FILE__ << ":" << __LINE__ << ": Don't know how to deserialize constant value of type '" << Ty->getName() << "'\n"; - return failure(true); + return true; } return false; @@ -375,9 +403,9 @@ bool BytecodeParser::ParseConstantPool(const uchar *&Buf, const uchar *EndBuf, 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) { @@ -386,15 +414,22 @@ bool BytecodeParser::ParseConstantPool(const uchar *&Buf, const uchar *EndBuf, 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; } diff --git a/lib/Bytecode/Reader/InstructionReader.cpp b/lib/Bytecode/Reader/InstructionReader.cpp index 0de8f39c579..979b3944bc2 100644 --- a/lib/Bytecode/Reader/InstructionReader.cpp +++ b/lib/Bytecode/Reader/InstructionReader.cpp @@ -16,14 +16,13 @@ #include "llvm/iMemory.h" #include "llvm/iPHINode.h" #include "llvm/iOther.h" -#include 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 // -------------------------- @@ -70,40 +69,40 @@ bool BytecodeParser::ParseRawInst(const uchar *&Buf, const uchar *EndBuf, 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(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; } @@ -120,7 +119,7 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf, 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) { @@ -146,7 +145,7 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf, 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(getValue(Type::LabelTy,Raw.Arg2))); break; @@ -156,7 +155,7 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf, if (Raw.VarArgs->size() & 1) { cerr << "PHI Node with ODD number of arguments!\n"; delete PN; - return failure(true); + return true; } else { vector &args = *Raw.VarArgs; for (unsigned i = 0; i < args.size(); i+=2) @@ -206,7 +205,7 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf, 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 &args = *Raw.VarArgs; @@ -220,13 +219,13 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf, 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(M->getType()); - if (PTy == 0) return failure(true); + if (PTy == 0) return true; const FunctionType *MTy = dyn_cast(PTy->getElementType()); - if (MTy == 0) return failure(true); + if (MTy == 0) return true; vector Params; const FunctionType::ParamTypes &PL = MTy->getParamTypes(); @@ -236,39 +235,39 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf, 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 &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 &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; @@ -280,13 +279,13 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf, } 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(M->getType()); - if (PTy == 0) return failure(true); + if (PTy == 0) return true; const FunctionType *MTy = dyn_cast(PTy->getElementType()); - if (MTy == 0) return failure(true); + if (MTy == 0) return true; vector Params; const FunctionType::ParamTypes &PL = MTy->getParamTypes(); @@ -295,27 +294,27 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf, BasicBlock *Normal, *Except; if (!MTy->isVarArg()) { - if (Raw.NumOperands < 3) return failure(true); + if (Raw.NumOperands < 3) return true; Normal = cast(getValue(Type::LabelTy, Raw.Arg2)); Except = cast(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(getValue(Type::LabelTy, args[0])); Except = cast(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])); @@ -327,62 +326,62 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf, 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(V->getType())) return failure(true); + if (!isa(V->getType())) return true; Res = new FreeInst(V); return false; case Instruction::Load: case Instruction::GetElementPtr: { vector Idx; - if (!isa(Raw.Ty)) return failure(true); + if (!isa(Raw.Ty)) return true; const CompositeType *TopTy = dyn_cast(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(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 &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(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; @@ -400,17 +399,17 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf, } case Instruction::Store: { vector Idx; - if (!isa(Raw.Ty)) return failure(true); + if (!isa(Raw.Ty)) return true; const CompositeType *TopTy = dyn_cast(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 &args = *Raw.VarArgs; @@ -418,20 +417,20 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf, 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(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; @@ -440,5 +439,5 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf, cerr << "Unrecognized instruction! " << Raw.Opcode << " ADDR = 0x" << (void*)Buf << "\n"; - return failure(true); + return true; } diff --git a/lib/Bytecode/Reader/Reader.cpp b/lib/Bytecode/Reader/Reader.cpp index 8d4ad564065..0e406259769 100644 --- a/lib/Bytecode/Reader/Reader.cpp +++ b/lib/Bytecode/Reader/Reader.cpp @@ -5,7 +5,7 @@ // 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 // //===----------------------------------------------------------------------===// @@ -13,7 +13,6 @@ #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" @@ -24,7 +23,6 @@ #include #include #include -#include using std::cerr; using std::pair; using std::make_pair; @@ -56,14 +54,14 @@ const Type *BytecodeParser::getType(unsigned ID) { //cerr << "Looking up Type ID: " << ID << "\n"; const Value *D = getValue(Type::TypeTy, ID, false); - if (D == 0) return failure(0); + if (D == 0) return 0; return cast(D); } int BytecodeParser::insertValue(Value *Val, std::vector &ValueTab) { unsigned type; - if (getTypeSlot(Val->getType(), type)) return failure(-1); + if (getTypeSlot(Val->getType(), type)) return -1; assert(type != Type::TypeTyID && "Types should never be insertValue'd!"); if (ValueTab.size() <= type) @@ -80,7 +78,7 @@ Value *BytecodeParser::getValue(const Type *Ty, unsigned oNum, bool Create) { unsigned Num = oNum; unsigned type; // The type plane it lives in... - if (getTypeSlot(Ty, type)) return failure(0); // TODO: true + if (getTypeSlot(Ty, type)) return 0; if (type == Type::TypeTyID) { // The 'type' plane has implicit values assert(Create == false); @@ -111,22 +109,26 @@ Value *BytecodeParser::getValue(const Type *Ty, unsigned oNum, bool Create) { if (Values.size() > type && Values[type].size() > Num) return Values[type][Num]; - if (!Create) return failure(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(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(0); + if (insertValue(d, LateResolveValues) == -1) return 0; return d; } @@ -168,11 +170,11 @@ bool BytecodeParser::ParseBasicBlock(const uchar *&Buf, const uchar *EndBuf, 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); @@ -188,9 +190,9 @@ bool BytecodeParser::ParseSymbolTable(const uchar *&Buf, const uchar *EndBuf, // 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"); @@ -198,15 +200,15 @@ bool BytecodeParser::ParseSymbolTable(const uchar *&Buf, const uchar *EndBuf, 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(D)) cerr << "\n"); @@ -215,141 +217,53 @@ bool BytecodeParser::ParseSymbolTable(const uchar *&Buf, const uchar *EndBuf, } } - 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(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& 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(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(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(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(VPH->use_back()); + unsigned numReplaced = C->mutateReferences(VPH, NewV); + assert(numReplaced > 0 && "Supposed user wasn't really a user?"); - if (GlobalValue* GVal = dyn_cast(NewV)) { - // Remove the placeholder GlobalValue from the module... - GVal->getParent()->getGlobalList().remove(cast(vph)); - } + if (GlobalValue* GVal = dyn_cast(NewV)) { + // Remove the placeholder GlobalValue from the module... + GVal->getParent()->getGlobalList().remove(cast(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); + delete VPH; // Delete the old placeholder + GlobalRefs.erase(I); // Remove the map entry for it } -// resolveRefsToConstant - Patch up forward references to constants -// -void BytecodeParser::resolveRefsToConstant(Constant *C, unsigned Slot) { - fwdRefs.ResolveRefsToValue(C, Slot); -} - - 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(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"); @@ -360,7 +274,7 @@ bool BytecodeParser::ParseMethod(const uchar *&Buf, const uchar *EndBuf, 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); } @@ -370,14 +284,14 @@ bool BytecodeParser::ParseMethod(const uchar *&Buf, const uchar *EndBuf, 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; @@ -386,7 +300,7 @@ bool BytecodeParser::ParseMethod(const uchar *&Buf, const uchar *EndBuf, 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); @@ -396,14 +310,14 @@ bool BytecodeParser::ParseMethod(const uchar *&Buf, const uchar *EndBuf, 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 :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"); @@ -411,19 +325,19 @@ bool BytecodeParser::ParseMethod(const uchar *&Buf, const uchar *EndBuf, 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(MethPHolder) && "Not a function?"); + Value *FunctionPHolder = getValue(PMTy, MethSlot, false); + assert(FunctionPHolder && "Something is broken no placeholder found!"); + assert(isa(FunctionPHolder) && "Not a function?"); unsigned type; // Type slot assert(!getTypeSlot(MTy, type) && "How can meth type not exist?"); @@ -438,37 +352,37 @@ bool BytecodeParser::ParseMethod(const uchar *&Buf, const uchar *EndBuf, 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(Ty)) { Error = "Global not pointer type! Ty = " + Ty->getDescription(); - return failure(true); + return true; } const PointerType *PTy = cast(Ty); @@ -480,10 +394,10 @@ bool BytecodeParser::ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End, // 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(V); } @@ -491,28 +405,28 @@ bool BytecodeParser::ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End, 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(Ty) || !isa(cast(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... @@ -524,25 +438,29 @@ bool BytecodeParser::ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End, // 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(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. @@ -552,73 +470,72 @@ bool BytecodeParser::ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End, } 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"); @@ -632,7 +549,7 @@ Module *BytecodeParser::ParseBytecode(const uchar *Buf, const uchar *EndBuf) { if (read(Buf, EndBuf, Sig) || Sig != ('l' | ('l' << 8) | ('v' << 16) | 'm' << 24)) { Error = "Invalid bytecode signature!"; - return failure(0); // Invalid signature! + return 0; // Invalid signature! } Module *Result; @@ -656,21 +573,21 @@ Module *ParseBytecodeFile(const std::string &Filename, std::string *ErrorStr) { int FD = open(Filename.c_str(), O_RDONLY); if (FD == -1) { if (ErrorStr) *ErrorStr = "Error opening file!"; - return failure(0); + return 0; } - if (fstat(FD, &StatBuf) == -1) { close(FD); return failure(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(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(0); + close(FD); return 0; } BytecodeParser Parser; @@ -684,7 +601,7 @@ Module *ParseBytecodeFile(const std::string &Filename, std::string *ErrorStr) { int BlockSize; uchar Buffer[4096], *FileData = 0; while ((BlockSize = read(0, Buffer, 4))) { - if (BlockSize == -1) { free(FileData); return failure(0); } + if (BlockSize == -1) { free(FileData); return 0; } FileData = (uchar*)realloc(FileData, FileSize+BlockSize); memcpy(FileData+FileSize, Buffer, BlockSize); @@ -693,7 +610,7 @@ Module *ParseBytecodeFile(const std::string &Filename, std::string *ErrorStr) { if (FileSize == 0) { if (ErrorStr) *ErrorStr = "Standard Input empty!"; - free(FileData); return failure(0); + free(FileData); return 0; } #define ALIGN_PTRS 1 diff --git a/lib/Bytecode/Reader/ReaderInternals.h b/lib/Bytecode/Reader/ReaderInternals.h index 4b1974e0196..fdaf13d13c1 100644 --- a/lib/Bytecode/Reader/ReaderInternals.h +++ b/lib/Bytecode/Reader/ReaderInternals.h @@ -8,16 +8,11 @@ #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 #include -#include -#include +#include // Enable to trace to figure out what the heck is going on when parsing fails #define TRACE_LEVEL 0 @@ -41,38 +36,10 @@ struct RawInst { // The raw fields out of the bytecode stream... }; }; - -class ConstantFwdRefs: public NonCopyable { - Module* TheModule; - - // GlobalRefs - This maintains a mapping between '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, - 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. @@ -95,8 +62,14 @@ private: // All of this data is transient across calls to ParseBytecode ValueTable Values, LateResolveValues; ValueTable ModuleValues, LateResolveModuleValues; - // fwdRefs - This manages forward references to global values. - ConstantFwdRefs fwdRefs; + // GlobalRefs - This maintains a mapping between '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, + Value*> GlobalRefsType; + GlobalRefsType GlobalRefs; // TypesLoaded - This vector mirrors the Values[TypeTyID] plane. It is used // to deal with forward references to types. @@ -108,12 +81,12 @@ private: // All of this data is transient across calls to ParseBytecode // 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 > MethodSignatureList; + std::vector > FunctionSignatureList; private: bool ParseModule (const uchar * Buf, const uchar *End, Module *&); @@ -140,11 +113,9 @@ private: 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... @@ -155,7 +126,8 @@ private: template 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; } @@ -174,8 +146,8 @@ struct BBPlaceHolderHelper : public BasicBlock { } }; -struct MethPlaceHolderHelper : public Function { - MethPlaceHolderHelper(const Type *Ty) +struct FunctionPlaceHolderHelper : public Function { + FunctionPlaceHolderHelper(const Type *Ty) : Function(cast(Ty), true) { } }; @@ -186,21 +158,21 @@ struct ConstantPlaceHolderHelper : public Constant { virtual bool isNullValue() const { return false; } }; -typedef PlaceholderDef DefPHolder; +typedef PlaceholderDef ValPHolder; typedef PlaceholderDef BBPHolder; -typedef PlaceholderDef MethPHolder; +typedef PlaceholderDef FunctionPHolder; typedef PlaceholderDef ConstPHolder; -static inline unsigned getValueIDNumberFromPlaceHolder(Value *Def) { - if (isa(Def)) - return ((ConstPHolder*)Def)->getID(); +static inline unsigned getValueIDNumberFromPlaceHolder(Value *Val) { + if (isa(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(); } } @@ -216,13 +188,4 @@ static inline bool readBlock(const uchar *&Buf, const uchar *EndBuf, #endif } - -// failure Template - This template function is used as a place to put -// breakpoints in to debug failures of the bytecode parser. -// -template -static X failure(X Value) { - return Value; -} - #endif