LLVM API Documentation
00001 //===- Interpreter.cpp - Top-Level LLVM Interpreter Implementation --------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by the LLVM research group and is distributed under 00006 // the University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the top-level functionality for the LLVM interpreter. 00011 // This interpreter is designed to be a very simple, portable, inefficient 00012 // interpreter. 00013 // 00014 //===----------------------------------------------------------------------===// 00015 00016 #include "Interpreter.h" 00017 #include "llvm/CodeGen/IntrinsicLowering.h" 00018 #include "llvm/DerivedTypes.h" 00019 #include "llvm/Module.h" 00020 using namespace llvm; 00021 00022 /// create - Create a new interpreter object. This can never fail. 00023 /// 00024 ExecutionEngine *Interpreter::create(Module *M, IntrinsicLowering *IL) { 00025 bool isLittleEndian = false; 00026 switch (M->getEndianness()) { 00027 case Module::LittleEndian: isLittleEndian = true; break; 00028 case Module::BigEndian: isLittleEndian = false; break; 00029 case Module::AnyPointerSize: 00030 int Test = 0; 00031 *(char*)&Test = 1; // Return true if the host is little endian 00032 isLittleEndian = (Test == 1); 00033 break; 00034 } 00035 00036 bool isLongPointer = false; 00037 switch (M->getPointerSize()) { 00038 case Module::Pointer32: isLongPointer = false; break; 00039 case Module::Pointer64: isLongPointer = true; break; 00040 case Module::AnyPointerSize: 00041 isLongPointer = (sizeof(void*) == 8); // Follow host 00042 break; 00043 } 00044 00045 return new Interpreter(M, isLittleEndian, isLongPointer, IL); 00046 } 00047 00048 //===----------------------------------------------------------------------===// 00049 // Interpreter ctor - Initialize stuff 00050 // 00051 Interpreter::Interpreter(Module *M, bool isLittleEndian, bool isLongPointer, 00052 IntrinsicLowering *il) 00053 : ExecutionEngine(M), ExitCode(0), 00054 TD("lli", isLittleEndian, isLongPointer ? 8 : 4, isLongPointer ? 8 : 4, 00055 isLongPointer ? 8 : 4), IL(il) { 00056 00057 setTargetData(TD); 00058 // Initialize the "backend" 00059 initializeExecutionEngine(); 00060 initializeExternalFunctions(); 00061 emitGlobals(); 00062 00063 if (IL == 0) IL = new DefaultIntrinsicLowering(); 00064 } 00065 00066 Interpreter::~Interpreter() { 00067 delete IL; 00068 } 00069 00070 void Interpreter::runAtExitHandlers () { 00071 while (!AtExitHandlers.empty()) { 00072 callFunction(AtExitHandlers.back(), std::vector<GenericValue>()); 00073 AtExitHandlers.pop_back(); 00074 run(); 00075 } 00076 } 00077 00078 /// run - Start execution with the specified function and arguments. 00079 /// 00080 GenericValue Interpreter::runFunction(Function *F, 00081 const std::vector<GenericValue> &ArgValues) { 00082 assert (F && "Function *F was null at entry to run()"); 00083 00084 // Try extra hard not to pass extra args to a function that isn't 00085 // expecting them. C programmers frequently bend the rules and 00086 // declare main() with fewer parameters than it actually gets 00087 // passed, and the interpreter barfs if you pass a function more 00088 // parameters than it is declared to take. This does not attempt to 00089 // take into account gratuitous differences in declared types, 00090 // though. 00091 std::vector<GenericValue> ActualArgs; 00092 const unsigned ArgCount = F->getFunctionType()->getNumParams(); 00093 for (unsigned i = 0; i < ArgCount; ++i) 00094 ActualArgs.push_back(ArgValues[i]); 00095 00096 // Set up the function call. 00097 callFunction(F, ActualArgs); 00098 00099 // Start executing the function. 00100 run(); 00101 00102 GenericValue rv; 00103 rv.IntVal = ExitCode; 00104 return rv; 00105 } 00106