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
22 // CommandTable - Build a lookup table for the commands available to the user...
23 static struct CommandTableElement {
27 inline bool operator<(const CommandTableElement &E) const {
28 return string(Name) < string(E.Name);
30 inline bool operator==(const string &S) const {
31 return string(Name) == S;
34 { "quit" , Quit }, { "q", Quit }, { "", Quit }, // Empty str = eof
35 { "help" , Help }, { "h", Help },
37 { "print" , Print }, { "p", Print },
40 { "backtrace", StackTrace }, { "bt", StackTrace }, { "where", StackTrace },
44 { "next" , Next }, { "n", Next },
45 { "step" , Step }, { "s", Step },
47 { "finish" , Finish },
50 { "break" , Break }, { "b", Break },
56 static CommandTableElement *CommandTableEnd =
57 CommandTable+sizeof(CommandTable)/sizeof(CommandTable[0]);
60 //===----------------------------------------------------------------------===//
61 // handleUserInput - Enter the input loop for the interpreter. This function
62 // returns when the user quits the interpreter.
64 void Interpreter::handleUserInput() {
65 bool UserQuit = false;
68 sort(CommandTable, CommandTableEnd);
70 // Print the instruction that we are stopped at...
71 printCurrentInstruction();
75 cout << "lli> " << flush;
78 CommandTableElement *E = find(CommandTable, CommandTableEnd, Command);
80 if (E == CommandTableEnd) {
81 cout << "Error: '" << Command << "' not recognized!\n";
86 case Quit: UserQuit = true; break;
91 case Flush: flushModule(); break;
101 case List: list(); break;
102 case StackTrace: printStackTrace(); break;
104 if (CurFrame > 0) --CurFrame;
105 else cout << "Error: Already at root of stack!\n";
108 if ((unsigned)CurFrame < ECStack.size()-1) ++CurFrame;
109 else cout << "Error: Already at bottom of stack!\n";
111 case Next: nextInstruction(); break;
112 case Step: stepInstruction(); break;
113 case Run: run(); break;
114 case Finish: finish(); break;
117 callMethod(Command); // Enter the specified method
118 finish(); // Run until it's complete
122 cout << "Command '" << Command << "' unimplemented!\n";
129 //===----------------------------------------------------------------------===//
130 // loadModule - Load a new module to execute...
132 void Interpreter::loadModule(const string &Filename) {
134 if (CurMod && !flushModule()) return; // Kill current execution
136 CurMod = ParseBytecodeFile(Filename, &ErrorMsg);
138 cout << "Error parsing '" << Filename << "': No module loaded: "
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: "
149 cerr << "Error loading runtime library '"+RuntimeLib+"': "
155 //===----------------------------------------------------------------------===//
156 // flushModule - Return true if the current program has been unloaded.
158 bool Interpreter::flushModule() {
160 cout << "Error flushing: No module loaded!\n";
164 if (!ECStack.empty()) {
165 // TODO: if use is not sure, return false
166 cout << "Killing current execution!\n";
177 //===----------------------------------------------------------------------===//
178 // setBreakpoint - Enable a breakpoint at the specified location
180 void Interpreter::setBreakpoint(const string &Name) {
181 Value *PickedVal = ChooseOneOption(Name, LookupMatchingNames(Name));
182 // TODO: Set a breakpoint on PickedVal
185 //===----------------------------------------------------------------------===//
186 // callMethod - Enter the specified method...
188 bool Interpreter::callMethod(const string &Name) {
189 vector<Value*> Options = LookupMatchingNames(Name);
191 for (unsigned i = 0; i < Options.size(); ++i) { // Remove nonmethod matches...
192 if (!isa<Method>(Options[i])) {
193 Options.erase(Options.begin()+i);
198 Value *PickedMeth = ChooseOneOption(Name, Options);
202 Method *M = cast<Method>(PickedMeth);
204 vector<GenericValue> Args;
205 // TODO, get args from user...
207 callMethod(M, Args); // Start executing it...
209 // Reset the current frame location to the top of stack
210 CurFrame = ECStack.size()-1;
215 static void *CreateArgv(const vector<string> &InputArgv) {
216 // Pointers are 64 bits...
217 uint64_t *Result = new uint64_t[InputArgv.size()+1];
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);
224 Result[i] = (uint64_t)Dest;
227 Result[InputArgv.size()] = 0;
232 // callMainMethod - This is a nasty gross hack that will dissapear when
233 // callMethod can parse command line options and stuff for us.
235 bool Interpreter::callMainMethod(const string &Name,
236 const vector<string> &InputArgv) {
237 vector<Value*> Options = LookupMatchingNames(Name);
239 for (unsigned i = 0; i < Options.size(); ++i) { // Remove nonmethod matches...
240 if (!isa<Method>(Options[i])) {
241 Options.erase(Options.begin()+i);
246 Value *PickedMeth = ChooseOneOption(Name, Options);
250 Method *M = cast<Method>(PickedMeth);
251 const MethodType *MT = M->getMethodType();
253 vector<GenericValue> Args;
254 switch (MT->getParamTypes().size()) {
256 cout << "Unknown number of arguments to synthesize for '" << Name << "'!\n";
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";
266 GenericValue GV; GV.PointerVal = (uint64_t)CreateArgv(InputArgv);
271 if (!MT->getParamTypes()[0]->isIntegral()) {
272 cout << "First argument of '" << Name << "' should be integral!\n";
275 GenericValue GV; GV.UIntVal = InputArgv.size();
276 Args.insert(Args.begin(), GV);
283 callMethod(M, Args); // Start executing it...
285 // Reset the current frame location to the top of stack
286 CurFrame = ECStack.size()-1;