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