From d554ebfcf76e09a65561dcd972310f404a8bc72b Mon Sep 17 00:00:00 2001 From: Misha Brukman Date: Tue, 23 Sep 2003 16:17:50 +0000 Subject: [PATCH] Stop returning bool and pass Instruction by reference; return std::auto_ptr and use exceptions git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@8684 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Bytecode/Reader/InstructionReader.cpp | 277 +++++++++++----------- lib/Bytecode/Reader/ReaderInternals.h | 4 +- 2 files changed, 146 insertions(+), 135 deletions(-) diff --git a/lib/Bytecode/Reader/InstructionReader.cpp b/lib/Bytecode/Reader/InstructionReader.cpp index 0ab26552ab7..f3340857791 100644 --- a/lib/Bytecode/Reader/InstructionReader.cpp +++ b/lib/Bytecode/Reader/InstructionReader.cpp @@ -17,30 +17,32 @@ #include "llvm/iPHINode.h" #include "llvm/iOther.h" -bool BytecodeParser::ParseRawInst(const unsigned char *&Buf, - const unsigned char *EndBuf, - RawInst &Result) { +std::auto_ptr +BytecodeParser::ParseRawInst(const unsigned char *&Buf, + const unsigned char *EndBuf) { unsigned Op, Typ; - if (read(Buf, EndBuf, Op)) return true; + std::auto_ptr Result = std::auto_ptr(new RawInst()); + if (read(Buf, EndBuf, Op)) + throw std::string("Error reading from buffer."); // bits Instruction format: Common to all formats // -------------------------- // 01-00: Opcode type, fixed to 1. // 07-02: Opcode - Result.NumOperands = (Op >> 0) & 03; - Result.Opcode = (Op >> 2) & 63; + Result->NumOperands = (Op >> 0) & 03; + Result->Opcode = (Op >> 2) & 63; - switch (Result.NumOperands) { + switch (Result->NumOperands) { case 1: // bits Instruction format: // -------------------------- // 19-08: Resulting type plane // 31-20: Operand #1 (if set to (2^12-1), then zero operands) // - Result.Ty = getType((Op >> 8) & 4095); - Result.Arg1 = (Op >> 20) & 4095; - if (Result.Arg1 == 4095) // Handle special encoding for 0 operands... - Result.NumOperands = 0; + Result->Ty = getType((Op >> 8) & 4095); + Result->Arg1 = (Op >> 20) & 4095; + if (Result->Arg1 == 4095) // Handle special encoding for 0 operands... + Result->NumOperands = 0; break; case 2: // bits Instruction format: @@ -49,9 +51,9 @@ bool BytecodeParser::ParseRawInst(const unsigned char *&Buf, // 23-16: Operand #1 // 31-24: Operand #2 // - Result.Ty = getType((Op >> 8) & 255); - Result.Arg1 = (Op >> 16) & 255; - Result.Arg2 = (Op >> 24) & 255; + Result->Ty = getType((Op >> 8) & 255); + Result->Arg1 = (Op >> 16) & 255; + Result->Arg2 = (Op >> 24) & 255; break; case 3: // bits Instruction format: @@ -61,112 +63,121 @@ bool BytecodeParser::ParseRawInst(const unsigned char *&Buf, // 25-20: Operand #2 // 31-26: Operand #3 // - Result.Ty = getType((Op >> 8) & 63); - Result.Arg1 = (Op >> 14) & 63; - Result.Arg2 = (Op >> 20) & 63; - Result.Arg3 = (Op >> 26) & 63; + Result->Ty = getType((Op >> 8) & 63); + Result->Arg1 = (Op >> 14) & 63; + Result->Arg2 = (Op >> 20) & 63; + Result->Arg3 = (Op >> 26) & 63; break; case 0: Buf -= 4; // Hrm, try this again... - if (read_vbr(Buf, EndBuf, Result.Opcode)) return true; - Result.Opcode >>= 2; - if (read_vbr(Buf, EndBuf, Typ)) return true; - Result.Ty = getType(Typ); - if (Result.Ty == 0) return true; - if (read_vbr(Buf, EndBuf, Result.NumOperands)) return true; - - switch (Result.NumOperands) { + if (read_vbr(Buf, EndBuf, Result->Opcode)) + throw std::string("Error reading from buffer."); + Result->Opcode >>= 2; + if (read_vbr(Buf, EndBuf, Typ)) + throw std::string("Error reading from buffer."); + Result->Ty = getType(Typ); + if (Result->Ty == 0) + throw std::string("Invalid type read in instruction."); + if (read_vbr(Buf, EndBuf, Result->NumOperands)) + throw std::string("Error reading from buffer."); + + switch (Result->NumOperands) { case 0: - std::cerr << "Zero Arg instr found!\n"; - return true; // This encoding is invalid! + throw std::string("Zero-argument instruction found; this is invalid."); case 1: - if (read_vbr(Buf, EndBuf, Result.Arg1)) return true; + if (read_vbr(Buf, EndBuf, Result->Arg1)) + throw std::string("Error reading from buffer"); break; case 2: - if (read_vbr(Buf, EndBuf, Result.Arg1) || - read_vbr(Buf, EndBuf, Result.Arg2)) return true; + if (read_vbr(Buf, EndBuf, Result->Arg1) || + read_vbr(Buf, EndBuf, Result->Arg2)) + throw std::string("Error reading from buffer"); break; case 3: - if (read_vbr(Buf, EndBuf, Result.Arg1) || - read_vbr(Buf, EndBuf, Result.Arg2) || - read_vbr(Buf, EndBuf, Result.Arg3)) return true; + if (read_vbr(Buf, EndBuf, Result->Arg1) || + read_vbr(Buf, EndBuf, Result->Arg2) || + read_vbr(Buf, EndBuf, Result->Arg3)) + throw std::string("Error reading from buffer"); break; default: - if (read_vbr(Buf, EndBuf, Result.Arg1) || - read_vbr(Buf, EndBuf, Result.Arg2)) return true; + if (read_vbr(Buf, EndBuf, Result->Arg1) || + read_vbr(Buf, EndBuf, Result->Arg2)) + throw std::string("Error reading from buffer"); // Allocate a vector to hold arguments 3, 4, 5, 6 ... - Result.VarArgs = new std::vector(Result.NumOperands-2); - for (unsigned a = 0; a < Result.NumOperands-2; a++) - if (read_vbr(Buf, EndBuf, (*Result.VarArgs)[a])) return true; + Result->VarArgs = new std::vector(Result->NumOperands-2); + for (unsigned a = 0; a < Result->NumOperands-2; a++) + if (read_vbr(Buf, EndBuf, (*Result->VarArgs)[a])) + throw std::string("Error reading from buffer"); + break; } - if (align32(Buf, EndBuf)) return true; + if (align32(Buf, EndBuf)) + throw std::string("Unaligned bytecode buffer."); break; } #if 0 - std::cerr << "NO: " << Result.NumOperands << " opcode: " << Result.Opcode - << " Ty: " << Result.Ty->getDescription() << " arg1: "<< Result.Arg1 - << " arg2: " << Result.Arg2 << " arg3: " << Result.Arg3 << "\n"; + std::cerr << "NO: " << Result->NumOperands << " opcode: " << Result->Opcode + << " Ty: "<< Result->Ty->getDescription()<< " arg1: "<< Result->Arg1 + << " arg2: " << Result->Arg2 << " arg3: " << Result->Arg3 << "\n"; #endif - return false; + return Result; } bool BytecodeParser::ParseInstruction(const unsigned char *&Buf, const unsigned char *EndBuf, Instruction *&Res) { - RawInst Raw; - if (ParseRawInst(Buf, EndBuf, Raw)) - return true; - - if (Raw.Opcode >= Instruction::BinaryOpsBegin && - Raw.Opcode < Instruction::BinaryOpsEnd && Raw.NumOperands == 2) { - Res = BinaryOperator::create((Instruction::BinaryOps)Raw.Opcode, - getValue(Raw.Ty, Raw.Arg1), - getValue(Raw.Ty, Raw.Arg2)); + std::auto_ptr Raw = ParseRawInst(Buf, EndBuf); + + if (Raw->Opcode >= Instruction::BinaryOpsBegin && + Raw->Opcode < Instruction::BinaryOpsEnd && Raw->NumOperands == 2) { + Res = BinaryOperator::create((Instruction::BinaryOps)Raw->Opcode, + getValue(Raw->Ty, Raw->Arg1), + getValue(Raw->Ty, Raw->Arg2)); return false; - } + } Value *V; - switch (Raw.Opcode) { + switch (Raw->Opcode) { case Instruction::VarArg: case Instruction::Cast: { - V = getValue(Raw.Ty, Raw.Arg1); - const Type *Ty = getType(Raw.Arg2); + V = getValue(Raw->Ty, Raw->Arg1); + const Type *Ty = getType(Raw->Arg2); if (V == 0 || Ty == 0) { std::cerr << "Invalid cast!\n"; return true; } - if (Raw.Opcode == Instruction::Cast) + if (Raw->Opcode == Instruction::Cast) Res = new CastInst(V, Ty); else Res = new VarArgInst(V, Ty); return false; } case Instruction::PHINode: { - PHINode *PN = new PHINode(Raw.Ty); - switch (Raw.NumOperands) { + PHINode *PN = new PHINode(Raw->Ty); + switch (Raw->NumOperands) { case 0: case 1: case 3: std::cerr << "Invalid phi node encountered!\n"; delete PN; return true; - case 2: PN->addIncoming(getValue(Raw.Ty, Raw.Arg1), - cast(getValue(Type::LabelTy,Raw.Arg2))); + case 2: PN->addIncoming(getValue(Raw->Ty, Raw->Arg1), + cast(getValue(Type::LabelTy, + Raw->Arg2))); break; default: - PN->addIncoming(getValue(Raw.Ty, Raw.Arg1), - cast(getValue(Type::LabelTy, Raw.Arg2))); - if (Raw.VarArgs->size() & 1) { + PN->addIncoming(getValue(Raw->Ty, Raw->Arg1), + cast(getValue(Type::LabelTy, Raw->Arg2))); + if (Raw->VarArgs->size() & 1) { std::cerr << "PHI Node with ODD number of arguments!\n"; delete PN; return true; } else { - std::vector &args = *Raw.VarArgs; + std::vector &args = *Raw->VarArgs; for (unsigned i = 0; i < args.size(); i+=2) - PN->addIncoming(getValue(Raw.Ty, args[i]), + PN->addIncoming(getValue(Raw->Ty, args[i]), cast(getValue(Type::LabelTy, args[i+1]))); } - delete Raw.VarArgs; + delete Raw->VarArgs; break; } Res = PN; @@ -175,54 +186,54 @@ bool BytecodeParser::ParseInstruction(const unsigned char *&Buf, case Instruction::Shl: case Instruction::Shr: - Res = new ShiftInst((Instruction::OtherOps)Raw.Opcode, - getValue(Raw.Ty, Raw.Arg1), - getValue(Type::UByteTy, Raw.Arg2)); + Res = new ShiftInst((Instruction::OtherOps)Raw->Opcode, + getValue(Raw->Ty, Raw->Arg1), + getValue(Type::UByteTy, Raw->Arg2)); return false; case Instruction::Ret: - if (Raw.NumOperands == 0) { + if (Raw->NumOperands == 0) { Res = new ReturnInst(); return false; - } else if (Raw.NumOperands == 1) { - Res = new ReturnInst(getValue(Raw.Ty, Raw.Arg1)); return false; + } else if (Raw->NumOperands == 1) { + Res = new ReturnInst(getValue(Raw->Ty, Raw->Arg1)); return false; } break; case Instruction::Br: - if (Raw.NumOperands == 1) { - Res = new BranchInst(cast(getValue(Type::LabelTy, Raw.Arg1))); + if (Raw->NumOperands == 1) { + Res = new BranchInst(cast(getValue(Type::LabelTy,Raw->Arg1))); return false; - } else if (Raw.NumOperands == 3) { - Res = new BranchInst(cast(getValue(Type::LabelTy, Raw.Arg1)), - cast(getValue(Type::LabelTy, Raw.Arg2)), - getValue(Type::BoolTy , Raw.Arg3)); + } else if (Raw->NumOperands == 3) { + Res = new BranchInst(cast(getValue(Type::LabelTy, Raw->Arg1)), + cast(getValue(Type::LabelTy, Raw->Arg2)), + getValue(Type::BoolTy , Raw->Arg3)); return false; } break; case Instruction::Switch: { SwitchInst *I = - new SwitchInst(getValue(Raw.Ty, Raw.Arg1), - cast(getValue(Type::LabelTy, Raw.Arg2))); + new SwitchInst(getValue(Raw->Ty, Raw->Arg1), + cast(getValue(Type::LabelTy, Raw->Arg2))); Res = I; - if (Raw.NumOperands < 3) return false; // No destinations? Weird. + if (Raw->NumOperands < 3) return false; // No destinations? Weird. - if (Raw.NumOperands == 3 || Raw.VarArgs->size() & 1) { + if (Raw->NumOperands == 3 || Raw->VarArgs->size() & 1) { std::cerr << "Switch statement with odd number of arguments!\n"; delete I; return true; } - std::vector &args = *Raw.VarArgs; + std::vector &args = *Raw->VarArgs; for (unsigned i = 0; i < args.size(); i += 2) - I->addCase(cast(getValue(Raw.Ty, args[i])), + I->addCase(cast(getValue(Raw->Ty, args[i])), cast(getValue(Type::LabelTy, args[i+1]))); - delete Raw.VarArgs; + delete Raw->VarArgs; return false; } case Instruction::Call: { - Value *F = getValue(Raw.Ty, Raw.Arg1); + Value *F = getValue(Raw->Ty, Raw->Arg1); if (F == 0) return true; // Check to make sure we have a pointer to method type @@ -237,30 +248,30 @@ bool BytecodeParser::ParseInstruction(const unsigned char *&Buf, if (!FTy->isVarArg()) { FunctionType::ParamTypes::const_iterator It = PL.begin(); - switch (Raw.NumOperands) { + switch (Raw->NumOperands) { case 0: std::cerr << "Invalid call instruction encountered!\n"; return true; case 1: break; - case 2: Params.push_back(getValue(*It++, Raw.Arg2)); break; - case 3: Params.push_back(getValue(*It++, Raw.Arg2)); + case 2: Params.push_back(getValue(*It++, Raw->Arg2)); break; + case 3: Params.push_back(getValue(*It++, Raw->Arg2)); if (It == PL.end()) return true; - Params.push_back(getValue(*It++, Raw.Arg3)); break; + Params.push_back(getValue(*It++, Raw->Arg3)); break; default: - Params.push_back(getValue(*It++, Raw.Arg2)); + Params.push_back(getValue(*It++, Raw->Arg2)); { - std::vector &args = *Raw.VarArgs; + std::vector &args = *Raw->VarArgs; for (unsigned i = 0; i < args.size(); i++) { if (It == PL.end()) return true; Params.push_back(getValue(*It++, args[i])); if (Params.back() == 0) return true; } } - delete Raw.VarArgs; + delete Raw->VarArgs; } if (It != PL.end()) return true; } else { - if (Raw.NumOperands > 2) { - std::vector &args = *Raw.VarArgs; + if (Raw->NumOperands > 2) { + std::vector &args = *Raw->VarArgs; if (args.size() < 1) return true; if ((args.size() & 1) != 0) @@ -274,7 +285,7 @@ bool BytecodeParser::ParseInstruction(const unsigned char *&Buf, if (V == 0) return true; Params.push_back(V); } - delete Raw.VarArgs; + delete Raw->VarArgs; } } @@ -282,7 +293,7 @@ bool BytecodeParser::ParseInstruction(const unsigned char *&Buf, return false; } case Instruction::Invoke: { - Value *F = getValue(Raw.Ty, Raw.Arg1); + Value *F = getValue(Raw->Ty, Raw->Arg1); if (F == 0) return true; // Check to make sure we have a pointer to method type @@ -293,16 +304,16 @@ bool BytecodeParser::ParseInstruction(const unsigned char *&Buf, std::vector Params; const FunctionType::ParamTypes &PL = FTy->getParamTypes(); - std::vector &args = *Raw.VarArgs; + std::vector &args = *Raw->VarArgs; BasicBlock *Normal, *Except; if (!FTy->isVarArg()) { - if (Raw.NumOperands < 3) return true; + if (Raw->NumOperands < 3) return true; - Normal = cast(getValue(Type::LabelTy, Raw.Arg2)); - if (Raw.NumOperands == 3) - Except = cast(getValue(Type::LabelTy, Raw.Arg3)); + Normal = cast(getValue(Type::LabelTy, Raw->Arg2)); + if (Raw->NumOperands == 3) + Except = cast(getValue(Type::LabelTy, Raw->Arg3)); else { Except = cast(getValue(Type::LabelTy, args[0])); @@ -329,105 +340,105 @@ bool BytecodeParser::ParseInstruction(const unsigned char *&Buf, } } - if (Raw.NumOperands > 3) - delete Raw.VarArgs; + if (Raw->NumOperands > 3) + delete Raw->VarArgs; Res = new InvokeInst(F, Normal, Except, Params); return false; } case Instruction::Malloc: - if (Raw.NumOperands > 2) return true; - V = Raw.NumOperands ? getValue(Type::UIntTy, Raw.Arg1) : 0; - if (const PointerType *PTy = dyn_cast(Raw.Ty)) + if (Raw->NumOperands > 2) return true; + V = Raw->NumOperands ? getValue(Type::UIntTy, Raw->Arg1) : 0; + if (const PointerType *PTy = dyn_cast(Raw->Ty)) Res = new MallocInst(PTy->getElementType(), V); else return true; return false; case Instruction::Alloca: - if (Raw.NumOperands > 2) return true; - V = Raw.NumOperands ? getValue(Type::UIntTy, Raw.Arg1) : 0; - if (const PointerType *PTy = dyn_cast(Raw.Ty)) + if (Raw->NumOperands > 2) return true; + V = Raw->NumOperands ? getValue(Type::UIntTy, Raw->Arg1) : 0; + if (const PointerType *PTy = dyn_cast(Raw->Ty)) Res = new AllocaInst(PTy->getElementType(), V); else return true; return false; case Instruction::Free: - V = getValue(Raw.Ty, Raw.Arg1); + V = getValue(Raw->Ty, Raw->Arg1); if (!isa(V->getType())) return true; Res = new FreeInst(V); return false; case Instruction::GetElementPtr: { std::vector Idx; - if (!isa(Raw.Ty)) return true; - const CompositeType *TopTy = dyn_cast(Raw.Ty); + if (!isa(Raw->Ty)) return true; + const CompositeType *TopTy = dyn_cast(Raw->Ty); - switch (Raw.NumOperands) { + switch (Raw->NumOperands) { case 0: std::cerr << "Invalid getelementptr encountered!\n"; return true; case 1: break; case 2: if (!TopTy) return true; - Idx.push_back(V = getValue(TopTy->getIndexType(), Raw.Arg2)); + Idx.push_back(V = getValue(TopTy->getIndexType(), Raw->Arg2)); if (!V) return true; break; case 3: { if (!TopTy) return true; - Idx.push_back(V = getValue(TopTy->getIndexType(), Raw.Arg2)); + Idx.push_back(V = getValue(TopTy->getIndexType(), Raw->Arg2)); if (!V) return true; const Type *ETy = GetElementPtrInst::getIndexedType(TopTy, Idx, true); const CompositeType *ElTy = dyn_cast_or_null(ETy); if (!ElTy) return true; - Idx.push_back(V = getValue(ElTy->getIndexType(), Raw.Arg3)); + Idx.push_back(V = getValue(ElTy->getIndexType(), Raw->Arg3)); if (!V) return true; break; } default: if (!TopTy) return true; - Idx.push_back(V = getValue(TopTy->getIndexType(), Raw.Arg2)); + Idx.push_back(V = getValue(TopTy->getIndexType(), Raw->Arg2)); if (!V) return true; - std::vector &args = *Raw.VarArgs; + std::vector &args = *Raw->VarArgs; for (unsigned i = 0, E = args.size(); i != E; ++i) { - const Type *ETy = GetElementPtrInst::getIndexedType(Raw.Ty, Idx, true); + const Type *ETy = GetElementPtrInst::getIndexedType(Raw->Ty, Idx, true); const CompositeType *ElTy = dyn_cast_or_null(ETy); if (!ElTy) return true; Idx.push_back(V = getValue(ElTy->getIndexType(), args[i])); if (!V) return true; } - delete Raw.VarArgs; + delete Raw->VarArgs; break; } - Res = new GetElementPtrInst(getValue(Raw.Ty, Raw.Arg1), Idx); + Res = new GetElementPtrInst(getValue(Raw->Ty, Raw->Arg1), Idx); return false; } case 62: // volatile load case Instruction::Load: - if (Raw.NumOperands != 1) return true; - if (!isa(Raw.Ty)) return true; - Res = new LoadInst(getValue(Raw.Ty, Raw.Arg1), "", Raw.Opcode == 62); + if (Raw->NumOperands != 1) return true; + if (!isa(Raw->Ty)) return true; + Res = new LoadInst(getValue(Raw->Ty, Raw->Arg1), "", Raw->Opcode == 62); return false; case 63: // volatile store case Instruction::Store: { - if (!isa(Raw.Ty) || Raw.NumOperands != 2) return true; + if (!isa(Raw->Ty) || Raw->NumOperands != 2) return true; - Value *Ptr = getValue(Raw.Ty, Raw.Arg2); + Value *Ptr = getValue(Raw->Ty, Raw->Arg2); const Type *ValTy = cast(Ptr->getType())->getElementType(); - Res = new StoreInst(getValue(ValTy, Raw.Arg1), Ptr, Raw.Opcode == 63); + Res = new StoreInst(getValue(ValTy, Raw->Arg1), Ptr, Raw->Opcode == 63); return false; } case Instruction::Unwind: - if (Raw.NumOperands != 0) return true; + if (Raw->NumOperands != 0) return true; Res = new UnwindInst(); return false; - } // end switch(Raw.Opcode) + } // end switch(Raw->Opcode) - std::cerr << "Unrecognized instruction! " << Raw.Opcode + std::cerr << "Unrecognized instruction! " << Raw->Opcode << " ADDR = 0x" << (void*)Buf << "\n"; return true; } diff --git a/lib/Bytecode/Reader/ReaderInternals.h b/lib/Bytecode/Reader/ReaderInternals.h index 7ca80031ea5..e7154051eab 100644 --- a/lib/Bytecode/Reader/ReaderInternals.h +++ b/lib/Bytecode/Reader/ReaderInternals.h @@ -164,8 +164,8 @@ private: bool ParseInstruction (const unsigned char *&Buf, const unsigned char *End, Instruction *&); - bool ParseRawInst (const unsigned char *&Buf, const unsigned char *End, - RawInst &); + std::auto_ptr ParseRawInst(const unsigned char *&Buf, + const unsigned char *End); void ParseConstantPool(const unsigned char *&Buf, const unsigned char *EndBuf, ValueTable &Tab, TypeValuesListTy &TypeTab); -- 2.34.1