Add support for isnan
[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/Utils/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 // callMainMethod - This is a nasty gross hack that will dissapear when
242 // callMethod can parse command line options and stuff for us.
243 //
244 bool Interpreter::callMainMethod(const string &Name,
245                                  const std::vector<string> &InputArgv) {
246   std::vector<Value*> Options = LookupMatchingNames(Name);
247
248   for (unsigned i = 0; i < Options.size(); ++i) { // Remove non-fn matches...
249     if (!isa<Function>(Options[i])) {
250       Options.erase(Options.begin()+i);
251       --i;
252     }
253   }
254
255   Value *PickedMeth = ChooseOneOption(Name, Options);
256   if (PickedMeth == 0)
257     return true;
258
259   Function *M = cast<Function>(PickedMeth);
260   const FunctionType *MT = M->getFunctionType();
261
262   std::vector<GenericValue> Args;
263   switch (MT->getParamTypes().size()) {
264   default:
265     cout << "Unknown number of arguments to synthesize for '" << Name << "'!\n";
266     return true;
267   case 2: {
268     PointerType *SPP = PointerType::get(PointerType::get(Type::SByteTy));
269     if (MT->getParamTypes()[1] != SPP) {
270       CW << "Second argument of '" << Name << "' should have type: '"
271          << SPP << "'!\n";
272       return true;
273     }
274
275     Args.push_back(CreateArgv(InputArgv));
276   }
277     // fallthrough
278   case 1:
279     if (!MT->getParamTypes()[0]->isInteger()) {
280       cout << "First argument of '" << Name << "' should be an integer!\n";
281       return true;
282     } else {
283       GenericValue GV; GV.UIntVal = InputArgv.size();
284       Args.insert(Args.begin(), GV);
285     }
286     // fallthrough
287   case 0:
288     break;
289   }
290
291   callMethod(M, Args);  // Start executing it...
292
293   // Reset the current frame location to the top of stack
294   CurFrame = ECStack.size()-1;
295
296   return false;
297 }
298
299
300
301 void Interpreter::list() {
302   if (ECStack.empty())
303     cout << "Error: No program executing!\n";
304   else
305     CW << ECStack[CurFrame].CurMethod;   // Just print the function out...
306 }
307
308 void Interpreter::printStackTrace() {
309   if (ECStack.empty()) cout << "No program executing!\n";
310
311   for (unsigned i = 0; i < ECStack.size(); ++i) {
312     printStackFrame((int)i);
313   }
314 }