1 | //===-- Interpreter.h ------------------------------------------*- C++ -*--===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This header file defines the interpreter structure |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #ifndef LLVM_LIB_EXECUTIONENGINE_INTERPRETER_INTERPRETER_H |
14 | #define LLVM_LIB_EXECUTIONENGINE_INTERPRETER_INTERPRETER_H |
15 | |
16 | #include "llvm/ExecutionEngine/ExecutionEngine.h" |
17 | #include "llvm/ExecutionEngine/GenericValue.h" |
18 | #include "llvm/IR/CallSite.h" |
19 | #include "llvm/IR/DataLayout.h" |
20 | #include "llvm/IR/Function.h" |
21 | #include "llvm/IR/InstVisitor.h" |
22 | #include "llvm/Support/DataTypes.h" |
23 | #include "llvm/Support/ErrorHandling.h" |
24 | #include "llvm/Support/raw_ostream.h" |
25 | namespace llvm { |
26 | |
27 | class IntrinsicLowering; |
28 | template<typename T> class generic_gep_type_iterator; |
29 | class ConstantExpr; |
30 | typedef generic_gep_type_iterator<User::const_op_iterator> gep_type_iterator; |
31 | |
32 | |
33 | // AllocaHolder - Object to track all of the blocks of memory allocated by |
34 | // alloca. When the function returns, this object is popped off the execution |
35 | // stack, which causes the dtor to be run, which frees all the alloca'd memory. |
36 | // |
37 | class AllocaHolder { |
38 | std::vector<void *> Allocations; |
39 | |
40 | public: |
41 | AllocaHolder() {} |
42 | |
43 | // Make this type move-only. |
44 | AllocaHolder(AllocaHolder &&) = default; |
45 | AllocaHolder &operator=(AllocaHolder &&RHS) = default; |
46 | |
47 | ~AllocaHolder() { |
48 | for (void *Allocation : Allocations) |
49 | free(Allocation); |
50 | } |
51 | |
52 | void add(void *Mem) { Allocations.push_back(Mem); } |
53 | }; |
54 | |
55 | typedef std::vector<GenericValue> ValuePlaneTy; |
56 | |
57 | // ExecutionContext struct - This struct represents one stack frame currently |
58 | // executing. |
59 | // |
60 | struct ExecutionContext { |
61 | Function *CurFunction;// The currently executing function |
62 | BasicBlock *CurBB; // The currently executing BB |
63 | BasicBlock::iterator CurInst; // The next instruction to execute |
64 | CallSite Caller; // Holds the call that called subframes. |
65 | // NULL if main func or debugger invoked fn |
66 | std::map<Value *, GenericValue> Values; // LLVM values used in this invocation |
67 | std::vector<GenericValue> VarArgs; // Values passed through an ellipsis |
68 | AllocaHolder Allocas; // Track memory allocated by alloca |
69 | |
70 | ExecutionContext() : CurFunction(nullptr), CurBB(nullptr), CurInst(nullptr) {} |
71 | }; |
72 | |
73 | // Interpreter - This class represents the entirety of the interpreter. |
74 | // |
75 | class Interpreter : public ExecutionEngine, public InstVisitor<Interpreter> { |
76 | GenericValue ExitValue; // The return value of the called function |
77 | IntrinsicLowering *IL; |
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 | |
87 | public: |
88 | explicit Interpreter(std::unique_ptr<Module> M); |
89 | ~Interpreter() override; |
90 | |
91 | /// runAtExitHandlers - Run any functions registered by the program's calls to |
92 | /// atexit(3), which we intercept and store in AtExitHandlers. |
93 | /// |
94 | void runAtExitHandlers(); |
95 | |
96 | static void Register() { |
97 | InterpCtor = create; |
98 | } |
99 | |
100 | /// Create an interpreter ExecutionEngine. |
101 | /// |
102 | static ExecutionEngine *create(std::unique_ptr<Module> M, |
103 | std::string *ErrorStr = nullptr); |
104 | |
105 | /// run - Start execution with the specified function and arguments. |
106 | /// |
107 | GenericValue runFunction(Function *F, |
108 | ArrayRef<GenericValue> ArgValues) override; |
109 | |
110 | void *getPointerToNamedFunction(StringRef Name, |
111 | bool AbortOnFailure = true) override { |
112 | // FIXME: not implemented. |
113 | return nullptr; |
114 | } |
115 | |
116 | // Methods used to execute code: |
117 | // Place a call on the stack |
118 | void callFunction(Function *F, ArrayRef<GenericValue> ArgVals); |
119 | void run(); // Execute instructions until nothing left to do |
120 | |
121 | // Opcode Implementations |
122 | void visitReturnInst(ReturnInst &I); |
123 | void visitBranchInst(BranchInst &I); |
124 | void visitSwitchInst(SwitchInst &I); |
125 | void visitIndirectBrInst(IndirectBrInst &I); |
126 | |
127 | void visitUnaryOperator(UnaryOperator &I); |
128 | void visitBinaryOperator(BinaryOperator &I); |
129 | void visitICmpInst(ICmpInst &I); |
130 | void visitFCmpInst(FCmpInst &I); |
131 | void visitAllocaInst(AllocaInst &I); |
132 | void visitLoadInst(LoadInst &I); |
133 | void visitStoreInst(StoreInst &I); |
134 | void visitGetElementPtrInst(GetElementPtrInst &I); |
135 | void visitPHINode(PHINode &PN) { |
136 | llvm_unreachable("PHI nodes already handled!" ); |
137 | } |
138 | void visitTruncInst(TruncInst &I); |
139 | void visitZExtInst(ZExtInst &I); |
140 | void visitSExtInst(SExtInst &I); |
141 | void visitFPTruncInst(FPTruncInst &I); |
142 | void visitFPExtInst(FPExtInst &I); |
143 | void visitUIToFPInst(UIToFPInst &I); |
144 | void visitSIToFPInst(SIToFPInst &I); |
145 | void visitFPToUIInst(FPToUIInst &I); |
146 | void visitFPToSIInst(FPToSIInst &I); |
147 | void visitPtrToIntInst(PtrToIntInst &I); |
148 | void visitIntToPtrInst(IntToPtrInst &I); |
149 | void visitBitCastInst(BitCastInst &I); |
150 | void visitSelectInst(SelectInst &I); |
151 | |
152 | |
153 | void visitCallSite(CallSite CS); |
154 | void visitCallInst(CallInst &I) { visitCallSite (CallSite (&I)); } |
155 | void visitInvokeInst(InvokeInst &I) { visitCallSite (CallSite (&I)); } |
156 | void visitUnreachableInst(UnreachableInst &I); |
157 | |
158 | void visitShl(BinaryOperator &I); |
159 | void visitLShr(BinaryOperator &I); |
160 | void visitAShr(BinaryOperator &I); |
161 | |
162 | void visitVAArgInst(VAArgInst &I); |
163 | void (ExtractElementInst &I); |
164 | void visitInsertElementInst(InsertElementInst &I); |
165 | void visitShuffleVectorInst(ShuffleVectorInst &I); |
166 | |
167 | void (ExtractValueInst &I); |
168 | void visitInsertValueInst(InsertValueInst &I); |
169 | |
170 | void visitInstruction(Instruction &I) { |
171 | errs() << I << "\n" ; |
172 | llvm_unreachable("Instruction not interpretable yet!" ); |
173 | } |
174 | |
175 | GenericValue callExternalFunction(Function *F, |
176 | ArrayRef<GenericValue> ArgVals); |
177 | void exitCalled(GenericValue GV); |
178 | |
179 | void addAtExitHandler(Function *F) { |
180 | AtExitHandlers.push_back(F); |
181 | } |
182 | |
183 | GenericValue *getFirstVarArg () { |
184 | return &(ECStack.back ().VarArgs[0]); |
185 | } |
186 | |
187 | private: // Helper functions |
188 | GenericValue executeGEPOperation(Value *Ptr, gep_type_iterator I, |
189 | gep_type_iterator E, ExecutionContext &SF); |
190 | |
191 | // SwitchToNewBasicBlock - Start execution in a new basic block and run any |
192 | // PHI nodes in the top of the block. This is used for intraprocedural |
193 | // control flow. |
194 | // |
195 | void SwitchToNewBasicBlock(BasicBlock *Dest, ExecutionContext &SF); |
196 | |
197 | void *getPointerToFunction(Function *F) override { return (void*)F; } |
198 | |
199 | void initializeExecutionEngine() { } |
200 | void initializeExternalFunctions(); |
201 | GenericValue getConstantExprValue(ConstantExpr *CE, ExecutionContext &SF); |
202 | GenericValue getOperandValue(Value *V, ExecutionContext &SF); |
203 | GenericValue executeTruncInst(Value *SrcVal, Type *DstTy, |
204 | ExecutionContext &SF); |
205 | GenericValue executeSExtInst(Value *SrcVal, Type *DstTy, |
206 | ExecutionContext &SF); |
207 | GenericValue executeZExtInst(Value *SrcVal, Type *DstTy, |
208 | ExecutionContext &SF); |
209 | GenericValue executeFPTruncInst(Value *SrcVal, Type *DstTy, |
210 | ExecutionContext &SF); |
211 | GenericValue executeFPExtInst(Value *SrcVal, Type *DstTy, |
212 | ExecutionContext &SF); |
213 | GenericValue executeFPToUIInst(Value *SrcVal, Type *DstTy, |
214 | ExecutionContext &SF); |
215 | GenericValue executeFPToSIInst(Value *SrcVal, Type *DstTy, |
216 | ExecutionContext &SF); |
217 | GenericValue executeUIToFPInst(Value *SrcVal, Type *DstTy, |
218 | ExecutionContext &SF); |
219 | GenericValue executeSIToFPInst(Value *SrcVal, Type *DstTy, |
220 | ExecutionContext &SF); |
221 | GenericValue executePtrToIntInst(Value *SrcVal, Type *DstTy, |
222 | ExecutionContext &SF); |
223 | GenericValue executeIntToPtrInst(Value *SrcVal, Type *DstTy, |
224 | ExecutionContext &SF); |
225 | GenericValue executeBitCastInst(Value *SrcVal, Type *DstTy, |
226 | ExecutionContext &SF); |
227 | GenericValue executeCastOperation(Instruction::CastOps opcode, Value *SrcVal, |
228 | Type *Ty, ExecutionContext &SF); |
229 | void popStackAndReturnValueToCaller(Type *RetTy, GenericValue Result); |
230 | |
231 | }; |
232 | |
233 | } // End llvm namespace |
234 | |
235 | #endif |
236 | |