Path: blob/main/contrib/llvm-project/llvm/lib/ExecutionEngine/Interpreter/Interpreter.cpp
35271 views
//===- Interpreter.cpp - Top-Level LLVM Interpreter Implementation --------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements the top-level functionality for the LLVM interpreter.9// This interpreter is designed to be a very simple, portable, inefficient10// interpreter.11//12//===----------------------------------------------------------------------===//1314#include "Interpreter.h"15#include "llvm/CodeGen/IntrinsicLowering.h"16#include "llvm/IR/DerivedTypes.h"17#include "llvm/IR/Module.h"18#include <cstring>19using namespace llvm;2021namespace {2223static struct RegisterInterp {24RegisterInterp() { Interpreter::Register(); }25} InterpRegistrator;2627}2829extern "C" void LLVMLinkInInterpreter() { }3031/// Create a new interpreter object.32///33ExecutionEngine *Interpreter::create(std::unique_ptr<Module> M,34std::string *ErrStr) {35// Tell this Module to materialize everything and release the GVMaterializer.36if (Error Err = M->materializeAll()) {37std::string Msg;38handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) {39Msg = EIB.message();40});41if (ErrStr)42*ErrStr = Msg;43// We got an error, just return 044return nullptr;45}4647return new Interpreter(std::move(M));48}4950//===----------------------------------------------------------------------===//51// Interpreter ctor - Initialize stuff52//53Interpreter::Interpreter(std::unique_ptr<Module> M)54: ExecutionEngine(std::move(M)) {5556memset(&ExitValue.Untyped, 0, sizeof(ExitValue.Untyped));57// Initialize the "backend"58initializeExecutionEngine();59initializeExternalFunctions();60emitGlobals();6162IL = new IntrinsicLowering(getDataLayout());63}6465Interpreter::~Interpreter() {66delete IL;67}6869void Interpreter::runAtExitHandlers () {70while (!AtExitHandlers.empty()) {71callFunction(AtExitHandlers.back(), std::nullopt);72AtExitHandlers.pop_back();73run();74}75}7677/// run - Start execution with the specified function and arguments.78///79GenericValue Interpreter::runFunction(Function *F,80ArrayRef<GenericValue> ArgValues) {81assert (F && "Function *F was null at entry to run()");8283// Try extra hard not to pass extra args to a function that isn't84// expecting them. C programmers frequently bend the rules and85// declare main() with fewer parameters than it actually gets86// passed, and the interpreter barfs if you pass a function more87// parameters than it is declared to take. This does not attempt to88// take into account gratuitous differences in declared types,89// though.90const size_t ArgCount = F->getFunctionType()->getNumParams();91ArrayRef<GenericValue> ActualArgs =92ArgValues.slice(0, std::min(ArgValues.size(), ArgCount));9394// Set up the function call.95callFunction(F, ActualArgs);9697// Start executing the function.98run();99100return ExitValue;101}102103104