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