* Implement exit() builtin function
authorChris Lattner <sabre@nondot.org>
Sat, 27 Oct 2001 04:15:57 +0000 (04:15 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 27 Oct 2001 04:15:57 +0000 (04:15 +0000)
* Implement linked in runtime library with puts(char*) in it
* implement builtin putchar(int) function

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

lib/ExecutionEngine/Interpreter/Execution.cpp
lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp
lib/ExecutionEngine/Interpreter/Interpreter.h
lib/ExecutionEngine/Interpreter/UserInput.cpp
lib/ExecutionEngine/Makefile
tools/lli/Makefile

index b8cb4909342a29b3b940a63d46b0b560bc9d51f0..9ad5abab2d92adc07052876fd34a39ea3c94b081 100644 (file)
@@ -419,6 +419,15 @@ static void executeBinaryInst(BinaryOperator *I, ExecutionContext &SF) {
 //                     Terminator Instruction Implementations
 //===----------------------------------------------------------------------===//
 
+void Interpreter::exitCalled(GenericValue GV) {
+  cout << "Program returned ";
+  print(Type::IntTy, GV);
+  cout << " via 'void exit(int)'\n";
+
+  ExitCode = GV.SByteVal;
+  ECStack.clear();
+}
+
 void Interpreter::executeRetInst(ReturnInst *I, ExecutionContext &SF) {
   const Type *RetTy = 0;
   GenericValue Result;
index bcd584a6b5c4a834b168fd9b122a9d67fbf7b911..973cca68422b5f693fc3c844f51d515c1bf81ad0 100644 (file)
 typedef GenericValue (*ExFunc)(MethodType *, const vector<GenericValue> &);
 static map<const Method *, ExFunc> Functions;
 
+static Interpreter *TheInterpreter;
+
+// getCurrentExecutablePath() - Return the directory that the lli executable
+// lives in.
+//
+string Interpreter::getCurrentExecutablePath() const {
+  Dl_info Info;
+  if (dladdr(&TheInterpreter, &Info) == 0) return "";
+  
+  string LinkAddr(Info.dli_fname);
+  unsigned SlashPos = LinkAddr.rfind('/');
+  if (SlashPos != 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';
@@ -61,6 +79,8 @@ static ExFunc lookupMethod(const Method *M) {
 
 void Interpreter::callExternalMethod(Method *M,
                                     const vector<GenericValue> &ArgVals) {
+  TheInterpreter = this;
+
   // Do a lookup to see if the method is in our cache... this should just be a
   // defered annotation!
   map<const Method *, ExFunc>::iterator FI = Functions.find(M);
@@ -127,10 +147,16 @@ GenericValue lle_Vb_putchar(MethodType *M, const vector<GenericValue> &Args) {
   return GenericValue();
 }
 
+// int "putchar"(int)
+GenericValue lle_ii_putchar(MethodType *M, const vector<GenericValue> &Args) {
+  cout << ((char)Args[0].IntVal) << flush;
+  return Args[0];
+}
+
 // void "putchar"(ubyte)
 GenericValue lle_VB_putchar(MethodType *M, const vector<GenericValue> &Args) {
-  cout << Args[0].UByteVal;
-  return GenericValue();
+  cout << Args[0].SByteVal << flush;
+  return Args[0];
 }
 
 // void "__main"()
@@ -138,4 +164,10 @@ GenericValue lle_V___main(MethodType *M, const vector<GenericValue> &Args) {
   return GenericValue();
 }
 
+// void "exit"(int)
+GenericValue lle_Vi_exit(MethodType *M, const vector<GenericValue> &Args) {
+  TheInterpreter->exitCalled(Args[0]);
+  return GenericValue();
+}
+
 } // End extern "C"
index 8c2f32566a509794359857793a2d77e99cf1a764..d9a6834128dc85f05ab63bdc9d272dbdc7a88969 100644 (file)
@@ -108,6 +108,7 @@ public:
   void executeRetInst(ReturnInst *I, ExecutionContext &SF);
   void executeBrInst(BranchInst *I, ExecutionContext &SF);
   void executeAllocInst(AllocationInst *I, ExecutionContext &SF);
+  void exitCalled(GenericValue GV);
 
   // getCurrentMethod - Return the currently executing method
   inline Method *getCurrentMethod() const {
@@ -120,6 +121,11 @@ public:
   inline bool isStopped() const { return !ECStack.empty(); }
 
 private:  // Helper functions
+  // getCurrentExecutablePath() - Return the directory that the lli executable
+  // lives in.
+  //
+  string getCurrentExecutablePath() const;
+
   // printCurrentInstruction - Print out the instruction that the virtual PC is
   // at, or fail silently if no program is running.
   //
index f579ef1a9b4059cbc61fd4182911a94f3d0820ae..2989ae95e86f03b94ff1d3d68f2a34cd4a8584ba 100644 (file)
@@ -8,6 +8,7 @@
 #include "llvm/Bytecode/Reader.h"
 #include "llvm/Assembly/Writer.h"
 #include "llvm/DerivedTypes.h"
+#include "llvm/Transforms/Linker.h"
 #include <algorithm>
 
 enum CommandID {
@@ -129,15 +130,25 @@ void Interpreter::handleUserInput() {
 // loadModule - Load a new module to execute...
 //
 void Interpreter::loadModule(const string &Filename) {
+  string ErrorMsg;
   if (CurMod && !flushModule()) return;  // Kill current execution
 
-  CurMod = ParseBytecodeFile(Filename);
+  CurMod = ParseBytecodeFile(Filename, &ErrorMsg);
   if (CurMod == 0) {
-    cout << "Error parsing '" << Filename << "': No module loaded.\n";
+    cout << "Error parsing '" << Filename << "': No module loaded: "
+         << ErrorMsg << "\n";
     return;
   }
 
-  // TODO: link in support library...
+  string RuntimeLib = getCurrentExecutablePath() + "/RuntimeLib.bc";
+  if (Module *SupportLib = ParseBytecodeFile(RuntimeLib, &ErrorMsg)) {
+    if (LinkModules(CurMod, SupportLib, &ErrorMsg))
+      cerr << "Error Linking runtime library into current module: "
+           << ErrorMsg << endl;
+  } else {
+    cerr << "Error loading runtime library '"+RuntimeLib+"': "
+         << ErrorMsg << "\n";
+  }
 }
 
 
index b1b936d3bf0ba92e6f88b269fe17e44177efcf40..3e70896c291cd56116817e92d7bb8c715ec7e86f 100644 (file)
@@ -1,6 +1,7 @@
 LEVEL = ../..
 TOOLNAME = lli
-USEDLIBS = opt bcreader bcwriter vmcore asmwriter analysis support target
+USEDLIBS = opt bcreader bcwriter vmcore asmwriter analysis support \
+          target transforms
 TOOLLINKOPTS = -ldl
 
 include $(LEVEL)/Makefile.common
@@ -14,6 +15,6 @@ Debug/RuntimeLib.o: Debug/RuntimeLib.c
        /home/vadve/lattner/cvs/gcc_install/bin/gcc $< -c -o $@
 
 $(LEVEL)/tools/Debug/RuntimeLib.bc: Debug/RuntimeLib.o
-       opt -dce $< -o $@ -f -q
+       ../Debug/opt -dce $< -o $@ -f -q
 
 
index b1b936d3bf0ba92e6f88b269fe17e44177efcf40..3e70896c291cd56116817e92d7bb8c715ec7e86f 100644 (file)
@@ -1,6 +1,7 @@
 LEVEL = ../..
 TOOLNAME = lli
-USEDLIBS = opt bcreader bcwriter vmcore asmwriter analysis support target
+USEDLIBS = opt bcreader bcwriter vmcore asmwriter analysis support \
+          target transforms
 TOOLLINKOPTS = -ldl
 
 include $(LEVEL)/Makefile.common
@@ -14,6 +15,6 @@ Debug/RuntimeLib.o: Debug/RuntimeLib.c
        /home/vadve/lattner/cvs/gcc_install/bin/gcc $< -c -o $@
 
 $(LEVEL)/tools/Debug/RuntimeLib.bc: Debug/RuntimeLib.o
-       opt -dce $< -o $@ -f -q
+       ../Debug/opt -dce $< -o $@ -f -q