brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.5 KiB · 41a0389 Raw
234 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8//9// This header file defines the interpreter structure10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_LIB_EXECUTIONENGINE_INTERPRETER_INTERPRETER_H14#define LLVM_LIB_EXECUTIONENGINE_INTERPRETER_INTERPRETER_H15 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"24namespace llvm {25 26class IntrinsicLowering;27template<typename T> class generic_gep_type_iterator;28class ConstantExpr;29typedef 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 by33// alloca.  When the function returns, this object is popped off the execution34// stack, which causes the dtor to be run, which frees all the alloca'd memory.35//36class AllocaHolder {37  std::vector<void *> Allocations;38 39public: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(Allocation);49  }50 51  void add(void *Mem) { Allocations.push_back(Mem); }52};53 54typedef std::vector<GenericValue> ValuePlaneTy;55 56// ExecutionContext struct - This struct represents one stack frame currently57// executing.58//59struct ExecutionContext {60  Function             *CurFunction;// The currently executing function61  BasicBlock           *CurBB;      // The currently executing BB62  BasicBlock::iterator  CurInst;    // The next instruction to execute63  CallBase             *Caller;     // Holds the call that called subframes.64                                    // NULL if main func or debugger invoked fn65  std::map<Value *, GenericValue> Values; // LLVM values used in this invocation66  std::vector<GenericValue>  VarArgs; // Values passed through an ellipsis67  AllocaHolder Allocas;            // Track memory allocated by alloca68 69  ExecutionContext() : CurFunction(nullptr), CurBB(nullptr), CurInst(nullptr) {}70};71 72// Interpreter - This class represents the entirety of the interpreter.73//74class Interpreter : public ExecutionEngine, public InstVisitor<Interpreter> {75  GenericValue ExitValue;          // The return value of the called function76  IntrinsicLowering *IL;77 78  // The runtime stack of executing code.  The top of the stack is the current79  // 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 86public:87  explicit Interpreter(std::unique_ptr<Module> M);88  ~Interpreter() override;89 90  /// runAtExitHandlers - Run any functions registered by the program's calls to91  /// 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 stack117  void callFunction(Function *F, ArrayRef<GenericValue> ArgVals);118  void run();                // Execute instructions until nothing left to do119 120  // Opcode Implementations121  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 visitExtractElementInst(ExtractElementInst &I);164  void visitInsertElementInst(InsertElementInst &I);165  void visitShuffleVectorInst(ShuffleVectorInst &I);166 167  void visitExtractValueInst(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 187private:  // Helper functions188  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 any192  // PHI nodes in the top of the block.  This is used for intraprocedural193  // 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 namespace232 233#endif234