X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FBytecode%2FReader%2FReader.cpp;h=ac6418d7a7d0f7c391558b14945b79f92556404f;hb=b74ed07bfd3af42331b1964c24c39912610a08f4;hp=e57101aeb57f97c876e11bca94702ed9c91a1604;hpb=6631601eeda2300abdce11fbd7a7a3daa2694d39;p=oota-llvm.git diff --git a/lib/Bytecode/Reader/Reader.cpp b/lib/Bytecode/Reader/Reader.cpp index e57101aeb57..ac6418d7a7d 100644 --- a/lib/Bytecode/Reader/Reader.cpp +++ b/lib/Bytecode/Reader/Reader.cpp @@ -22,6 +22,7 @@ #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" @@ -50,13 +51,10 @@ namespace { } // 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); } //===----------------------------------------------------------------------===// @@ -79,7 +77,7 @@ inline void BytecodeReader::checkPastBlockEnd(const char * block_name) { 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) @@ -469,7 +467,8 @@ Value * BytecodeReader::getValue(unsigned type, unsigned oNum, bool Create) { 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 @@ -543,10 +542,6 @@ Constant* BytecodeReader::getConstantValue(unsigned TypeSlot, unsigned Slot) { /// or FunctionValues data members of this class. unsigned BytecodeReader::insertValue(Value *Val, unsigned type, ValueTable &ValueTab) { - assert((!isa(Val) || !cast(Val)->isNullValue()) || - !hasImplicitNull(type) && - "Cannot read null values from bytecode!"); - if (ValueTab.size() <= type) ValueTab.resize(type+1); @@ -721,20 +716,42 @@ void BytecodeReader::ParseInstruction(std::vector &Oprnds, } case Instruction::ExtractElement: { if (Oprnds.size() != 2) - throw std::string("Invalid extractelement instruction!"); - Result = new ExtractElementInst(getValue(iType, Oprnds[0]), - getValue(Type::UIntTyID, Oprnds[1])); + 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(InstTy); if (!PackedTy || Oprnds.size() != 3) - throw std::string("Invalid insertelement instruction!"); - Result = - new InsertElementInst(getValue(iType, Oprnds[0]), - getValue(getTypeSlot(PackedTy->getElementType()), - Oprnds[1]), - getValue(Type::UIntTyID, Oprnds[2])); + 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(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: @@ -811,7 +828,15 @@ void BytecodeReader::ParseInstruction(std::vector &Oprnds, 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(F->getType()); if (PTy == 0) error("Call to non function pointer value!"); @@ -822,13 +847,6 @@ void BytecodeReader::ParseInstruction(std::vector &Oprnds, 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!"); @@ -860,7 +878,6 @@ void BytecodeReader::ParseInstruction(std::vector &Oprnds, Result = new CallInst(F, Params); if (isTailCall) cast(Result)->setTailCall(); if (CallingConv) cast(Result)->setCallingConv(CallingConv); - isCall = true; break; } case 56: // Invoke with encoded CC @@ -1033,13 +1050,6 @@ void BytecodeReader::ParseInstruction(std::vector &Oprnds, BB->getInstList().push_back(Result); - if (this->hasUpgradedIntrinsicFunctions && isCall) - if (Instruction* inst = UpgradeIntrinsicCall(cast(Result))) { - Result->replaceAllUsesWith(inst); - Result->eraseFromParent(); - Result = inst; - } - unsigned TypeSlot; if (Result->getType() == InstTy) TypeSlot = iType; @@ -1404,7 +1414,7 @@ void BytecodeReader::ParseTypes(TypeListTy &Tab, unsigned NumEntries){ } /// 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. // @@ -1412,11 +1422,32 @@ Constant *BytecodeReader::ParseConstantValue(unsigned TypeID) { 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(getType(TypeID)); + const FunctionType *FTy = + PTy ? dyn_cast(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 ArgVec; ArgVec.reserve(isExprNumArgs); @@ -1471,18 +1502,29 @@ Constant *BytecodeReader::ParseConstantValue(unsigned TypeID) { if (Handler) Handler->handleConstantExpression(Opcode, ArgVec, Result); return Result; } else if (Opcode == Instruction::ExtractElement) { - if (ArgVec.size() != 2) - error("ExtractElement instruction must have two arguments."); + 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) - error("InsertElement instruction must have three arguments."); - Constant* Result = + 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); @@ -1492,14 +1534,15 @@ Constant *BytecodeReader::ParseConstantValue(unsigned TypeID) { // 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... @@ -1508,43 +1551,42 @@ Constant *BytecodeReader::ParseConstantValue(unsigned TypeID) { unsigned Val = read_vbr_uint(); if (!ConstantUInt::isValueValidForType(Ty, Val)) error("Invalid unsigned byte/short/int read."); - Constant* Result = ConstantUInt::get(Ty, Val); + Result = ConstantUInt::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 = ConstantUInt::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)) error("Invalid signed byte/short/int/long read."); - Constant* Result = ConstantSInt::get(Ty, Val); + Result = ConstantSInt::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: { @@ -1556,9 +1598,9 @@ Constant *BytecodeReader::ParseConstantValue(unsigned TypeID) { 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: { @@ -1570,9 +1612,9 @@ Constant *BytecodeReader::ParseConstantValue(unsigned TypeID) { 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: { @@ -1584,9 +1626,9 @@ Constant *BytecodeReader::ParseConstantValue(unsigned TypeID) { 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). @@ -1610,7 +1652,15 @@ Constant *BytecodeReader::ParseConstantValue(unsigned TypeID) { 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(Result) || !cast(Result)->isNullValue()) || + !hasImplicitNull(TypeID) && + "Cannot read null values from bytecode!"); + return Result; } /// Resolve references for constants. This function resolves the forward @@ -1695,9 +1745,9 @@ void BytecodeReader::ParseConstantPool(ValueTable &Tab, 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. @@ -1705,7 +1755,8 @@ void BytecodeReader::ParseConstantPool(ValueTable &Tab, if (&Tab != &ModuleValues && Typ < ModuleValues.size() && ModuleValues[Typ]) Slot += ModuleValues[Typ]->size(); - ResolveReferencesToConstant(C, Typ, Slot); + if (Constant *C = dyn_cast(V)) + ResolveReferencesToConstant(C, Typ, Slot); } } } @@ -1740,6 +1791,9 @@ void BytecodeReader::ParseFunctionBody(Function* F) { 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; @@ -1839,6 +1893,22 @@ void BytecodeReader::ParseFunctionBody(Function* F) { 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(II++)) { + std::map::iterator FI = + upgradedFunctions.find(CI->getCalledFunction()); + if (FI != upgradedFunctions.end()) + UpgradeIntrinsicCall(CI, FI->second); + } + } + // Clear out function-level types... FunctionTypes.clear(); CompactionTypes.clear(); @@ -1876,14 +1946,18 @@ void BytecodeReader::ParseFunctionLazily() { /// 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; @@ -1893,6 +1967,7 @@ void BytecodeReader::ParseFunction(Function* Func) { LazyFunctionLoadMap.erase(Fi); this->ParseFunctionBody(Func); + return false; } /// The ParseAllFunctionBodies method parses through all the previously @@ -1902,7 +1977,10 @@ void BytecodeReader::ParseFunction(Function* Func) { /// 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(); @@ -1914,6 +1992,7 @@ void BytecodeReader::ParseAllFunctionBodies() { ++Fi; } LazyFunctionLoadMap.clear(); + return false; } /// Parse the global type list @@ -1971,6 +2050,9 @@ void BytecodeReader::ParseModuleGlobalInfo() { 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; @@ -2032,13 +2114,6 @@ void BytecodeReader::ParseModuleGlobalInfo() { Function *Func = new Function(FTy, GlobalValue::ExternalLinkage, "", TheModule); - // Replace with upgraded intrinsic function, if applicable. - if (Function* upgrdF = UpgradeIntrinsicFunction(Func)) { - hasUpgradedIntrinsicFunctions = true; - Func->eraseFromParent(); - Func = upgrdF; - } - insertValue(Func, (FnSignature & (~0U >> 1)) >> 5, ModuleValues); // Flags are not used yet. @@ -2060,6 +2135,14 @@ void BytecodeReader::ParseModuleGlobalInfo() { 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); @@ -2340,105 +2423,113 @@ void BytecodeReader::ParseModule() { /// 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; + } //===----------------------------------------------------------------------===//