brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.1 KiB · 2b9149e Raw
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