1996fe010SChris Lattner //===- Interpreter.cpp - Top-Level LLVM Interpreter Implementation --------===//
2996fe010SChris Lattner //
3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
5*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6482202a6SJohn Criswell //
7482202a6SJohn Criswell //===----------------------------------------------------------------------===//
8482202a6SJohn Criswell //
9996fe010SChris Lattner // This file implements the top-level functionality for the LLVM interpreter.
10996fe010SChris Lattner // This interpreter is designed to be a very simple, portable, inefficient
11996fe010SChris Lattner // interpreter.
12996fe010SChris Lattner //
13996fe010SChris Lattner //===----------------------------------------------------------------------===//
14996fe010SChris Lattner
15996fe010SChris Lattner #include "Interpreter.h"
16bcdadf37SChris Lattner #include "llvm/CodeGen/IntrinsicLowering.h"
179fb823bbSChandler Carruth #include "llvm/IR/DerivedTypes.h"
189fb823bbSChandler Carruth #include "llvm/IR/Module.h"
19579f0713SAnton Korobeynikov #include <cstring>
2018099661SChris Lattner using namespace llvm;
21960707c3SBrian Gaeke
22d78c400bSDan Gohman namespace {
23d78c400bSDan Gohman
242d52c1b8SChris Lattner static struct RegisterInterp {
RegisterInterp__anonc3db43d00111::RegisterInterp252d52c1b8SChris Lattner RegisterInterp() { Interpreter::Register(); }
262d52c1b8SChris Lattner } InterpRegistrator;
272d52c1b8SChris Lattner
28d78c400bSDan Gohman }
29d78c400bSDan Gohman
LLVMLinkInInterpreter()30a1d3e660SBob Wilson extern "C" void LLVMLinkInInterpreter() { }
310eafbc35SJeff Cohen
322a8a2795SRafael Espindola /// Create a new interpreter object.
33996fe010SChris Lattner ///
create(std::unique_ptr<Module> M,std::string * ErrStr)342a8a2795SRafael Espindola ExecutionEngine *Interpreter::create(std::unique_ptr<Module> M,
352a8a2795SRafael Espindola std::string *ErrStr) {
36091217beSJeffrey Yasskin // Tell this Module to materialize everything and release the GVMaterializer.
377f00d0a1SPeter Collingbourne if (Error Err = M->materializeAll()) {
387f00d0a1SPeter Collingbourne std::string Msg;
397f00d0a1SPeter Collingbourne handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) {
407f00d0a1SPeter Collingbourne Msg = EIB.message();
417f00d0a1SPeter Collingbourne });
42e9fab9b0SRafael Espindola if (ErrStr)
437f00d0a1SPeter Collingbourne *ErrStr = Msg;
44603682adSReid Spencer // We got an error, just return 0
45353eda48SCraig Topper return nullptr;
46e9fab9b0SRafael Espindola }
47603682adSReid Spencer
482a8a2795SRafael Espindola return new Interpreter(std::move(M));
49996fe010SChris Lattner }
50996fe010SChris Lattner
51996fe010SChris Lattner //===----------------------------------------------------------------------===//
52996fe010SChris Lattner // Interpreter ctor - Initialize stuff
53996fe010SChris Lattner //
Interpreter(std::unique_ptr<Module> M)542a8a2795SRafael Espindola Interpreter::Interpreter(std::unique_ptr<Module> M)
55a3fcefb6SMehdi Amini : ExecutionEngine(std::move(M)) {
56996fe010SChris Lattner
57ff38cf88SReid Spencer memset(&ExitValue.Untyped, 0, sizeof(ExitValue.Untyped));
58996fe010SChris Lattner // Initialize the "backend"
59996fe010SChris Lattner initializeExecutionEngine();
60470754e3SChris Lattner initializeExternalFunctions();
61b78244f9SChris Lattner emitGlobals();
62c8c6c03dSChris Lattner
63a3fcefb6SMehdi Amini IL = new IntrinsicLowering(getDataLayout());
64c8c6c03dSChris Lattner }
65c8c6c03dSChris Lattner
~Interpreter()66c8c6c03dSChris Lattner Interpreter::~Interpreter() {
67c8c6c03dSChris Lattner delete IL;
68996fe010SChris Lattner }
69996fe010SChris Lattner
runAtExitHandlers()70a7669038SBrian Gaeke void Interpreter::runAtExitHandlers () {
71a7669038SBrian Gaeke while (!AtExitHandlers.empty()) {
72bd7b1c89SBenjamin Kramer callFunction(AtExitHandlers.back(), None);
734a5bb957SChris Lattner AtExitHandlers.pop_back();
744a5bb957SChris Lattner run();
754a5bb957SChris Lattner }
76996fe010SChris Lattner }
77996fe010SChris Lattner
78a7669038SBrian Gaeke /// run - Start execution with the specified function and arguments.
79a7669038SBrian Gaeke ///
runFunction(Function * F,ArrayRef<GenericValue> ArgValues)80bd7b1c89SBenjamin Kramer GenericValue Interpreter::runFunction(Function *F,
81bd7b1c89SBenjamin Kramer ArrayRef<GenericValue> ArgValues) {
82a7669038SBrian Gaeke assert (F && "Function *F was null at entry to run()");
8384217657SBrian Gaeke
84a7669038SBrian Gaeke // Try extra hard not to pass extra args to a function that isn't
85a7669038SBrian Gaeke // expecting them. C programmers frequently bend the rules and
86a7669038SBrian Gaeke // declare main() with fewer parameters than it actually gets
87a7669038SBrian Gaeke // passed, and the interpreter barfs if you pass a function more
88a7669038SBrian Gaeke // parameters than it is declared to take. This does not attempt to
89a7669038SBrian Gaeke // take into account gratuitous differences in declared types,
90a7669038SBrian Gaeke // though.
91bd7b1c89SBenjamin Kramer const size_t ArgCount = F->getFunctionType()->getNumParams();
92bd7b1c89SBenjamin Kramer ArrayRef<GenericValue> ActualArgs =
93bd7b1c89SBenjamin Kramer ArgValues.slice(0, std::min(ArgValues.size(), ArgCount));
9484217657SBrian Gaeke
95a7669038SBrian Gaeke // Set up the function call.
96a7669038SBrian Gaeke callFunction(F, ActualArgs);
9784217657SBrian Gaeke
98a7669038SBrian Gaeke // Start executing the function.
99a7669038SBrian Gaeke run();
100a7669038SBrian Gaeke
1012439669cSJeff Cohen return ExitValue;
10284217657SBrian Gaeke }
103