1 //===-- UserInput.cpp - Interpreter Input Loop support --------------------===//
3 // This file implements the interpreter Input I/O loop.
5 //===----------------------------------------------------------------------===//
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"
16 Print, Info, List, StackTrace, Up, Down, // Inspection
17 Next, Step, Run, Finish, Call, // Control flow changes
18 Break, Watch, // Debugging
20 TraceOpt, ProfileOpt // Toggle features
23 // CommandTable - Build a lookup table for the commands available to the user...
24 static struct CommandTableElement {
28 inline bool operator<(const CommandTableElement &E) const {
29 return string(Name) < string(E.Name);
31 inline bool operator==(const string &S) const {
32 return string(Name) == S;
35 { "quit" , Quit }, { "q", Quit }, { "", Quit }, // Empty str = eof
36 { "help" , Help }, { "h", Help },
38 { "print" , Print }, { "p", Print },
41 { "backtrace", StackTrace }, { "bt", StackTrace }, { "where", StackTrace },
45 { "next" , Next }, { "n", Next },
46 { "step" , Step }, { "s", Step },
48 { "finish" , Finish },
51 { "break" , Break }, { "b", Break },
57 { "trace" , TraceOpt },
58 { "profile" , ProfileOpt },
60 static CommandTableElement *CommandTableEnd =
61 CommandTable+sizeof(CommandTable)/sizeof(CommandTable[0]);
64 //===----------------------------------------------------------------------===//
65 // handleUserInput - Enter the input loop for the interpreter. This function
66 // returns when the user quits the interpreter.
68 void Interpreter::handleUserInput() {
69 bool UserQuit = false;
72 sort(CommandTable, CommandTableEnd);
74 // Print the instruction that we are stopped at...
75 printCurrentInstruction();
79 cout << "lli> " << flush;
82 CommandTableElement *E = find(CommandTable, CommandTableEnd, Command);
84 if (E == CommandTableEnd) {
85 cout << "Error: '" << Command << "' not recognized!\n";
90 case Quit: UserQuit = true; break;
95 case Flush: flushModule(); break;
105 case List: list(); break;
106 case StackTrace: printStackTrace(); break;
108 if (CurFrame > 0) { --CurFrame; printStackFrame(); }
109 else cout << "Error: Already at root of stack!\n";
112 if ((unsigned)CurFrame < ECStack.size()-1) {
116 cout << "Error: Already at bottom of stack!\n";
118 case Next: nextInstruction(); break;
119 case Step: stepInstruction(); break;
120 case Run: run(); break;
121 case Finish: finish(); break;
124 callMethod(Command); // Enter the specified method
125 finish(); // Run until it's complete
130 cout << "Tracing " << (Trace ? "enabled\n" : "disabled\n");
135 cout << "Profiling " << (Trace ? "enabled\n" : "disabled\n");
139 cout << "Command '" << Command << "' unimplemented!\n";
146 //===----------------------------------------------------------------------===//
147 // loadModule - Load a new module to execute...
149 void Interpreter::loadModule(const string &Filename) {
151 if (CurMod && !flushModule()) return; // Kill current execution
153 CurMod = ParseBytecodeFile(Filename, &ErrorMsg);
155 cout << "Error parsing '" << Filename << "': No module loaded: "
159 CW.setModule(CurMod); // Update Writer
161 string RuntimeLib = getCurrentExecutablePath();
162 if (!RuntimeLib.empty()) RuntimeLib += "/";
163 RuntimeLib += "RuntimeLib.bc";
165 if (Module *SupportLib = ParseBytecodeFile(RuntimeLib, &ErrorMsg)) {
166 if (LinkModules(CurMod, SupportLib, &ErrorMsg))
167 cerr << "Error Linking runtime library into current module: "
170 cerr << "Error loading runtime library '"+RuntimeLib+"': "
176 //===----------------------------------------------------------------------===//
177 // flushModule - Return true if the current program has been unloaded.
179 bool Interpreter::flushModule() {
181 cout << "Error flushing: No module loaded!\n";
185 if (!ECStack.empty()) {
186 // TODO: if use is not sure, return false
187 cout << "Killing current execution!\n";
199 //===----------------------------------------------------------------------===//
200 // setBreakpoint - Enable a breakpoint at the specified location
202 void Interpreter::setBreakpoint(const string &Name) {
203 Value *PickedVal = ChooseOneOption(Name, LookupMatchingNames(Name));
204 // TODO: Set a breakpoint on PickedVal
207 //===----------------------------------------------------------------------===//
208 // callMethod - Enter the specified method...
210 bool Interpreter::callMethod(const string &Name) {
211 vector<Value*> Options = LookupMatchingNames(Name);
213 for (unsigned i = 0; i < Options.size(); ++i) { // Remove nonmethod matches...
214 if (!isa<Method>(Options[i])) {
215 Options.erase(Options.begin()+i);
220 Value *PickedMeth = ChooseOneOption(Name, Options);
224 Method *M = cast<Method>(PickedMeth);
226 vector<GenericValue> Args;
227 // TODO, get args from user...
229 callMethod(M, Args); // Start executing it...
231 // Reset the current frame location to the top of stack
232 CurFrame = ECStack.size()-1;
237 static void *CreateArgv(const vector<string> &InputArgv) {
238 // Pointers are 64 bits...
239 uint64_t *Result = new uint64_t[InputArgv.size()+1];
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);
246 Result[i] = (uint64_t)Dest;
249 Result[InputArgv.size()] = 0;
254 // callMainMethod - This is a nasty gross hack that will dissapear when
255 // callMethod can parse command line options and stuff for us.
257 bool Interpreter::callMainMethod(const string &Name,
258 const vector<string> &InputArgv) {
259 vector<Value*> Options = LookupMatchingNames(Name);
261 for (unsigned i = 0; i < Options.size(); ++i) { // Remove nonmethod matches...
262 if (!isa<Method>(Options[i])) {
263 Options.erase(Options.begin()+i);
268 Value *PickedMeth = ChooseOneOption(Name, Options);
272 Method *M = cast<Method>(PickedMeth);
273 const MethodType *MT = M->getMethodType();
275 vector<GenericValue> Args;
276 switch (MT->getParamTypes().size()) {
278 cout << "Unknown number of arguments to synthesize for '" << Name << "'!\n";
281 PointerType *SPP = PointerType::get(PointerType::get(Type::SByteTy));
282 if (MT->getParamTypes()[1] != SPP) {
283 CW << "Second argument of '" << Name << "' should have type: '"
288 GenericValue GV; GV.PointerVal = (uint64_t)CreateArgv(InputArgv);
293 if (!MT->getParamTypes()[0]->isIntegral()) {
294 cout << "First argument of '" << Name << "' should be integral!\n";
297 GenericValue GV; GV.UIntVal = InputArgv.size();
298 Args.insert(Args.begin(), GV);
305 callMethod(M, Args); // Start executing it...
307 // Reset the current frame location to the top of stack
308 CurFrame = ECStack.size()-1;
315 void Interpreter::list() {
317 cout << "Error: No program executing!\n";
319 CW << ECStack[CurFrame].CurMethod; // Just print the method out...
322 void Interpreter::printStackTrace() {
323 if (ECStack.empty()) cout << "No program executing!\n";
325 for (unsigned i = 0; i < ECStack.size(); ++i) {
326 printStackFrame((int)i);