| 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 |