3f4493d19be8f30d031a79318f821820bc716966
[oota-llvm.git] / lib / ExecutionEngine / Interpreter / UserInput.cpp
1 //===-- UserInput.cpp - Interpreter Input Loop support --------------------===//
2 // 
3 //  This file implements the interpreter Input I/O loop.
4 //
5 //===----------------------------------------------------------------------===//
6
7 #include "Interpreter.h"
8 #include "llvm/Bytecode/Reader.h"
9 #include "llvm/DerivedTypes.h"
10 #include "llvm/Function.h"
11 #include "llvm/Transforms/Utils/Linker.h"
12 #include <algorithm>
13
14 enum CommandID {
15   Quit, Help,                                 // Basics
16   Print, Info, List, StackTrace, Up, Down,    // Inspection
17   Next, Step, Run, Finish, Call,              // Control flow changes
18   Break, Watch,                               // Debugging
19   Flush,
20   TraceOpt,                                   // Toggle features
21 };
22
23 // CommandTable - Build a lookup table for the commands available to the user...
24 static struct CommandTableElement {
25   const char *Name;
26   enum CommandID CID;
27
28   inline bool operator<(const CommandTableElement &E) const {
29     return std::string(Name) < std::string(E.Name);
30   }
31   inline bool operator==(const std::string &S) const { 
32     return std::string(Name) == S;
33   }
34 } CommandTable[] = {
35   { "quit"     , Quit       }, { "q", Quit }, { "", Quit }, // Empty str = eof
36   { "help"     , Help       }, { "h", Help },
37
38   { "print"    , Print      }, { "p", Print },
39   { "list"     , List       },
40   { "info"     , Info       },
41   { "backtrace", StackTrace }, { "bt", StackTrace }, { "where", StackTrace },
42   { "up"       , Up         },
43   { "down"     , Down       },
44
45   { "next"     , Next       }, { "n", Next },
46   { "step"     , Step       }, { "s", Step },
47   { "run"      , Run        },
48   { "finish"   , Finish     },
49   { "call"     , Call       },
50
51   { "break"    , Break      }, { "b", Break },
52   { "watch"    , Watch      },
53
54   { "flush"    , Flush      },
55
56   { "trace"    , TraceOpt   },
57 };
58 static CommandTableElement *CommandTableEnd = 
59    CommandTable+sizeof(CommandTable)/sizeof(CommandTable[0]);
60
61
62 //===----------------------------------------------------------------------===//
63 // handleUserInput - Enter the input loop for the interpreter.  This function
64 // returns when the user quits the interpreter.
65 //
66 void Interpreter::handleUserInput() {
67   bool UserQuit = false;
68
69   // Sort the table...
70   std::sort(CommandTable, CommandTableEnd);
71
72   // Print the instruction that we are stopped at...
73   printCurrentInstruction();
74
75   do {
76     std::string Command;
77     std::cout << "lli> " << std::flush;
78     std::cin >> Command;
79
80     CommandTableElement *E = find(CommandTable, CommandTableEnd, Command);
81
82     if (E == CommandTableEnd) {
83       std::cout << "Error: '" << Command << "' not recognized!\n";
84       continue;
85     }
86
87     switch (E->CID) {
88     case Quit:       UserQuit = true;   break;
89     case Print:
90       std::cin >> Command;
91       print(Command);
92       break;
93     case Info:
94       std::cin >> Command;
95       infoValue(Command);
96       break;
97      
98     case List:       list();            break;
99     case StackTrace: printStackTrace(); break;
100     case Up: 
101       if (CurFrame > 0) { --CurFrame; printStackFrame(); }
102       else std::cout << "Error: Already at root of stack!\n";
103       break;
104     case Down:
105       if ((unsigned)CurFrame < ECStack.size()-1) {
106         ++CurFrame;
107         printStackFrame();
108       } else
109         std::cout << "Error: Already at bottom of stack!\n";
110       break;
111     case Next:       nextInstruction(); break;
112     case Step:       stepInstruction(); break;
113     case Run:        run();             break;
114     case Finish:     finish();          break;
115     case Call:
116       std::cin >> Command;
117       callFunction(Command);    // Enter the specified function
118       finish();                 // Run until it's complete
119       break;
120
121     case TraceOpt:
122       Trace = !Trace;
123       std::cout << "Tracing " << (Trace ? "enabled\n" : "disabled\n");
124       break;
125
126     default:
127       std::cout << "Command '" << Command << "' unimplemented!\n";
128       break;
129     }
130
131   } while (!UserQuit);
132   AtExitHandlers.clear();
133 }
134
135 //===----------------------------------------------------------------------===//
136 // setBreakpoint - Enable a breakpoint at the specified location
137 //
138 void Interpreter::setBreakpoint(const std::string &Name) {
139   Value *PickedVal = ChooseOneOption(Name, LookupMatchingNames(Name));
140   // TODO: Set a breakpoint on PickedVal
141 }
142
143 //===----------------------------------------------------------------------===//
144 // callFunction - Enter the specified function...
145 //
146 bool Interpreter::callFunction(const std::string &Name) {
147   std::vector<Value*> Options = LookupMatchingNames(Name);
148
149   for (unsigned i = 0; i < Options.size(); ++i) { // Remove non-fn matches...
150     if (!isa<Function>(Options[i])) {
151       Options.erase(Options.begin()+i);
152       --i;
153     }
154   }
155
156   Value *PickedMeth = ChooseOneOption(Name, Options);
157   if (PickedMeth == 0)
158     return true;
159
160   Function *F = cast<Function>(PickedMeth);
161
162   std::vector<GenericValue> Args;
163   // TODO, get args from user...
164
165   callFunction(F, Args);  // Start executing it...
166
167   // Reset the current frame location to the top of stack
168   CurFrame = ECStack.size()-1;
169
170   return false;
171 }
172
173 // callMainFunction - This is a nasty gross hack that will dissapear when
174 // callFunction can parse command line options and stuff for us.
175 //
176 bool Interpreter::callMainFunction(const std::string &Name,
177                                    const std::vector<std::string> &InputArgv) {
178   std::vector<Value*> Options = LookupMatchingNames(Name);
179
180   for (unsigned i = 0; i < Options.size(); ++i) { // Remove non-fn matches...
181     if (!isa<Function>(Options[i])) {
182       Options.erase(Options.begin()+i);
183       --i;
184     }
185   }
186
187   Value *PickedMeth = ChooseOneOption(Name, Options);
188   if (PickedMeth == 0)
189     return true;
190
191   Function *M = cast<Function>(PickedMeth);
192   const FunctionType *MT = M->getFunctionType();
193
194   std::vector<GenericValue> Args;
195   switch (MT->getParamTypes().size()) {
196   default:
197     std::cout << "Unknown number of arguments to synthesize for '" << Name
198               << "'!\n";
199     return true;
200   case 2: {
201     PointerType *SPP = PointerType::get(PointerType::get(Type::SByteTy));
202     if (MT->getParamTypes()[1] != SPP) {
203       CW << "Second argument of '" << Name << "' should have type: '"
204          << SPP << "'!\n";
205       return true;
206     }
207
208     Args.push_back(PTOGV(CreateArgv(InputArgv)));
209   }
210     // fallthrough
211   case 1:
212     if (!MT->getParamTypes()[0]->isInteger()) {
213       std::cout << "First argument of '" << Name << "' should be an integer!\n";
214       return true;
215     } else {
216       GenericValue GV; GV.UIntVal = InputArgv.size();
217       Args.insert(Args.begin(), GV);
218     }
219     // fallthrough
220   case 0:
221     break;
222   }
223
224   callFunction(M, Args);  // Start executing it...
225
226   // Reset the current frame location to the top of stack
227   CurFrame = ECStack.size()-1;
228
229   return false;
230 }
231
232
233
234 void Interpreter::list() {
235   if (ECStack.empty())
236     std::cout << "Error: No program executing!\n";
237   else
238     CW << ECStack[CurFrame].CurFunction;   // Just print the function out...
239 }
240
241 void Interpreter::printStackTrace() {
242   if (ECStack.empty()) std::cout << "No program executing!\n";
243
244   for (unsigned i = 0; i < ECStack.size(); ++i) {
245     printStackFrame((int)i);
246   }
247 }