[llvm-commits] CVS: llvm/tools/lli/Interpreter/ExternalFunctions.cpp Interpreter.cpp Interpreter.h

Brian Gaeke gaeke at cs.uiuc.edu
Fri Sep 5 13:43:08 PDT 2003


Changes in directory llvm/tools/lli/Interpreter:

ExternalFunctions.cpp updated: 1.57 -> 1.58
Interpreter.cpp updated: 1.11 -> 1.12
Interpreter.h updated: 1.38 -> 1.39

---
Log message:

Make CreateArgv part of lli rather than part of ExecutionEngine.
Switch Interpreter and JIT's "run" methods to take a Function and a vector of
 GenericValues.
Move (almost all of) the stuff that constructs a canonical call to main()
 into lli (new methods "callAsMain", "makeStringVector").
Nuke getCurrentExecutablePath(), enableTracing(), getCurrentFunction(),
 isStopped(), and many dead decls from interpreter.
Add linux strdup() support to interpreter.
Make interpreter's atexit handler runner and JIT's runAtExitHandlers() look
 more alike, in preparation for refactoring.
atexit() is spelled "atexit", not "at_exit".


---
Diffs of the changes:

Index: llvm/tools/lli/Interpreter/ExternalFunctions.cpp
diff -u llvm/tools/lli/Interpreter/ExternalFunctions.cpp:1.57 llvm/tools/lli/Interpreter/ExternalFunctions.cpp:1.58
--- llvm/tools/lli/Interpreter/ExternalFunctions.cpp:1.57	Sun Aug 24 09:02:47 2003
+++ llvm/tools/lli/Interpreter/ExternalFunctions.cpp	Fri Sep  5 13:42:00 2003
@@ -29,22 +29,6 @@
 
 static Interpreter *TheInterpreter;
 
-// getCurrentExecutablePath() - Return the directory that the lli executable
-// lives in.
-//
-std::string Interpreter::getCurrentExecutablePath() const {
-  Dl_info Info;
-  if (dladdr(&TheInterpreter, &Info) == 0) return "";
-  
-  std::string LinkAddr(Info.dli_fname);
-  unsigned SlashPos = LinkAddr.rfind('/');
-  if (SlashPos != std::string::npos)
-    LinkAddr.resize(SlashPos);    // Trim the executable name off...
-
-  return LinkAddr;
-}
-
-
 static char getTypeID(const Type *Ty) {
   switch (Ty->getPrimitiveID()) {
   case Type::VoidTyID:    return 'V';
@@ -496,6 +480,12 @@
   GenericValue Ret;
   Ret.LongVal = strlen((char*)GVTOP(Args[0]));
   return Ret;
+}
+
+// char *strdup(const char *src);
+GenericValue lle_X_strdup(FunctionType *M, const vector<GenericValue> &Args) {
+  assert(Args.size() == 1);
+  return PTOGV(strdup((char*)GVTOP(Args[0])));
 }
 
 // char *__strdup(const char *src);


Index: llvm/tools/lli/Interpreter/Interpreter.cpp
diff -u llvm/tools/lli/Interpreter/Interpreter.cpp:1.11 llvm/tools/lli/Interpreter/Interpreter.cpp:1.12
--- llvm/tools/lli/Interpreter/Interpreter.cpp:1.11	Thu Sep  4 23:46:26 2003
+++ llvm/tools/lli/Interpreter/Interpreter.cpp	Fri Sep  5 13:42:00 2003
@@ -54,69 +54,46 @@
   emitGlobals();
 }
 
