Interpreter.h revision c1a2be18eaf1e9862af973126be1f1ef975185f1
1//===-- Interpreter.h ------------------------------------------*- C++ -*--===// 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 header file defines the interpreter structure 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLI_INTERPRETER_H 15#define LLI_INTERPRETER_H 16 17#include "llvm/Function.h" 18#include "llvm/ExecutionEngine/ExecutionEngine.h" 19#include "llvm/ExecutionEngine/GenericValue.h" 20#include "llvm/Support/InstVisitor.h" 21#include "llvm/Support/CallSite.h" 22#include "llvm/Target/TargetData.h" 23#include "Support/DataTypes.h" 24 25struct FunctionInfo; // Defined in ExecutionAnnotations.h 26 27// AllocaHolder - Object to track all of the blocks of memory allocated by 28// alloca. When the function returns, this object is poped off the execution 29// stack, which causes the dtor to be run, which frees all the alloca'd memory. 30// 31class AllocaHolder { 32 friend class AllocaHolderHandle; 33 std::vector<void*> Allocations; 34 unsigned RefCnt; 35public: 36 AllocaHolder() : RefCnt(0) {} 37 void add(void *mem) { Allocations.push_back(mem); } 38 ~AllocaHolder() { 39 for (unsigned i = 0; i < Allocations.size(); ++i) 40 free(Allocations[i]); 41 } 42}; 43 44// AllocaHolderHandle gives AllocaHolder value semantics so we can stick it into 45// a vector... 46// 47class AllocaHolderHandle { 48 AllocaHolder *H; 49public: 50 AllocaHolderHandle() : H(new AllocaHolder()) { H->RefCnt++; } 51 AllocaHolderHandle(const AllocaHolderHandle &AH) : H(AH.H) { H->RefCnt++; } 52 ~AllocaHolderHandle() { if (--H->RefCnt == 0) delete H; } 53 54 void add(void *mem) { H->add(mem); } 55}; 56 57typedef std::vector<GenericValue> ValuePlaneTy; 58 59// ExecutionContext struct - This struct represents one stack frame currently 60// executing. 61// 62struct ExecutionContext { 63 Function *CurFunction;// The currently executing function 64 BasicBlock *CurBB; // The currently executing BB 65 BasicBlock::iterator CurInst; // The next instruction to execute 66 std::map<Value *, GenericValue> Values; // LLVM values used in this invocation 67 std::vector<GenericValue> VarArgs; // Values passed through an ellipsis 68 CallSite Caller; // Holds the call that called subframes. 69 // NULL if main func or debugger invoked fn 70 AllocaHolderHandle Allocas; // Track memory allocated by alloca 71}; 72 73// Interpreter - This class represents the entirety of the interpreter. 74// 75class Interpreter : public ExecutionEngine, public InstVisitor<Interpreter> { 76 int ExitCode; // The exit code to be returned by the lli util 77 TargetData TD; 78 79 // The runtime stack of executing code. The top of the stack is the current 80 // function record. 81 std::vector<ExecutionContext> ECStack; 82 83 // AtExitHandlers - List of functions to call when the program exits, 84 // registered with the atexit() library function. 85 std::vector<Function*> AtExitHandlers; 86 87public: 88 Interpreter(Module *M, bool isLittleEndian, bool isLongPointer); 89 inline ~Interpreter() { } 90 91 /// runAtExitHandlers - Run any functions registered by the 92 /// program's calls to atexit(3), which we intercept and store in 93 /// AtExitHandlers. 94 /// 95 void runAtExitHandlers (); 96 97 /// create - Create an interpreter ExecutionEngine. This can never fail. 98 /// 99 static ExecutionEngine *create(Module *M); 100 101 /// run - Start execution with the specified function and arguments. 102 /// 103 virtual GenericValue run(Function *F, 104 const std::vector<GenericValue> &ArgValues); 105 106 // Methods used to execute code: 107 // Place a call on the stack 108 void callFunction(Function *F, const std::vector<GenericValue> &ArgVals); 109 void run(); // Execute instructions until nothing left to do 110 111 // Opcode Implementations 112 void visitReturnInst(ReturnInst &I); 113 void visitBranchInst(BranchInst &I); 114 void visitSwitchInst(SwitchInst &I); 115 116 void visitBinaryOperator(BinaryOperator &I); 117 void visitAllocationInst(AllocationInst &I); 118 void visitFreeInst(FreeInst &I); 119 void visitLoadInst(LoadInst &I); 120 void visitStoreInst(StoreInst &I); 121 void visitGetElementPtrInst(GetElementPtrInst &I); 122 void visitPHINode(PHINode &PN) { assert(0 && "PHI nodes already handled!"); } 123 void visitCastInst(CastInst &I); 124 125 void visitCallSite(CallSite CS); 126 void visitCallInst(CallInst &I) { visitCallSite (CallSite (&I)); } 127 void visitInvokeInst(InvokeInst &I) { visitCallSite (CallSite (&I)); } 128 void visitUnwindInst(UnwindInst &I); 129 130 void visitShl(ShiftInst &I); 131 void visitShr(ShiftInst &I); 132 void visitVANextInst(VANextInst &I); 133 void visitVAArgInst(VAArgInst &I); 134 void visitInstruction(Instruction &I) { 135 std::cerr << I; 136 assert(0 && "Instruction not interpretable yet!"); 137 } 138 139 GenericValue callExternalFunction(Function *F, 140 const std::vector<GenericValue> &ArgVals); 141 void exitCalled(GenericValue GV); 142 143 void addAtExitHandler(Function *F) { 144 AtExitHandlers.push_back(F); 145 } 146 147 //FIXME: private: 148public: 149 GenericValue executeGEPOperation(Value *Ptr, User::op_iterator I, 150 User::op_iterator E, ExecutionContext &SF); 151 152private: // Helper functions 153 // SwitchToNewBasicBlock - Start execution in a new basic block and run any 154 // PHI nodes in the top of the block. This is used for intraprocedural 155 // control flow. 156 // 157 void SwitchToNewBasicBlock(BasicBlock *Dest, ExecutionContext &SF); 158 159 void *getPointerToFunction(Function *F) { return (void*)F; } 160 161 void initializeExecutionEngine(); 162 void initializeExternalFunctions(); 163 GenericValue getOperandValue(Value *V, ExecutionContext &SF); 164 GenericValue executeCastOperation(Value *SrcVal, const Type *Ty, 165 ExecutionContext &SF); 166 void popStackAndReturnValueToCaller(const Type *RetTy, GenericValue Result); 167}; 168 169#endif 170