Interpreter.cpp revision 2cab55d7e1bde83cd5f5dccee9a331ada8c1a67c
1//===- Interpreter.cpp - Top-Level LLVM Interpreter Implementation --------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by the LLVM research group and is distributed under 6// the University of Illinois Open Source License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the top-level functionality for the LLVM interpreter. 11// This interpreter is designed to be a very simple, portable, inefficient 12// interpreter. 13// 14//===----------------------------------------------------------------------===// 15 16#include "Interpreter.h" 17#include "llvm/Module.h" 18#include "llvm/DerivedTypes.h" 19using namespace llvm; 20 21/// create - Create a new interpreter object. This can never fail. 22/// 23ExecutionEngine *Interpreter::create(Module *M){ 24 bool isLittleEndian = false; 25 switch (M->getEndianness()) { 26 case Module::LittleEndian: isLittleEndian = true; break; 27 case Module::BigEndian: isLittleEndian = false; break; 28 case Module::AnyPointerSize: 29 int Test = 0; 30 *(char*)&Test = 1; // Return true if the host is little endian 31 isLittleEndian = (Test == 1); 32 break; 33 } 34 35 bool isLongPointer = false; 36 switch (M->getPointerSize()) { 37 case Module::Pointer32: isLongPointer = false; break; 38 case Module::Pointer64: isLongPointer = true; break; 39 case Module::AnyPointerSize: 40 isLongPointer = (sizeof(void*) == 8); // Follow host 41 break; 42 } 43 44 return new Interpreter(M, isLittleEndian, isLongPointer); 45} 46 47//===----------------------------------------------------------------------===// 48// Interpreter ctor - Initialize stuff 49// 50Interpreter::Interpreter(Module *M, bool isLittleEndian, bool isLongPointer) 51 : ExecutionEngine(M), ExitCode(0), 52 TD("lli", isLittleEndian, isLongPointer ? 8 : 4, isLongPointer ? 8 : 4, 53 isLongPointer ? 8 : 4) { 54 55 setTargetData(TD); 56 // Initialize the "backend" 57 initializeExecutionEngine(); 58 initializeExternalFunctions(); 59 emitGlobals(); 60} 61 62void Interpreter::runAtExitHandlers () { 63 while (!AtExitHandlers.empty()) { 64 callFunction(AtExitHandlers.back(), std::vector<GenericValue>()); 65 AtExitHandlers.pop_back(); 66 run(); 67 } 68} 69 70/// run - Start execution with the specified function and arguments. 71/// 72GenericValue Interpreter::runFunction(Function *F, 73 const std::vector<GenericValue> &ArgValues) { 74 assert (F && "Function *F was null at entry to run()"); 75 76 // Try extra hard not to pass extra args to a function that isn't 77 // expecting them. C programmers frequently bend the rules and 78 // declare main() with fewer parameters than it actually gets 79 // passed, and the interpreter barfs if you pass a function more 80 // parameters than it is declared to take. This does not attempt to 81 // take into account gratuitous differences in declared types, 82 // though. 83 std::vector<GenericValue> ActualArgs; 84 const unsigned ArgCount = F->getFunctionType()->getParamTypes().size(); 85 for (unsigned i = 0; i < ArgCount; ++i) 86 ActualArgs.push_back (ArgValues[i]); 87 88 // Set up the function call. 89 callFunction(F, ActualArgs); 90 91 // Start executing the function. 92 run(); 93 94 GenericValue rv; 95 rv.IntVal = ExitCode; 96 return rv; 97} 98 99