blob: 6f540e2d1a8a3d0a161c22e6b0b31aaf42e5cde0 [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
Brian Gaeke82d82772003-09-03 20:34:19 +000012/// create - Create a new interpreter object. This can never fail.
Chris Lattnerbd199fb2002-12-24 00:01:05 +000013///
Brian Gaeke82d82772003-09-03 20:34:19 +000014ExecutionEngine *Interpreter::create(Module *M, bool DebugMode, bool TraceMode){
Chris Lattner39c07262003-08-24 19:50:53 +000015 bool isLittleEndian;
16 switch (M->getEndianness()) {
17 case Module::LittleEndian: isLittleEndian = true; break;
18 case Module::BigEndian: isLittleEndian = false; break;
19 case Module::AnyPointerSize:
20 int Test = 0;
21 *(char*)&Test = 1; // Return true if the host is little endian
22 isLittleEndian = (Test == 1);
23 break;
24 }
25
26 bool isLongPointer;
27 switch (M->getPointerSize()) {
28 case Module::Pointer32: isLongPointer = false; break;
29 case Module::Pointer64: isLongPointer = true; break;
30 case Module::AnyPointerSize:
31 isLongPointer = (sizeof(void*) == 8); // Follow host
32 break;
33 }
34
35 return new Interpreter(M, isLittleEndian, isLongPointer, DebugMode,TraceMode);
Chris Lattnerbd199fb2002-12-24 00:01:05 +000036}
37
38//===----------------------------------------------------------------------===//
39// Interpreter ctor - Initialize stuff
40//
Chris Lattner39c07262003-08-24 19:50:53 +000041Interpreter::Interpreter(Module *M, bool isLittleEndian, bool isLongPointer,
42 bool DebugMode, bool TraceMode)
Chris Lattnerbd199fb2002-12-24 00:01:05 +000043 : ExecutionEngine(M), ExitCode(0), Debug(DebugMode), Trace(TraceMode),
Chris Lattner39c07262003-08-24 19:50:53 +000044 CurFrame(-1), TD("lli", isLittleEndian, isLongPointer ? 8 : 4,
45 isLongPointer ? 8 : 4, isLongPointer ? 8 : 4) {
Chris Lattnerbd199fb2002-12-24 00:01:05 +000046
47 setTargetData(TD);
48 // Initialize the "backend"
49 initializeExecutionEngine();
Chris Lattnerda82ed52003-05-08 16:18:31 +000050 initializeExternalFunctions();
Chris Lattnerbd199fb2002-12-24 00:01:05 +000051 CW.setModule(M); // Update Writer
Chris Lattner56adf152003-05-12 02:14:34 +000052 emitGlobals();
Chris Lattnerbd199fb2002-12-24 00:01:05 +000053}
54
55/// run - Start execution with the specified function and arguments.
56///
57int Interpreter::run(const std::string &MainFunction,
John Criswell69582b32003-08-21 21:12:30 +000058 const std::vector<std::string> &Args,
59 const char ** envp) {
Chris Lattnerbd199fb2002-12-24 00:01:05 +000060 // Start interpreter into the main function...
61 //
Chris Lattnerda82ed52003-05-08 16:18:31 +000062 if (!callMainFunction(MainFunction, Args) && !Debug) {
Chris Lattnerbd199fb2002-12-24 00:01:05 +000063 // If not in debug mode and if the call succeeded, run the code now...
64 run();
65 }
66
Chris Lattner44edb6b2003-05-14 14:21:30 +000067 do {
68 // If debug mode, allow the user to interact... also, if the user pressed
69 // ctrl-c or execution hit an error, enter the event loop...
70 if (Debug || isStopped())
71 handleUserInput();
72
73 // If the program has exited, run atexit handlers...
74 if (ECStack.empty() && !AtExitHandlers.empty()) {
75 callFunction(AtExitHandlers.back(), std::vector<GenericValue>());
76 AtExitHandlers.pop_back();
77 run();
78 }
79 } while (!ECStack.empty());
80
81 PerformExitStuff();
Chris Lattnerbd199fb2002-12-24 00:01:05 +000082 return ExitCode;
83}
84