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