Handle value promotion properly to work with tracing better
[oota-llvm.git] / lib / ExecutionEngine / Interpreter / UserInput.cpp
index e9fc9db3436234adebe8a603bc6988381326ead4..3d2b1de60a45464f9c1b05a5148d2a232b3891d3 100644 (file)
@@ -5,15 +5,22 @@
 //===----------------------------------------------------------------------===//
 
 #include "Interpreter.h"
-#include "llvm/Assembly/Writer.h"
+#include "llvm/Bytecode/Reader.h"
+#include "llvm/DerivedTypes.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...
@@ -47,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]);
@@ -62,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);
@@ -83,7 +91,7 @@ void Interpreter::handleUserInput() {
     case Quit:       UserQuit = true;   break;
     case Print:
       cin >> Command;
-      printValue(Command);
+      print(Command);
       break;
     case Info:
       cin >> Command;
@@ -93,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;
@@ -106,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;
@@ -118,7 +134,6 @@ void Interpreter::handleUserInput() {
   } while (!UserQuit);
 }
 
-
 //===----------------------------------------------------------------------===//
 // setBreakpoint - Enable a breakpoint at the specified location
 //
@@ -131,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;
     }
@@ -144,11 +159,69 @@ 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(F, Args);  // Start executing it...
+
+  // Reset the current frame location to the top of stack
+  CurFrame = ECStack.size()-1;
+
+  return false;
+}
+
+// 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 std::vector<string> &InputArgv) {
+  std::vector<Value*> Options = LookupMatchingNames(Name);
+
+  for (unsigned i = 0; i < Options.size(); ++i) { // Remove non-fn matches...
+    if (!isa<Function>(Options[i])) {
+      Options.erase(Options.begin()+i);
+      --i;
+    }
+  }
+
+  Value *PickedMeth = ChooseOneOption(Name, Options);
+  if (PickedMeth == 0)
+    return true;
+
+  Function *M = cast<Function>(PickedMeth);
+  const FunctionType *MT = M->getFunctionType();
+
+  std::vector<GenericValue> Args;
+  switch (MT->getParamTypes().size()) {
+  default:
+    cout << "Unknown number of arguments to synthesize for '" << Name << "'!\n";
+    return true;
+  case 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)));
+  }
+    // fallthrough
+  case 1:
+    if (!MT->getParamTypes()[0]->isInteger()) {
+      cout << "First argument of '" << Name << "' should be an integer!\n";
+      return true;
+    } else {
+      GenericValue GV; GV.UIntVal = InputArgv.size();
+      Args.insert(Args.begin(), GV);
+    }
+    // fallthrough
+  case 0:
+    break;
+  }
+
   callMethod(M, Args);  // Start executing it...
 
   // Reset the current frame location to the top of stack
@@ -156,3 +229,20 @@ bool Interpreter::callMethod(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);
+  }
+}