018e6f7c0f40d69b8a44612274a0b7195293186e
[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/Transforms/Linker.h"
11 #include <algorithm>
12 using std::string;
13 using std::cout;
14 using std::cin;
15
16 enum CommandID {
17   Quit, Help,                                 // Basics
18   Print, Info, List, StackTrace, Up, Down,    // Inspection
19   Next, Step, Run, Finish, Call,              // Control flow changes
20   Break, Watch,                               // Debugging
21   Load, Flush,
22   TraceOpt, ProfileOpt                              // Toggle features
23 };
24
25 // CommandTable - Build a lookup table for the commands available to the user...
26 static struct CommandTableElement {
27   const char *Name;
28   enum CommandID CID;
29
30   inline bool operator<(const CommandTableElement &E) const {
31     return string(Name) < string(E.Name);
32   }
33   inline bool operator==(const string &S) const { 
34     return string(Name) == S;
35   }
36 } CommandTable[] = {
37   { "quit"     , Quit       }, { "q", Quit }, { "", Quit }, // Empty str = eof
38   { "help"     , Help       }, { "h", Help },
39
40   { "print"    , Print      }, { "p", Print },
41   { "list"     , List       },
42   { "info"     , Info       },
43   { "backtrace", StackTrace }, { "bt", StackTrace }, { "where", StackTrace },
44   { "up"       , Up         },
45   { "down"     , Down       },
46
47   { "next"     , Next       }, { "n", Next },
48   { "step"     , Step       }, { "s", Step },
49   { "run"      , Run        },
50   { "finish"   , Finish     },
51   { "call"     , Call       },
52
53   { "break"    , Break      }, { "b", Break },
54   { "watch"    , Watch      },
55
56   { "load"     , Load       },
57   { "flush"    , Flush      },
58
59   { "trace"    , TraceOpt   },
60   { "profile"  , ProfileOpt },
61 };
62 static CommandTableElement *CommandTableEnd = 
63    CommandTable+sizeof(CommandTable)/sizeof(CommandTable[0]);
64
65
66 //===----------------------------------------------------------------------===//
67 // handleUserInput - Enter the input loop for the interpreter.  This function
68 // returns when the user quits the interpreter.
69 //
70 void Interpreter::handleUserInput() {
71   bool UserQuit = false;
72
73   // Sort the table...
74   std::sort(CommandTable, CommandTableEnd);
75
76   // Print the instruction that we are stopped at...
77   printCurrentInstruction();
78
79   do {
80     string Command;
81     cout << "lli> " << std::flush;
82     cin >> Command;
83
84     CommandTableElement *E = find(CommandTable, CommandTableEnd, Command);
85
86     if (E == CommandTableEnd) {
87       cout << "Error: '" << Command << "' not recognized!\n";
88       continue;
89     }
90
91     switch (E->CID) {
92     case Quit:       UserQuit = true;   break;
93     case Load:
94       cin >> Command;
95       loadModule(Command);
96       break;
97     case Flush: flushModule(); break;
98     case Print:
99       cin >> Command;
100       print(Command);
101       break;
102     case Info:
103       cin >> Command;
104       infoValue(Command);
105       break;
106      
107     case List:       list();            break;
108     case StackTrace: printStackTrace(); break;
109     case Up: 
110       if (CurFrame > 0) { --CurFrame; printStackFrame(); }
111       else cout << "Error: Already at root of stack!\n";
112       break;
113     case Down:
114       if ((unsigned)CurFrame < ECStack.size()-1) {
115         ++CurFrame;
116         printStackFrame();
117       } else
118         cout << "Error: Already at bottom of stack!\n";
119       break;
120     case Next:       nextInstruction(); break;
121     case Step:       stepInstruction(); break;
122     case Run:        run();             break;
123     case Finish:     finish();          break;
124     case Call:
125       cin >> Command;
126       callMethod(Command);    // Enter the specified function
127       finish();               // Run until it's complete
128       break;
129
130     case TraceOpt:
131       Trace = !Trace;
132       cout << "Tracing " << (Trace ? "enabled\n" : "disabled\n");
133       break;
134
135     case ProfileOpt:
136       Profile = !Profile;
137       cout << "Profiling " << (Trace ? "enabled\n" : "disabled\n");
138       break;
139
140     default:
141       cout << "Command '" << Command << "' unimplemented!\n";
142       break;
143     }
144
145   } while (!UserQuit);
146 }
147
148 //===----------------------------------------------------------------------===//
149 // loadModule - Load a new module to execute...
150 //
151 void Interpreter::loadModule(const string &Filename) {
152   string ErrorMsg;
153   if (CurMod && !flushModule()) return;  // Kill current execution
154
155   CurMod = ParseBytecodeFile(Filename, &ErrorMsg);
156   if (CurMod == 0) {
157     cout << "Error parsing '" << Filename << "': No module loaded: "
158          << ErrorMsg << "\n";
159     return;
160   }
161   CW.setModule(CurMod);  // Update Writer
162
163 #if 0
164   string RuntimeLib = getCurrentExecutablePath();
165   if (!RuntimeLib.empty()) RuntimeLib += "/";
166   RuntimeLib += "RuntimeLib.bc";
167
168   if (Module *SupportLib = ParseBytecodeFile(RuntimeLib, &ErrorMsg)) {
169     if (LinkModules(CurMod, SupportLib, &ErrorMsg))
170       std::cerr << "Error Linking runtime library into current module: "
171                 << ErrorMsg << "\n";
172   } else {
173     std::cerr << "Error loading runtime library '"+RuntimeLib+"': "
174               << ErrorMsg << "\n";
175   }
176 #endif
177 }
178
179
180 //===----------------------------------------------------------------------===//
181 // flushModule - Return true if the current program has been unloaded.
182 //
183 bool Interpreter::flushModule() {
184   if (CurMod == 0) {
185     cout << "Error flushing: No module loaded!\n";
186     return false;
187   }
188
189   if (!ECStack.empty()) {
190     // TODO: if use is not sure, return false
191     cout << "Killing current execution!\n";
192     ECStack.clear();
193     CurFrame = -1;
194   }
195
196   CW.setModule(0);
197   delete CurMod;
198   CurMod = 0;
199   ExitCode = 0;
200   return true;
201 }
202
203 //===----------------------------------------------------------------------===//
204 // setBreakpoint - Enable a breakpoint at the specified location
205 //
206 void Interpreter::setBreakpoint(const string &Name) {
207   Value *PickedVal = ChooseOneOption(Name, LookupMatchingNames(Name));
208   // TODO: Set a breakpoint on PickedVal
209 }
210
211 //===----------------------------------------------------------------------===//
212 // callMethod - Enter the specified method...
213 //
214 bool Interpreter::callMethod(const string &Name) {
215   std::vector<Value*> Options = LookupMatchingNames(Name);
216
217   for (unsigned i = 0; i < Options.size(); ++i) { // Remove non-fn matches...
218     if (!isa<Function>(Options[i])) {
219       Options.erase(Options.begin()+i);
220       --i;
221     }
222   }
223
224   Value *PickedMeth = ChooseOneOption(Name, Options);
225   if (PickedMeth == 0)
226     return true;
227
228   Function *F = cast<Function>(PickedMeth);
229
230   std::vector<GenericValue> Args;
231   // TODO, get args from user...
232
233   callMethod(F, Args);  // Start executing it...
234
235   // Reset the current frame location to the top of stack
236   CurFrame = ECStack.size()-1;
237
238   return false;
239 }
240
241 static void *CreateArgv(const std::vector<string> &InputArgv) {
242   // Pointers are 64 bits...
243   uint64_t *Result = new PointerTy[InputArgv.size()+1];
244
245   for (unsigned i = 0; i < InputArgv.size(); ++i) {
246     unsigned Size = InputArgv[i].size()+1;
247     char *Dest = new char[Size];
248     copy(InputArgv[i].begin(), InputArgv[i].end(), Dest);
249     Dest[Size-1] = 0;
250     Result[i] = (PointerTy)Dest;
251   }
252
253   Result[InputArgv.size()] = 0;
254   return Result;
255 }
256
257
258 // callMainMethod - This is a nasty gross hack that will dissapear when
259 // callMethod can parse command line options and stuff for us.
260 //
261 bool Interpreter::callMainMethod(const string &Name,
262                                  const std::vector<string> &InputArgv) {
263   std::vector<Value*> Options = LookupMatchingNames(Name);
264
265   for (unsigned i = 0; i < Options.size(); ++i) { // Remove non-fn matches...
266     if (!isa<Function>(Options[i])) {
267       Options.erase(Options.begin()+i);
268       --i;
269     }
270   }
271
272   Value *PickedMeth = ChooseOneOption(Name, Options);
273   if (PickedMeth == 0)
274     return true;
275
276   Function *M = cast<Function>(PickedMeth);
277   const FunctionType *MT = M->getFunctionType();
278
279   std::vector<GenericValue> Args;
280   switch (MT->getParamTypes().size()) {
281   default:
282     cout << "Unknown number of arguments to synthesize for '" << Name << "'!\n";
283     return true;
284   case 2: {
285     PointerType *SPP = PointerType::get(PointerType::get(Type::SByteTy));
286     if (MT->getParamTypes()[1] != SPP) {
287       CW << "Second argument of '" << Name << "' should have type: '"
288          << SPP << "'!\n";
289       return true;
290     }
291
292     GenericValue GV; GV.PointerVal = (uint64_t)CreateArgv(InputArgv);
293     Args.push_back(GV);
294   }
295     // fallthrough
296   case 1:
297     if (!MT->getParamTypes()[0]->isIntegral()) {
298       cout << "First argument of '" << Name << "' should be integral!\n";
299       return true;
300     } else {
301       GenericValue GV; GV.UIntVal = InputArgv.size();
302       Args.insert(Args.begin(), GV);
303     }
304     // fallthrough
305   case 0:
306     break;
307   }
308
309   callMethod(M, Args);  // Start executing it...
310
311   // Reset the current frame location to the top of stack
312   CurFrame = ECStack.size()-1;
313
314   return false;
315 }
316
317
318
319 void Interpreter::list() {
320   if (ECStack.empty())
321     cout << "Error: No program executing!\n";
322   else
323     CW << ECStack[CurFrame].CurMethod;   // Just print the function out...
324 }
325
326 void Interpreter::printStackTrace() {
327   if (ECStack.empty()) cout << "No program executing!\n";
328
329   for (unsigned i = 0; i < ECStack.size(); ++i) {
330     printStackFrame((int)i);
331   }
332 }