103 lines · cpp
1//===- Interpreter.cpp - Top-Level LLVM Interpreter Implementation --------===//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 file implements the top-level functionality for the LLVM interpreter.10// This interpreter is designed to be a very simple, portable, inefficient11// interpreter.12//13//===----------------------------------------------------------------------===//14 15#include "Interpreter.h"16#include "llvm/CodeGen/IntrinsicLowering.h"17#include "llvm/IR/DerivedTypes.h"18#include "llvm/IR/Module.h"19#include <cstring>20using namespace llvm;21 22namespace {23 24static struct RegisterInterp {25 RegisterInterp() { Interpreter::Register(); }26} InterpRegistrator;27 28}29 30extern "C" void LLVMLinkInInterpreter() { }31 32/// Create a new interpreter object.33///34ExecutionEngine *Interpreter::create(std::unique_ptr<Module> M,35 std::string *ErrStr) {36 // Tell this Module to materialize everything and release the GVMaterializer.37 if (Error Err = M->materializeAll()) {38 std::string Msg;39 handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) {40 Msg = EIB.message();41 });42 if (ErrStr)43 *ErrStr = Msg;44 // We got an error, just return 045 return nullptr;46 }47 48 return new Interpreter(std::move(M));49}50 51//===----------------------------------------------------------------------===//52// Interpreter ctor - Initialize stuff53//54Interpreter::Interpreter(std::unique_ptr<Module> M)55 : ExecutionEngine(std::move(M)) {56 57 memset(&ExitValue.Untyped, 0, sizeof(ExitValue.Untyped));58 // Initialize the "backend"59 initializeExecutionEngine();60 initializeExternalFunctions();61 emitGlobals();62 63 IL = new IntrinsicLowering(getDataLayout());64}65 66Interpreter::~Interpreter() {67 delete IL;68}69 70void Interpreter::runAtExitHandlers () {71 while (!AtExitHandlers.empty()) {72 callFunction(AtExitHandlers.back(), {});73 AtExitHandlers.pop_back();74 run();75 }76}77 78/// run - Start execution with the specified function and arguments.79///80GenericValue Interpreter::runFunction(Function *F,81 ArrayRef<GenericValue> ArgValues) {82 assert (F && "Function *F was null at entry to run()");83 84 // Try extra hard not to pass extra args to a function that isn't85 // expecting them. C programmers frequently bend the rules and86 // declare main() with fewer parameters than it actually gets87 // passed, and the interpreter barfs if you pass a function more88 // parameters than it is declared to take. This does not attempt to89 // take into account gratuitous differences in declared types,90 // though.91 const size_t ArgCount = F->getFunctionType()->getNumParams();92 ArrayRef<GenericValue> ActualArgs =93 ArgValues.slice(0, std::min(ArgValues.size(), ArgCount));94 95 // Set up the function call.96 callFunction(F, ActualArgs);97 98 // Start executing the function.99 run();100 101 return ExitValue;102}103