Add support for atexit function, remove support for __main function
authorChris Lattner <sabre@nondot.org>
Wed, 14 May 2003 14:21:30 +0000 (14:21 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 14 May 2003 14:21:30 +0000 (14:21 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6194 91177308-0d34-0410-b5e6-96231b3b80d8

lib/ExecutionEngine/Interpreter/Execution.cpp
lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp
lib/ExecutionEngine/Interpreter/Interpreter.cpp
lib/ExecutionEngine/Interpreter/Interpreter.h
lib/ExecutionEngine/Interpreter/UserInput.cpp

index f03514dba2bb129c0d245a31cde12fd33e93db0f..44c1e48c337115076074edd7da0fdbe039dac7c7 100644 (file)
@@ -520,7 +520,9 @@ void Interpreter::visitBinaryOperator(BinaryOperator &I) {
 //                     Terminator Instruction Implementations
 //===----------------------------------------------------------------------===//
 
-static void PerformExitStuff() {
+// PerformExitStuff - Print out counters and profiling information if
+// applicable...
+void Interpreter::PerformExitStuff() {
 #ifdef PROFILE_STRUCTURE_FIELDS
   // Print out structure field accounting information...
   if (!FieldAccessCounts.empty()) {
@@ -575,7 +577,6 @@ void Interpreter::exitCalled(GenericValue GV) {
 
   ExitCode = GV.SByteVal;
   ECStack.clear();
-  PerformExitStuff();
 }
 
 void Interpreter::visitReturnInst(ReturnInst &I) {
@@ -609,8 +610,6 @@ void Interpreter::visitReturnInst(ReturnInst &I) {
     } else {
       ExitCode = 0;
     }
-
-    PerformExitStuff();
     return;
   }
 
index 88b994caad9ad554bf3eef5549e33305646d5cd2..8eaae50cdd503661318fc7719031e34baebee54c 100644 (file)
@@ -91,7 +91,7 @@ static ExFunc lookupFunction(const Function *M) {
 }
 
 GenericValue Interpreter::callExternalFunction(Function *M,
-                                         const vector<GenericValue> &ArgVals) {
+                                     const std::vector<GenericValue> &ArgVals) {
   TheInterpreter = this;
 
   // Do a lookup to see if the function is in our cache... this should just be a
@@ -134,9 +134,13 @@ GenericValue lle_VB_putchar(FunctionType *M, const vector<GenericValue> &Args) {
   return Args[0];
 }
 
-// void __main()
-GenericValue lle_V___main(FunctionType *M, const vector<GenericValue> &Args) {
-  return GenericValue();
+// void atexit(Function*)
+GenericValue lle_X_atexit(FunctionType *M, const vector<GenericValue> &Args) {
+  assert(Args.size() == 1);
+  TheInterpreter->addAtExitHandler((Function*)GVTOP(Args[0]));
+  GenericValue GV;
+  GV.IntVal = 0;
+  return GV;
 }
 
 // void exit(int)
@@ -731,7 +735,6 @@ void Interpreter::initializeExternalFunctions() {
   FuncNames["lle_Vb_putchar"]     = lle_Vb_putchar;
   FuncNames["lle_ii_putchar"]     = lle_ii_putchar;
   FuncNames["lle_VB_putchar"]     = lle_VB_putchar;
-  FuncNames["lle_V___main"]       = lle_V___main;
   FuncNames["lle_X_exit"]         = lle_X_exit;
   FuncNames["lle_X_abort"]        = lle_X_abort;
   FuncNames["lle_X_malloc"]       = lle_X_malloc;
index 4582a6f26d4eef08bf02e6fca53c7f3106bd7354..3453d831957b5bef88d541527c375c702b061b7b 100644 (file)
@@ -48,10 +48,21 @@ int Interpreter::run(const std::string &MainFunction,
     run();
   }
 
-  // If debug mode, allow the user to interact... also, if the user pressed 
-  // ctrl-c or execution hit an error, enter the event loop...
-  if (Debug || isStopped())
-    handleUserInput();
+  do {
+    // If debug mode, allow the user to interact... also, if the user pressed 
+    // ctrl-c or execution hit an error, enter the event loop...
+    if (Debug || isStopped())
+      handleUserInput();
+
+    // If the program has exited, run atexit handlers...
+    if (ECStack.empty() && !AtExitHandlers.empty()) {
+      callFunction(AtExitHandlers.back(), std::vector<GenericValue>());
+      AtExitHandlers.pop_back();
+      run();
+    }
+  } while (!ECStack.empty());
+
+  PerformExitStuff();
   return ExitCode;
 }
 
index 6481cb7d42e8a32c6a82a0008f84858cef488c33..50765810abf4fedffc0e4d1a141bca569c23de92 100644 (file)
@@ -84,6 +84,8 @@ class Interpreter : public ExecutionEngine, public InstVisitor<Interpreter> {
   // function record.
   std::vector<ExecutionContext> ECStack;
 
+  // AtExitHandlers - List of functions to call when the program exits.
+  std::vector<Function*> AtExitHandlers;
 public:
   Interpreter(Module *M, unsigned Config, bool DebugMode, bool TraceMode);
   inline ~Interpreter() { CW.setModule(0); }
@@ -164,6 +166,10 @@ public:
   //
   inline bool isStopped() const { return !ECStack.empty(); }
 
+  void addAtExitHandler(Function *F) {
+    AtExitHandlers.push_back(F);
+  }
+
   //FIXME: private:
 public:
   GenericValue executeGEPOperation(Value *Ptr, User::op_iterator I,
@@ -207,6 +213,9 @@ private:  // Helper functions
   Value *ChooseOneOption(const std::string &Name,
                          const std::vector<Value*> &Opts);
 
+  // PerformExitStuff - Print out counters and profiling information if
+  // applicable...
+  void PerformExitStuff();
 
   void initializeExecutionEngine();
   void initializeExternalFunctions();
index 0ed0f04b15b1d7c0f5db71f2320d30bebb6215e2..3f4493d19be8f30d031a79318f821820bc716966 100644 (file)
@@ -115,7 +115,7 @@ void Interpreter::handleUserInput() {
     case Call:
       std::cin >> Command;
       callFunction(Command);    // Enter the specified function
-      finish();               // Run until it's complete
+      finish();                 // Run until it's complete
       break;
 
     case TraceOpt:
@@ -129,6 +129,7 @@ void Interpreter::handleUserInput() {
     }
 
   } while (!UserQuit);
+  AtExitHandlers.clear();
 }
 
 //===----------------------------------------------------------------------===//