File: | src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ADT/IntrusiveRefCntPtr.h |
Warning: | line 219, column 7 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===--------------- OrcV2CBindings.cpp - C bindings OrcV2 APIs -----------===// | |||
2 | // | |||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |||
4 | // See https://llvm.org/LICENSE.txt for license information. | |||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |||
6 | // | |||
7 | //===----------------------------------------------------------------------===// | |||
8 | ||||
9 | #include "llvm-c/LLJIT.h" | |||
10 | #include "llvm-c/Orc.h" | |||
11 | #include "llvm-c/OrcEE.h" | |||
12 | #include "llvm-c/TargetMachine.h" | |||
13 | ||||
14 | #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h" | |||
15 | #include "llvm/ExecutionEngine/Orc/LLJIT.h" | |||
16 | #include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h" | |||
17 | #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" | |||
18 | #include "llvm/ExecutionEngine/SectionMemoryManager.h" | |||
19 | ||||
20 | using namespace llvm; | |||
21 | using namespace llvm::orc; | |||
22 | ||||
23 | namespace llvm { | |||
24 | namespace orc { | |||
25 | ||||
26 | class InProgressLookupState; | |||
27 | ||||
28 | class OrcV2CAPIHelper { | |||
29 | public: | |||
30 | using PoolEntry = SymbolStringPtr::PoolEntry; | |||
31 | using PoolEntryPtr = SymbolStringPtr::PoolEntryPtr; | |||
32 | ||||
33 | // Move from SymbolStringPtr to PoolEntryPtr (no change in ref count). | |||
34 | static PoolEntryPtr moveFromSymbolStringPtr(SymbolStringPtr S) { | |||
35 | PoolEntryPtr Result = nullptr; | |||
36 | std::swap(Result, S.S); | |||
37 | return Result; | |||
38 | } | |||
39 | ||||
40 | // Move from a PoolEntryPtr to a SymbolStringPtr (no change in ref count). | |||
41 | static SymbolStringPtr moveToSymbolStringPtr(PoolEntryPtr P) { | |||
42 | SymbolStringPtr S; | |||
43 | S.S = P; | |||
44 | return S; | |||
45 | } | |||
46 | ||||
47 | // Copy a pool entry to a SymbolStringPtr (increments ref count). | |||
48 | static SymbolStringPtr copyToSymbolStringPtr(PoolEntryPtr P) { | |||
49 | return SymbolStringPtr(P); | |||
50 | } | |||
51 | ||||
52 | static PoolEntryPtr getRawPoolEntryPtr(const SymbolStringPtr &S) { | |||
53 | return S.S; | |||
54 | } | |||
55 | ||||
56 | static void retainPoolEntry(PoolEntryPtr P) { | |||
57 | SymbolStringPtr S(P); | |||
58 | S.S = nullptr; | |||
59 | } | |||
60 | ||||
61 | static void releasePoolEntry(PoolEntryPtr P) { | |||
62 | SymbolStringPtr S; | |||
63 | S.S = P; | |||
64 | } | |||
65 | ||||
66 | static InProgressLookupState *extractLookupState(LookupState &LS) { | |||
67 | return LS.IPLS.release(); | |||
68 | } | |||
69 | ||||
70 | static void resetLookupState(LookupState &LS, InProgressLookupState *IPLS) { | |||
71 | return LS.reset(IPLS); | |||
72 | } | |||
73 | }; | |||
74 | ||||
75 | } // namespace orc | |||
76 | } // namespace llvm | |||
77 | ||||
78 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ExecutionSession, LLVMOrcExecutionSessionRef)inline ExecutionSession *unwrap(LLVMOrcExecutionSessionRef P) { return reinterpret_cast<ExecutionSession*>(P); } inline LLVMOrcExecutionSessionRef wrap(const ExecutionSession *P) { return reinterpret_cast<LLVMOrcExecutionSessionRef>(const_cast <ExecutionSession*>(P)); } | |||
79 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SymbolStringPool, LLVMOrcSymbolStringPoolRef)inline SymbolStringPool *unwrap(LLVMOrcSymbolStringPoolRef P) { return reinterpret_cast<SymbolStringPool*>(P); } inline LLVMOrcSymbolStringPoolRef wrap(const SymbolStringPool *P) { return reinterpret_cast<LLVMOrcSymbolStringPoolRef>(const_cast <SymbolStringPool*>(P)); } | |||
80 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcV2CAPIHelper::PoolEntry,inline OrcV2CAPIHelper::PoolEntry *unwrap(LLVMOrcSymbolStringPoolEntryRef P) { return reinterpret_cast<OrcV2CAPIHelper::PoolEntry*> (P); } inline LLVMOrcSymbolStringPoolEntryRef wrap(const OrcV2CAPIHelper ::PoolEntry *P) { return reinterpret_cast<LLVMOrcSymbolStringPoolEntryRef >(const_cast<OrcV2CAPIHelper::PoolEntry*>(P)); } | |||
81 | LLVMOrcSymbolStringPoolEntryRef)inline OrcV2CAPIHelper::PoolEntry *unwrap(LLVMOrcSymbolStringPoolEntryRef P) { return reinterpret_cast<OrcV2CAPIHelper::PoolEntry*> (P); } inline LLVMOrcSymbolStringPoolEntryRef wrap(const OrcV2CAPIHelper ::PoolEntry *P) { return reinterpret_cast<LLVMOrcSymbolStringPoolEntryRef >(const_cast<OrcV2CAPIHelper::PoolEntry*>(P)); } | |||
82 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MaterializationUnit,inline MaterializationUnit *unwrap(LLVMOrcMaterializationUnitRef P) { return reinterpret_cast<MaterializationUnit*>(P); } inline LLVMOrcMaterializationUnitRef wrap(const MaterializationUnit *P) { return reinterpret_cast<LLVMOrcMaterializationUnitRef >(const_cast<MaterializationUnit*>(P)); } | |||
83 | LLVMOrcMaterializationUnitRef)inline MaterializationUnit *unwrap(LLVMOrcMaterializationUnitRef P) { return reinterpret_cast<MaterializationUnit*>(P); } inline LLVMOrcMaterializationUnitRef wrap(const MaterializationUnit *P) { return reinterpret_cast<LLVMOrcMaterializationUnitRef >(const_cast<MaterializationUnit*>(P)); } | |||
84 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MaterializationResponsibility,inline MaterializationResponsibility *unwrap(LLVMOrcMaterializationResponsibilityRef P) { return reinterpret_cast<MaterializationResponsibility *>(P); } inline LLVMOrcMaterializationResponsibilityRef wrap (const MaterializationResponsibility *P) { return reinterpret_cast <LLVMOrcMaterializationResponsibilityRef>(const_cast< MaterializationResponsibility*>(P)); } | |||
85 | LLVMOrcMaterializationResponsibilityRef)inline MaterializationResponsibility *unwrap(LLVMOrcMaterializationResponsibilityRef P) { return reinterpret_cast<MaterializationResponsibility *>(P); } inline LLVMOrcMaterializationResponsibilityRef wrap (const MaterializationResponsibility *P) { return reinterpret_cast <LLVMOrcMaterializationResponsibilityRef>(const_cast< MaterializationResponsibility*>(P)); } | |||
86 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(JITDylib, LLVMOrcJITDylibRef)inline JITDylib *unwrap(LLVMOrcJITDylibRef P) { return reinterpret_cast <JITDylib*>(P); } inline LLVMOrcJITDylibRef wrap(const JITDylib *P) { return reinterpret_cast<LLVMOrcJITDylibRef>(const_cast <JITDylib*>(P)); } | |||
87 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ResourceTracker, LLVMOrcResourceTrackerRef)inline ResourceTracker *unwrap(LLVMOrcResourceTrackerRef P) { return reinterpret_cast<ResourceTracker*>(P); } inline LLVMOrcResourceTrackerRef wrap(const ResourceTracker *P) { return reinterpret_cast<LLVMOrcResourceTrackerRef>(const_cast <ResourceTracker*>(P)); } | |||
88 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DefinitionGenerator,inline DefinitionGenerator *unwrap(LLVMOrcDefinitionGeneratorRef P) { return reinterpret_cast<DefinitionGenerator*>(P); } inline LLVMOrcDefinitionGeneratorRef wrap(const DefinitionGenerator *P) { return reinterpret_cast<LLVMOrcDefinitionGeneratorRef >(const_cast<DefinitionGenerator*>(P)); } | |||
89 | LLVMOrcDefinitionGeneratorRef)inline DefinitionGenerator *unwrap(LLVMOrcDefinitionGeneratorRef P) { return reinterpret_cast<DefinitionGenerator*>(P); } inline LLVMOrcDefinitionGeneratorRef wrap(const DefinitionGenerator *P) { return reinterpret_cast<LLVMOrcDefinitionGeneratorRef >(const_cast<DefinitionGenerator*>(P)); } | |||
90 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(InProgressLookupState, LLVMOrcLookupStateRef)inline InProgressLookupState *unwrap(LLVMOrcLookupStateRef P) { return reinterpret_cast<InProgressLookupState*>(P); } inline LLVMOrcLookupStateRef wrap(const InProgressLookupState *P) { return reinterpret_cast<LLVMOrcLookupStateRef>(const_cast <InProgressLookupState*>(P)); } | |||
91 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ThreadSafeContext,inline ThreadSafeContext *unwrap(LLVMOrcThreadSafeContextRef P ) { return reinterpret_cast<ThreadSafeContext*>(P); } inline LLVMOrcThreadSafeContextRef wrap(const ThreadSafeContext *P) { return reinterpret_cast<LLVMOrcThreadSafeContextRef> (const_cast<ThreadSafeContext*>(P)); } | |||
92 | LLVMOrcThreadSafeContextRef)inline ThreadSafeContext *unwrap(LLVMOrcThreadSafeContextRef P ) { return reinterpret_cast<ThreadSafeContext*>(P); } inline LLVMOrcThreadSafeContextRef wrap(const ThreadSafeContext *P) { return reinterpret_cast<LLVMOrcThreadSafeContextRef> (const_cast<ThreadSafeContext*>(P)); } | |||
93 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ThreadSafeModule, LLVMOrcThreadSafeModuleRef)inline ThreadSafeModule *unwrap(LLVMOrcThreadSafeModuleRef P) { return reinterpret_cast<ThreadSafeModule*>(P); } inline LLVMOrcThreadSafeModuleRef wrap(const ThreadSafeModule *P) { return reinterpret_cast<LLVMOrcThreadSafeModuleRef>(const_cast <ThreadSafeModule*>(P)); } | |||
94 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(JITTargetMachineBuilder,inline JITTargetMachineBuilder *unwrap(LLVMOrcJITTargetMachineBuilderRef P) { return reinterpret_cast<JITTargetMachineBuilder*> (P); } inline LLVMOrcJITTargetMachineBuilderRef wrap(const JITTargetMachineBuilder *P) { return reinterpret_cast<LLVMOrcJITTargetMachineBuilderRef >(const_cast<JITTargetMachineBuilder*>(P)); } | |||
95 | LLVMOrcJITTargetMachineBuilderRef)inline JITTargetMachineBuilder *unwrap(LLVMOrcJITTargetMachineBuilderRef P) { return reinterpret_cast<JITTargetMachineBuilder*> (P); } inline LLVMOrcJITTargetMachineBuilderRef wrap(const JITTargetMachineBuilder *P) { return reinterpret_cast<LLVMOrcJITTargetMachineBuilderRef >(const_cast<JITTargetMachineBuilder*>(P)); } | |||
96 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ObjectLayer, LLVMOrcObjectLayerRef)inline ObjectLayer *unwrap(LLVMOrcObjectLayerRef P) { return reinterpret_cast <ObjectLayer*>(P); } inline LLVMOrcObjectLayerRef wrap( const ObjectLayer *P) { return reinterpret_cast<LLVMOrcObjectLayerRef >(const_cast<ObjectLayer*>(P)); } | |||
97 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IRTransformLayer, LLVMOrcIRTransformLayerRef)inline IRTransformLayer *unwrap(LLVMOrcIRTransformLayerRef P) { return reinterpret_cast<IRTransformLayer*>(P); } inline LLVMOrcIRTransformLayerRef wrap(const IRTransformLayer *P) { return reinterpret_cast<LLVMOrcIRTransformLayerRef>(const_cast <IRTransformLayer*>(P)); } | |||
98 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ObjectTransformLayer,inline ObjectTransformLayer *unwrap(LLVMOrcObjectTransformLayerRef P) { return reinterpret_cast<ObjectTransformLayer*>(P) ; } inline LLVMOrcObjectTransformLayerRef wrap(const ObjectTransformLayer *P) { return reinterpret_cast<LLVMOrcObjectTransformLayerRef >(const_cast<ObjectTransformLayer*>(P)); } | |||
99 | LLVMOrcObjectTransformLayerRef)inline ObjectTransformLayer *unwrap(LLVMOrcObjectTransformLayerRef P) { return reinterpret_cast<ObjectTransformLayer*>(P) ; } inline LLVMOrcObjectTransformLayerRef wrap(const ObjectTransformLayer *P) { return reinterpret_cast<LLVMOrcObjectTransformLayerRef >(const_cast<ObjectTransformLayer*>(P)); } | |||
100 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DumpObjects, LLVMOrcDumpObjectsRef)inline DumpObjects *unwrap(LLVMOrcDumpObjectsRef P) { return reinterpret_cast <DumpObjects*>(P); } inline LLVMOrcDumpObjectsRef wrap( const DumpObjects *P) { return reinterpret_cast<LLVMOrcDumpObjectsRef >(const_cast<DumpObjects*>(P)); } | |||
101 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IndirectStubsManager,inline IndirectStubsManager *unwrap(LLVMOrcIndirectStubsManagerRef P) { return reinterpret_cast<IndirectStubsManager*>(P) ; } inline LLVMOrcIndirectStubsManagerRef wrap(const IndirectStubsManager *P) { return reinterpret_cast<LLVMOrcIndirectStubsManagerRef >(const_cast<IndirectStubsManager*>(P)); } | |||
102 | LLVMOrcIndirectStubsManagerRef)inline IndirectStubsManager *unwrap(LLVMOrcIndirectStubsManagerRef P) { return reinterpret_cast<IndirectStubsManager*>(P) ; } inline LLVMOrcIndirectStubsManagerRef wrap(const IndirectStubsManager *P) { return reinterpret_cast<LLVMOrcIndirectStubsManagerRef >(const_cast<IndirectStubsManager*>(P)); } | |||
103 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LazyCallThroughManager,inline LazyCallThroughManager *unwrap(LLVMOrcLazyCallThroughManagerRef P) { return reinterpret_cast<LazyCallThroughManager*>( P); } inline LLVMOrcLazyCallThroughManagerRef wrap(const LazyCallThroughManager *P) { return reinterpret_cast<LLVMOrcLazyCallThroughManagerRef >(const_cast<LazyCallThroughManager*>(P)); } | |||
104 | LLVMOrcLazyCallThroughManagerRef)inline LazyCallThroughManager *unwrap(LLVMOrcLazyCallThroughManagerRef P) { return reinterpret_cast<LazyCallThroughManager*>( P); } inline LLVMOrcLazyCallThroughManagerRef wrap(const LazyCallThroughManager *P) { return reinterpret_cast<LLVMOrcLazyCallThroughManagerRef >(const_cast<LazyCallThroughManager*>(P)); } | |||
105 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLJITBuilder, LLVMOrcLLJITBuilderRef)inline LLJITBuilder *unwrap(LLVMOrcLLJITBuilderRef P) { return reinterpret_cast<LLJITBuilder*>(P); } inline LLVMOrcLLJITBuilderRef wrap(const LLJITBuilder *P) { return reinterpret_cast<LLVMOrcLLJITBuilderRef >(const_cast<LLJITBuilder*>(P)); } | |||
106 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLJIT, LLVMOrcLLJITRef)inline LLJIT *unwrap(LLVMOrcLLJITRef P) { return reinterpret_cast <LLJIT*>(P); } inline LLVMOrcLLJITRef wrap(const LLJIT * P) { return reinterpret_cast<LLVMOrcLLJITRef>(const_cast <LLJIT*>(P)); } | |||
107 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)inline TargetMachine *unwrap(LLVMTargetMachineRef P) { return reinterpret_cast<TargetMachine*>(P); } inline LLVMTargetMachineRef wrap(const TargetMachine *P) { return reinterpret_cast<LLVMTargetMachineRef >(const_cast<TargetMachine*>(P)); } | |||
108 | ||||
109 | namespace llvm { | |||
110 | namespace orc { | |||
111 | ||||
112 | class CAPIDefinitionGenerator final : public DefinitionGenerator { | |||
113 | public: | |||
114 | CAPIDefinitionGenerator( | |||
115 | void *Ctx, | |||
116 | LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction TryToGenerate) | |||
117 | : Ctx(Ctx), TryToGenerate(TryToGenerate) {} | |||
118 | ||||
119 | Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD, | |||
120 | JITDylibLookupFlags JDLookupFlags, | |||
121 | const SymbolLookupSet &LookupSet) override { | |||
122 | ||||
123 | // Take the lookup state. | |||
124 | LLVMOrcLookupStateRef LSR = ::wrap(OrcV2CAPIHelper::extractLookupState(LS)); | |||
125 | ||||
126 | // Translate the lookup kind. | |||
127 | LLVMOrcLookupKind CLookupKind; | |||
128 | switch (K) { | |||
129 | case LookupKind::Static: | |||
130 | CLookupKind = LLVMOrcLookupKindStatic; | |||
131 | break; | |||
132 | case LookupKind::DLSym: | |||
133 | CLookupKind = LLVMOrcLookupKindDLSym; | |||
134 | break; | |||
135 | } | |||
136 | ||||
137 | // Translate the JITDylibSearchFlags. | |||
138 | LLVMOrcJITDylibLookupFlags CJDLookupFlags; | |||
139 | switch (JDLookupFlags) { | |||
140 | case JITDylibLookupFlags::MatchExportedSymbolsOnly: | |||
141 | CJDLookupFlags = LLVMOrcJITDylibLookupFlagsMatchExportedSymbolsOnly; | |||
142 | break; | |||
143 | case JITDylibLookupFlags::MatchAllSymbols: | |||
144 | CJDLookupFlags = LLVMOrcJITDylibLookupFlagsMatchAllSymbols; | |||
145 | break; | |||
146 | } | |||
147 | ||||
148 | // Translate the lookup set. | |||
149 | std::vector<LLVMOrcCLookupSetElement> CLookupSet; | |||
150 | CLookupSet.reserve(LookupSet.size()); | |||
151 | for (auto &KV : LookupSet) { | |||
152 | LLVMOrcSymbolLookupFlags SLF; | |||
153 | LLVMOrcSymbolStringPoolEntryRef Name = | |||
154 | ::wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(KV.first)); | |||
155 | switch (KV.second) { | |||
156 | case SymbolLookupFlags::RequiredSymbol: | |||
157 | SLF = LLVMOrcSymbolLookupFlagsRequiredSymbol; | |||
158 | break; | |||
159 | case SymbolLookupFlags::WeaklyReferencedSymbol: | |||
160 | SLF = LLVMOrcSymbolLookupFlagsWeaklyReferencedSymbol; | |||
161 | break; | |||
162 | } | |||
163 | CLookupSet.push_back({Name, SLF}); | |||
164 | } | |||
165 | ||||
166 | // Run the C TryToGenerate function. | |||
167 | auto Err = unwrap(TryToGenerate(::wrap(this), Ctx, &LSR, CLookupKind, | |||
168 | ::wrap(&JD), CJDLookupFlags, | |||
169 | CLookupSet.data(), CLookupSet.size())); | |||
170 | ||||
171 | // Restore the lookup state. | |||
172 | OrcV2CAPIHelper::resetLookupState(LS, ::unwrap(LSR)); | |||
173 | ||||
174 | return Err; | |||
175 | } | |||
176 | ||||
177 | private: | |||
178 | void *Ctx; | |||
179 | LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction TryToGenerate; | |||
180 | }; | |||
181 | ||||
182 | } // end namespace orc | |||
183 | } // end namespace llvm | |||
184 | ||||
185 | namespace { | |||
186 | ||||
187 | class OrcCAPIMaterializationUnit : public llvm::orc::MaterializationUnit { | |||
188 | public: | |||
189 | OrcCAPIMaterializationUnit( | |||
190 | std::string Name, SymbolFlagsMap InitialSymbolFlags, | |||
191 | SymbolStringPtr InitSymbol, void *Ctx, | |||
192 | LLVMOrcMaterializationUnitMaterializeFunction Materialize, | |||
193 | LLVMOrcMaterializationUnitDiscardFunction Discard, | |||
194 | LLVMOrcMaterializationUnitDestroyFunction Destroy) | |||
195 | : llvm::orc::MaterializationUnit(std::move(InitialSymbolFlags), | |||
196 | std::move(InitSymbol)), | |||
197 | Name(std::move(Name)), Ctx(Ctx), Materialize(Materialize), | |||
198 | Discard(Discard), Destroy(Destroy) {} | |||
199 | ||||
200 | ~OrcCAPIMaterializationUnit() { | |||
201 | if (Ctx) | |||
202 | Destroy(Ctx); | |||
203 | } | |||
204 | ||||
205 | StringRef getName() const override { return Name; } | |||
206 | ||||
207 | void materialize(std::unique_ptr<MaterializationResponsibility> R) override { | |||
208 | void *Tmp = Ctx; | |||
209 | Ctx = nullptr; | |||
210 | Materialize(Tmp, wrap(R.release())); | |||
211 | } | |||
212 | ||||
213 | private: | |||
214 | void discard(const JITDylib &JD, const SymbolStringPtr &Name) override { | |||
215 | Discard(Ctx, wrap(&JD), wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(Name))); | |||
216 | } | |||
217 | ||||
218 | std::string Name; | |||
219 | void *Ctx = nullptr; | |||
220 | LLVMOrcMaterializationUnitMaterializeFunction Materialize = nullptr; | |||
221 | LLVMOrcMaterializationUnitDiscardFunction Discard = nullptr; | |||
222 | LLVMOrcMaterializationUnitDestroyFunction Destroy = nullptr; | |||
223 | }; | |||
224 | ||||
225 | static JITSymbolFlags toJITSymbolFlags(LLVMJITSymbolFlags F) { | |||
226 | ||||
227 | JITSymbolFlags JSF; | |||
228 | ||||
229 | if (F.GenericFlags & LLVMJITSymbolGenericFlagsExported) | |||
230 | JSF |= JITSymbolFlags::Exported; | |||
231 | if (F.GenericFlags & LLVMJITSymbolGenericFlagsWeak) | |||
232 | JSF |= JITSymbolFlags::Weak; | |||
233 | if (F.GenericFlags & LLVMJITSymbolGenericFlagsCallable) | |||
234 | JSF |= JITSymbolFlags::Callable; | |||
235 | if (F.GenericFlags & LLVMJITSymbolGenericFlagsMaterializationSideEffectsOnly) | |||
236 | JSF |= JITSymbolFlags::MaterializationSideEffectsOnly; | |||
237 | ||||
238 | JSF.getTargetFlags() = F.TargetFlags; | |||
239 | ||||
240 | return JSF; | |||
241 | } | |||
242 | ||||
243 | static LLVMJITSymbolFlags fromJITSymbolFlags(JITSymbolFlags JSF) { | |||
244 | LLVMJITSymbolFlags F = {0, 0}; | |||
245 | if (JSF & JITSymbolFlags::Exported) | |||
246 | F.GenericFlags |= LLVMJITSymbolGenericFlagsExported; | |||
247 | if (JSF & JITSymbolFlags::Weak) | |||
248 | F.GenericFlags |= LLVMJITSymbolGenericFlagsWeak; | |||
249 | if (JSF & JITSymbolFlags::Callable) | |||
250 | F.GenericFlags |= LLVMJITSymbolGenericFlagsCallable; | |||
251 | if (JSF & JITSymbolFlags::MaterializationSideEffectsOnly) | |||
252 | F.GenericFlags |= LLVMJITSymbolGenericFlagsMaterializationSideEffectsOnly; | |||
253 | ||||
254 | F.TargetFlags = JSF.getTargetFlags(); | |||
255 | ||||
256 | return F; | |||
257 | } | |||
258 | ||||
259 | static SymbolMap toSymbolMap(LLVMOrcCSymbolMapPairs Syms, size_t NumPairs) { | |||
260 | SymbolMap SM; | |||
261 | for (size_t I = 0; I != NumPairs; ++I) { | |||
262 | JITSymbolFlags Flags = toJITSymbolFlags(Syms[I].Sym.Flags); | |||
263 | SM[OrcV2CAPIHelper::moveToSymbolStringPtr(unwrap(Syms[I].Name))] = | |||
264 | JITEvaluatedSymbol(Syms[I].Sym.Address, Flags); | |||
265 | } | |||
266 | return SM; | |||
267 | } | |||
268 | ||||
269 | static SymbolDependenceMap | |||
270 | toSymbolDependenceMap(LLVMOrcCDependenceMapPairs Pairs, size_t NumPairs) { | |||
271 | SymbolDependenceMap SDM; | |||
272 | for (size_t I = 0; I != NumPairs; ++I) { | |||
273 | JITDylib *JD = unwrap(Pairs[I].JD); | |||
274 | SymbolNameSet Names; | |||
275 | ||||
276 | for (size_t J = 0; J != Pairs[I].Names.Length; ++J) { | |||
277 | auto Sym = Pairs[I].Names.Symbols[J]; | |||
278 | Names.insert(OrcV2CAPIHelper::moveToSymbolStringPtr(unwrap(Sym))); | |||
279 | } | |||
280 | SDM[JD] = Names; | |||
281 | } | |||
282 | return SDM; | |||
283 | } | |||
284 | ||||
285 | } // end anonymous namespace | |||
286 | ||||
287 | void LLVMOrcExecutionSessionSetErrorReporter( | |||
288 | LLVMOrcExecutionSessionRef ES, LLVMOrcErrorReporterFunction ReportError, | |||
289 | void *Ctx) { | |||
290 | unwrap(ES)->setErrorReporter( | |||
291 | [=](Error Err) { ReportError(Ctx, wrap(std::move(Err))); }); | |||
292 | } | |||
293 | ||||
294 | LLVMOrcSymbolStringPoolRef | |||
295 | LLVMOrcExecutionSessionGetSymbolStringPool(LLVMOrcExecutionSessionRef ES) { | |||
296 | return wrap( | |||
297 | unwrap(ES)->getExecutorProcessControl().getSymbolStringPool().get()); | |||
298 | } | |||
299 | ||||
300 | void LLVMOrcSymbolStringPoolClearDeadEntries(LLVMOrcSymbolStringPoolRef SSP) { | |||
301 | unwrap(SSP)->clearDeadEntries(); | |||
302 | } | |||
303 | ||||
304 | LLVMOrcSymbolStringPoolEntryRef | |||
305 | LLVMOrcExecutionSessionIntern(LLVMOrcExecutionSessionRef ES, const char *Name) { | |||
306 | return wrap( | |||
307 | OrcV2CAPIHelper::moveFromSymbolStringPtr(unwrap(ES)->intern(Name))); | |||
308 | } | |||
309 | ||||
310 | void LLVMOrcRetainSymbolStringPoolEntry(LLVMOrcSymbolStringPoolEntryRef S) { | |||
311 | OrcV2CAPIHelper::retainPoolEntry(unwrap(S)); | |||
312 | } | |||
313 | ||||
314 | void LLVMOrcReleaseSymbolStringPoolEntry(LLVMOrcSymbolStringPoolEntryRef S) { | |||
315 | OrcV2CAPIHelper::releasePoolEntry(unwrap(S)); | |||
316 | } | |||
317 | ||||
318 | const char *LLVMOrcSymbolStringPoolEntryStr(LLVMOrcSymbolStringPoolEntryRef S) { | |||
319 | return unwrap(S)->getKey().data(); | |||
320 | } | |||
321 | ||||
322 | LLVMOrcResourceTrackerRef | |||
323 | LLVMOrcJITDylibCreateResourceTracker(LLVMOrcJITDylibRef JD) { | |||
324 | auto RT = unwrap(JD)->createResourceTracker(); | |||
325 | // Retain the pointer for the C API client. | |||
326 | RT->Retain(); | |||
327 | return wrap(RT.get()); | |||
328 | } | |||
329 | ||||
330 | LLVMOrcResourceTrackerRef | |||
331 | LLVMOrcJITDylibGetDefaultResourceTracker(LLVMOrcJITDylibRef JD) { | |||
332 | auto RT = unwrap(JD)->getDefaultResourceTracker(); | |||
333 | // Retain the pointer for the C API client. | |||
334 | return wrap(RT.get()); | |||
335 | } | |||
336 | ||||
337 | void LLVMOrcReleaseResourceTracker(LLVMOrcResourceTrackerRef RT) { | |||
338 | ResourceTrackerSP TmpRT(unwrap(RT)); | |||
| ||||
339 | TmpRT->Release(); | |||
340 | } | |||
341 | ||||
342 | void LLVMOrcResourceTrackerTransferTo(LLVMOrcResourceTrackerRef SrcRT, | |||
343 | LLVMOrcResourceTrackerRef DstRT) { | |||
344 | ResourceTrackerSP TmpRT(unwrap(SrcRT)); | |||
345 | TmpRT->transferTo(*unwrap(DstRT)); | |||
346 | } | |||
347 | ||||
348 | LLVMErrorRef LLVMOrcResourceTrackerRemove(LLVMOrcResourceTrackerRef RT) { | |||
349 | ResourceTrackerSP TmpRT(unwrap(RT)); | |||
350 | return wrap(TmpRT->remove()); | |||
351 | } | |||
352 | ||||
353 | void LLVMOrcDisposeDefinitionGenerator(LLVMOrcDefinitionGeneratorRef DG) { | |||
354 | std::unique_ptr<DefinitionGenerator> TmpDG(unwrap(DG)); | |||
355 | } | |||
356 | ||||
357 | void LLVMOrcDisposeMaterializationUnit(LLVMOrcMaterializationUnitRef MU) { | |||
358 | std::unique_ptr<MaterializationUnit> TmpMU(unwrap(MU)); | |||
359 | } | |||
360 | ||||
361 | LLVMOrcMaterializationUnitRef LLVMOrcCreateCustomMaterializationUnit( | |||
362 | const char *Name, void *Ctx, LLVMOrcCSymbolFlagsMapPairs Syms, | |||
363 | size_t NumSyms, LLVMOrcSymbolStringPoolEntryRef InitSym, | |||
364 | LLVMOrcMaterializationUnitMaterializeFunction Materialize, | |||
365 | LLVMOrcMaterializationUnitDiscardFunction Discard, | |||
366 | LLVMOrcMaterializationUnitDestroyFunction Destroy) { | |||
367 | SymbolFlagsMap SFM; | |||
368 | for (size_t I = 0; I != NumSyms; ++I) | |||
369 | SFM[OrcV2CAPIHelper::moveToSymbolStringPtr(unwrap(Syms[I].Name))] = | |||
370 | toJITSymbolFlags(Syms[I].Flags); | |||
371 | ||||
372 | auto IS = OrcV2CAPIHelper::moveToSymbolStringPtr(unwrap(InitSym)); | |||
373 | ||||
374 | return wrap(new OrcCAPIMaterializationUnit( | |||
375 | Name, std::move(SFM), std::move(IS), Ctx, Materialize, Discard, Destroy)); | |||
376 | } | |||
377 | ||||
378 | LLVMOrcMaterializationUnitRef | |||
379 | LLVMOrcAbsoluteSymbols(LLVMOrcCSymbolMapPairs Syms, size_t NumPairs) { | |||
380 | SymbolMap SM = toSymbolMap(Syms, NumPairs); | |||
381 | return wrap(absoluteSymbols(std::move(SM)).release()); | |||
382 | } | |||
383 | ||||
384 | LLVMOrcMaterializationUnitRef LLVMOrcLazyReexports( | |||
385 | LLVMOrcLazyCallThroughManagerRef LCTM, LLVMOrcIndirectStubsManagerRef ISM, | |||
386 | LLVMOrcJITDylibRef SourceJD, LLVMOrcCSymbolAliasMapPairs CallableAliases, | |||
387 | size_t NumPairs) { | |||
388 | ||||
389 | SymbolAliasMap SAM; | |||
390 | for (size_t I = 0; I != NumPairs; ++I) { | |||
391 | auto pair = CallableAliases[I]; | |||
392 | JITSymbolFlags Flags = toJITSymbolFlags(pair.Entry.Flags); | |||
393 | SymbolStringPtr Name = | |||
394 | OrcV2CAPIHelper::moveToSymbolStringPtr(unwrap(pair.Entry.Name)); | |||
395 | SAM[OrcV2CAPIHelper::moveToSymbolStringPtr(unwrap(pair.Name))] = | |||
396 | SymbolAliasMapEntry(Name, Flags); | |||
397 | } | |||
398 | ||||
399 | return wrap(lazyReexports(*unwrap(LCTM), *unwrap(ISM), *unwrap(SourceJD), | |||
400 | std::move(SAM)) | |||
401 | .release()); | |||
402 | } | |||
403 | ||||
404 | void LLVMOrcDisposeMaterializationResponsibility( | |||
405 | LLVMOrcMaterializationResponsibilityRef MR) { | |||
406 | std::unique_ptr<MaterializationResponsibility> TmpMR(unwrap(MR)); | |||
407 | } | |||
408 | ||||
409 | LLVMOrcJITDylibRef LLVMOrcMaterializationResponsibilityGetTargetDylib( | |||
410 | LLVMOrcMaterializationResponsibilityRef MR) { | |||
411 | return wrap(&unwrap(MR)->getTargetJITDylib()); | |||
412 | } | |||
413 | ||||
414 | LLVMOrcExecutionSessionRef | |||
415 | LLVMOrcMaterializationResponsibilityGetExecutionSession( | |||
416 | LLVMOrcMaterializationResponsibilityRef MR) { | |||
417 | return wrap(&unwrap(MR)->getExecutionSession()); | |||
418 | } | |||
419 | ||||
420 | LLVMOrcCSymbolFlagsMapPairs LLVMOrcMaterializationResponsibilityGetSymbols( | |||
421 | LLVMOrcMaterializationResponsibilityRef MR, size_t *NumPairs) { | |||
422 | ||||
423 | auto Symbols = unwrap(MR)->getSymbols(); | |||
424 | LLVMOrcCSymbolFlagsMapPairs Result = static_cast<LLVMOrcCSymbolFlagsMapPairs>( | |||
425 | safe_malloc(Symbols.size() * sizeof(LLVMOrcCSymbolFlagsMapPair))); | |||
426 | size_t I = 0; | |||
427 | for (auto const &pair : Symbols) { | |||
428 | auto Name = wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(pair.first)); | |||
429 | auto Flags = pair.second; | |||
430 | Result[I] = {Name, fromJITSymbolFlags(Flags)}; | |||
431 | I++; | |||
432 | } | |||
433 | *NumPairs = Symbols.size(); | |||
434 | return Result; | |||
435 | } | |||
436 | ||||
437 | void LLVMOrcDisposeCSymbolFlagsMap(LLVMOrcCSymbolFlagsMapPairs Pairs) { | |||
438 | free(Pairs); | |||
439 | } | |||
440 | ||||
441 | LLVMOrcSymbolStringPoolEntryRef | |||
442 | LLVMOrcMaterializationResponsibilityGetInitializerSymbol( | |||
443 | LLVMOrcMaterializationResponsibilityRef MR) { | |||
444 | auto Sym = unwrap(MR)->getInitializerSymbol(); | |||
445 | return wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(Sym)); | |||
446 | } | |||
447 | ||||
448 | LLVMOrcSymbolStringPoolEntryRef * | |||
449 | LLVMOrcMaterializationResponsibilityGetRequestedSymbols( | |||
450 | LLVMOrcMaterializationResponsibilityRef MR, size_t *NumSymbols) { | |||
451 | ||||
452 | auto Symbols = unwrap(MR)->getRequestedSymbols(); | |||
453 | LLVMOrcSymbolStringPoolEntryRef *Result = | |||
454 | static_cast<LLVMOrcSymbolStringPoolEntryRef *>(safe_malloc( | |||
455 | Symbols.size() * sizeof(LLVMOrcSymbolStringPoolEntryRef))); | |||
456 | size_t I = 0; | |||
457 | for (auto &Name : Symbols) { | |||
458 | Result[I] = wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(Name)); | |||
459 | I++; | |||
460 | } | |||
461 | *NumSymbols = Symbols.size(); | |||
462 | return Result; | |||
463 | } | |||
464 | ||||
465 | void LLVMOrcDisposeSymbols(LLVMOrcSymbolStringPoolEntryRef *Symbols) { | |||
466 | free(Symbols); | |||
467 | } | |||
468 | ||||
469 | LLVMErrorRef LLVMOrcMaterializationResponsibilityNotifyResolved( | |||
470 | LLVMOrcMaterializationResponsibilityRef MR, LLVMOrcCSymbolMapPairs Symbols, | |||
471 | size_t NumPairs) { | |||
472 | SymbolMap SM = toSymbolMap(Symbols, NumPairs); | |||
473 | return wrap(unwrap(MR)->notifyResolved(std::move(SM))); | |||
474 | } | |||
475 | ||||
476 | LLVMErrorRef LLVMOrcMaterializationResponsibilityNotifyEmitted( | |||
477 | LLVMOrcMaterializationResponsibilityRef MR) { | |||
478 | return wrap(unwrap(MR)->notifyEmitted()); | |||
479 | } | |||
480 | ||||
481 | LLVMErrorRef LLVMOrcMaterializationResponsibilityDefineMaterializing( | |||
482 | LLVMOrcMaterializationResponsibilityRef MR, | |||
483 | LLVMOrcCSymbolFlagsMapPairs Syms, size_t NumSyms) { | |||
484 | SymbolFlagsMap SFM; | |||
485 | for (size_t I = 0; I != NumSyms; ++I) | |||
486 | SFM[OrcV2CAPIHelper::moveToSymbolStringPtr(unwrap(Syms[I].Name))] = | |||
487 | toJITSymbolFlags(Syms[I].Flags); | |||
488 | ||||
489 | return wrap(unwrap(MR)->defineMaterializing(std::move(SFM))); | |||
490 | } | |||
491 | ||||
492 | LLVMErrorRef LLVMOrcMaterializationResponsibilityReplace( | |||
493 | LLVMOrcMaterializationResponsibilityRef MR, | |||
494 | LLVMOrcMaterializationUnitRef MU) { | |||
495 | std::unique_ptr<MaterializationUnit> TmpMU(unwrap(MU)); | |||
496 | return wrap(unwrap(MR)->replace(std::move(TmpMU))); | |||
497 | } | |||
498 | ||||
499 | LLVMErrorRef LLVMOrcMaterializationResponsibilityDelegate( | |||
500 | LLVMOrcMaterializationResponsibilityRef MR, | |||
501 | LLVMOrcSymbolStringPoolEntryRef *Symbols, size_t NumSymbols, | |||
502 | LLVMOrcMaterializationResponsibilityRef *Result) { | |||
503 | SymbolNameSet Syms; | |||
504 | for (size_t I = 0; I != NumSymbols; I++) { | |||
505 | Syms.insert(OrcV2CAPIHelper::moveToSymbolStringPtr(unwrap(Symbols[I]))); | |||
506 | } | |||
507 | auto OtherMR = unwrap(MR)->delegate(Syms); | |||
508 | ||||
509 | if (!OtherMR) { | |||
510 | return wrap(OtherMR.takeError()); | |||
511 | } | |||
512 | *Result = wrap(OtherMR->release()); | |||
513 | return LLVMErrorSuccess0; | |||
514 | } | |||
515 | ||||
516 | void LLVMOrcMaterializationResponsibilityAddDependencies( | |||
517 | LLVMOrcMaterializationResponsibilityRef MR, | |||
518 | LLVMOrcSymbolStringPoolEntryRef Name, | |||
519 | LLVMOrcCDependenceMapPairs Dependencies, size_t NumPairs) { | |||
520 | ||||
521 | SymbolDependenceMap SDM = toSymbolDependenceMap(Dependencies, NumPairs); | |||
522 | auto Sym = OrcV2CAPIHelper::moveToSymbolStringPtr(unwrap(Name)); | |||
523 | unwrap(MR)->addDependencies(Sym, SDM); | |||
524 | } | |||
525 | ||||
526 | void LLVMOrcMaterializationResponsibilityAddDependenciesForAll( | |||
527 | LLVMOrcMaterializationResponsibilityRef MR, | |||
528 | LLVMOrcCDependenceMapPairs Dependencies, size_t NumPairs) { | |||
529 | ||||
530 | SymbolDependenceMap SDM = toSymbolDependenceMap(Dependencies, NumPairs); | |||
531 | unwrap(MR)->addDependenciesForAll(SDM); | |||
532 | } | |||
533 | ||||
534 | void LLVMOrcMaterializationResponsibilityFailMaterialization( | |||
535 | LLVMOrcMaterializationResponsibilityRef MR) { | |||
536 | unwrap(MR)->failMaterialization(); | |||
537 | } | |||
538 | ||||
539 | void LLVMOrcIRTransformLayerEmit(LLVMOrcIRTransformLayerRef IRLayer, | |||
540 | LLVMOrcMaterializationResponsibilityRef MR, | |||
541 | LLVMOrcThreadSafeModuleRef TSM) { | |||
542 | std::unique_ptr<ThreadSafeModule> TmpTSM(unwrap(TSM)); | |||
543 | unwrap(IRLayer)->emit( | |||
544 | std::unique_ptr<MaterializationResponsibility>(unwrap(MR)), | |||
545 | std::move(*TmpTSM)); | |||
546 | } | |||
547 | ||||
548 | LLVMOrcJITDylibRef | |||
549 | LLVMOrcExecutionSessionCreateBareJITDylib(LLVMOrcExecutionSessionRef ES, | |||
550 | const char *Name) { | |||
551 | return wrap(&unwrap(ES)->createBareJITDylib(Name)); | |||
552 | } | |||
553 | ||||
554 | LLVMErrorRef | |||
555 | LLVMOrcExecutionSessionCreateJITDylib(LLVMOrcExecutionSessionRef ES, | |||
556 | LLVMOrcJITDylibRef *Result, | |||
557 | const char *Name) { | |||
558 | auto JD = unwrap(ES)->createJITDylib(Name); | |||
559 | if (!JD) | |||
560 | return wrap(JD.takeError()); | |||
561 | *Result = wrap(&*JD); | |||
562 | return LLVMErrorSuccess0; | |||
563 | } | |||
564 | ||||
565 | LLVMOrcJITDylibRef | |||
566 | LLVMOrcExecutionSessionGetJITDylibByName(LLVMOrcExecutionSessionRef ES, | |||
567 | const char *Name) { | |||
568 | return wrap(unwrap(ES)->getJITDylibByName(Name)); | |||
569 | } | |||
570 | ||||
571 | LLVMErrorRef LLVMOrcJITDylibDefine(LLVMOrcJITDylibRef JD, | |||
572 | LLVMOrcMaterializationUnitRef MU) { | |||
573 | std::unique_ptr<MaterializationUnit> TmpMU(unwrap(MU)); | |||
574 | ||||
575 | if (auto Err = unwrap(JD)->define(TmpMU)) { | |||
576 | TmpMU.release(); | |||
577 | return wrap(std::move(Err)); | |||
578 | } | |||
579 | return LLVMErrorSuccess0; | |||
580 | } | |||
581 | ||||
582 | LLVMErrorRef LLVMOrcJITDylibClear(LLVMOrcJITDylibRef JD) { | |||
583 | return wrap(unwrap(JD)->clear()); | |||
584 | } | |||
585 | ||||
586 | void LLVMOrcJITDylibAddGenerator(LLVMOrcJITDylibRef JD, | |||
587 | LLVMOrcDefinitionGeneratorRef DG) { | |||
588 | unwrap(JD)->addGenerator(std::unique_ptr<DefinitionGenerator>(unwrap(DG))); | |||
589 | } | |||
590 | ||||
591 | LLVMOrcDefinitionGeneratorRef LLVMOrcCreateCustomCAPIDefinitionGenerator( | |||
592 | LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction F, void *Ctx) { | |||
593 | auto DG = std::make_unique<CAPIDefinitionGenerator>(Ctx, F); | |||
594 | return wrap(DG.release()); | |||
595 | } | |||
596 | ||||
597 | LLVMErrorRef LLVMOrcCreateDynamicLibrarySearchGeneratorForProcess( | |||
598 | LLVMOrcDefinitionGeneratorRef *Result, char GlobalPrefix, | |||
599 | LLVMOrcSymbolPredicate Filter, void *FilterCtx) { | |||
600 | assert(Result && "Result can not be null")((void)0); | |||
601 | assert((Filter || !FilterCtx) &&((void)0) | |||
602 | "if Filter is null then FilterCtx must also be null")((void)0); | |||
603 | ||||
604 | DynamicLibrarySearchGenerator::SymbolPredicate Pred; | |||
605 | if (Filter) | |||
606 | Pred = [=](const SymbolStringPtr &Name) -> bool { | |||
607 | return Filter(FilterCtx, wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(Name))); | |||
608 | }; | |||
609 | ||||
610 | auto ProcessSymsGenerator = | |||
611 | DynamicLibrarySearchGenerator::GetForCurrentProcess(GlobalPrefix, Pred); | |||
612 | ||||
613 | if (!ProcessSymsGenerator) { | |||
614 | *Result = 0; | |||
615 | return wrap(ProcessSymsGenerator.takeError()); | |||
616 | } | |||
617 | ||||
618 | *Result = wrap(ProcessSymsGenerator->release()); | |||
619 | return LLVMErrorSuccess0; | |||
620 | } | |||
621 | ||||
622 | LLVMOrcThreadSafeContextRef LLVMOrcCreateNewThreadSafeContext(void) { | |||
623 | return wrap(new ThreadSafeContext(std::make_unique<LLVMContext>())); | |||
624 | } | |||
625 | ||||
626 | LLVMContextRef | |||
627 | LLVMOrcThreadSafeContextGetContext(LLVMOrcThreadSafeContextRef TSCtx) { | |||
628 | return wrap(unwrap(TSCtx)->getContext()); | |||
629 | } | |||
630 | ||||
631 | void LLVMOrcDisposeThreadSafeContext(LLVMOrcThreadSafeContextRef TSCtx) { | |||
632 | delete unwrap(TSCtx); | |||
633 | } | |||
634 | ||||
635 | LLVMErrorRef | |||
636 | LLVMOrcThreadSafeModuleWithModuleDo(LLVMOrcThreadSafeModuleRef TSM, | |||
637 | LLVMOrcGenericIRModuleOperationFunction F, | |||
638 | void *Ctx) { | |||
639 | return wrap(unwrap(TSM)->withModuleDo( | |||
640 | [&](Module &M) { return unwrap(F(Ctx, wrap(&M))); })); | |||
641 | } | |||
642 | ||||
643 | LLVMOrcThreadSafeModuleRef | |||
644 | LLVMOrcCreateNewThreadSafeModule(LLVMModuleRef M, | |||
645 | LLVMOrcThreadSafeContextRef TSCtx) { | |||
646 | return wrap( | |||
647 | new ThreadSafeModule(std::unique_ptr<Module>(unwrap(M)), *unwrap(TSCtx))); | |||
648 | } | |||
649 | ||||
650 | void LLVMOrcDisposeThreadSafeModule(LLVMOrcThreadSafeModuleRef TSM) { | |||
651 | delete unwrap(TSM); | |||
652 | } | |||
653 | ||||
654 | LLVMErrorRef LLVMOrcJITTargetMachineBuilderDetectHost( | |||
655 | LLVMOrcJITTargetMachineBuilderRef *Result) { | |||
656 | assert(Result && "Result can not be null")((void)0); | |||
657 | ||||
658 | auto JTMB = JITTargetMachineBuilder::detectHost(); | |||
659 | if (!JTMB) { | |||
660 | Result = 0; | |||
661 | return wrap(JTMB.takeError()); | |||
662 | } | |||
663 | ||||
664 | *Result = wrap(new JITTargetMachineBuilder(std::move(*JTMB))); | |||
665 | return LLVMErrorSuccess0; | |||
666 | } | |||
667 | ||||
668 | LLVMOrcJITTargetMachineBuilderRef | |||
669 | LLVMOrcJITTargetMachineBuilderCreateFromTargetMachine(LLVMTargetMachineRef TM) { | |||
670 | auto *TemplateTM = unwrap(TM); | |||
671 | ||||
672 | auto JTMB = | |||
673 | std::make_unique<JITTargetMachineBuilder>(TemplateTM->getTargetTriple()); | |||
674 | ||||
675 | (*JTMB) | |||
676 | .setCPU(TemplateTM->getTargetCPU().str()) | |||
677 | .setRelocationModel(TemplateTM->getRelocationModel()) | |||
678 | .setCodeModel(TemplateTM->getCodeModel()) | |||
679 | .setCodeGenOptLevel(TemplateTM->getOptLevel()) | |||
680 | .setFeatures(TemplateTM->getTargetFeatureString()) | |||
681 | .setOptions(TemplateTM->Options); | |||
682 | ||||
683 | LLVMDisposeTargetMachine(TM); | |||
684 | ||||
685 | return wrap(JTMB.release()); | |||
686 | } | |||
687 | ||||
688 | void LLVMOrcDisposeJITTargetMachineBuilder( | |||
689 | LLVMOrcJITTargetMachineBuilderRef JTMB) { | |||
690 | delete unwrap(JTMB); | |||
691 | } | |||
692 | ||||
693 | char *LLVMOrcJITTargetMachineBuilderGetTargetTriple( | |||
694 | LLVMOrcJITTargetMachineBuilderRef JTMB) { | |||
695 | auto Tmp = unwrap(JTMB)->getTargetTriple().str(); | |||
696 | char *TargetTriple = (char *)malloc(Tmp.size() + 1); | |||
697 | strcpy(TargetTriple, Tmp.c_str()); | |||
698 | return TargetTriple; | |||
699 | } | |||
700 | ||||
701 | void LLVMOrcJITTargetMachineBuilderSetTargetTriple( | |||
702 | LLVMOrcJITTargetMachineBuilderRef JTMB, const char *TargetTriple) { | |||
703 | unwrap(JTMB)->getTargetTriple() = Triple(TargetTriple); | |||
704 | } | |||
705 | ||||
706 | LLVMErrorRef LLVMOrcObjectLayerAddObjectFile(LLVMOrcObjectLayerRef ObjLayer, | |||
707 | LLVMOrcJITDylibRef JD, | |||
708 | LLVMMemoryBufferRef ObjBuffer) { | |||
709 | return wrap(unwrap(ObjLayer)->add( | |||
710 | *unwrap(JD), std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer)))); | |||
711 | } | |||
712 | ||||
713 | LLVMErrorRef LLVMOrcLLJITAddObjectFileWithRT(LLVMOrcObjectLayerRef ObjLayer, | |||
714 | LLVMOrcResourceTrackerRef RT, | |||
715 | LLVMMemoryBufferRef ObjBuffer) { | |||
716 | return wrap( | |||
717 | unwrap(ObjLayer)->add(ResourceTrackerSP(unwrap(RT)), | |||
718 | std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer)))); | |||
719 | } | |||
720 | ||||
721 | void LLVMOrcObjectLayerEmit(LLVMOrcObjectLayerRef ObjLayer, | |||
722 | LLVMOrcMaterializationResponsibilityRef R, | |||
723 | LLVMMemoryBufferRef ObjBuffer) { | |||
724 | unwrap(ObjLayer)->emit( | |||
725 | std::unique_ptr<MaterializationResponsibility>(unwrap(R)), | |||
726 | std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer))); | |||
727 | } | |||
728 | ||||
729 | void LLVMOrcDisposeObjectLayer(LLVMOrcObjectLayerRef ObjLayer) { | |||
730 | delete unwrap(ObjLayer); | |||
731 | } | |||
732 | ||||
733 | void LLVMOrcIRTransformLayerSetTransform( | |||
734 | LLVMOrcIRTransformLayerRef IRTransformLayer, | |||
735 | LLVMOrcIRTransformLayerTransformFunction TransformFunction, void *Ctx) { | |||
736 | unwrap(IRTransformLayer) | |||
737 | ->setTransform( | |||
738 | [=](ThreadSafeModule TSM, | |||
739 | MaterializationResponsibility &R) -> Expected<ThreadSafeModule> { | |||
740 | LLVMOrcThreadSafeModuleRef TSMRef = | |||
741 | wrap(new ThreadSafeModule(std::move(TSM))); | |||
742 | if (LLVMErrorRef Err = TransformFunction(Ctx, &TSMRef, wrap(&R))) { | |||
743 | assert(!TSMRef && "TSMRef was not reset to null on error")((void)0); | |||
744 | return unwrap(Err); | |||
745 | } | |||
746 | return std::move(*unwrap(TSMRef)); | |||
747 | }); | |||
748 | } | |||
749 | ||||
750 | void LLVMOrcObjectTransformLayerSetTransform( | |||
751 | LLVMOrcObjectTransformLayerRef ObjTransformLayer, | |||
752 | LLVMOrcObjectTransformLayerTransformFunction TransformFunction, void *Ctx) { | |||
753 | unwrap(ObjTransformLayer) | |||
754 | ->setTransform([TransformFunction, Ctx](std::unique_ptr<MemoryBuffer> Obj) | |||
755 | -> Expected<std::unique_ptr<MemoryBuffer>> { | |||
756 | LLVMMemoryBufferRef ObjBuffer = wrap(Obj.release()); | |||
757 | if (LLVMErrorRef Err = TransformFunction(Ctx, &ObjBuffer)) { | |||
758 | assert(!ObjBuffer && "ObjBuffer was not reset to null on error")((void)0); | |||
759 | return unwrap(Err); | |||
760 | } | |||
761 | return std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer)); | |||
762 | }); | |||
763 | } | |||
764 | ||||
765 | LLVMOrcDumpObjectsRef LLVMOrcCreateDumpObjects(const char *DumpDir, | |||
766 | const char *IdentifierOverride) { | |||
767 | assert(DumpDir && "DumpDir should not be null")((void)0); | |||
768 | assert(IdentifierOverride && "IdentifierOverride should not be null")((void)0); | |||
769 | return wrap(new DumpObjects(DumpDir, IdentifierOverride)); | |||
770 | } | |||
771 | ||||
772 | void LLVMOrcDisposeDumpObjects(LLVMOrcDumpObjectsRef DumpObjects) { | |||
773 | delete unwrap(DumpObjects); | |||
774 | } | |||
775 | ||||
776 | LLVMErrorRef LLVMOrcDumpObjects_CallOperator(LLVMOrcDumpObjectsRef DumpObjects, | |||
777 | LLVMMemoryBufferRef *ObjBuffer) { | |||
778 | std::unique_ptr<MemoryBuffer> OB(unwrap(*ObjBuffer)); | |||
779 | if (auto Result = (*unwrap(DumpObjects))(std::move(OB))) { | |||
780 | *ObjBuffer = wrap(Result->release()); | |||
781 | return LLVMErrorSuccess0; | |||
782 | } else { | |||
783 | *ObjBuffer = nullptr; | |||
784 | return wrap(Result.takeError()); | |||
785 | } | |||
786 | } | |||
787 | ||||
788 | LLVMOrcLLJITBuilderRef LLVMOrcCreateLLJITBuilder(void) { | |||
789 | return wrap(new LLJITBuilder()); | |||
790 | } | |||
791 | ||||
792 | void LLVMOrcDisposeLLJITBuilder(LLVMOrcLLJITBuilderRef Builder) { | |||
793 | delete unwrap(Builder); | |||
794 | } | |||
795 | ||||
796 | void LLVMOrcLLJITBuilderSetJITTargetMachineBuilder( | |||
797 | LLVMOrcLLJITBuilderRef Builder, LLVMOrcJITTargetMachineBuilderRef JTMB) { | |||
798 | unwrap(Builder)->setJITTargetMachineBuilder(std::move(*unwrap(JTMB))); | |||
799 | LLVMOrcDisposeJITTargetMachineBuilder(JTMB); | |||
800 | } | |||
801 | ||||
802 | void LLVMOrcLLJITBuilderSetObjectLinkingLayerCreator( | |||
803 | LLVMOrcLLJITBuilderRef Builder, | |||
804 | LLVMOrcLLJITBuilderObjectLinkingLayerCreatorFunction F, void *Ctx) { | |||
805 | unwrap(Builder)->setObjectLinkingLayerCreator( | |||
806 | [=](ExecutionSession &ES, const Triple &TT) { | |||
807 | auto TTStr = TT.str(); | |||
808 | return std::unique_ptr<ObjectLayer>( | |||
809 | unwrap(F(Ctx, wrap(&ES), TTStr.c_str()))); | |||
810 | }); | |||
811 | } | |||
812 | ||||
813 | LLVMErrorRef LLVMOrcCreateLLJIT(LLVMOrcLLJITRef *Result, | |||
814 | LLVMOrcLLJITBuilderRef Builder) { | |||
815 | assert(Result && "Result can not be null")((void)0); | |||
816 | ||||
817 | if (!Builder) | |||
818 | Builder = LLVMOrcCreateLLJITBuilder(); | |||
819 | ||||
820 | auto J = unwrap(Builder)->create(); | |||
821 | LLVMOrcDisposeLLJITBuilder(Builder); | |||
822 | ||||
823 | if (!J) { | |||
824 | Result = 0; | |||
825 | return wrap(J.takeError()); | |||
826 | } | |||
827 | ||||
828 | *Result = wrap(J->release()); | |||
829 | return LLVMErrorSuccess0; | |||
830 | } | |||
831 | ||||
832 | LLVMErrorRef LLVMOrcDisposeLLJIT(LLVMOrcLLJITRef J) { | |||
833 | delete unwrap(J); | |||
834 | return LLVMErrorSuccess0; | |||
835 | } | |||
836 | ||||
837 | LLVMOrcExecutionSessionRef LLVMOrcLLJITGetExecutionSession(LLVMOrcLLJITRef J) { | |||
838 | return wrap(&unwrap(J)->getExecutionSession()); | |||
839 | } | |||
840 | ||||
841 | LLVMOrcJITDylibRef LLVMOrcLLJITGetMainJITDylib(LLVMOrcLLJITRef J) { | |||
842 | return wrap(&unwrap(J)->getMainJITDylib()); | |||
843 | } | |||
844 | ||||
845 | const char *LLVMOrcLLJITGetTripleString(LLVMOrcLLJITRef J) { | |||
846 | return unwrap(J)->getTargetTriple().str().c_str(); | |||
847 | } | |||
848 | ||||
849 | char LLVMOrcLLJITGetGlobalPrefix(LLVMOrcLLJITRef J) { | |||
850 | return unwrap(J)->getDataLayout().getGlobalPrefix(); | |||
851 | } | |||
852 | ||||
853 | LLVMOrcSymbolStringPoolEntryRef | |||
854 | LLVMOrcLLJITMangleAndIntern(LLVMOrcLLJITRef J, const char *UnmangledName) { | |||
855 | return wrap(OrcV2CAPIHelper::moveFromSymbolStringPtr( | |||
856 | unwrap(J)->mangleAndIntern(UnmangledName))); | |||
857 | } | |||
858 | ||||
859 | LLVMErrorRef LLVMOrcLLJITAddObjectFile(LLVMOrcLLJITRef J, LLVMOrcJITDylibRef JD, | |||
860 | LLVMMemoryBufferRef ObjBuffer) { | |||
861 | return wrap(unwrap(J)->addObjectFile( | |||
862 | *unwrap(JD), std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer)))); | |||
863 | } | |||
864 | ||||
865 | LLVMErrorRef LLVMOrcLLJITAddObjectFileWithRT(LLVMOrcLLJITRef J, | |||
866 | LLVMOrcResourceTrackerRef RT, | |||
867 | LLVMMemoryBufferRef ObjBuffer) { | |||
868 | return wrap(unwrap(J)->addObjectFile( | |||
869 | ResourceTrackerSP(unwrap(RT)), | |||
870 | std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer)))); | |||
871 | } | |||
872 | ||||
873 | LLVMErrorRef LLVMOrcLLJITAddLLVMIRModule(LLVMOrcLLJITRef J, | |||
874 | LLVMOrcJITDylibRef JD, | |||
875 | LLVMOrcThreadSafeModuleRef TSM) { | |||
876 | std::unique_ptr<ThreadSafeModule> TmpTSM(unwrap(TSM)); | |||
877 | return wrap(unwrap(J)->addIRModule(*unwrap(JD), std::move(*TmpTSM))); | |||
878 | } | |||
879 | ||||
880 | LLVMErrorRef LLVMOrcLLJITAddLLVMIRModuleWithRT(LLVMOrcLLJITRef J, | |||
881 | LLVMOrcResourceTrackerRef RT, | |||
882 | LLVMOrcThreadSafeModuleRef TSM) { | |||
883 | std::unique_ptr<ThreadSafeModule> TmpTSM(unwrap(TSM)); | |||
884 | return wrap(unwrap(J)->addIRModule(ResourceTrackerSP(unwrap(RT)), | |||
885 | std::move(*TmpTSM))); | |||
886 | } | |||
887 | ||||
888 | LLVMErrorRef LLVMOrcLLJITLookup(LLVMOrcLLJITRef J, | |||
889 | LLVMOrcJITTargetAddress *Result, | |||
890 | const char *Name) { | |||
891 | assert(Result && "Result can not be null")((void)0); | |||
892 | ||||
893 | auto Sym = unwrap(J)->lookup(Name); | |||
894 | if (!Sym) { | |||
895 | *Result = 0; | |||
896 | return wrap(Sym.takeError()); | |||
897 | } | |||
898 | ||||
899 | *Result = Sym->getAddress(); | |||
900 | return LLVMErrorSuccess0; | |||
901 | } | |||
902 | ||||
903 | LLVMOrcObjectLayerRef LLVMOrcLLJITGetObjLinkingLayer(LLVMOrcLLJITRef J) { | |||
904 | return wrap(&unwrap(J)->getObjLinkingLayer()); | |||
905 | } | |||
906 | ||||
907 | LLVMOrcObjectTransformLayerRef | |||
908 | LLVMOrcLLJITGetObjTransformLayer(LLVMOrcLLJITRef J) { | |||
909 | return wrap(&unwrap(J)->getObjTransformLayer()); | |||
910 | } | |||
911 | ||||
912 | LLVMOrcObjectLayerRef | |||
913 | LLVMOrcCreateRTDyldObjectLinkingLayerWithSectionMemoryManager( | |||
914 | LLVMOrcExecutionSessionRef ES) { | |||
915 | assert(ES && "ES must not be null")((void)0); | |||
916 | return wrap(new RTDyldObjectLinkingLayer( | |||
917 | *unwrap(ES), [] { return std::make_unique<SectionMemoryManager>(); })); | |||
918 | } | |||
919 | ||||
920 | void LLVMOrcRTDyldObjectLinkingLayerRegisterJITEventListener( | |||
921 | LLVMOrcObjectLayerRef RTDyldObjLinkingLayer, | |||
922 | LLVMJITEventListenerRef Listener) { | |||
923 | assert(RTDyldObjLinkingLayer && "RTDyldObjLinkingLayer must not be null")((void)0); | |||
924 | assert(Listener && "Listener must not be null")((void)0); | |||
925 | reinterpret_cast<RTDyldObjectLinkingLayer *>(unwrap(RTDyldObjLinkingLayer)) | |||
926 | ->registerJITEventListener(*unwrap(Listener)); | |||
927 | } | |||
928 | ||||
929 | LLVMOrcIRTransformLayerRef LLVMOrcLLJITGetIRTransformLayer(LLVMOrcLLJITRef J) { | |||
930 | return wrap(&unwrap(J)->getIRTransformLayer()); | |||
931 | } | |||
932 | ||||
933 | const char *LLVMOrcLLJITGetDataLayoutStr(LLVMOrcLLJITRef J) { | |||
934 | return unwrap(J)->getDataLayout().getStringRepresentation().c_str(); | |||
935 | } | |||
936 | ||||
937 | LLVMOrcIndirectStubsManagerRef | |||
938 | LLVMOrcCreateLocalIndirectStubsManager(const char *TargetTriple) { | |||
939 | auto builder = createLocalIndirectStubsManagerBuilder(Triple(TargetTriple)); | |||
940 | return wrap(builder().release()); | |||
941 | } | |||
942 | ||||
943 | void LLVMOrcDisposeIndirectStubsManager(LLVMOrcIndirectStubsManagerRef ISM) { | |||
944 | std::unique_ptr<IndirectStubsManager> TmpISM(unwrap(ISM)); | |||
945 | } | |||
946 | ||||
947 | LLVMErrorRef LLVMOrcCreateLocalLazyCallThroughManager( | |||
948 | const char *TargetTriple, LLVMOrcExecutionSessionRef ES, | |||
949 | LLVMOrcJITTargetAddress ErrorHandlerAddr, | |||
950 | LLVMOrcLazyCallThroughManagerRef *Result) { | |||
951 | auto LCTM = createLocalLazyCallThroughManager(Triple(TargetTriple), | |||
952 | *unwrap(ES), ErrorHandlerAddr); | |||
953 | ||||
954 | if (!LCTM) | |||
955 | return wrap(LCTM.takeError()); | |||
956 | *Result = wrap(LCTM->release()); | |||
957 | return LLVMErrorSuccess0; | |||
958 | } | |||
959 | ||||
960 | void LLVMOrcDisposeLazyCallThroughManager( | |||
961 | LLVMOrcLazyCallThroughManagerRef LCM) { | |||
962 | std::unique_ptr<LazyCallThroughManager> TmpLCM(unwrap(LCM)); | |||
963 | } |
1 | //==- llvm/ADT/IntrusiveRefCntPtr.h - Smart Refcounting Pointer --*- C++ -*-==// | ||||
2 | // | ||||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||||
4 | // See https://llvm.org/LICENSE.txt for license information. | ||||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||||
6 | // | ||||
7 | //===----------------------------------------------------------------------===// | ||||
8 | // | ||||
9 | // This file defines the RefCountedBase, ThreadSafeRefCountedBase, and | ||||
10 | // IntrusiveRefCntPtr classes. | ||||
11 | // | ||||
12 | // IntrusiveRefCntPtr is a smart pointer to an object which maintains a | ||||
13 | // reference count. (ThreadSafe)RefCountedBase is a mixin class that adds a | ||||
14 | // refcount member variable and methods for updating the refcount. An object | ||||
15 | // that inherits from (ThreadSafe)RefCountedBase deletes itself when its | ||||
16 | // refcount hits zero. | ||||
17 | // | ||||
18 | // For example: | ||||
19 | // | ||||
20 | // class MyClass : public RefCountedBase<MyClass> {}; | ||||
21 | // | ||||
22 | // void foo() { | ||||
23 | // // Constructing an IntrusiveRefCntPtr increases the pointee's refcount by | ||||
24 | // // 1 (from 0 in this case). | ||||
25 | // IntrusiveRefCntPtr<MyClass> Ptr1(new MyClass()); | ||||
26 | // | ||||
27 | // // Copying an IntrusiveRefCntPtr increases the pointee's refcount by 1. | ||||
28 | // IntrusiveRefCntPtr<MyClass> Ptr2(Ptr1); | ||||
29 | // | ||||
30 | // // Constructing an IntrusiveRefCntPtr has no effect on the object's | ||||
31 | // // refcount. After a move, the moved-from pointer is null. | ||||
32 | // IntrusiveRefCntPtr<MyClass> Ptr3(std::move(Ptr1)); | ||||
33 | // assert(Ptr1 == nullptr); | ||||
34 | // | ||||
35 | // // Clearing an IntrusiveRefCntPtr decreases the pointee's refcount by 1. | ||||
36 | // Ptr2.reset(); | ||||
37 | // | ||||
38 | // // The object deletes itself when we return from the function, because | ||||
39 | // // Ptr3's destructor decrements its refcount to 0. | ||||
40 | // } | ||||
41 | // | ||||
42 | // You can use IntrusiveRefCntPtr with isa<T>(), dyn_cast<T>(), etc.: | ||||
43 | // | ||||
44 | // IntrusiveRefCntPtr<MyClass> Ptr(new MyClass()); | ||||
45 | // OtherClass *Other = dyn_cast<OtherClass>(Ptr); // Ptr.get() not required | ||||
46 | // | ||||
47 | // IntrusiveRefCntPtr works with any class that | ||||
48 | // | ||||
49 | // - inherits from (ThreadSafe)RefCountedBase, | ||||
50 | // - has Retain() and Release() methods, or | ||||
51 | // - specializes IntrusiveRefCntPtrInfo. | ||||
52 | // | ||||
53 | //===----------------------------------------------------------------------===// | ||||
54 | |||||
55 | #ifndef LLVM_ADT_INTRUSIVEREFCNTPTR_H | ||||
56 | #define LLVM_ADT_INTRUSIVEREFCNTPTR_H | ||||
57 | |||||
58 | #include <atomic> | ||||
59 | #include <cassert> | ||||
60 | #include <cstddef> | ||||
61 | #include <memory> | ||||
62 | |||||
63 | namespace llvm { | ||||
64 | |||||
65 | /// A CRTP mixin class that adds reference counting to a type. | ||||
66 | /// | ||||
67 | /// The lifetime of an object which inherits from RefCountedBase is managed by | ||||
68 | /// calls to Release() and Retain(), which increment and decrement the object's | ||||
69 | /// refcount, respectively. When a Release() call decrements the refcount to 0, | ||||
70 | /// the object deletes itself. | ||||
71 | template <class Derived> class RefCountedBase { | ||||
72 | mutable unsigned RefCount = 0; | ||||
73 | |||||
74 | protected: | ||||
75 | RefCountedBase() = default; | ||||
76 | RefCountedBase(const RefCountedBase &) {} | ||||
77 | RefCountedBase &operator=(const RefCountedBase &) = delete; | ||||
78 | |||||
79 | #ifndef NDEBUG1 | ||||
80 | ~RefCountedBase() { | ||||
81 | assert(RefCount == 0 &&((void)0) | ||||
82 | "Destruction occured when there are still references to this.")((void)0); | ||||
83 | } | ||||
84 | #else | ||||
85 | // Default the destructor in release builds, A trivial destructor may enable | ||||
86 | // better codegen. | ||||
87 | ~RefCountedBase() = default; | ||||
88 | #endif | ||||
89 | |||||
90 | public: | ||||
91 | void Retain() const { ++RefCount; } | ||||
92 | |||||
93 | void Release() const { | ||||
94 | assert(RefCount > 0 && "Reference count is already zero.")((void)0); | ||||
95 | if (--RefCount == 0) | ||||
96 | delete static_cast<const Derived *>(this); | ||||
97 | } | ||||
98 | }; | ||||
99 | |||||
100 | /// A thread-safe version of \c RefCountedBase. | ||||
101 | template <class Derived> class ThreadSafeRefCountedBase { | ||||
102 | mutable std::atomic<int> RefCount{0}; | ||||
103 | |||||
104 | protected: | ||||
105 | ThreadSafeRefCountedBase() = default; | ||||
106 | ThreadSafeRefCountedBase(const ThreadSafeRefCountedBase &) {} | ||||
107 | ThreadSafeRefCountedBase & | ||||
108 | operator=(const ThreadSafeRefCountedBase &) = delete; | ||||
109 | |||||
110 | #ifndef NDEBUG1 | ||||
111 | ~ThreadSafeRefCountedBase() { | ||||
112 | assert(RefCount == 0 &&((void)0) | ||||
113 | "Destruction occured when there are still references to this.")((void)0); | ||||
114 | } | ||||
115 | #else | ||||
116 | // Default the destructor in release builds, A trivial destructor may enable | ||||
117 | // better codegen. | ||||
118 | ~ThreadSafeRefCountedBase() = default; | ||||
119 | #endif | ||||
120 | |||||
121 | public: | ||||
122 | void Retain() const { RefCount.fetch_add(1, std::memory_order_relaxed); } | ||||
123 | |||||
124 | void Release() const { | ||||
125 | int NewRefCount = RefCount.fetch_sub(1, std::memory_order_acq_rel) - 1; | ||||
126 | assert(NewRefCount >= 0 && "Reference count was already zero.")((void)0); | ||||
127 | if (NewRefCount == 0) | ||||
128 | delete static_cast<const Derived *>(this); | ||||
129 | } | ||||
130 | }; | ||||
131 | |||||
132 | /// Class you can specialize to provide custom retain/release functionality for | ||||
133 | /// a type. | ||||
134 | /// | ||||
135 | /// Usually specializing this class is not necessary, as IntrusiveRefCntPtr | ||||
136 | /// works with any type which defines Retain() and Release() functions -- you | ||||
137 | /// can define those functions yourself if RefCountedBase doesn't work for you. | ||||
138 | /// | ||||
139 | /// One case when you might want to specialize this type is if you have | ||||
140 | /// - Foo.h defines type Foo and includes Bar.h, and | ||||
141 | /// - Bar.h uses IntrusiveRefCntPtr<Foo> in inline functions. | ||||
142 | /// | ||||
143 | /// Because Foo.h includes Bar.h, Bar.h can't include Foo.h in order to pull in | ||||
144 | /// the declaration of Foo. Without the declaration of Foo, normally Bar.h | ||||
145 | /// wouldn't be able to use IntrusiveRefCntPtr<Foo>, which wants to call | ||||
146 | /// T::Retain and T::Release. | ||||
147 | /// | ||||
148 | /// To resolve this, Bar.h could include a third header, FooFwd.h, which | ||||
149 | /// forward-declares Foo and specializes IntrusiveRefCntPtrInfo<Foo>. Then | ||||
150 | /// Bar.h could use IntrusiveRefCntPtr<Foo>, although it still couldn't call any | ||||
151 | /// functions on Foo itself, because Foo would be an incomplete type. | ||||
152 | template <typename T> struct IntrusiveRefCntPtrInfo { | ||||
153 | static void retain(T *obj) { obj->Retain(); } | ||||
154 | static void release(T *obj) { obj->Release(); } | ||||
155 | }; | ||||
156 | |||||
157 | /// A smart pointer to a reference-counted object that inherits from | ||||
158 | /// RefCountedBase or ThreadSafeRefCountedBase. | ||||
159 | /// | ||||
160 | /// This class increments its pointee's reference count when it is created, and | ||||
161 | /// decrements its refcount when it's destroyed (or is changed to point to a | ||||
162 | /// different object). | ||||
163 | template <typename T> class IntrusiveRefCntPtr { | ||||
164 | T *Obj = nullptr; | ||||
165 | |||||
166 | public: | ||||
167 | using element_type = T; | ||||
168 | |||||
169 | explicit IntrusiveRefCntPtr() = default; | ||||
170 | IntrusiveRefCntPtr(T *obj) : Obj(obj) { retain(); } | ||||
171 | IntrusiveRefCntPtr(const IntrusiveRefCntPtr &S) : Obj(S.Obj) { retain(); } | ||||
172 | IntrusiveRefCntPtr(IntrusiveRefCntPtr &&S) : Obj(S.Obj) { S.Obj = nullptr; } | ||||
173 | |||||
174 | template <class X, | ||||
175 | std::enable_if_t<std::is_convertible<X *, T *>::value, bool> = true> | ||||
176 | IntrusiveRefCntPtr(IntrusiveRefCntPtr<X> S) : Obj(S.get()) { | ||||
177 | S.Obj = nullptr; | ||||
178 | } | ||||
179 | |||||
180 | template <class X, | ||||
181 | std::enable_if_t<std::is_convertible<X *, T *>::value, bool> = true> | ||||
182 | IntrusiveRefCntPtr(std::unique_ptr<X> S) : Obj(S.release()) { | ||||
183 | retain(); | ||||
184 | } | ||||
185 | |||||
186 | ~IntrusiveRefCntPtr() { release(); } | ||||
187 | |||||
188 | IntrusiveRefCntPtr &operator=(IntrusiveRefCntPtr S) { | ||||
189 | swap(S); | ||||
190 | return *this; | ||||
191 | } | ||||
192 | |||||
193 | T &operator*() const { return *Obj; } | ||||
194 | T *operator->() const { return Obj; } | ||||
195 | T *get() const { return Obj; } | ||||
196 | explicit operator bool() const { return Obj; } | ||||
197 | |||||
198 | void swap(IntrusiveRefCntPtr &other) { | ||||
199 | T *tmp = other.Obj; | ||||
200 | other.Obj = Obj; | ||||
201 | Obj = tmp; | ||||
202 | } | ||||
203 | |||||
204 | void reset() { | ||||
205 | release(); | ||||
206 | Obj = nullptr; | ||||
207 | } | ||||
208 | |||||
209 | void resetWithoutRelease() { Obj = nullptr; } | ||||
210 | |||||
211 | private: | ||||
212 | void retain() { | ||||
213 | if (Obj) | ||||
214 | IntrusiveRefCntPtrInfo<T>::retain(Obj); | ||||
215 | } | ||||
216 | |||||
217 | void release() { | ||||
218 | if (Obj
| ||||
219 | IntrusiveRefCntPtrInfo<T>::release(Obj); | ||||
| |||||
220 | } | ||||
221 | |||||
222 | template <typename X> friend class IntrusiveRefCntPtr; | ||||
223 | }; | ||||
224 | |||||
225 | template <class T, class U> | ||||
226 | inline bool operator==(const IntrusiveRefCntPtr<T> &A, | ||||
227 | const IntrusiveRefCntPtr<U> &B) { | ||||
228 | return A.get() == B.get(); | ||||
229 | } | ||||
230 | |||||
231 | template <class T, class U> | ||||
232 | inline bool operator!=(const IntrusiveRefCntPtr<T> &A, | ||||
233 | const IntrusiveRefCntPtr<U> &B) { | ||||
234 | return A.get() != B.get(); | ||||
235 | } | ||||
236 | |||||
237 | template <class T, class U> | ||||
238 | inline bool operator==(const IntrusiveRefCntPtr<T> &A, U *B) { | ||||
239 | return A.get() == B; | ||||
240 | } | ||||
241 | |||||
242 | template <class T, class U> | ||||
243 | inline bool operator!=(const IntrusiveRefCntPtr<T> &A, U *B) { | ||||
244 | return A.get() != B; | ||||
245 | } | ||||
246 | |||||
247 | template <class T, class U> | ||||
248 | inline bool operator==(T *A, const IntrusiveRefCntPtr<U> &B) { | ||||
249 | return A == B.get(); | ||||
250 | } | ||||
251 | |||||
252 | template <class T, class U> | ||||
253 | inline bool operator!=(T *A, const IntrusiveRefCntPtr<U> &B) { | ||||
254 | return A != B.get(); | ||||
255 | } | ||||
256 | |||||
257 | template <class T> | ||||
258 | bool operator==(std::nullptr_t, const IntrusiveRefCntPtr<T> &B) { | ||||
259 | return !B; | ||||
260 | } | ||||
261 | |||||
262 | template <class T> | ||||
263 | bool operator==(const IntrusiveRefCntPtr<T> &A, std::nullptr_t B) { | ||||
264 | return B == A; | ||||
265 | } | ||||
266 | |||||
267 | template <class T> | ||||
268 | bool operator!=(std::nullptr_t A, const IntrusiveRefCntPtr<T> &B) { | ||||
269 | return !(A == B); | ||||
270 | } | ||||
271 | |||||
272 | template <class T> | ||||
273 | bool operator!=(const IntrusiveRefCntPtr<T> &A, std::nullptr_t B) { | ||||
274 | return !(A == B); | ||||
275 | } | ||||
276 | |||||
277 | // Make IntrusiveRefCntPtr work with dyn_cast, isa, and the other idioms from | ||||
278 | // Casting.h. | ||||
279 | template <typename From> struct simplify_type; | ||||
280 | |||||
281 | template <class T> struct simplify_type<IntrusiveRefCntPtr<T>> { | ||||
282 | using SimpleType = T *; | ||||
283 | |||||
284 | static SimpleType getSimplifiedValue(IntrusiveRefCntPtr<T> &Val) { | ||||
285 | return Val.get(); | ||||
286 | } | ||||
287 | }; | ||||
288 | |||||
289 | template <class T> struct simplify_type<const IntrusiveRefCntPtr<T>> { | ||||
290 | using SimpleType = /*const*/ T *; | ||||
291 | |||||
292 | static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr<T> &Val) { | ||||
293 | return Val.get(); | ||||
294 | } | ||||
295 | }; | ||||
296 | |||||
297 | /// Factory function for creating intrusive ref counted pointers. | ||||
298 | template <typename T, typename... Args> | ||||
299 | IntrusiveRefCntPtr<T> makeIntrusiveRefCnt(Args &&...A) { | ||||
300 | return IntrusiveRefCntPtr<T>(new T(std::forward<Args>(A)...)); | ||||
301 | } | ||||
302 | |||||
303 | } // end namespace llvm | ||||
304 | |||||
305 | #endif // LLVM_ADT_INTRUSIVEREFCNTPTR_H |