From d4c0e62413ac4c81467ce59025c81210ea431752 Mon Sep 17 00:00:00 2001 From: Reid Spencer Date: Sat, 3 Mar 2007 18:19:18 +0000 Subject: [PATCH] Deal with error handling better. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34887 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/ExecutionEngine/ExecutionEngine.cpp | 8 ++++--- .../Interpreter/Interpreter.cpp | 22 +++++++++++++------ lib/ExecutionEngine/Interpreter/Interpreter.h | 2 +- lib/ExecutionEngine/JIT/JIT.h | 2 +- lib/ExecutionEngine/JIT/TargetSelect.cpp | 11 ++++++++-- 5 files changed, 31 insertions(+), 14 deletions(-) diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp index ca077fcef05..92e0020ca8f 100644 --- a/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/lib/ExecutionEngine/ExecutionEngine.cpp @@ -45,6 +45,7 @@ ExecutionEngine::ExecutionEngine(Module *M) { } ExecutionEngine::~ExecutionEngine() { + clearAllGlobalMappings(); for (unsigned i = 0, e = Modules.size(); i != e; ++i) delete Modules[i]; } @@ -252,16 +253,17 @@ int ExecutionEngine::runFunctionAsMain(Function *Fn, /// NULL is returned. /// ExecutionEngine *ExecutionEngine::create(ModuleProvider *MP, - bool ForceInterpreter) { + bool ForceInterpreter, + std::string *ErrorStr) { ExecutionEngine *EE = 0; // Unless the interpreter was explicitly selected, try making a JIT. if (!ForceInterpreter && JITCtor) - EE = JITCtor(MP); + EE = JITCtor(MP, ErrorStr); // If we can't make a JIT, make an interpreter instead. if (EE == 0 && InterpCtor) - EE = InterpCtor(MP); + EE = InterpCtor(MP, ErrorStr); if (EE) { // Make sure we can resolve symbols in the program as well. The zero arg diff --git a/lib/ExecutionEngine/Interpreter/Interpreter.cpp b/lib/ExecutionEngine/Interpreter/Interpreter.cpp index 1cce7cb8d3c..cc8cbf9e288 100644 --- a/lib/ExecutionEngine/Interpreter/Interpreter.cpp +++ b/lib/ExecutionEngine/Interpreter/Interpreter.cpp @@ -18,6 +18,7 @@ #include "llvm/DerivedTypes.h" #include "llvm/Module.h" #include "llvm/ModuleProvider.h" +#include using namespace llvm; static struct RegisterInterp { @@ -31,13 +32,20 @@ namespace llvm { /// create - Create a new interpreter object. This can never fail. /// -ExecutionEngine *Interpreter::create(ModuleProvider *MP) { - Module *M; - try { - M = MP->materializeModule(); - } catch (...) { - return 0; // error materializing the module. - } +ExecutionEngine *Interpreter::create(ModuleProvider *MP, std::string* ErrStr) { + // Tell this ModuleProvide to materialize and release the module + Module *M = MP->releaseModule(ErrStr); + if (!M) + // We got an error, just return 0 + return 0; + + // This is a bit nasty, but the ExecutionEngine won't be able to delete the + // module due to use/def issues if we don't delete this MP here. Below we + // construct a new Interpreter with the Module we just got. This creates a + // new ExistingModuleProvider in the EE instance. Consequently, MP is left + // dangling and it contains references into the module which cause problems + // when the module is deleted via the ExistingModuleProvide via EE. + delete MP; // FIXME: This should probably compute the entire data layout std::string DataLayout; diff --git a/lib/ExecutionEngine/Interpreter/Interpreter.h b/lib/ExecutionEngine/Interpreter/Interpreter.h index abc3e08336a..04c9e2af62e 100644 --- a/lib/ExecutionEngine/Interpreter/Interpreter.h +++ b/lib/ExecutionEngine/Interpreter/Interpreter.h @@ -120,7 +120,7 @@ public: /// create - Create an interpreter ExecutionEngine. This can never fail. /// - static ExecutionEngine *create(ModuleProvider *M); + static ExecutionEngine *create(ModuleProvider *M, std::string *ErrorStr = 0); /// run - Start execution with the specified function and arguments. /// diff --git a/lib/ExecutionEngine/JIT/JIT.h b/lib/ExecutionEngine/JIT/JIT.h index c8c89871e82..95105c9b6f1 100644 --- a/lib/ExecutionEngine/JIT/JIT.h +++ b/lib/ExecutionEngine/JIT/JIT.h @@ -71,7 +71,7 @@ public: /// create - Create an return a new JIT compiler if there is one available /// for the current target. Otherwise, return null. /// - static ExecutionEngine *create(ModuleProvider *MP); + static ExecutionEngine *create(ModuleProvider *MP, std::string* = 0); /// run - Start execution with the specified function and arguments. /// diff --git a/lib/ExecutionEngine/JIT/TargetSelect.cpp b/lib/ExecutionEngine/JIT/TargetSelect.cpp index c30f88c572e..30fd2fae4bc 100644 --- a/lib/ExecutionEngine/JIT/TargetSelect.cpp +++ b/lib/ExecutionEngine/JIT/TargetSelect.cpp @@ -38,11 +38,15 @@ MAttrs("mattr", /// create - Create an return a new JIT compiler if there is one available /// for the current target. Otherwise, return null. /// -ExecutionEngine *JIT::create(ModuleProvider *MP) { +ExecutionEngine *JIT::create(ModuleProvider *MP, std::string *ErrorStr) { if (MArch == 0) { std::string Error; MArch = TargetMachineRegistry::getClosestTargetForJIT(Error); - if (MArch == 0) return 0; + if (MArch == 0) { + if (ErrorStr) + *ErrorStr = Error; + return 0; + } } else if (MArch->JITMatchQualityFn() == 0) { cerr << "WARNING: This target JIT is not designed for the host you are" << " running. If bad things happen, please choose a different " @@ -66,5 +70,8 @@ ExecutionEngine *JIT::create(ModuleProvider *MP) { // If the target supports JIT code generation, return a new JIT now. if (TargetJITInfo *TJ = Target->getJITInfo()) return new JIT(MP, *Target, *TJ); + + if (ErrorStr) + *ErrorStr = "target does not support JIT code generation"; return 0; }