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 #include "llvm/ModuleProvider.h" 00021 using namespace llvm; 00022 00023 static struct RegisterInterp { 00024 RegisterInterp() { Interpreter::Register(); } 00025 } InterpRegistrator; 00026 00027 namespace llvm { 00028 void LinkInInterpreter() { 00029 } 00030 } 00031 00032 /// create - Create a new interpreter object. This can never fail. 00033 /// 00034 ExecutionEngine *Interpreter::create(ModuleProvider *MP) { 00035 Module *M; 00036 try { 00037 M = MP->materializeModule(); 00038 } catch (...) { 00039 return 0; // error materializing the module. 00040 } 00041 00042 bool isLittleEndian = false; 00043 switch (M->getEndianness()) { 00044 case Module::LittleEndian: isLittleEndian = true; break; 00045 case Module::BigEndian: isLittleEndian = false; break; 00046 case Module::AnyPointerSize: 00047 int Test = 0; 00048 *(char*)&Test = 1; // Return true if the host is little endian 00049 isLittleEndian = (Test == 1); 00050 break; 00051 } 00052 00053 bool isLongPointer = false; 00054 switch (M->getPointerSize()) { 00055 case Module::Pointer32: isLongPointer = false; break; 00056 case Module::Pointer64: isLongPointer = true; break; 00057 case Module::AnyPointerSize: 00058 isLongPointer = (sizeof(void*) == 8); // Follow host 00059 break; 00060 } 00061 00062 return new Interpreter(M, isLittleEndian, isLongPointer); 00063 } 00064 00065 //===----------------------------------------------------------------------===// 00066 // Interpreter ctor - Initialize stuff 00067 // 00068 Interpreter::Interpreter(Module *M, bool isLittleEndian, bool isLongPointer) 00069 : ExecutionEngine(M), 00070 TD("lli", isLittleEndian, isLongPointer ? 8 : 4, isLongPointer ? 8 : 4, 00071 isLongPointer ? 8 : 4) { 00072 00073 memset(&ExitValue, 0, sizeof(ExitValue)); 00074 setTargetData(TD); 00075 // Initialize the "backend" 00076 initializeExecutionEngine(); 00077 initializeExternalFunctions(); 00078 emitGlobals(); 00079 00080 IL = new DefaultIntrinsicLowering(); 00081 } 00082 00083 Interpreter::~Interpreter() { 00084 delete IL; 00085 } 00086 00087 void Interpreter::runAtExitHandlers () { 00088 while (!AtExitHandlers.empty()) { 00089 callFunction(AtExitHandlers.back(), std::vector<GenericValue>()); 00090 AtExitHandlers.pop_back(); 00091 run(); 00092 } 00093 } 00094 00095 /// run - Start execution with the specified function and arguments. 00096 /// 00097 GenericValue 00098 Interpreter::runFunction(Function *F, 00099 const std::vector<GenericValue> &ArgValues) { 00100 assert (F && "Function *F was null at entry to run()"); 00101 00102 // Try extra hard not to pass extra args to a function that isn't 00103 // expecting them. C programmers frequently bend the rules and 00104 // declare main() with fewer parameters than it actually gets 00105 // passed, and the interpreter barfs if you pass a function more 00106 // parameters than it is declared to take. This does not attempt to 00107 // take into account gratuitous differences in declared types, 00108 // though. 00109 std::vector<GenericValue> ActualArgs; 00110 const unsigned ArgCount = F->getFunctionType()->getNumParams(); 00111 for (unsigned i = 0; i < ArgCount; ++i) 00112 ActualArgs.push_back(ArgValues[i]); 00113 00114 // Set up the function call. 00115 callFunction(F, ActualArgs); 00116 00117 // Start executing the function. 00118 run(); 00119 00120 return ExitValue; 00121 } 00122