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