mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-25 21:16:19 +00:00
For PR797:
Make the Bytecode Reader use setjmp/longjump instead of exceptions to handle errors. The alternative was even uglier than setjmp/longjump as it would impact the interface and workings of nearly every function in the reader. llvm-svn: 29819
This commit is contained in:
parent
88b3207059
commit
d00c37651a
@ -51,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);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -470,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
|
||||
@ -718,12 +716,12 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
||||
}
|
||||
case Instruction::ExtractElement: {
|
||||
if (Oprnds.size() != 2)
|
||||
throw std::string("Invalid extractelement instruction!");
|
||||
error("Invalid extractelement instruction!");
|
||||
Value *V1 = getValue(iType, Oprnds[0]);
|
||||
Value *V2 = getValue(Type::UIntTyID, Oprnds[1]);
|
||||
|
||||
if (!ExtractElementInst::isValidOperands(V1, V2))
|
||||
throw std::string("Invalid extractelement instruction!");
|
||||
error("Invalid extractelement instruction!");
|
||||
|
||||
Result = new ExtractElementInst(V1, V2);
|
||||
break;
|
||||
@ -731,28 +729,28 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
||||
case Instruction::InsertElement: {
|
||||
const PackedType *PackedTy = dyn_cast<PackedType>(InstTy);
|
||||
if (!PackedTy || Oprnds.size() != 3)
|
||||
throw std::string("Invalid insertelement instruction!");
|
||||
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))
|
||||
throw std::string("Invalid insertelement instruction!");
|
||||
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)
|
||||
throw std::string("Invalid shufflevector instruction!");
|
||||
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))
|
||||
throw std::string("Invalid shufflevector instruction!");
|
||||
error("Invalid shufflevector instruction!");
|
||||
Result = new ShuffleVectorInst(V1, V2, V3);
|
||||
break;
|
||||
}
|
||||
@ -2403,10 +2401,28 @@ 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) {
|
||||
bool BytecodeReader::ParseBytecode(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;
|
||||
}
|
||||
|
||||
try {
|
||||
RevisionNum = 0;
|
||||
At = MemStart = BlockStart = Buf;
|
||||
MemEnd = BlockEnd = Buf + Length;
|
||||
@ -2490,28 +2506,8 @@ void BytecodeReader::ParseBytecode(BufPtr Buf, unsigned Length,
|
||||
// Tell the handler we're finished the parse
|
||||
if (Handler) Handler->handleFinish();
|
||||
|
||||
} 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;
|
||||
}
|
||||
throw msg;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "llvm/Bytecode/Analyzer.h"
|
||||
#include <utility>
|
||||
#include <map>
|
||||
#include <setjmp.h>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -136,11 +137,13 @@ public:
|
||||
/// @name Methods
|
||||
/// @{
|
||||
public:
|
||||
/// @returns true if an error occurred
|
||||
/// @brief Main interface to parsing a bytecode buffer.
|
||||
void ParseBytecode(
|
||||
bool ParseBytecode(
|
||||
const unsigned char *Buf, ///< Beginning of the bytecode buffer
|
||||
unsigned Length, ///< Length of the bytecode buffer
|
||||
const std::string &ModuleID ///< An identifier for the module constructed.
|
||||
const std::string &ModuleID, ///< An identifier for the module constructed.
|
||||
std::string* ErrMsg = 0 ///< Optional place for error message
|
||||
);
|
||||
|
||||
/// @brief Parse all function bodies
|
||||
@ -260,6 +263,8 @@ protected:
|
||||
/// @name Data
|
||||
/// @{
|
||||
private:
|
||||
std::string ErrorMsg; ///< A place to hold an error message through longjmp
|
||||
jmp_buf context; ///< Where to return to if an error occurs.
|
||||
char* decompressedBlock; ///< Result of decompression
|
||||
BufPtr MemStart; ///< Start of the memory buffer
|
||||
BufPtr MemEnd; ///< End of the memory buffer
|
||||
@ -487,7 +492,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
inline void error(std::string errmsg);
|
||||
inline void error(const std::string& errmsg);
|
||||
|
||||
BytecodeReader(const BytecodeReader &); // DO NOT IMPLEMENT
|
||||
void operator=(const BytecodeReader &); // DO NOT IMPLEMENT
|
||||
|
Loading…
Reference in New Issue
Block a user