[Orc] Add support for emitting indirect stubs directly into the JIT target's
[oota-llvm.git] / include / llvm / ExecutionEngine / Orc / LogicalDylib.h
1 //===--- LogicalDylib.h - Simulates dylib-style symbol lookup ---*- 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 // Simulates symbol resolution inside a dylib.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_EXECUTIONENGINE_ORC_LOGICALDYLIB_H
15 #define LLVM_EXECUTIONENGINE_ORC_LOGICALDYLIB_H
16
17 namespace llvm {
18 namespace orc {
19
20 template <typename BaseLayerT,
21           typename LogicalModuleResources,
22           typename LogicalDylibResources>
23 class LogicalDylib {
24 public:
25   typedef typename BaseLayerT::ModuleSetHandleT BaseLayerModuleSetHandleT;
26 private:
27
28   typedef std::vector<BaseLayerModuleSetHandleT> BaseLayerHandleList;
29
30   struct LogicalModule {
31     // Make this move-only to ensure they don't get duplicated across moves of
32     // LogicalDylib or anything like that.
33     LogicalModule(LogicalModule &&RHS)
34         : Resources(std::move(RHS.Resources)),
35           BaseLayerHandles(std::move(RHS.BaseLayerHandles)) {}
36     LogicalModule() = default;
37     LogicalModuleResources Resources;
38     BaseLayerHandleList BaseLayerHandles;
39   };
40   typedef std::vector<LogicalModule> LogicalModuleList;
41
42 public:
43
44   typedef typename BaseLayerHandleList::iterator BaseLayerHandleIterator;
45   typedef typename LogicalModuleList::iterator LogicalModuleHandle;
46
47   LogicalDylib(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {}
48
49   ~LogicalDylib() {
50     for (auto &LM : LogicalModules)
51       for (auto BLH : LM.BaseLayerHandles)
52         BaseLayer.removeModuleSet(BLH);
53   }
54
55   // If possible, remove this and ~LogicalDylib once the work in the dtor is
56   // moved to members (eg: self-unregistering base layer handles).
57   LogicalDylib(LogicalDylib &&RHS)
58       : BaseLayer(std::move(RHS.BaseLayer)),
59         LogicalModules(std::move(RHS.LogicalModules)),
60         DylibResources(std::move(RHS.DylibResources)) {}
61
62   LogicalModuleHandle createLogicalModule() {
63     LogicalModules.push_back(LogicalModule());
64     return std::prev(LogicalModules.end());
65   }
66
67   void addToLogicalModule(LogicalModuleHandle LMH,
68                           BaseLayerModuleSetHandleT BaseLayerHandle) {
69     LMH->BaseLayerHandles.push_back(BaseLayerHandle);
70   }
71
72   LogicalModuleResources& getLogicalModuleResources(LogicalModuleHandle LMH) {
73     return LMH->Resources;
74   }
75
76   BaseLayerHandleIterator moduleHandlesBegin(LogicalModuleHandle LMH) {
77     return LMH->BaseLayerHandles.begin();
78   }
79
80   BaseLayerHandleIterator moduleHandlesEnd(LogicalModuleHandle LMH) {
81     return LMH->BaseLayerHandles.end();
82   }
83
84   JITSymbol findSymbolInLogicalModule(LogicalModuleHandle LMH,
85                                       const std::string &Name,
86                                       bool ExportedSymbolsOnly) {
87
88     if (auto StubSym = LMH->Resources.findSymbol(Name, ExportedSymbolsOnly))
89       return StubSym;
90
91     for (auto BLH : LMH->BaseLayerHandles)
92       if (auto Symbol = BaseLayer.findSymbolIn(BLH, Name, ExportedSymbolsOnly))
93         return Symbol;
94     return nullptr;
95   }
96
97   JITSymbol findSymbolInternally(LogicalModuleHandle LMH,
98                                  const std::string &Name) {
99     if (auto Symbol = findSymbolInLogicalModule(LMH, Name, false))
100       return Symbol;
101
102     for (auto LMI = LogicalModules.begin(), LME = LogicalModules.end();
103            LMI != LME; ++LMI) {
104       if (LMI != LMH)
105         if (auto Symbol = findSymbolInLogicalModule(LMI, Name, false))
106           return Symbol;
107     }
108
109     return nullptr;
110   }
111
112   JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
113     for (auto LMI = LogicalModules.begin(), LME = LogicalModules.end();
114          LMI != LME; ++LMI)
115       if (auto Sym = findSymbolInLogicalModule(LMI, Name, ExportedSymbolsOnly))
116         return Sym;
117     return nullptr;
118   }
119
120   LogicalDylibResources& getDylibResources() { return DylibResources; }
121
122 protected:
123   BaseLayerT BaseLayer;
124   LogicalModuleList LogicalModules;
125   LogicalDylibResources DylibResources;
126 };
127
128 } // End namespace orc.
129 } // End namespace llvm.
130
131 #endif // LLVM_EXECUTIONENGINE_ORC_LOGICALDYLIB_H