Handle value promotion properly to work with tracing better
[oota-llvm.git] / lib / ExecutionEngine / Interpreter / UserInput.cpp
index a24b31175063d149ca1b0694e2035c585db7cd70..3d2b1de60a45464f9c1b05a5148d2a232b3891d3 100644 (file)
@@ -6,17 +6,21 @@
 
 #include "Interpreter.h"
 #include "llvm/Bytecode/Reader.h"
-#include "llvm/Assembly/Writer.h"
 #include "llvm/DerivedTypes.h"
-#include "llvm/Transforms/Linker.h"
+#include "llvm/Function.h"
+#include "llvm/Transforms/Utils/Linker.h"
 #include <algorithm>
+using std::string;
+using std::cout;
+using std::cin;
 
 enum CommandID {
   Quit, Help,                                 // Basics
   Print, Info, List, StackTrace, Up, Down,    // Inspection
   Next, Step, Run, Finish, Call,              // Control flow changes
   Break, Watch,                               // Debugging
-  Load, Flush
+  Flush,
+  TraceOpt,                                   // Toggle features
 };
 
 // CommandTable - Build a lookup table for the commands available to the user...
@@ -50,8 +54,9 @@ static struct CommandTableElement {
   { "break"    , Break      }, { "b", Break },
   { "watch"    , Watch      },
 
-  { "load"     , Load       },
   { "flush"    , Flush      },
+
+  { "trace"    , TraceOpt   },
 };
 static CommandTableElement *CommandTableEnd = 
    CommandTable+sizeof(CommandTable)/sizeof(CommandTable[0]);
