Home | History | Annotate | Download | only in Interpreter
      1 //===- Interpreter.cpp - Top-Level LLVM Interpreter Implementation --------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file implements the top-level functionality for the LLVM interpreter.
     11 // This interpreter is designed to be a very simple, portable, inefficient
     12 // interpreter.
     13 //
     14 //===----------------------------------------------------------------------===//
     15 
     16 #include "Interpreter.h"
     17 #include "llvm/CodeGen/IntrinsicLowering.h"
     18 #include "llvm/IR/DerivedTypes.h"
     19 #include "llvm/IR/Module.h"
     20 #include <cstring>
     21 using namespace llvm;
     22 
     23 namespace {
     24 
     25 static struct RegisterInterp {
     26   RegisterInterp() { Interpreter::Register(); }
     27 } InterpRegistrator;
     28 
     29 }
     30 
     31 extern "C" void LLVMLinkInInterpreter() { }
     32 
     33 /// Create a new interpreter object.
     34 ///
     35 ExecutionEngine *Interpreter::create(std::unique_ptr<Module> M,
     36                                      std::string *ErrStr) {
     37   // Tell this Module to materialize everything and release the GVMaterializer.
     38   if (std::error_code EC = M->materializeAll()) {
     39     if (ErrStr)
     40       *ErrStr = EC.message();
     41     // We got an error, just return 0
     42     return nullptr;
     43   }
     44 
     45   return new Interpreter(std::move(M));
     46 }
     47 
     48 //===----------------------------------------------------------------------===//
     49 // Interpreter ctor - Initialize stuff
     50 //
     51 Interpreter::Interpreter(std::unique_ptr<Module> M)
     52     : ExecutionEngine(std::move(M)) {
     53 
     54   memset(&ExitValue.Untyped, 0, sizeof(ExitValue.Untyped));
     55   // Initialize the "backend"
     56   initializeExecutionEngine();
     57   initializeExternalFunctions();
     58   emitGlobals();
     59 
     60   IL = new IntrinsicLowering(getDataLayout());
     61 }
     62 
     63 Interpreter::~Interpreter() {
     64   delete IL;
     65 }
     66 
     67 void Interpreter::runAtExitHandlers () {
     68   while (!AtExitHandlers.empty()) {
     69     callFunction(AtExitHandlers.back(), None);
     70     AtExitHandlers.pop_back();
     71     run();
     72   }
     73 }
     74 
     75 /// run - Start execution with the specified function and arguments.
     76 ///
     77 GenericValue Interpreter::runFunction(Function *F,
     78                                       ArrayRef<GenericValue> ArgValues) {
     79   assert (F && "Function *F was null at entry to run()");
     80 
     81   // Try extra hard not to pass extra args to a function that isn't
     82   // expecting them.  C programmers frequently bend the rules and
     83   // declare main() with fewer parameters than it actually gets
     84   // passed, and the interpreter barfs if you pass a function more
     85   // parameters than it is declared to take. This does not attempt to
     86   // take into account gratuitous differences in declared types,
     87   // though.
     88   const size_t ArgCount = F->getFunctionType()->getNumParams();
     89   ArrayRef<GenericValue> ActualArgs =
     90       ArgValues.slice(0, std::min(ArgValues.size(), ArgCount));
     91 
     92   // Set up the function call.
     93   callFunction(F, ActualArgs);
     94 
     95   // Start executing the function.
     96   run();
     97 
     98   return ExitValue;
     99 }
    100