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