//===----------------------------------------------------------------------===//
#include "Reader.h"
+#include "llvm/Assembly/AutoUpgrade.h"
#include "llvm/Bytecode/BytecodeHandler.h"
#include "llvm/BasicBlock.h"
#include "llvm/CallingConv.h"
#include "llvm/Constants.h"
+#include "llvm/InlineAsm.h"
#include "llvm/Instructions.h"
#include "llvm/SymbolTable.h"
#include "llvm/Bytecode/Format.h"
}
// Provide some details on error
-inline void BytecodeReader::error(std::string err) {
- err += " (Vers=" ;
- err += itostr(RevisionNum) ;
- err += ", Pos=" ;
- err += itostr(At-MemStart);
- err += ")";
- throw err;
+inline void BytecodeReader::error(const std::string& err) {
+ ErrorMsg = err + " (Vers=" + itostr(RevisionNum) + ", Pos="
+ + itostr(At-MemStart) + ")";
+ longjmp(context,1);
}
//===----------------------------------------------------------------------===//
inline void BytecodeReader::align32() {
if (hasAlignment) {
BufPtr Save = At;
- At = (const unsigned char *)((unsigned long)(At+3) & (~3UL));
+ At = (const unsigned char *)((intptr_t)(At+3) & (~3UL));
if (At > Save)
if (Handler) Handler->handleAlignment(At - Save);
if (At > BlockEnd)
ForwardReferences.insert(I, std::make_pair(KeyValue, Val));
return Val;
}
- throw "Can't create placeholder for value of type slot #" + utostr(type);
+ error("Can't create placeholder for value of type slot #" + utostr(type));
+ return 0; // just silence warning, error calls longjmp
}
/// This is just like getValue, but when a compaction table is in use, it
/// or FunctionValues data members of this class.
unsigned BytecodeReader::insertValue(Value *Val, unsigned type,
ValueTable &ValueTab) {
- assert((!isa<Constant>(Val) || !cast<Constant>(Val)->isNullValue()) ||
- !hasImplicitNull(type) &&
- "Cannot read null values from bytecode!");
-
if (ValueTab.size() <= type)
ValueTab.resize(type+1);
getValue(iType, Oprnds[0]),
getValue(iType, Oprnds[1]));
+ bool isCall = false;
switch (Opcode) {
default:
if (Result == 0)
Result = new VAArgInst(foo, getSanitizedType(Oprnds[1]));
break;
}
+ case Instruction::ExtractElement: {
+ if (Oprnds.size() != 2)
+ error("Invalid extractelement instruction!");
+ Value *V1 = getValue(iType, Oprnds[0]);
+ Value *V2 = getValue(Type::UIntTyID, Oprnds[1]);
+
+ if (!ExtractElementInst::isValidOperands(V1, V2))
+ error("Invalid extractelement instruction!");
+
+ Result = new ExtractElementInst(V1, V2);
+ break;
+ }
+ case Instruction::InsertElement: {
+ const PackedType *PackedTy = dyn_cast<PackedType>(InstTy);
+ if (!PackedTy || Oprnds.size() != 3)
+ error("Invalid insertelement instruction!");
+
+ Value *V1 = getValue(iType, Oprnds[0]);
+ Value *V2 = getValue(getTypeSlot(PackedTy->getElementType()), Oprnds[1]);
+ Value *V3 = getValue(Type::UIntTyID, Oprnds[2]);
+
+ if (!InsertElementInst::isValidOperands(V1, V2, V3))
+ error("Invalid insertelement instruction!");
+ Result = new InsertElementInst(V1, V2, V3);
+ break;
+ }
+ case Instruction::ShuffleVector: {
+ const PackedType *PackedTy = dyn_cast<PackedType>(InstTy);
+ if (!PackedTy || Oprnds.size() != 3)
+ error("Invalid shufflevector instruction!");
+ Value *V1 = getValue(iType, Oprnds[0]);
+ Value *V2 = getValue(iType, Oprnds[1]);
+ const PackedType *EltTy =
+ PackedType::get(Type::UIntTy, PackedTy->getNumElements());
+ Value *V3 = getValue(getTypeSlot(EltTy), Oprnds[2]);
+ if (!ShuffleVectorInst::isValidOperands(V1, V2, V3))
+ error("Invalid shufflevector instruction!");
+ Result = new ShuffleVectorInst(V1, V2, V3);
+ break;
+ }
case Instruction::Cast:
Result = new CastInst(getValue(iType, Oprnds[0]),
getSanitizedType(Oprnds[1]));
if (Opcode == 61 || Opcode == 59)
isTailCall = true;
-
+
+ if (Opcode == 58) {
+ isTailCall = Oprnds.back() & 1;
+ CallingConv = Oprnds.back() >> 1;
+ Oprnds.pop_back();
+ } else if (Opcode == 59 || Opcode == 60) {
+ CallingConv = CallingConv::Fast;
+ }
+
// Check to make sure we have a pointer to function type
const PointerType *PTy = dyn_cast<PointerType>(F->getType());
if (PTy == 0) error("Call to non function pointer value!");
if (!FTy->isVarArg()) {
FunctionType::param_iterator It = FTy->param_begin();
- if (Opcode == 58) {
- isTailCall = Oprnds.back() & 1;
- CallingConv = Oprnds.back() >> 1;
- Oprnds.pop_back();
- } else if (Opcode == 59 || Opcode == 60)
- CallingConv = CallingConv::Fast;
-
for (unsigned i = 1, e = Oprnds.size(); i != e; ++i) {
if (It == FTy->param_end())
error("Invalid call instruction!");
// Convert ubyte struct indices into uint struct indices.
if (isa<StructType>(TopTy) && hasRestrictedGEPTypes)
- if (ConstantUInt *C = dyn_cast<ConstantUInt>(Idx.back()))
- Idx[Idx.size()-1] = ConstantExpr::getCast(C, Type::UIntTy);
+ if (ConstantInt *C = dyn_cast<ConstantInt>(Idx.back()))
+ if (C->getType() == Type::UByteTy)
+ Idx[Idx.size()-1] = ConstantExpr::getCast(C, Type::UIntTy);
NextTy = GetElementPtrInst::getIndexedType(InstTy, Idx, true);
}
break;
} // end switch(Opcode)
+ BB->getInstList().push_back(Result);
+
unsigned TypeSlot;
if (Result->getType() == InstTy)
TypeSlot = iType;
TypeSlot = getTypeSlot(Result->getType());
insertValue(Result, TypeSlot, FunctionValues);
- BB->getInstList().push_back(Result);
}
/// Get a particular numbered basic block, which might be a forward reference.
}
/// Parse a single constant value
-Constant *BytecodeReader::ParseConstantValue(unsigned TypeID) {
+Value *BytecodeReader::ParseConstantPoolValue(unsigned TypeID) {
// We must check for a ConstantExpr before switching by type because
// a ConstantExpr can be of any type, and has no explicit value.
//
unsigned isExprNumArgs = read_vbr_uint();
if (isExprNumArgs) {
- // 'undef' is encoded with 'exprnumargs' == 1.
- if (!hasNoUndefValue)
- if (--isExprNumArgs == 0)
+ if (!hasNoUndefValue) {
+ // 'undef' is encoded with 'exprnumargs' == 1.
+ if (isExprNumArgs == 1)
return UndefValue::get(getType(TypeID));
+ // Inline asm is encoded with exprnumargs == ~0U.
+ if (isExprNumArgs == ~0U) {
+ std::string AsmStr = read_str();
+ std::string ConstraintStr = read_str();
+ unsigned Flags = read_vbr_uint();
+
+ const PointerType *PTy = dyn_cast<PointerType>(getType(TypeID));
+ const FunctionType *FTy =
+ PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : 0;
+
+ if (!FTy || !InlineAsm::Verify(FTy, ConstraintStr))
+ error("Invalid constraints for inline asm");
+ if (Flags & ~1U)
+ error("Invalid flags for inline asm");
+ bool HasSideEffects = Flags & 1;
+ return InlineAsm::get(FTy, AsmStr, ConstraintStr, HasSideEffects);
+ }
+
+ --isExprNumArgs;
+ }
+
// FIXME: Encoding of constant exprs could be much more compact!
std::vector<Constant*> ArgVec;
ArgVec.reserve(isExprNumArgs);
ArgVec[2]);
if (Handler) Handler->handleConstantExpression(Opcode, ArgVec, Result);
return Result;
+ } else if (Opcode == Instruction::ExtractElement) {
+ if (ArgVec.size() != 2 ||
+ !ExtractElementInst::isValidOperands(ArgVec[0], ArgVec[1]))
+ error("Invalid extractelement constand expr arguments");
+ Constant* Result = ConstantExpr::getExtractElement(ArgVec[0], ArgVec[1]);
+ if (Handler) Handler->handleConstantExpression(Opcode, ArgVec, Result);
+ return Result;
+ } else if (Opcode == Instruction::InsertElement) {
+ if (ArgVec.size() != 3 ||
+ !InsertElementInst::isValidOperands(ArgVec[0], ArgVec[1], ArgVec[2]))
+ error("Invalid insertelement constand expr arguments");
+
+ Constant *Result =
+ ConstantExpr::getInsertElement(ArgVec[0], ArgVec[1], ArgVec[2]);
+ if (Handler) Handler->handleConstantExpression(Opcode, ArgVec, Result);
+ return Result;
+ } else if (Opcode == Instruction::ShuffleVector) {
+ if (ArgVec.size() != 3 ||
+ !ShuffleVectorInst::isValidOperands(ArgVec[0], ArgVec[1], ArgVec[2]))
+ error("Invalid shufflevector constant expr arguments.");
+ Constant *Result =
+ ConstantExpr::getShuffleVector(ArgVec[0], ArgVec[1], ArgVec[2]);
+ if (Handler) Handler->handleConstantExpression(Opcode, ArgVec, Result);
+ return Result;
} else { // All other 2-operand expressions
Constant* Result = ConstantExpr::get(Opcode, ArgVec[0], ArgVec[1]);
if (Handler) Handler->handleConstantExpression(Opcode, ArgVec, Result);
// Ok, not an ConstantExpr. We now know how to read the given type...
const Type *Ty = getType(TypeID);
+ Constant *Result = 0;
switch (Ty->getTypeID()) {
case Type::BoolTyID: {
unsigned Val = read_vbr_uint();
if (Val != 0 && Val != 1)
error("Invalid boolean value read.");
- Constant* Result = ConstantBool::get(Val == 1);
+ Result = ConstantBool::get(Val == 1);
if (Handler) Handler->handleConstantValue(Result);
- return Result;
+ break;
}
case Type::UByteTyID: // Unsigned integer types...
case Type::UShortTyID:
case Type::UIntTyID: {
unsigned Val = read_vbr_uint();
- if (!ConstantUInt::isValueValidForType(Ty, Val))
+ if (!ConstantInt::isValueValidForType(Ty, uint64_t(Val)))
error("Invalid unsigned byte/short/int read.");
- Constant* Result = ConstantUInt::get(Ty, Val);
+ Result = ConstantInt::get(Ty, Val);
if (Handler) Handler->handleConstantValue(Result);
- return Result;
+ break;
}
- case Type::ULongTyID: {
- Constant* Result = ConstantUInt::get(Ty, read_vbr_uint64());
+ case Type::ULongTyID:
+ Result = ConstantInt::get(Ty, read_vbr_uint64());
if (Handler) Handler->handleConstantValue(Result);
- return Result;
- }
-
+ break;
+
case Type::SByteTyID: // Signed integer types...
case Type::ShortTyID:
- case Type::IntTyID: {
- case Type::LongTyID:
+ case Type::IntTyID:
+ case Type::LongTyID: {
int64_t Val = read_vbr_int64();
- if (!ConstantSInt::isValueValidForType(Ty, Val))
+ if (!ConstantInt::isValueValidForType(Ty, Val))
error("Invalid signed byte/short/int/long read.");
- Constant* Result = ConstantSInt::get(Ty, Val);
+ Result = ConstantInt::get(Ty, Val);
if (Handler) Handler->handleConstantValue(Result);
- return Result;
+ break;
}
case Type::FloatTyID: {
float Val;
read_float(Val);
- Constant* Result = ConstantFP::get(Ty, Val);
+ Result = ConstantFP::get(Ty, Val);
if (Handler) Handler->handleConstantValue(Result);
- return Result;
+ break;
}
case Type::DoubleTyID: {
double Val;
read_double(Val);
- Constant* Result = ConstantFP::get(Ty, Val);
+ Result = ConstantFP::get(Ty, Val);
if (Handler) Handler->handleConstantValue(Result);
- return Result;
+ break;
}
case Type::ArrayTyID: {
while (NumElements--) // Read all of the elements of the constant.
Elements.push_back(getConstantValue(TypeSlot,
read_vbr_uint()));
- Constant* Result = ConstantArray::get(AT, Elements);
+ Result = ConstantArray::get(AT, Elements);
if (Handler) Handler->handleConstantArray(AT, Elements, TypeSlot, Result);
- return Result;
+ break;
}
case Type::StructTyID: {
Elements.push_back(getConstantValue(ST->getElementType(i),
read_vbr_uint()));
- Constant* Result = ConstantStruct::get(ST, Elements);
+ Result = ConstantStruct::get(ST, Elements);
if (Handler) Handler->handleConstantStruct(ST, Elements, Result);
- return Result;
+ break;
}
case Type::PackedTyID: {
while (NumElements--) // Read all of the elements of the constant.
Elements.push_back(getConstantValue(TypeSlot,
read_vbr_uint()));
- Constant* Result = ConstantPacked::get(PT, Elements);
+ Result = ConstantPacked::get(PT, Elements);
if (Handler) Handler->handleConstantPacked(PT, Elements, TypeSlot, Result);
- return Result;
+ break;
}
case Type::PointerTyID: { // ConstantPointerRef value (backwards compat).
Ty->getDescription());
break;
}
- return 0;
+
+ // Check that we didn't read a null constant if they are implicit for this
+ // type plane. Do not do this check for constantexprs, as they may be folded
+ // to a null value in a way that isn't predicted when a .bc file is initially
+ // produced.
+ assert((!isa<Constant>(Result) || !cast<Constant>(Result)->isNullValue()) ||
+ !hasImplicitNull(TypeID) &&
+ "Cannot read null values from bytecode!");
+ return Result;
}
/// Resolve references for constants. This function resolves the forward
read_data(Data, Data+ATy->getNumElements());
std::vector<Constant*> Elements(ATy->getNumElements());
- if (ATy->getElementType() == Type::SByteTy)
- for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i)
- Elements[i] = ConstantSInt::get(Type::SByteTy, (signed char)Data[i]);
- else
- for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i)
- Elements[i] = ConstantUInt::get(Type::UByteTy, (unsigned char)Data[i]);
+ const Type* ElemType = ATy->getElementType();
+ for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i)
+ Elements[i] = ConstantInt::get(ElemType, (unsigned char)Data[i]);
// Create the constant, inserting it as needed.
Constant *C = ConstantArray::get(ATy, Elements);
ParseStringConstants(NumEntries, Tab);
} else {
for (unsigned i = 0; i < NumEntries; ++i) {
- Constant *C = ParseConstantValue(Typ);
- assert(C && "ParseConstantValue returned NULL!");
- unsigned Slot = insertValue(C, Typ, Tab);
+ Value *V = ParseConstantPoolValue(Typ);
+ assert(V && "ParseConstantPoolValue returned NULL!");
+ unsigned Slot = insertValue(V, Typ, Tab);
// 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 && Typ < ModuleValues.size() &&
ModuleValues[Typ])
Slot += ModuleValues[Typ]->size();
- ResolveReferencesToConstant(C, Typ, Slot);
+ if (Constant *C = dyn_cast<Constant>(V))
+ ResolveReferencesToConstant(C, Typ, Slot);
}
}
}
case 2: Linkage = GlobalValue::AppendingLinkage; break;
case 3: Linkage = GlobalValue::InternalLinkage; break;
case 4: Linkage = GlobalValue::LinkOnceLinkage; break;
+ case 5: Linkage = GlobalValue::DLLImportLinkage; break;
+ case 6: Linkage = GlobalValue::DLLExportLinkage; break;
+ case 7: Linkage = GlobalValue::ExternalWeakLinkage; break;
default:
error("Invalid linkage type for Function.");
Linkage = GlobalValue::InternalLinkage;
delete PlaceHolder;
}
+ // If upgraded intrinsic functions were detected during reading of the
+ // module information, then we need to look for instructions that need to
+ // be upgraded. This can't be done while the instructions are read in because
+ // additional instructions inserted mess up the slot numbering.
+ if (!upgradedFunctions.empty()) {
+ for (Function::iterator BI = F->begin(), BE = F->end(); BI != BE; ++BI)
+ for (BasicBlock::iterator II = BI->begin(), IE = BI->end();
+ II != IE;)
+ if (CallInst* CI = dyn_cast<CallInst>(II++)) {
+ std::map<Function*,Function*>::iterator FI =
+ upgradedFunctions.find(CI->getCalledFunction());
+ if (FI != upgradedFunctions.end())
+ UpgradeIntrinsicCall(CI, FI->second);
+ }
+ }
+
// Clear out function-level types...
FunctionTypes.clear();
CompactionTypes.clear();
/// ParseAllFunctionBodies.
/// @see ParseAllFunctionBodies
/// @see ParseBytecode
-void BytecodeReader::ParseFunction(Function* Func) {
+bool BytecodeReader::ParseFunction(Function* Func, std::string* ErrMsg) {
+
+ if (setjmp(context))
+ return true;
+
// Find {start, end} pointers and slot in the map. If not there, we're done.
LazyFunctionMap::iterator Fi = LazyFunctionLoadMap.find(Func);
// Make sure we found it
if (Fi == LazyFunctionLoadMap.end()) {
error("Unrecognized function of type " + Func->getType()->getDescription());
- return;
+ return true;
}
BlockStart = At = Fi->second.Buf;
LazyFunctionLoadMap.erase(Fi);
this->ParseFunctionBody(Func);
+ return false;
}
/// The ParseAllFunctionBodies method parses through all the previously
/// the function definitions are located. This function uses that information
/// to materialize the functions.
/// @see ParseBytecode
-void BytecodeReader::ParseAllFunctionBodies() {
+bool BytecodeReader::ParseAllFunctionBodies(std::string* ErrMsg) {
+ if (setjmp(context))
+ return true;
+
LazyFunctionMap::iterator Fi = LazyFunctionLoadMap.begin();
LazyFunctionMap::iterator Fe = LazyFunctionLoadMap.end();
++Fi;
}
LazyFunctionLoadMap.clear();
+ return false;
}
/// Parse the global type list
case 2: Linkage = GlobalValue::AppendingLinkage; break;
case 3: Linkage = GlobalValue::InternalLinkage; break;
case 4: Linkage = GlobalValue::LinkOnceLinkage; break;
+ case 5: Linkage = GlobalValue::DLLImportLinkage; break;
+ case 6: Linkage = GlobalValue::DLLExportLinkage; break;
+ case 7: Linkage = GlobalValue::ExternalWeakLinkage; break;
default:
error("Unknown linkage type: " + utostr(LinkageID));
Linkage = GlobalValue::InternalLinkage;
// Insert the place holder.
Function *Func = new Function(FTy, GlobalValue::ExternalLinkage,
"", TheModule);
+
insertValue(Func, (FnSignature & (~0U >> 1)) >> 5, ModuleValues);
// Flags are not used yet.
if (ExtWord & (1 << 10)) // Has a section ID.
SectionID[Func] = read_vbr_uint();
+
+ // Parse external declaration linkage
+ switch ((ExtWord >> 11) & 3) {
+ case 0: break;
+ case 1: Func->setLinkage(Function::DLLImportLinkage); break;
+ case 2: Func->setLinkage(Function::ExternalWeakLinkage); break;
+ default: assert(0 && "Unsupported external linkage");
+ }
}
Func->setCallingConv(CC-1);
if (Handler)
Handler->handleTargetTriple(triple);
- if (At != BlockEnd) {
+ if (!hasAlignment && At != BlockEnd) {
// If the file has section info in it, read the section names now.
unsigned NumSections = read_vbr_uint();
while (NumSections--)
SectionNames.push_back(read_str());
}
+
+ // If the file has module-level inline asm, read it now.
+ if (!hasAlignment && At != BlockEnd)
+ TheModule->setModuleInlineAsm(read_str());
}
// If any globals are in specified sections, assign them now.
/// This function completely parses a bytecode buffer given by the \p Buf
/// and \p Length parameters.
-void BytecodeReader::ParseBytecode(BufPtr Buf, unsigned Length,
- const std::string &ModuleID) {
-
- try {
- RevisionNum = 0;
- At = MemStart = BlockStart = Buf;
- MemEnd = BlockEnd = Buf + Length;
-
- // Create the module
- TheModule = new Module(ModuleID);
-
- if (Handler) Handler->handleStart(TheModule, Length);
-
- // Read the four bytes of the signature.
- unsigned Sig = read_uint();
-
- // If this is a compressed file
- if (Sig == ('l' | ('l' << 8) | ('v' << 16) | ('c' << 24))) {
-
- // Invoke the decompression of the bytecode. Note that we have to skip the
- // file's magic number which is not part of the compressed block. Hence,
- // the Buf+4 and Length-4. The result goes into decompressedBlock, a data
- // member for retention until BytecodeReader is destructed.
- unsigned decompressedLength = Compressor::decompressToNewBuffer(
- (char*)Buf+4,Length-4,decompressedBlock);
-
- // We must adjust the buffer pointers used by the bytecode reader to point
- // into the new decompressed block. After decompression, the
- // decompressedBlock will point to a contiguous memory area that has
- // the decompressed data.
- At = MemStart = BlockStart = Buf = (BufPtr) decompressedBlock;
- MemEnd = BlockEnd = Buf + decompressedLength;
-
- // else if this isn't a regular (uncompressed) bytecode file, then its
- // and error, generate that now.
- } else if (Sig != ('l' | ('l' << 8) | ('v' << 16) | ('m' << 24))) {
- error("Invalid bytecode signature: " + utohexstr(Sig));
+bool BytecodeReader::ParseBytecode(volatile BufPtr Buf, unsigned Length,
+ const std::string &ModuleID,
+ std::string* ErrMsg) {
+
+ /// We handle errors by
+ if (setjmp(context)) {
+ // Cleanup after error
+ if (Handler) Handler->handleError(ErrorMsg);
+ freeState();
+ delete TheModule;
+ TheModule = 0;
+ if (decompressedBlock != 0 ) {
+ ::free(decompressedBlock);
+ decompressedBlock = 0;
}
+ // Set caller's error message, if requested
+ if (ErrMsg)
+ *ErrMsg = ErrorMsg;
+ // Indicate an error occurred
+ return true;
+ }
- // Tell the handler we're starting a module
- if (Handler) Handler->handleModuleBegin(ModuleID);
+ RevisionNum = 0;
+ At = MemStart = BlockStart = Buf;
+ MemEnd = BlockEnd = Buf + Length;
- // Get the module block and size and verify. This is handled specially
- // because the module block/size is always written in long format. Other
- // blocks are written in short format so the read_block method is used.
- unsigned Type, Size;
- Type = read_uint();
- Size = read_uint();
- if (Type != BytecodeFormat::ModuleBlockID) {
- error("Expected Module Block! Type:" + utostr(Type) + ", Size:"
- + utostr(Size));
- }
+ // Create the module
+ TheModule = new Module(ModuleID);
- // It looks like the darwin ranlib program is broken, and adds trailing
- // garbage to the end of some bytecode files. This hack allows the bc
- // reader to ignore trailing garbage on bytecode files.
- if (At + Size < MemEnd)
- MemEnd = BlockEnd = At+Size;
+ if (Handler) Handler->handleStart(TheModule, Length);
- if (At + Size != MemEnd)
- error("Invalid Top Level Block Length! Type:" + utostr(Type)
- + ", Size:" + utostr(Size));
+ // Read the four bytes of the signature.
+ unsigned Sig = read_uint();
- // Parse the module contents
- this->ParseModule();
+ // If this is a compressed file
+ if (Sig == ('l' | ('l' << 8) | ('v' << 16) | ('c' << 24))) {
- // Check for missing functions
- if (hasFunctions())
- error("Function expected, but bytecode stream ended!");
+ // Invoke the decompression of the bytecode. Note that we have to skip the
+ // file's magic number which is not part of the compressed block. Hence,
+ // the Buf+4 and Length-4. The result goes into decompressedBlock, a data
+ // member for retention until BytecodeReader is destructed.
+ unsigned decompressedLength = Compressor::decompressToNewBuffer(
+ (char*)Buf+4,Length-4,decompressedBlock);
- // Tell the handler we're done with the module
- if (Handler)
- Handler->handleModuleEnd(ModuleID);
+ // We must adjust the buffer pointers used by the bytecode reader to point
+ // into the new decompressed block. After decompression, the
+ // decompressedBlock will point to a contiguous memory area that has
+ // the decompressed data.
+ At = MemStart = BlockStart = Buf = (BufPtr) decompressedBlock;
+ MemEnd = BlockEnd = Buf + decompressedLength;
- // Tell the handler we're finished the parse
- if (Handler) Handler->handleFinish();
+ // else if this isn't a regular (uncompressed) bytecode file, then its
+ // and error, generate that now.
+ } else if (Sig != ('l' | ('l' << 8) | ('v' << 16) | ('m' << 24))) {
+ error("Invalid bytecode signature: " + utohexstr(Sig));
+ }
- } catch (std::string& errstr) {
- if (Handler) Handler->handleError(errstr);
- freeState();
- delete TheModule;
- TheModule = 0;
- if (decompressedBlock != 0 ) {
- ::free(decompressedBlock);
- decompressedBlock = 0;
- }
- throw;
- } catch (...) {
- std::string msg("Unknown Exception Occurred");
- if (Handler) Handler->handleError(msg);
- freeState();
- delete TheModule;
- TheModule = 0;
- if (decompressedBlock != 0) {
- ::free(decompressedBlock);
- decompressedBlock = 0;
+ // Tell the handler we're starting a module
+ if (Handler) Handler->handleModuleBegin(ModuleID);
+
+ // Get the module block and size and verify. This is handled specially
+ // because the module block/size is always written in long format. Other
+ // blocks are written in short format so the read_block method is used.
+ unsigned Type, Size;
+ Type = read_uint();
+ Size = read_uint();
+ if (Type != BytecodeFormat::ModuleBlockID) {
+ error("Expected Module Block! Type:" + utostr(Type) + ", Size:"
+ + utostr(Size));
+ }
+
+ // It looks like the darwin ranlib program is broken, and adds trailing
+ // garbage to the end of some bytecode files. This hack allows the bc
+ // reader to ignore trailing garbage on bytecode files.
+ if (At + Size < MemEnd)
+ MemEnd = BlockEnd = At+Size;
+
+ if (At + Size != MemEnd)
+ error("Invalid Top Level Block Length! Type:" + utostr(Type)
+ + ", Size:" + utostr(Size));
+
+ // Parse the module contents
+ this->ParseModule();
+
+ // Check for missing functions
+ if (hasFunctions())
+ error("Function expected, but bytecode stream ended!");
+
+ // Look for intrinsic functions to upgrade, upgrade them, and save the
+ // mapping from old function to new for use later when instructions are
+ // converted.
+ for (Module::iterator FI = TheModule->begin(), FE = TheModule->end();
+ FI != FE; ++FI)
+ if (Function* newF = UpgradeIntrinsicFunction(FI)) {
+ upgradedFunctions.insert(std::make_pair(FI, newF));
+ FI->setName("");
}
- throw msg;
- }
+
+ // Tell the handler we're done with the module
+ if (Handler)
+ Handler->handleModuleEnd(ModuleID);
+
+ // Tell the handler we're finished the parse
+ if (Handler) Handler->handleFinish();
+
+ return false;
+
}
//===----------------------------------------------------------------------===//