Interpreter.cpp revision 8c9191c644cf8c3aceac8e0d1ddc72273355588c
1bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner//===- Interpreter.cpp - Top-Level LLVM Interpreter Implementation --------===//
2d1c881a8d4da8b4d99c2a40512fbcca652ab445eMisha Brukman//
3b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//                     The LLVM Compiler Infrastructure
4b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//
5b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// This file was developed by the LLVM research group and is distributed under
6b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// the University of Illinois Open Source 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"
18413ab6655bfe0b1e58d0da6c3f4c3a9833e8a952Brian Gaeke#include "llvm/DerivedTypes.h"
197301178aac1baf1cc334e7c7a66bfe50a65fbf49Chris Lattner#include "llvm/Module.h"
20f7a743d7ed6e96af4c836e512c9cd59812c8186eChris Lattnerusing namespace llvm;
21d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
2282d8277ad5862b54341808812bb4016e52347060Brian Gaeke/// create - Create a new interpreter object.  This can never fail.
23bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner///
247301178aac1baf1cc334e7c7a66bfe50a65fbf49Chris LattnerExecutionEngine *Interpreter::create(Module *M, IntrinsicLowering *IL) {
25021c190f8dba1aedf09707c2e1f3572dbfefb78bChris Lattner  bool isLittleEndian = false;
2639c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner  switch (M->getEndianness()) {
2739c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner  case Module::LittleEndian: isLittleEndian = true; break;
2839c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner  case Module::BigEndian:    isLittleEndian = false; break;
2939c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner  case Module::AnyPointerSize:
3039c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner    int Test = 0;
3139c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner    *(char*)&Test = 1;    // Return true if the host is little endian
3239c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner    isLittleEndian = (Test == 1);
3339c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner    break;
3439c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner  }
3539c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner
36021c190f8dba1aedf09707c2e1f3572dbfefb78bChris Lattner  bool isLongPointer = false;
3739c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner  switch (M->getPointerSize()) {
3839c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner  case Module::Pointer32: isLongPointer = false; break;
3939c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner  case Module::Pointer64: isLongPointer = true; break;
4039c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner  case Module::AnyPointerSize:
4139c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner    isLongPointer = (sizeof(void*) == 8);  // Follow host
4239c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner    break;
4339c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner  }
4439c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner
457301178aac1baf1cc334e7c7a66bfe50a65fbf49Chris Lattner  return new Interpreter(M, isLittleEndian, isLongPointer, IL);
46bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner}
47bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner
48bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner//===----------------------------------------------------------------------===//
49bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner// Interpreter ctor - Initialize stuff
50bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner//
517301178aac1baf1cc334e7c7a66bfe50a65fbf49Chris LattnerInterpreter::Interpreter(Module *M, bool isLittleEndian, bool isLongPointer,
527301178aac1baf1cc334e7c7a66bfe50a65fbf49Chris Lattner                         IntrinsicLowering *il)
538c9191c644cf8c3aceac8e0d1ddc72273355588cJeff Cohen  : ExecutionEngine(M),
54a824f420741a54cf8b09cbb91ef9bee358432bd9Brian Gaeke    TD("lli", isLittleEndian, isLongPointer ? 8 : 4, isLongPointer ? 8 : 4,
557301178aac1baf1cc334e7c7a66bfe50a65fbf49Chris Lattner       isLongPointer ? 8 : 4), IL(il) {
56bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner
578c9191c644cf8c3aceac8e0d1ddc72273355588cJeff Cohen  memset(&ExitValue, 0, sizeof(ExitValue));
58bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner  setTargetData(TD);
59bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner  // Initialize the "backend"
60bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner  initializeExecutionEngine();
61da82ed52ac02497d343b898cca0bb2cf303f062dChris Lattner  initializeExternalFunctions();
6256adf152f6354a9b5609e059050fd2315ad5960cChris Lattner  emitGlobals();
637301178aac1baf1cc334e7c7a66bfe50a65fbf49Chris Lattner
647301178aac1baf1cc334e7c7a66bfe50a65fbf49Chris Lattner  if (IL == 0) IL = new DefaultIntrinsicLowering();
657301178aac1baf1cc334e7c7a66bfe50a65fbf49Chris Lattner}
667301178aac1baf1cc334e7c7a66bfe50a65fbf49Chris Lattner
677301178aac1baf1cc334e7c7a66bfe50a65fbf49Chris LattnerInterpreter::~Interpreter() {
687301178aac1baf1cc334e7c7a66bfe50a65fbf49Chris Lattner  delete IL;
69bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner}
70bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner
7170975eef572b9e132bbaade16ba9edb76f15f287Brian Gaekevoid Interpreter::runAtExitHandlers () {
7270975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  while (!AtExitHandlers.empty()) {
7370975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke    callFunction(AtExitHandlers.back(), std::vector<GenericValue>());
7470975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke    AtExitHandlers.pop_back();
75bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner    run();
76bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner  }
77bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner}
78bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner
7970975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke/// run - Start execution with the specified function and arguments.
8070975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke///
8100b16889ab461b7ecef1c91ade101186b7f1fce2Jeff CohenGenericValue
823c94497ec7852eccd68c1bc1663e8ac2a7bb1ab9Misha BrukmanInterpreter::runFunction(Function *F,
833c94497ec7852eccd68c1bc1663e8ac2a7bb1ab9Misha Brukman                         const std::vector<GenericValue> &ArgValues) {
8470975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  assert (F && "Function *F was null at entry to run()");
8570975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke
8670975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  // Try extra hard not to pass extra args to a function that isn't
8770975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  // expecting them.  C programmers frequently bend the rules and
8870975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  // declare main() with fewer parameters than it actually gets
8970975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  // passed, and the interpreter barfs if you pass a function more
9070975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  // parameters than it is declared to take. This does not attempt to
9170975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  // take into account gratuitous differences in declared types,
9270975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  // though.
9370975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  std::vector<GenericValue> ActualArgs;
94d5d89967206e1153d24abdb7b22002f7533f55c7Chris Lattner  const unsigned ArgCount = F->getFunctionType()->getNumParams();
95a824f420741a54cf8b09cbb91ef9bee358432bd9Brian Gaeke  for (unsigned i = 0; i < ArgCount; ++i)
96d5d89967206e1153d24abdb7b22002f7533f55c7Chris Lattner    ActualArgs.push_back(ArgValues[i]);
97d1c881a8d4da8b4d99c2a40512fbcca652ab445eMisha Brukman
9870975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  // Set up the function call.
9970975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  callFunction(F, ActualArgs);
100413ab6655bfe0b1e58d0da6c3f4c3a9833e8a952Brian Gaeke
10170975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  // Start executing the function.
10270975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke  run();
103d1c881a8d4da8b4d99c2a40512fbcca652ab445eMisha Brukman
1048c9191c644cf8c3aceac8e0d1ddc72273355588cJeff Cohen  return ExitValue;
105413ab6655bfe0b1e58d0da6c3f4c3a9833e8a952Brian Gaeke}
106d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
107