1. Handle errors around the ModuleProvider. This is necessary since it is
authorReid Spencer <rspencer@reidspencer.com>
Sat, 3 Mar 2007 18:21:44 +0000 (18:21 +0000)
committerReid Spencer <rspencer@reidspencer.com>
Sat, 3 Mar 2007 18:21:44 +0000 (18:21 +0000)
   reading bytecode.
2. The interpreter can delete the ModuleProvider and replace it with
   another so don't depend on it being around after the EE is created.
3. Don't just run llvm_shutdown on exit but actually delete the EE as well.
   This cleans up a vast amount of memory (but not all) that EE retained
   through exit.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34888 91177308-0d34-0410-b5e6-96231b3b80d8

tools/lli/lli.cpp

index 0f96a4a2b15b3742024409ae7fbb4179fd337414..c02d2a441929b1904d705b4fe457decddee0236e 100644 (file)
@@ -54,11 +54,18 @@ namespace {
                    cl::desc("Disable emission of core files if possible"));
 }
 
+static ExecutionEngine *EE = 0;
+
+static void do_shutdown() {
+  delete EE;
+  llvm_shutdown();
+}
+
 //===----------------------------------------------------------------------===//
 // main Driver function
 //
 int main(int argc, char **argv, char * const *envp) {
-  atexit(llvm_shutdown);  // Call llvm_shutdown() on exit.
+  atexit(do_shutdown);  // Call llvm_shutdown() on exit.
   try {
     cl::ParseCommandLineOptions(argc, argv,
                                 " llvm interpreter & dynamic compiler\n");
@@ -70,22 +77,27 @@ int main(int argc, char **argv, char * const *envp) {
     
     // Load the bytecode...
     std::string ErrorMsg;
-    ModuleProvider *MP = 0;
-    MP = getBytecodeModuleProvider(InputFile, 
-                                   Compressor::decompressToNewBuffer,
-                                   &ErrorMsg);
+    ModuleProvider *MP = getBytecodeModuleProvider(InputFile, 
+                                              Compressor::decompressToNewBuffer,
+                                              &ErrorMsg);
     if (!MP) {
-      std::cerr << "Error loading program '" << InputFile << "': "
+      std::cerr << argv[0] << ": error loading program '" << InputFile << "': "
                 << ErrorMsg << "\n";
       exit(1);
     }
 
+    // Get the module as the MP could go away once EE takes over.
+    Module *Mod = MP->getModule();
+
     // If we are supposed to override the target triple, do so now.
     if (!TargetTriple.empty())
-      MP->getModule()->setTargetTriple(TargetTriple);
+      Mod->setTargetTriple(TargetTriple);
     
-    ExecutionEngine *EE = ExecutionEngine::create(MP, ForceInterpreter);
-    assert(EE &&"Couldn't create an ExecutionEngine, not even an interpreter?");
+    EE = ExecutionEngine::create(MP, ForceInterpreter, &ErrorMsg);
+    if (!EE && !ErrorMsg.empty()) {
+      std::cerr << argv[0] << ":error creating EE: " << ErrorMsg << "\n";
+      exit(1);
+    }
 
     // If the user specifically requested an argv[0] to pass into the program,
     // do it now.
@@ -106,7 +118,7 @@ int main(int argc, char **argv, char * const *envp) {
     // using the contents of Args to determine argc & argv, and the contents of
     // EnvVars to determine envp.
     //
-    Function *Fn = MP->getModule()->getFunction("main");
+    Function *Fn = Mod->getFunction("main");
     if (!Fn) {
       std::cerr << "'main' function not found in module.\n";
       return -1;
@@ -123,7 +135,7 @@ int main(int argc, char **argv, char * const *envp) {
     
     // If the program didn't explicitly call exit, call exit now, for the
     // program. This ensures that any atexit handlers get called correctly.
-    Constant *Exit = MP->getModule()->getOrInsertFunction("exit", Type::VoidTy,
+    Constant *Exit = Mod->getOrInsertFunction("exit", Type::VoidTy,
                                                           Type::Int32Ty, NULL);
     if (Function *ExitF = dyn_cast<Function>(Exit)) {
       std::vector<GenericValue> Args;