4456404565654f6b8af850f685834fd8dc83dfe8
[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 namespace orc {
24
25 /// @brief Defines an adapter for RuntimeDyldMM that allows lookups for external
26 ///        symbols to go via a functor, before falling back to the lookup logic
27 ///        provided by the underlying RuntimeDyldMM instance.
28 ///
29 ///   This class is useful for redirecting symbol lookup back to various layers
30 /// of a JIT component stack, e.g. to enable lazy module emission.
31 ///
32 template <typename BaseRTDyldMM, typename ExternalLookupFtor,
33           typename DylibLookupFtor>
34 class LookasideRTDyldMM : public BaseRTDyldMM {
35 public:
36   /// @brief Create a LookasideRTDyldMM intance.
37   LookasideRTDyldMM(ExternalLookupFtor ExternalLookup,
38                     DylibLookupFtor DylibLookup)
39       : ExternalLookup(std::move(ExternalLookup)),
40         DylibLookup(std::move(DylibLookup)) {}
41
42   /// @brief Look up the given symbol address, first via the functor this
43   ///        instance was created with, then (if the symbol isn't found)
44   ///        via the underlying RuntimeDyldMM.
45   uint64_t getSymbolAddress(const std::string &Name) override {
46     if (uint64_t Addr = ExternalLookup(Name))
47       return Addr;
48     return BaseRTDyldMM::getSymbolAddress(Name);
49   }
50
51   uint64_t getSymbolAddressInLogicalDylib(const std::string &Name) override {
52     if (uint64_t Addr = DylibLookup(Name))
53       return Addr;
54     return BaseRTDyldMM::getSymbolAddressInLogicalDylib(Name);
55   };
56
57   /// @brief Get a reference to the ExternalLookup functor.
58   ExternalLookupFtor &getExternalLookup() { return ExternalLookup; }
59
60   /// @brief Get a const-reference to the ExternalLookup functor.
61   const ExternalLookupFtor &getExternalLookup() const { return ExternalLookup; }
62
63   /// @brief Get a reference to the DylibLookup functor.
64   DylibLookupFtor &getDylibLookup() { return DylibLookup; }
65
66   /// @brief Get a const-reference to the DylibLookup functor.
67   const DylibLookupFtor &getDylibLookup() const { return DylibLookup; }
68
69 private:
70   ExternalLookupFtor ExternalLookup;
71   DylibLookupFtor DylibLookup;
72 };
73
74 /// @brief Create a LookasideRTDyldMM from a base memory manager type, an
75 ///        external lookup functor, and a dylib lookup functor.
76 template <typename BaseRTDyldMM, typename ExternalLookupFtor,
77           typename DylibLookupFtor>
78 std::unique_ptr<
79     LookasideRTDyldMM<BaseRTDyldMM, ExternalLookupFtor, DylibLookupFtor>>
80 createLookasideRTDyldMM(ExternalLookupFtor &&ExternalLookup,
81                         DylibLookupFtor &&DylibLookup) {
82   typedef LookasideRTDyldMM<BaseRTDyldMM, ExternalLookupFtor, DylibLookupFtor>
83       ThisLookasideMM;
84   return llvm::make_unique<ThisLookasideMM>(
85       std::forward<ExternalLookupFtor>(ExternalLookup),
86       std::forward<DylibLookupFtor>(DylibLookup));
87 }
88
89 } // End namespace orc.
90 } // End namespace llvm.
91
92 #endif // LLVM_EXECUTIONENGINE_ORC_LOOKASIDERTDYLDMM_H