@@ -65,14 +70,14 @@ void Interpreter::handleUserInput() {
   bool UserQuit = false;
 
   // Sort the table...
-  sort(CommandTable, CommandTableEnd);
+  std::sort(CommandTable, CommandTableEnd);
 
   // Print the instruction that we are stopped at...
   printCurrentInstruction();
 
   do {
     string Command;
-    cout << "lli> " << flush;
+    cout << "lli> " << std::flush;
     cin >> Command;
 
     CommandTableElement *E = find(CommandTable, CommandTableEnd, Command);
@@ -84,11 +89,6 @@ void Interpreter::handleUserInput() {
 
     switch (E->CID) {
     case Quit:       UserQuit = true;   break;
-    case Load:
-      cin >> Command;
-      loadModule(Command);
-      break;
-    case Flush: flushModule(); break;
     case Print:
       cin >> Command;
       print(Command);
@@ -101,12 +101,15 @@ void Interpreter::handleUserInput() {
     case List:       list();            break;
     case StackTrace: printStackTrace(); break;
     case Up: 
-      if (CurFrame > 0) --CurFrame;
+      if (CurFrame > 0) { --CurFrame; printStackFrame(); }
       else cout << "Error: Already at root of stack!\n";
       break;
     case Down:
-      if ((unsigned)CurFrame < ECStack.size()-1) ++CurFrame;
-      else cout << "Error: Already at bottom of stack!\n";
+      if ((unsigned)CurFrame < ECStack.size()-1) {
+        ++CurFrame;
+        printStackFrame();
+      } else
+        cout << "Error: Already at bottom of stack!\n";
       break;
     case Next:       nextInstruction(); break;
     case Step:       stepInstruction(); break;
@@ -114,10 +117,15 @@ void Interpreter::handleUserInput() {
     case Finish:     finish();          break;
     case Call:
       cin >> Command;
-      callMethod(Command);    // Enter the specified method
+      callMethod(Command);    // Enter the specified function
       finish();               // Run until it's complete
       break;
 
+    case TraceOpt:
+      Trace = !Trace;
+      cout << "Tracing " << (Trace ? "enabled\n" : "disabled\n");
+      break;
+
     default:
       cout << "Command '" << Command << "' unimplemented!\n";
       break;
@@ -126,54 +134,6 @@ void Interpreter::handleUserInput() {
   } while (!UserQuit);
 }
 
-//===----------------------------------------------------------------------===//
-// 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, &ErrorMsg);
-  if (CurMod == 0) {
-    cout << "Error parsing '" << Filename << "': No module loaded: "
-         << ErrorMsg << "\n";
-    return;
-  }
-
-  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";
-  }
-}
-
-
-//===----------------------------------------------------------------------===//
-// flushModule - Return true if the current program has been unloaded.
-//
-bool Interpreter::flushModule() {
-  if (CurMod == 0) {
-    cout << "Error flushing: No module loaded!\n";
-    return false;
-  }
-
-  if (!ECStack.empty()) {
-    // TODO: if use is not sure, return false
-    cout << "Killing current execution!\n";
-    ECStack.clear();
-    CurFrame = -1;
-  }
-
-  delete CurMod;
-  CurMod = 0;
-  ExitCode = 0;
-  return true;
-}
-
 //===----------------------------------------------------------------------===//
 // setBreakpoint - Enable a breakpoint at the specified location
 //
@@ -186,10 +146,10 @@ void Interpreter::setBreakpoint(const string &Name) {
 // callMethod - Enter the specified method...
 //
 bool Interpreter::callMethod(const string &Name) {
-  vector<Value*> Options = LookupMatchingNames(Name);
+  std::vector<Value*> Options = LookupMatchingNames(Name);
 
-  for (unsigned i = 0; i < Options.size(); ++i) { // Remove nonmethod matches...
-    if (!isa<Method>(Options[i])) {
+  for (unsigned i = 0; i < Options.size(); ++i) { // Remove non-fn matches...
+    if (!isa<Function>(Options[i])) {
       Options.erase(Options.begin()+i);
       --i;
     }
@@ -199,12 +159,12 @@ bool Interpreter::callMethod(const string &Name) {
   if (PickedMeth == 0)
     return true;
 
-  Method *M = cast<Method>(PickedMeth);
+  Function *F = cast<Function>(PickedMeth);
 
-  vector<GenericValue> Args;
+  std::vector<GenericValue> Args;
   // TODO, get args from user...
 
-  callMethod(M, Args);  // Start executing it...
+  callMethod(F, Args);  // Start executing it...
 
   // Reset the current frame location to the top of stack
   CurFrame = ECStack.size()-1;
@@ -212,32 +172,15 @@ bool Interpreter::callMethod(const string &Name) {
   return false;
 }
 
-static void *CreateArgv(const vector<string> &InputArgv) {
-  // Pointers are 64 bits...
-  uint64_t *Result = new uint64_t[InputArgv.size()+1];
-
-  for (unsigned i = 0; i < InputArgv.size(); ++i) {
-    unsigned Size = InputArgv[i].size()+1;
-    char *Dest = new char[Size];
-    copy(InputArgv[i].begin(), InputArgv[i].end(), Dest);
-    Dest[Size-1] = 0;
-    Result[i] = (uint64_t)Dest;
-  }
-
-  Result[InputArgv.size()] = 0;
-  return Result;
-}
-
-
 // callMainMethod - This is a nasty gross hack that will dissapear when
 // callMethod can parse command line options and stuff for us.
 //
 bool Interpreter::callMainMethod(const string &Name,
-                                 const vector<string> &InputArgv) {
-  vector<Value*> Options = LookupMatchingNames(Name);
+                                 const std::vector<string> &InputArgv) {
+  std::vector<Value*> Options = LookupMatchingNames(Name);
 
-  for (unsigned i = 0; i < Options.size(); ++i) { // Remove nonmethod matches...
-    if (!isa<Method>(Options[i])) {
+  for (unsigned i = 0; i < Options.size(); ++i) { // Remove non-fn matches...
+    if (!isa<Function>(Options[i])) {
       Options.erase(Options.begin()+i);
       --i;
     }
@@ -247,10 +190,10 @@ bool Interpreter::callMainMethod(const string &Name,
   if (PickedMeth == 0)
     return true;
 
-  Method *M = cast<Method>(PickedMeth);
-  const MethodType *MT = M->getMethodType();
+  Function *M = cast<Function>(PickedMeth);
+  const FunctionType *MT = M->getFunctionType();
 
-  vector<GenericValue> Args;
+  std::vector<GenericValue> Args;
   switch (MT->getParamTypes().size()) {
   default:
     cout << "Unknown number of arguments to synthesize for '" << Name << "'!\n";
@@ -258,18 +201,17 @@ bool Interpreter::callMainMethod(const string &Name,
   case 2: {
     PointerType *SPP = PointerType::get(PointerType::get(Type::SByteTy));
     if (MT->getParamTypes()[1] != SPP) {
-      cout << "Second argument of '" << Name << "' should have type: '"
-           << SPP->getDescription() << "'!\n";
+      CW << "Second argument of '" << Name << "' should have type: '"
+         << SPP << "'!\n";
       return true;
     }
 
-    GenericValue GV; GV.PointerVal = (uint64_t)CreateArgv(InputArgv);
-    Args.push_back(GV);
+    Args.push_back(PTOGV(CreateArgv(InputArgv)));
   }
     // fallthrough
   case 1:
-    if (!MT->getParamTypes()[0]->isIntegral()) {
-      cout << "First argument of '" << Name << "' should be integral!\n";
+    if (!MT->getParamTypes()[0]->isInteger()) {
+      cout << "First argument of '" << Name << "' should be an integer!\n";
       return true;
     } else {
       GenericValue GV; GV.UIntVal = InputArgv.size();
@@ -287,3 +229,20 @@ bool Interpreter::callMainMethod(const string &Name,
 
   return false;
 }
+
+
+
+void Interpreter::list() {
+  if (ECStack.empty())
+    cout << "Error: No program executing!\n";
+  else
+    CW << ECStack[CurFrame].CurMethod;   // Just print the function out...
+}
+
+void Interpreter::printStackTrace() {
+  if (ECStack.empty()) cout << "No program executing!\n";
+
+  for (unsigned i = 0; i < ECStack.size(); ++i) {
+    printStackFrame((int)i);
+  }
+}