dd49c94dccaf064cf7ff1d3c8d48b60594828216
[oota-llvm.git] / include / llvm / ExecutionEngine / Orc / LookasideRTDyldMM.h
1 //===- LookasideRTDyldMM - Redirect symbol lookup via a functor -*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //   Defines an adapter for RuntimeDyldMM that allows lookups for external
11 // symbols to go via a functor.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_EXECUTIONENGINE_ORC_LOOKASIDERTDYLDMM_H
16 #define LLVM_EXECUTIONENGINE_ORC_LOOKASIDERTDYLDMM_H
17
18 #include "llvm/ADT/STLExtras.h"
19 #include <memory>
20 #include <vector>
21
22 namespace llvm {
23
24 /// @brief Defines an adapter for RuntimeDyldMM that allows lookups for external
25 ///        symbols to go via a functor, before falling back to the lookup logic
26 ///        provided by the underlying RuntimeDyldMM instance.
27 ///
28 ///   This class is useful for redirecting symbol lookup back to various layers
29 /// of a JIT component stack, e.g. to enable lazy module emission.
30 ///
31 template <typename BaseRTDyldMM, typename ExternalLookupFtor,
32           typename DylibLookupFtor>
33 class LookasideRTDyldMM : public BaseRTDyldMM {
34 public:
35   /// @brief Create a LookasideRTDyldMM intance.
36   LookasideRTDyldMM(ExternalLookupFtor ExternalLookup,
37                     DylibLookupFtor DylibLookup)
38       : ExternalLookup(std::move(ExternalLookup)),
39         DylibLookup(std::move(DylibLookup)) {}
40
41   /// @brief Look up the given symbol address, first via the functor this
42   ///        instance was created with, then (if the symbol isn't found)
43   ///        via the underlying RuntimeDyldMM.
44   uint64_t getSymbolAddress(const std::string &Name) override {
45     if (uint64_t Addr = ExternalLookup(Name))
46       return Addr;
47     return BaseRTDyldMM::getSymbolAddress(Name);
48   }
49
50   uint64_t getSymbolAddressInLogicalDylib(const std::string &Name) override {
51     if (uint64_t Addr = DylibLookup(Name))
52       return Addr;
53     return BaseRTDyldMM::getSymbolAddressInLogicalDylib(Name);
54   };
55
56   /// @brief Get a reference to the ExternalLookup functor.
57   ExternalLookupFtor &getExternalLookup() { return ExternalLookup; }
58
59   /// @brief Get a const-reference to the ExternalLookup functor.
60   const ExternalLookupFtor &getExternalLookup() const { return ExternalLookup; }
61
62   /// @brief Get a reference to the DylibLookup functor.
63   DylibLookupFtor &getDylibLookup() { return DylibLookup; }
64
65   /// @brief Get a const-reference to the DylibLookup functor.
66   const DylibLookupFtor &getDylibLookup() const { return DylibLookup; }
67
68 private:
69   ExternalLookupFtor ExternalLookup;
70   DylibLookupFtor DylibLookup;
71 };
72
73 /// @brief Create a LookasideRTDyldMM from a base memory manager type, an
74 ///        external lookup functor, and a dylib lookup functor.
75 template <typename BaseRTDyldMM, typename ExternalLookupFtor,
76           typename DylibLookupFtor>
77 std::unique_ptr<
78     LookasideRTDyldMM<BaseRTDyldMM, ExternalLookupFtor, DylibLookupFtor>>
79 createLookasideRTDyldMM(ExternalLookupFtor &&ExternalLookup,
80                         DylibLookupFtor &&DylibLookup) {
81   typedef LookasideRTDyldMM<BaseRTDyldMM, ExternalLookupFtor, DylibLookupFtor>
82       ThisLookasideMM;
83   return llvm::make_unique<ThisLookasideMM>(
84       std::forward<ExternalLookupFtor>(ExternalLookup),
85       std::forward<DylibLookupFtor>(DylibLookup));
86 }
87 }
88
89 #endif // LLVM_EXECUTIONENGINE_ORC_LOOKASIDERTDYLDMM_H