blob: 950e6a572732c3aac5e816d58e889ad6499eb4dd [file] [log] [blame]
Chris Lattnerbd199fb2002-12-24 00:01:05 +00001//===- Interpreter.cpp - Top-Level LLVM Interpreter Implementation --------===//
2//
3// This file implements the top-level functionality for the LLVM interpreter.
4// This interpreter is designed to be a very simple, portable, inefficient
5// interpreter.
6//
7//===----------------------------------------------------------------------===//
8
9#include "Interpreter.h"
Chris Lattner39c07262003-08-24 19:50:53 +000010#include "llvm/Module.h"
Chris Lattnerbd199fb2002-12-24 00:01:05 +000011
12/// createInterpreter - Create a new interpreter object. This can never fail.
13///
14ExecutionEngine *ExecutionEngine::createInterpreter(Module *M,
Chris Lattnerbd199fb2002-12-24 00:01:05 +000015 bool DebugMode,
16 bool TraceMode) {
Chris Lattner39c07262003-08-24 19:50:53 +000017 bool isLittleEndian;
18 switch (M->getEndianness()) {
19 case Module::LittleEndian: isLittleEndian = true; break;
20 case Module::BigEndian: isLittleEndian = false; break;
21 case Module::AnyPointerSize:
22 int Test = 0;
23 *(char*)&Test = 1; // Return true if the host is little endian
24 isLittleEndian = (Test == 1);
25 break;
26 }
27
28 bool isLongPointer;
29 switch (M->getPointerSize()) {
30 case Module::Pointer32: isLongPointer = false; break;
31 case Module::Pointer64: isLongPointer = true; break;
32 case Module::AnyPointerSize:
33 isLongPointer = (sizeof(void*) == 8); // Follow host
34 break;
35 }
36
37 return new Interpreter(M, isLittleEndian, isLongPointer, DebugMode,TraceMode);
Chris Lattnerbd199fb2002-12-24 00:01:05 +000038}
39
40//===----------------------------------------------------------------------===//
41// Interpreter ctor - Initialize stuff
42//
Chris Lattner39c07262003-08-24 19:50:53 +000043Interpreter::Interpreter(Module *M, bool isLittleEndian, bool isLongPointer,
44 bool DebugMode, bool TraceMode)
Chris Lattnerbd199fb2002-12-24 00:01:05 +000045 : ExecutionEngine(M), ExitCode(0), Debug(DebugMode), Trace(TraceMode),
Chris Lattner39c07262003-08-24 19:50:53 +000046 CurFrame(-1), TD("lli", isLittleEndian, isLongPointer ? 8 : 4,
47 isLongPointer ? 8 : 4, isLongPointer ? 8 : 4) {
Chris Lattnerbd199fb2002-12-24 00:01:05 +000048
49 setTargetData(TD);
50 // Initialize the "backend"
51 initializeExecutionEngine();
Chris Lattnerda82ed52003-05-08 16:18:31 +000052 initializeExternalFunctions();
Chris Lattnerbd199fb2002-12-24 00:01:05 +000053 CW.setModule(M); // Update Writer
Chris Lattner56adf152003-05-12 02:14:34 +000054 emitGlobals();
Chris Lattnerbd199fb2002-12-24 00:01:05 +000055}
56
57/// run - Start execution with the specified function and arguments.
58///
59int Interpreter::run(const std::string &MainFunction,
John Criswell69582b32003-08-21 21:12:30 +000060 const std::vector<std::string> &Args,
61 const char ** envp) {
Chris Lattnerbd199fb2002-12-24 00:01:05 +000062 // Start interpreter into the main function...
63 //
Chris Lattnerda82ed52003-05-08 16:18:31 +000064 if (!callMainFunction(MainFunction, Args) && !Debug) {
Chris Lattnerbd199fb2002-12-24 00:01:05 +000065 // If not in debug mode and if the call succeeded, run the code now...
66 run();
67 }
68
Chris Lattner44edb6b2003-05-14 14:21:30 +000069 do {
70 // If debug mode, allow the user to interact... also, if the user pressed
71 // ctrl-c or execution hit an error, enter the event loop...
72 if (Debug || isStopped())
73 handleUserInput();
74
75 // If the program has exited, run atexit handlers...
76 if (ECStack.empty() && !AtExitHandlers.empty()) {
77 callFunction(AtExitHandlers.back(), std::vector<GenericValue>());
78 AtExitHandlers.pop_back();
79 run();
80 }
81 } while (!ECStack.empty());
82
83 PerformExitStuff();
Chris Lattnerbd199fb2002-12-24 00:01:05 +000084 return ExitCode;
85}
86