-/// run - Start execution with the specified function and arguments.
-///
-int Interpreter::run(const std::string &MainFunction,
-		     const std::vector<std::string> &Args,
-                     const char ** envp) {
-  // Start interpreter into the main function...
-  //
-  if (!callMainFunction(MainFunction, Args)) {
-    // If the call succeeded, run the code now...
+void Interpreter::runAtExitHandlers () {
+  while (!AtExitHandlers.empty()) {
+    callFunction(AtExitHandlers.back(), std::vector<GenericValue>());
+    AtExitHandlers.pop_back();
     run();
   }
-
-  do {
-    // 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());
-
-  return ExitCode;
 }
 
-
-// callMainFunction - Construct call to typical C main() function and
-// call it using callFunction().
-//
-bool Interpreter::callMainFunction(const std::string &Name,
-                                   const std::vector<std::string> &InputArgv) {
-  Function *M = getModule().getNamedFunction(Name);
-  if (M == 0) {
-    std::cerr << "Could not find function '" << Name << "' in module!\n";
-    return 1;
-  }
-  const FunctionType *MT = M->getFunctionType();
-
-  std::vector<GenericValue> Args;
-  if (MT->getParamTypes().size() >= 2) {
-    PointerType *SPP = PointerType::get(PointerType::get(Type::SByteTy));
-    if (MT->getParamTypes()[1] != SPP) {
-      CW << "Second argument of '" << Name << "' should have type: '"
-	 << SPP << "'!\n";
-      return true;
-    }
-    Args.push_back(PTOGV(CreateArgv(InputArgv)));
-  }
-
-  if (MT->getParamTypes().size() >= 1) {
-    if (!MT->getParamTypes()[0]->isInteger()) {
-      std::cout << "First argument of '" << Name
-		<< "' should be an integer!\n";
-      return true;
-    } else {
-      GenericValue GV; GV.UIntVal = InputArgv.size();
-      Args.insert(Args.begin(), GV);
-    }
+/// run - Start execution with the specified function and arguments.
+///
+GenericValue Interpreter::run(Function *F,
+			      const std::vector<GenericValue> &ArgValues) {
+  assert (F && "Function *F was null at entry to run()");
+
+  // Try extra hard not to pass extra args to a function that isn't
+  // expecting them.  C programmers frequently bend the rules and
+  // declare main() with fewer parameters than it actually gets
+  // passed, and the interpreter barfs if you pass a function more
+  // parameters than it is declared to take. This does not attempt to
+  // take into account gratuitous differences in declared types,
+  // though.
+  std::vector<GenericValue> ActualArgs;
+  const unsigned ArgCount = F->getFunctionType()->getParamTypes().size();
+  for (unsigned i = 0; i < ArgCount; ++i) {
+    ActualArgs.push_back (ArgValues[i]);
   }
-
-  callFunction(M, Args);  // Start executing it...
+  
+  // Set up the function call.
+  callFunction(F, ActualArgs);
 
   // Reset the current frame location to the top of stack
   CurFrame = ECStack.size()-1;
 
-  return false;
+  // Start executing the function.
+  run();
+  
+  // Run any atexit handlers now!
+  runAtExitHandlers();
+
+  GenericValue rv;
+  rv.IntVal = ExitCode;
+  return rv;
 }


Index: llvm/tools/lli/Interpreter/Interpreter.h
diff -u llvm/tools/lli/Interpreter/Interpreter.h:1.38 llvm/tools/lli/Interpreter/Interpreter.h:1.39
--- llvm/tools/lli/Interpreter/Interpreter.h:1.38	Fri Sep  5 00:04:32 2003
+++ llvm/tools/lli/Interpreter/Interpreter.h	Fri Sep  5 13:42:00 2003
@@ -79,41 +79,38 @@
   // function record.
   std::vector<ExecutionContext> ECStack;
 
-  // AtExitHandlers - List of functions to call when the program exits.
+  // AtExitHandlers - List of functions to call when the program exits,
+  // registered with the atexit() library function.
   std::vector<Function*> AtExitHandlers;
 public:
   Interpreter(Module *M, bool isLittleEndian, bool isLongPointer,
               bool TraceMode);
   inline ~Interpreter() { CW.setModule(0); }
 
+  /// runAtExitHandlers - Run any functions registered by the
+  /// program's calls to atexit(3), which we intercept and store in
+  /// AtExitHandlers.
+  ///
+  void runAtExitHandlers ();
+
   /// create - Create an interpreter ExecutionEngine. This can never fail.
   ///
   static ExecutionEngine *create(Module *M, bool TraceMode);
 
   /// run - Start execution with the specified function and arguments.
   ///
-  virtual int run(const std::string &FnName,
-		  const std::vector<std::string> &Args,
-                  const char ** envp);
- 
-
-  void enableTracing() { Trace = true; }
+  virtual GenericValue run(Function *F,
+			   const std::vector<GenericValue> &ArgValues);
 
-  void handleUserInput();
-
-  // User Interation Methods...
-  bool callFunction(const std::string &Name);      // return true on failure
+  // Methods used for debug printouts:
   static void print(const Type *Ty, GenericValue V);
   static void printValue(const Type *Ty, GenericValue V);
 
-  bool callMainFunction(const std::string &MainName,
-                        const std::vector<std::string> &InputFilename);
-
-  // Code execution methods...
+  // Methods used to execute code:
+  // Place a call on the stack
   void callFunction(Function *F, const std::vector<GenericValue> &ArgVals);
-  void executeInstruction(); // Execute one instruction...
-
-  void run();              // Do the 'run' command
+  void executeInstruction(); // Execute one instruction
+  void run();                // Execute instructions until nothing left to do
 
   // Opcode Implementations
   void visitReturnInst(ReturnInst &I);
@@ -142,16 +139,6 @@
                                     const std::vector<GenericValue> &ArgVals);
   void exitCalled(GenericValue GV);
 
-  // getCurrentFunction - Return the currently executing function
-  inline Function *getCurrentFunction() const {
-    return CurFrame < 0 ? 0 : ECStack[CurFrame].CurFunction;
-  }
-
-  // isStopped - Return true if a program is stopped.  Return false if no
-  // program is running.
-  //
-  inline bool isStopped() const { return !ECStack.empty(); }
-
   void addAtExitHandler(Function *F) {
     AtExitHandlers.push_back(F);
   }
@@ -169,16 +156,6 @@
   void SwitchToNewBasicBlock(BasicBlock *Dest, ExecutionContext &SF);
 
   void *getPointerToFunction(Function *F) { return (void*)F; }
-
-  // getCurrentExecutablePath() - Return the directory that the lli executable
-  // lives in.
-  //
-  std::string getCurrentExecutablePath() const;
-
-  // printCurrentInstruction - Print out the instruction that the virtual PC is
-  // at, or fail silently if no program is running.
-  //
-  void printCurrentInstruction();
 
   void initializeExecutionEngine();
   void initializeExternalFunctions();





More information about the llvm-commits mailing list