Add a helper method for running static ctors/dtors in the module.
authorChris Lattner <sabre@nondot.org>
Wed, 8 Mar 2006 18:42:46 +0000 (18:42 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 8 Mar 2006 18:42:46 +0000 (18:42 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26619 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ExecutionEngine/ExecutionEngine.h
lib/ExecutionEngine/ExecutionEngine.cpp

index 301b6d6eeb849b3e8b9ba64c8af097af5b86fb62..6b248e54c8ec827c12275a4f20f43a7437603f1d 100644 (file)
@@ -95,6 +95,12 @@ public:
   virtual GenericValue runFunction(Function *F,
                                 const std::vector<GenericValue> &ArgValues) = 0;
 
+  /// runStaticConstructorsDestructors - This method is used to execute all of
+  /// the static constructors or destructors for a module, depending on the
+  /// value of isDtors.
+  void runStaticConstructorsDestructors(bool isDtors);
+  
+  
   /// runFunctionAsMain - This is a helper function which wraps runFunction to
   /// handle the common task of starting up main with the specified argc, argv,
   /// and envp parameters.
index 95610e65b60d4545e54f2dd00a028da1b980de53..86af7bfafea1f52003d050b863135c34850db3b9 100644 (file)
@@ -95,6 +95,37 @@ static void *CreateArgv(ExecutionEngine *EE,
   return Result;
 }
 
+
+/// runStaticConstructorsDestructors - This method is used to execute all of
+/// the static constructors or destructors for a module, depending on the
+/// value of isDtors.
+void ExecutionEngine::runStaticConstructorsDestructors(bool isDtors) {
+  const char *Name = isDtors ? "llvm.global_dtors" : "llvm.global_ctors";
+  GlobalVariable *GV = CurMod.getNamedGlobal(Name);
+  if (!GV || GV->isExternal() || !GV->hasInternalLinkage()) return;
+  
+  // Should be an array of '{ int, void ()* }' structs.  The first value is the
+  // init priority, which we ignore.
+  ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer());
+  if (!InitList) return;
+  for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i)
+    if (ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(i))){
+      if (CS->getNumOperands() != 2) return;  // Not array of 2-element structs.
+      
+      Constant *FP = CS->getOperand(1);
+      if (FP->isNullValue())
+        return;  // Found a null terminator, exit.
+      
+      if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP))
+        if (CE->getOpcode() == Instruction::Cast)
+          FP = CE->getOperand(0);
+      if (Function *F = dyn_cast<Function>(FP)) {
+        // Execute the ctor/dtor function!
+        runFunction(F, std::vector<GenericValue>());
+      }
+    }
+}
+
 /// runFunctionAsMain - This is a helper function which wraps runFunction to
 /// handle the common task of starting up main with the specified argc, argv,
 /// and envp parameters.
@@ -122,8 +153,6 @@ int ExecutionEngine::runFunctionAsMain(Function *Fn,
   return runFunction(Fn, GVArgs).IntVal;
 }
 
-
-
 /// If possible, create a JIT, unless the caller specifically requests an
 /// Interpreter or there's an error. If even an Interpreter cannot be created,
 /// NULL is returned.