1bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner//===- Interpreter.cpp - Top-Level LLVM Interpreter Implementation --------===//
2d1c881a8d4da8b4d99c2a40512fbcca652ab445eMisha Brukman//
3b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//                     The LLVM Compiler Infrastructure
4b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
7d1c881a8d4da8b4d99c2a40512fbcca652ab445eMisha Brukman//
8b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//===----------------------------------------------------------------------===//
9bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner//
10bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner// This file implements the top-level functionality for the LLVM interpreter.
11bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner// This interpreter is designed to be a very simple, portable, inefficient
12bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner// interpreter.
13bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner//
14bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner//===----------------------------------------------------------------------===//
15bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner
16bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner#include "Interpreter.h"
1730483737486d00e5c1c37f51138419aa08d8b5e3Chris Lattner#include "llvm/CodeGen/IntrinsicLowering.h"
180b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h"
190b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h"
20ae9f3a3b7c915f725aef5a7250e88eaeddda03c6Anton Korobeynikov#include <cstring>
21f7a743d7ed6e96af4c836e512c9cd59812c8186eChris Lattnerusing namespace llvm;
22d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
23844731a7f1909f55935e3514c9e713a62d67662eDan Gohmannamespace {
24844731a7f1909f55935e3514c9e713a62d67662eDan Gohman
252fe4bb06c6c40d16b7a5ae9cdf6bb6fe94d51be0Chris Lattnerstatic struct RegisterInterp {
262fe4bb06c6c40d16b7a5ae9cdf6bb6fe94d51be0Chris Lattner  RegisterInterp() { Interpreter::Register(); }
272fe4bb06c6c40d16b7a5ae9cdf6bb6fe94d51be0Chris Lattner} InterpRegistrator;
282fe4bb06c6c40d16b7a5ae9cdf6bb6fe94d51be0Chris Lattner
29844731a7f1909f55935e3514c9e713a62d67662eDan Gohman}
30844731a7f1909f55935e3514c9e713a62d67662eDan Gohman
31e46161f10c3e0c640b22e446b873df8b01413f52Bob Wilsonextern "C" void LLVMLinkInInterpreter() { }
322f51914d828b462b054195e73c75448f24e01979Jeff Cohen
3382d8277ad5862b54341808812bb4016e52347060Brian Gaeke/// create - Create a new interpreter object.  This can never fail.
34bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner///
35f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey YasskinExecutionEngine *Interpreter::create(Module *M, std::string* ErrStr) {
36f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin  // Tell this Module to materialize everything and release the GVMaterializer.
37f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin  if (M->MaterializeAllPermanently(ErrStr))
38d4c0e62413ac4c81467ce59025c81210ea431752Reid Spencer    // We got an error, just return 0
39d4c0e62413ac4c81467ce59025c81210ea431752Reid Spencer    return 0;
40d4c0e62413ac4c81467ce59025c81210ea431752Reid Spencer
41f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin  return new Interpreter(M);
42bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner}
43bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner
44bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner//===----------------------------------------------------------------------===//
45bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner// Interpreter ctor - Initialize stuff
46bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner//
47f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey YasskinInterpreter::Interpreter(Module *M)
48f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin  : ExecutionEngine(M), TD(M) {
49276f4b523564d205e59c8049a12c75705dd24b78Chris Lattner
50e770787be101e522425f658f76e4bb3091498f99Reid Spencer  memset(&ExitValue.Untyped, 0, sizeof(ExitValue.Untyped));
513574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow  setDataLayout(&TD);
52bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner  // Initialize the "backend"
53bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner  initializeExecutionEngine();
54da82ed52ac02497d343b898cca0bb2cf303f062dChris Lattner  initializeExternalFunctions();
5556adf152f6354a9b5609e059050fd2315ad5960cChris Lattner  emitGlobals();
567301178aac1baf1cc334e7c7a66bfe50a65fbf49Chris Lattner
57519e239b1f8e12a6566d5140bfd08733ff227706Reid Spencer  IL = new IntrinsicLowering(TD);
587301178aac1baf1cc334e7c7a66bfe50a65fbf49Chris Lattner}
597301178aac1baf1cc334e7c7a66bfe50a65fbf49Chris Lattner
607301178aac1baf1cc334e7c7a66bfe50a65fbf49Chris LattnerInterpreter::~Interpreter() {
617301178aac1baf1cc334e7c7a66bfe50a65fbf49Chris Lattner  delete IL;
62bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner}
63bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner
6470975eef572b9e132bbaade16ba9edb76f15f287Brian Gaekevoid Interpreter::runAtExitHandlers () {
6570975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  while (!AtExitHandlers.empty()) {
6670975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke    callFunction(AtExitHandlers.back(), std::vector<GenericValue>());
6770975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke    AtExitHandlers.pop_back();
68bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner    run();
69bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner  }
70bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner}
71bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner
7270975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke/// run - Start execution with the specified function and arguments.
7370975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke///
7400b16889ab461b7ecef1c91ade101186b7f1fce2Jeff CohenGenericValue
753c94497ec7852eccd68c1bc1663e8ac2a7bb1ab9Misha BrukmanInterpreter::runFunction(Function *F,
763c94497ec7852eccd68c1bc1663e8ac2a7bb1ab9Misha Brukman                         const std::vector<GenericValue> &ArgValues) {
7770975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  assert (F && "Function *F was null at entry to run()");
7870975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke
7970975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  // Try extra hard not to pass extra args to a function that isn't
8070975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  // expecting them.  C programmers frequently bend the rules and
8170975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  // declare main() with fewer parameters than it actually gets
8270975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  // passed, and the interpreter barfs if you pass a function more
8370975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  // parameters than it is declared to take. This does not attempt to
8470975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  // take into account gratuitous differences in declared types,
8570975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  // though.
8670975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  std::vector<GenericValue> ActualArgs;
87d5d89967206e1153d24abdb7b22002f7533f55c7Chris Lattner  const unsigned ArgCount = F->getFunctionType()->getNumParams();
88a824f420741a54cf8b09cbb91ef9bee358432bd9Brian Gaeke  for (unsigned i = 0; i < ArgCount; ++i)
89d5d89967206e1153d24abdb7b22002f7533f55c7Chris Lattner    ActualArgs.push_back(ArgValues[i]);
90d1c881a8d4da8b4d99c2a40512fbcca652ab445eMisha Brukman
9170975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  // Set up the function call.
9270975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  callFunction(F, ActualArgs);
93413ab6655bfe0b1e58d0da6c3f4c3a9833e8a952Brian Gaeke
9470975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  // Start executing the function.
9570975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  run();
96d1c881a8d4da8b4d99c2a40512fbcca652ab445eMisha Brukman
978c9191c644cf8c3aceac8e0d1ddc72273355588cJeff Cohen  return ExitValue;
98413ab6655bfe0b1e58d0da6c3f4c3a9833e8a952Brian Gaeke}
99