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/DataLayout.h" |
19 | #include "llvm/IR/Function.h" |
20 | #include "llvm/IR/InstVisitor.h" |
21 | #include "llvm/Support/DataTypes.h" |
22 | #include "llvm/Support/ErrorHandling.h" |
23 | #include "llvm/Support/raw_ostream.h" |
24 | namespace llvm { |
25 | |
26 | class IntrinsicLowering; |
27 | template<typename T> class generic_gep_type_iterator; |
28 | class ConstantExpr; |
29 | typedef generic_gep_type_iterator<User::const_op_iterator> gep_type_iterator; |
30 | |
31 | |
32 | // AllocaHolder - Object to track all of the blocks of memory allocated by |
33 | // alloca. When the function returns, this object is popped off the execution |
34 | // stack, which causes the dtor to be run, which frees all the alloca'd memory. |
35 | // |
36 | class AllocaHolder { |
37 | std::vector<void *> Allocations; |
38 | |
39 | public: |
40 | AllocaHolder() = default; |
41 | |
42 | // Make this type move-only. |
43 | AllocaHolder(AllocaHolder &&) = default; |
44 | AllocaHolder &operator=(AllocaHolder &&RHS) = default; |
45 | |
46 | ~AllocaHolder() { |
47 | for (void *Allocation : Allocations) |
48 | free(ptr: Allocation); |
49 | } |
50 | |
51 | void add(void *Mem) { Allocations.push_back(x: Mem); } |
52 | }; |
53 | |
54 | typedef std::vector<GenericValue> ValuePlaneTy; |
55 | |
56 | // ExecutionContext struct - This struct represents one stack frame currently |
57 | // executing. |
58 | // |
59 | struct ExecutionContext { |
60 | Function *CurFunction;// The currently executing function |
61 | BasicBlock *CurBB; // The currently executing BB |
62 | BasicBlock::iterator CurInst; // The next instruction to execute |
63 | CallBase *Caller; // Holds the call that called subframes. |
64 | // NULL if main func or debugger invoked fn |
65 | std::map<Value *, GenericValue> Values; // LLVM values used in this invocation |
66 | std::vector<GenericValue> VarArgs; // Values passed through an ellipsis |
67 | AllocaHolder Allocas; // Track memory allocated by alloca |
68 | |
69 | ExecutionContext() : CurFunction(nullptr), CurBB(nullptr), CurInst(nullptr) {} |
70 | }; |
71 | |
72 | // Interpreter - This class represents the entirety of the interpreter. |
73 | // |
74 | class Interpreter : public ExecutionEngine, public InstVisitor<Interpreter> { |
75 | GenericValue ExitValue; // The return value of the called function |
76 | IntrinsicLowering *IL; |
77 | |
78 | // The runtime stack of executing code. The top of the stack is the current |
79 | // function record. |
80 | std::vector<ExecutionContext> ECStack; |
81 | |
82 | // AtExitHandlers - List of functions to call when the program exits, |
83 | // registered with the atexit() library function. |
84 | std::vector<Function*> AtExitHandlers; |
85 | |
86 | public: |
87 | explicit Interpreter(std::unique_ptr<Module> M); |
88 | ~Interpreter() override; |
89 | |
90 | /// runAtExitHandlers - Run any functions registered by the program's calls to |
91 | /// atexit(3), which we intercept and store in AtExitHandlers. |
92 | /// |
93 | void runAtExitHandlers(); |
94 | |
95 | static void Register() { |
96 | InterpCtor = create; |
97 | } |
98 | |
99 | /// Create an interpreter ExecutionEngine. |
100 | /// |
101 | static ExecutionEngine *create(std::unique_ptr<Module> M, |
102 | std::string *ErrorStr = nullptr); |
103 | |
104 | /// run - Start execution with the specified function and arguments. |
105 | /// |
106 | GenericValue runFunction(Function *F, |
107 | ArrayRef<GenericValue> ArgValues) override; |
108 | |
109 | void *getPointerToNamedFunction(StringRef Name, |
110 | bool AbortOnFailure = true) override { |
111 | // FIXME: not implemented. |
112 | return nullptr; |
113 | } |
114 | |
115 | // Methods used to execute code: |
116 | // Place a call on the stack |
117 | void callFunction(Function *F, ArrayRef<GenericValue> ArgVals); |
118 | void run(); // Execute instructions until nothing left to do |
119 | |
120 | // Opcode Implementations |
121 | void visitReturnInst(ReturnInst &I); |
122 | void visitBranchInst(BranchInst &I); |
123 | void visitSwitchInst(SwitchInst &I); |
124 | void visitIndirectBrInst(IndirectBrInst &I); |
125 | |
126 | void visitUnaryOperator(UnaryOperator &I); |
127 | void visitBinaryOperator(BinaryOperator &I); |
128 | void visitICmpInst(ICmpInst &I); |
129 | void visitFCmpInst(FCmpInst &I); |
130 | void visitAllocaInst(AllocaInst &I); |
131 | void visitLoadInst(LoadInst &I); |
132 | void visitStoreInst(StoreInst &I); |
133 | void visitGetElementPtrInst(GetElementPtrInst &I); |
134 | void visitPHINode(PHINode &PN) { |
135 | llvm_unreachable("PHI nodes already handled!" ); |
136 | } |
137 | void visitTruncInst(TruncInst &I); |
138 | void visitZExtInst(ZExtInst &I); |
139 | void visitSExtInst(SExtInst &I); |
140 | void visitFPTruncInst(FPTruncInst &I); |
141 | void visitFPExtInst(FPExtInst &I); |
142 | void visitUIToFPInst(UIToFPInst &I); |
143 | void visitSIToFPInst(SIToFPInst &I); |
144 | void visitFPToUIInst(FPToUIInst &I); |
145 | void visitFPToSIInst(FPToSIInst &I); |
146 | void visitPtrToIntInst(PtrToIntInst &I); |
147 | void visitIntToPtrInst(IntToPtrInst &I); |
148 | void visitBitCastInst(BitCastInst &I); |
149 | void visitSelectInst(SelectInst &I); |
150 | |
151 | void visitVAStartInst(VAStartInst &I); |
152 | void visitVAEndInst(VAEndInst &I); |
153 | void visitVACopyInst(VACopyInst &I); |
154 | void visitIntrinsicInst(IntrinsicInst &I); |
155 | void visitCallBase(CallBase &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(x: 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 | void popStackAndReturnValueToCaller(Type *RetTy, GenericValue Result); |
228 | |
229 | }; |
230 | |
231 | } // End llvm namespace |
232 | |
233 | #endif |
234 | |