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