Interpreter.cpp revision 82d8277ad5862b54341808812bb4016e52347060
1bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner//===- Interpreter.cpp - Top-Level LLVM Interpreter Implementation --------===//
2bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner//
3bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner// This file implements the top-level functionality for the LLVM interpreter.
4bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner// This interpreter is designed to be a very simple, portable, inefficient
5bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner// interpreter.
6bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner//
7bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner//===----------------------------------------------------------------------===//
8bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner
9bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner#include "Interpreter.h"
1039c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner#include "llvm/Module.h"
11bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner
1282d8277ad5862b54341808812bb4016e52347060Brian Gaeke/// create - Create a new interpreter object.  This can never fail.
13bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner///
1482d8277ad5862b54341808812bb4016e52347060Brian GaekeExecutionEngine *Interpreter::create(Module *M, bool DebugMode, bool TraceMode){
1539c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner  bool isLittleEndian;
1639c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner  switch (M->getEndianness()) {
1739c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner  case Module::LittleEndian: isLittleEndian = true; break;
1839c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner  case Module::BigEndian:    isLittleEndian = false; break;
1939c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner  case Module::AnyPointerSize:
2039c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner    int Test = 0;
2139c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner    *(char*)&Test = 1;    // Return true if the host is little endian
2239c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner    isLittleEndian = (Test == 1);
2339c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner    break;
2439c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner  }
2539c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner
2639c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner  bool isLongPointer;
2739c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner  switch (M->getPointerSize()) {
2839c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner  case Module::Pointer32: isLongPointer = false; break;
2939c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner  case Module::Pointer64: isLongPointer = true; break;
3039c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner  case Module::AnyPointerSize:
3139c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner    isLongPointer = (sizeof(void*) == 8);  // Follow host
3239c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner    break;
3339c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner  }
3439c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner
3539c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner  return new Interpreter(M, isLittleEndian, isLongPointer, DebugMode,TraceMode);
36bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner}
37bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner
38bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner//===----------------------------------------------------------------------===//
39bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner// Interpreter ctor - Initialize stuff
40bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner//
4139c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris LattnerInterpreter::Interpreter(Module *M, bool isLittleEndian, bool isLongPointer,
4239c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner                         bool DebugMode, bool TraceMode)
43bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner  : ExecutionEngine(M), ExitCode(0), Debug(DebugMode), Trace(TraceMode),
4439c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner    CurFrame(-1), TD("lli", isLittleEndian, isLongPointer ? 8 : 4,
4539c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner                     isLongPointer ? 8 : 4, isLongPointer ? 8 : 4) {
46bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner
47bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner  setTargetData(TD);
48bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner  // Initialize the "backend"
49bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner  initializeExecutionEngine();
50da82ed52ac02497d343b898cca0bb2cf303f062dChris Lattner  initializeExternalFunctions();
51bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner  CW.setModule(M);  // Update Writer
5256adf152f6354a9b5609e059050fd2315ad5960cChris Lattner  emitGlobals();
53bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner}
54bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner
55bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner/// run - Start execution with the specified function and arguments.
56bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner///
57bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattnerint Interpreter::run(const std::string &MainFunction,
5869582b35b6aa4e48cbbad7f6f1193c967da96b25John Criswell		     const std::vector<std::string> &Args,
5969582b35b6aa4e48cbbad7f6f1193c967da96b25John Criswell                     const char ** envp) {
60bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner  // Start interpreter into the main function...
61bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner  //
62da82ed52ac02497d343b898cca0bb2cf303f062dChris Lattner  if (!callMainFunction(MainFunction, Args) && !Debug) {
63bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner    // If not in debug mode and if the call succeeded, run the code now...
64bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner    run();
65bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner  }
66bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner
6744edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner  do {
6844edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner    // If debug mode, allow the user to interact... also, if the user pressed
6944edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner    // ctrl-c or execution hit an error, enter the event loop...
7044edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner    if (Debug || isStopped())
7144edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner      handleUserInput();
7244edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner
7344edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner    // If the program has exited, run atexit handlers...
7444edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner    if (ECStack.empty() && !AtExitHandlers.empty()) {
7544edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner      callFunction(AtExitHandlers.back(), std::vector<GenericValue>());
7644edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner      AtExitHandlers.pop_back();
7744edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner      run();
7844edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner    }
7944edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner  } while (!ECStack.empty());
8044edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner
8144edb6bdd2edc48eb31ed160a09006b610cead67Chris Lattner  PerformExitStuff();
82bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner  return ExitCode;
83bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner}
84bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner
85