| //===--------------- OrcV2CBindings.cpp - C bindings OrcV2 APIs -----------===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "llvm-c/LLJIT.h" | |
| #include "llvm-c/Orc.h" | |
| #include "llvm-c/OrcEE.h" | |
| #include "llvm-c/TargetMachine.h" | |
| #include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h" | |
| #include "llvm/ExecutionEngine/Orc/AbsoluteSymbols.h" | |
| #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h" | |
| #include "llvm/ExecutionEngine/Orc/LLJIT.h" | |
| #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" | |
| #include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h" | |
| #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" | |
| #include "llvm/ExecutionEngine/SectionMemoryManager.h" | |
| using namespace llvm; | |
| using namespace llvm::orc; | |
| namespace llvm { | |
| namespace orc { | |
| class InProgressLookupState; | |
| class OrcV2CAPIHelper { | |
| public: | |
| static InProgressLookupState *extractLookupState(LookupState &LS) { | |
| return LS.IPLS.release(); | |
| } | |
| static void resetLookupState(LookupState &LS, InProgressLookupState *IPLS) { | |
| return LS.reset(IPLS); | |
| } | |
| }; | |
| } // namespace orc | |
| } // namespace llvm | |
| inline LLVMOrcSymbolStringPoolEntryRef wrap(SymbolStringPoolEntryUnsafe E) { | |
| return reinterpret_cast<LLVMOrcSymbolStringPoolEntryRef>(E.rawPtr()); | |
| } | |
| inline SymbolStringPoolEntryUnsafe unwrap(LLVMOrcSymbolStringPoolEntryRef E) { | |
| return reinterpret_cast<SymbolStringPoolEntryUnsafe::PoolEntry *>(E); | |
| } | |
| DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ExecutionSession, LLVMOrcExecutionSessionRef) | |
| DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SymbolStringPool, LLVMOrcSymbolStringPoolRef) | |
| DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MaterializationUnit, | |
| LLVMOrcMaterializationUnitRef) | |
| DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MaterializationResponsibility, | |
| LLVMOrcMaterializationResponsibilityRef) | |
| DEFINE_SIMPLE_CONVERSION_FUNCTIONS(JITDylib, LLVMOrcJITDylibRef) | |
| DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ResourceTracker, LLVMOrcResourceTrackerRef) | |
| DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DefinitionGenerator, | |
| LLVMOrcDefinitionGeneratorRef) | |
| DEFINE_SIMPLE_CONVERSION_FUNCTIONS(InProgressLookupState, LLVMOrcLookupStateRef) | |
| DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ThreadSafeContext, | |
| LLVMOrcThreadSafeContextRef) | |
| DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ThreadSafeModule, LLVMOrcThreadSafeModuleRef) | |
| DEFINE_SIMPLE_CONVERSION_FUNCTIONS(JITTargetMachineBuilder, | |
| LLVMOrcJITTargetMachineBuilderRef) | |
| DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ObjectLayer, LLVMOrcObjectLayerRef) | |
| DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IRTransformLayer, LLVMOrcIRTransformLayerRef) | |
| DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ObjectTransformLayer, | |
| LLVMOrcObjectTransformLayerRef) | |
| DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DumpObjects, LLVMOrcDumpObjectsRef) | |
| DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IndirectStubsManager, | |
| LLVMOrcIndirectStubsManagerRef) | |
| DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LazyCallThroughManager, | |
| LLVMOrcLazyCallThroughManagerRef) | |
| DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLJITBuilder, LLVMOrcLLJITBuilderRef) | |
| DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLJIT, LLVMOrcLLJITRef) | |
| DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef) | |
| namespace { | |
| class OrcCAPIMaterializationUnit : public llvm::orc::MaterializationUnit { | |
| public: | |
| OrcCAPIMaterializationUnit( | |
| std::string Name, SymbolFlagsMap InitialSymbolFlags, | |
| SymbolStringPtr InitSymbol, void *Ctx, | |
| LLVMOrcMaterializationUnitMaterializeFunction Materialize, | |
| LLVMOrcMaterializationUnitDiscardFunction Discard, | |
| LLVMOrcMaterializationUnitDestroyFunction Destroy) | |
| : llvm::orc::MaterializationUnit( | |
| Interface(std::move(InitialSymbolFlags), std::move(InitSymbol))), | |
| Name(std::move(Name)), Ctx(Ctx), Materialize(Materialize), | |
| Discard(Discard), Destroy(Destroy) {} | |
| ~OrcCAPIMaterializationUnit() override { | |
| if (Ctx) | |
| Destroy(Ctx); | |
| } | |
| StringRef getName() const override { return Name; } | |
| void materialize(std::unique_ptr<MaterializationResponsibility> R) override { | |
| void *Tmp = Ctx; | |
| Ctx = nullptr; | |
| Materialize(Tmp, wrap(R.release())); | |
| } | |
| private: | |
| void discard(const JITDylib &JD, const SymbolStringPtr &Name) override { | |
| Discard(Ctx, wrap(&JD), wrap(SymbolStringPoolEntryUnsafe::from(Name))); | |
| } | |
| std::string Name; | |
| void *Ctx = nullptr; | |
| LLVMOrcMaterializationUnitMaterializeFunction Materialize = nullptr; | |
| LLVMOrcMaterializationUnitDiscardFunction Discard = nullptr; | |
| LLVMOrcMaterializationUnitDestroyFunction Destroy = nullptr; | |
| }; | |
| static JITSymbolFlags toJITSymbolFlags(LLVMJITSymbolFlags F) { | |
| JITSymbolFlags JSF; | |
| if (F.GenericFlags & LLVMJITSymbolGenericFlagsExported) | |
| JSF |= JITSymbolFlags::Exported; | |
| if (F.GenericFlags & LLVMJITSymbolGenericFlagsWeak) | |
| JSF |= JITSymbolFlags::Weak; | |
| if (F.GenericFlags & LLVMJITSymbolGenericFlagsCallable) | |
| JSF |= JITSymbolFlags::Callable; | |
| if (F.GenericFlags & LLVMJITSymbolGenericFlagsMaterializationSideEffectsOnly) | |
| JSF |= JITSymbolFlags::MaterializationSideEffectsOnly; | |
| JSF.getTargetFlags() = F.TargetFlags; | |
| return JSF; | |
| } | |
| static LLVMJITSymbolFlags fromJITSymbolFlags(JITSymbolFlags JSF) { | |
| LLVMJITSymbolFlags F = {0, 0}; | |
| if (JSF & JITSymbolFlags::Exported) | |
| F.GenericFlags |= LLVMJITSymbolGenericFlagsExported; | |
| if (JSF & JITSymbolFlags::Weak) | |
| F.GenericFlags |= LLVMJITSymbolGenericFlagsWeak; | |
| if (JSF & JITSymbolFlags::Callable) | |
| F.GenericFlags |= LLVMJITSymbolGenericFlagsCallable; | |
| if (JSF & JITSymbolFlags::MaterializationSideEffectsOnly) | |
| F.GenericFlags |= LLVMJITSymbolGenericFlagsMaterializationSideEffectsOnly; | |
| F.TargetFlags = JSF.getTargetFlags(); | |
| return F; | |
| } | |
| static SymbolNameSet toSymbolNameSet(LLVMOrcCSymbolsList Symbols) { | |
| SymbolNameSet Result; | |
| Result.reserve(Symbols.Length); | |
| for (size_t I = 0; I != Symbols.Length; ++I) | |
| Result.insert(unwrap(Symbols.Symbols[I]).moveToSymbolStringPtr()); | |
| return Result; | |
| } | |
| static SymbolMap toSymbolMap(LLVMOrcCSymbolMapPairs Syms, size_t NumPairs) { | |
| SymbolMap SM; | |
| for (size_t I = 0; I != NumPairs; ++I) { | |
| JITSymbolFlags Flags = toJITSymbolFlags(Syms[I].Sym.Flags); | |
| SM[unwrap(Syms[I].Name).moveToSymbolStringPtr()] = { | |
| ExecutorAddr(Syms[I].Sym.Address), Flags}; | |
| } | |
| return SM; | |
| } | |
| static SymbolDependenceMap | |
| toSymbolDependenceMap(LLVMOrcCDependenceMapPairs Pairs, size_t NumPairs) { | |
| SymbolDependenceMap SDM; | |
| for (size_t I = 0; I != NumPairs; ++I) { | |
| JITDylib *JD = unwrap(Pairs[I].JD); | |
| SymbolNameSet Names; | |
| for (size_t J = 0; J != Pairs[I].Names.Length; ++J) { | |
| auto Sym = Pairs[I].Names.Symbols[J]; | |
| Names.insert(unwrap(Sym).moveToSymbolStringPtr()); | |
| } | |
| SDM[JD] = Names; | |
| } | |
| return SDM; | |
| } | |
| static LookupKind toLookupKind(LLVMOrcLookupKind K) { | |
| switch (K) { | |
| case LLVMOrcLookupKindStatic: | |
| return LookupKind::Static; | |
| case LLVMOrcLookupKindDLSym: | |
| return LookupKind::DLSym; | |
| } | |
| llvm_unreachable("unrecognized LLVMOrcLookupKind value"); | |
| } | |
| static LLVMOrcLookupKind fromLookupKind(LookupKind K) { | |
| switch (K) { | |
| case LookupKind::Static: | |
| return LLVMOrcLookupKindStatic; | |
| case LookupKind::DLSym: | |
| return LLVMOrcLookupKindDLSym; | |
| } | |
| llvm_unreachable("unrecognized LookupKind value"); | |
| } | |
| static JITDylibLookupFlags | |
| toJITDylibLookupFlags(LLVMOrcJITDylibLookupFlags LF) { | |
| switch (LF) { | |
| case LLVMOrcJITDylibLookupFlagsMatchExportedSymbolsOnly: | |
| return JITDylibLookupFlags::MatchExportedSymbolsOnly; | |
| case LLVMOrcJITDylibLookupFlagsMatchAllSymbols: | |
| return JITDylibLookupFlags::MatchAllSymbols; | |
| } | |
| llvm_unreachable("unrecognized LLVMOrcJITDylibLookupFlags value"); | |
| } | |
| static LLVMOrcJITDylibLookupFlags | |
| fromJITDylibLookupFlags(JITDylibLookupFlags LF) { | |
| switch (LF) { | |
| case JITDylibLookupFlags::MatchExportedSymbolsOnly: | |
| return LLVMOrcJITDylibLookupFlagsMatchExportedSymbolsOnly; | |
| case JITDylibLookupFlags::MatchAllSymbols: | |
| return LLVMOrcJITDylibLookupFlagsMatchAllSymbols; | |
| } | |
| llvm_unreachable("unrecognized JITDylibLookupFlags value"); | |
| } | |
| static SymbolLookupFlags toSymbolLookupFlags(LLVMOrcSymbolLookupFlags SLF) { | |
| switch (SLF) { | |
| case LLVMOrcSymbolLookupFlagsRequiredSymbol: | |
| return SymbolLookupFlags::RequiredSymbol; | |
| case LLVMOrcSymbolLookupFlagsWeaklyReferencedSymbol: | |
| return SymbolLookupFlags::WeaklyReferencedSymbol; | |
| } | |
| llvm_unreachable("unrecognized LLVMOrcSymbolLookupFlags value"); | |
| } | |
| static LLVMOrcSymbolLookupFlags fromSymbolLookupFlags(SymbolLookupFlags SLF) { | |
| switch (SLF) { | |
| case SymbolLookupFlags::RequiredSymbol: | |
| return LLVMOrcSymbolLookupFlagsRequiredSymbol; | |
| case SymbolLookupFlags::WeaklyReferencedSymbol: | |
| return LLVMOrcSymbolLookupFlagsWeaklyReferencedSymbol; | |
| } | |
| llvm_unreachable("unrecognized SymbolLookupFlags value"); | |
| } | |
| static LLVMJITEvaluatedSymbol | |
| fromExecutorSymbolDef(const ExecutorSymbolDef &S) { | |
| return {S.getAddress().getValue(), fromJITSymbolFlags(S.getFlags())}; | |
| } | |
| } // end anonymous namespace | |
| namespace llvm { | |
| namespace orc { | |
| class CAPIDefinitionGenerator final : public DefinitionGenerator { | |
| public: | |
| CAPIDefinitionGenerator( | |
| LLVMOrcDisposeCAPIDefinitionGeneratorFunction Dispose, void *Ctx, | |
| LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction TryToGenerate) | |
| : Dispose(Dispose), Ctx(Ctx), TryToGenerate(TryToGenerate) {} | |
| ~CAPIDefinitionGenerator() override { | |
| if (Dispose) | |
| Dispose(Ctx); | |
| } | |
| Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD, | |
| JITDylibLookupFlags JDLookupFlags, | |
| const SymbolLookupSet &LookupSet) override { | |
| // Take the lookup state. | |
| LLVMOrcLookupStateRef LSR = ::wrap(OrcV2CAPIHelper::extractLookupState(LS)); | |
| // Translate the lookup kind. | |
| LLVMOrcLookupKind CLookupKind = fromLookupKind(K); | |
| // Translate the JITDylibLookupFlags. | |
| LLVMOrcJITDylibLookupFlags CJDLookupFlags = | |
| fromJITDylibLookupFlags(JDLookupFlags); | |
| // Translate the lookup set. | |
| std::vector<LLVMOrcCLookupSetElement> CLookupSet; | |
| CLookupSet.reserve(LookupSet.size()); | |
| for (auto &KV : LookupSet) { | |
| LLVMOrcSymbolStringPoolEntryRef Name = | |
| ::wrap(SymbolStringPoolEntryUnsafe::from(KV.first)); | |
| LLVMOrcSymbolLookupFlags SLF = fromSymbolLookupFlags(KV.second); | |
| CLookupSet.push_back({Name, SLF}); | |
| } | |
| // Run the C TryToGenerate function. | |
| auto Err = unwrap(TryToGenerate(::wrap(this), Ctx, &LSR, CLookupKind, | |
| ::wrap(&JD), CJDLookupFlags, | |
| CLookupSet.data(), CLookupSet.size())); | |
| // Restore the lookup state. | |
| OrcV2CAPIHelper::resetLookupState(LS, ::unwrap(LSR)); | |
| return Err; | |
| } | |
| private: | |
| LLVMOrcDisposeCAPIDefinitionGeneratorFunction Dispose; | |
| void *Ctx; | |
| LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction TryToGenerate; | |
| }; | |
| } // end namespace orc | |
| } // end namespace llvm | |
| void LLVMOrcExecutionSessionSetErrorReporter( | |
| LLVMOrcExecutionSessionRef ES, LLVMOrcErrorReporterFunction ReportError, | |
| void *Ctx) { | |
| unwrap(ES)->setErrorReporter( | |
| [=](Error Err) { ReportError(Ctx, wrap(std::move(Err))); }); | |
| } | |
| LLVMOrcSymbolStringPoolRef | |
| LLVMOrcExecutionSessionGetSymbolStringPool(LLVMOrcExecutionSessionRef ES) { | |
| return wrap( | |
| unwrap(ES)->getExecutorProcessControl().getSymbolStringPool().get()); | |
| } | |
| void LLVMOrcSymbolStringPoolClearDeadEntries(LLVMOrcSymbolStringPoolRef SSP) { | |
| unwrap(SSP)->clearDeadEntries(); | |
| } | |
| LLVMOrcSymbolStringPoolEntryRef | |
| LLVMOrcExecutionSessionIntern(LLVMOrcExecutionSessionRef ES, const char *Name) { | |
| return wrap(SymbolStringPoolEntryUnsafe::take(unwrap(ES)->intern(Name))); | |
| } | |
| void LLVMOrcExecutionSessionLookup( | |
| LLVMOrcExecutionSessionRef ES, LLVMOrcLookupKind K, | |
| LLVMOrcCJITDylibSearchOrder SearchOrder, size_t SearchOrderSize, | |
| LLVMOrcCLookupSet Symbols, size_t SymbolsSize, | |
| LLVMOrcExecutionSessionLookupHandleResultFunction HandleResult, void *Ctx) { | |
| assert(ES && "ES cannot be null"); | |
| assert(SearchOrder && "SearchOrder cannot be null"); | |
| assert(Symbols && "Symbols cannot be null"); | |
| assert(HandleResult && "HandleResult cannot be null"); | |
| JITDylibSearchOrder SO; | |
| for (size_t I = 0; I != SearchOrderSize; ++I) | |
| SO.push_back({unwrap(SearchOrder[I].JD), | |
| toJITDylibLookupFlags(SearchOrder[I].JDLookupFlags)}); | |
| SymbolLookupSet SLS; | |
| for (size_t I = 0; I != SymbolsSize; ++I) | |
| SLS.add(unwrap(Symbols[I].Name).moveToSymbolStringPtr(), | |
| toSymbolLookupFlags(Symbols[I].LookupFlags)); | |
| unwrap(ES)->lookup( | |
| toLookupKind(K), SO, std::move(SLS), SymbolState::Ready, | |
| [HandleResult, Ctx](Expected<SymbolMap> Result) { | |
| if (Result) { | |
| SmallVector<LLVMOrcCSymbolMapPair> CResult; | |
| for (auto &KV : *Result) | |
| CResult.push_back(LLVMOrcCSymbolMapPair{ | |
| wrap(SymbolStringPoolEntryUnsafe::from(KV.first)), | |
| fromExecutorSymbolDef(KV.second)}); | |
| HandleResult(LLVMErrorSuccess, CResult.data(), CResult.size(), Ctx); | |
| } else | |
| HandleResult(wrap(Result.takeError()), nullptr, 0, Ctx); | |
| }, | |
| NoDependenciesToRegister); | |
| } | |
| void LLVMOrcRetainSymbolStringPoolEntry(LLVMOrcSymbolStringPoolEntryRef S) { | |
| unwrap(S).retain(); | |
| } | |
| void LLVMOrcReleaseSymbolStringPoolEntry(LLVMOrcSymbolStringPoolEntryRef S) { | |
| unwrap(S).release(); | |
| } | |
| const char *LLVMOrcSymbolStringPoolEntryStr(LLVMOrcSymbolStringPoolEntryRef S) { | |
| return unwrap(S).rawPtr()->getKey().data(); | |
| } | |
| LLVMOrcResourceTrackerRef | |
| LLVMOrcJITDylibCreateResourceTracker(LLVMOrcJITDylibRef JD) { | |
| auto RT = unwrap(JD)->createResourceTracker(); | |
| // Retain the pointer for the C API client. | |
| RT->Retain(); | |
| return wrap(RT.get()); | |
| } | |
| LLVMOrcResourceTrackerRef | |
| LLVMOrcJITDylibGetDefaultResourceTracker(LLVMOrcJITDylibRef JD) { | |
| auto RT = unwrap(JD)->getDefaultResourceTracker(); | |
| // Retain the pointer for the C API client. | |
| return wrap(RT.get()); | |
| } | |
| void LLVMOrcReleaseResourceTracker(LLVMOrcResourceTrackerRef RT) { | |
| ResourceTrackerSP TmpRT(unwrap(RT)); | |
| TmpRT->Release(); | |
| } | |
| void LLVMOrcResourceTrackerTransferTo(LLVMOrcResourceTrackerRef SrcRT, | |
| LLVMOrcResourceTrackerRef DstRT) { | |
| ResourceTrackerSP TmpRT(unwrap(SrcRT)); | |
| TmpRT->transferTo(*unwrap(DstRT)); | |
| } | |
| LLVMErrorRef LLVMOrcResourceTrackerRemove(LLVMOrcResourceTrackerRef RT) { | |
| ResourceTrackerSP TmpRT(unwrap(RT)); | |
| return wrap(TmpRT->remove()); | |
| } | |
| void LLVMOrcDisposeDefinitionGenerator(LLVMOrcDefinitionGeneratorRef DG) { | |
| std::unique_ptr<DefinitionGenerator> TmpDG(unwrap(DG)); | |
| } | |
| void LLVMOrcDisposeMaterializationUnit(LLVMOrcMaterializationUnitRef MU) { | |
| std::unique_ptr<MaterializationUnit> TmpMU(unwrap(MU)); | |
| } | |
| LLVMOrcMaterializationUnitRef LLVMOrcCreateCustomMaterializationUnit( | |
| const char *Name, void *Ctx, LLVMOrcCSymbolFlagsMapPairs Syms, | |
| size_t NumSyms, LLVMOrcSymbolStringPoolEntryRef InitSym, | |
| LLVMOrcMaterializationUnitMaterializeFunction Materialize, | |
| LLVMOrcMaterializationUnitDiscardFunction Discard, | |
| LLVMOrcMaterializationUnitDestroyFunction Destroy) { | |
| SymbolFlagsMap SFM; | |
| for (size_t I = 0; I != NumSyms; ++I) | |
| SFM[unwrap(Syms[I].Name).moveToSymbolStringPtr()] = | |
| toJITSymbolFlags(Syms[I].Flags); | |
| auto IS = unwrap(InitSym).moveToSymbolStringPtr(); | |
| return wrap(new OrcCAPIMaterializationUnit( | |
| Name, std::move(SFM), std::move(IS), Ctx, Materialize, Discard, Destroy)); | |
| } | |
| LLVMOrcMaterializationUnitRef | |
| LLVMOrcAbsoluteSymbols(LLVMOrcCSymbolMapPairs Syms, size_t NumPairs) { | |
| SymbolMap SM = toSymbolMap(Syms, NumPairs); | |
| return wrap(absoluteSymbols(std::move(SM)).release()); | |
| } | |
| LLVMOrcMaterializationUnitRef LLVMOrcLazyReexports( | |
| LLVMOrcLazyCallThroughManagerRef LCTM, LLVMOrcIndirectStubsManagerRef ISM, | |
| LLVMOrcJITDylibRef SourceJD, LLVMOrcCSymbolAliasMapPairs CallableAliases, | |
| size_t NumPairs) { | |
| SymbolAliasMap SAM; | |
| for (size_t I = 0; I != NumPairs; ++I) { | |
| auto pair = CallableAliases[I]; | |
| JITSymbolFlags Flags = toJITSymbolFlags(pair.Entry.Flags); | |
| SymbolStringPtr Name = unwrap(pair.Entry.Name).moveToSymbolStringPtr(); | |
| SAM[unwrap(pair.Name).moveToSymbolStringPtr()] = | |
| SymbolAliasMapEntry(Name, Flags); | |
| } | |
| return wrap(lazyReexports(*unwrap(LCTM), *unwrap(ISM), *unwrap(SourceJD), | |
| std::move(SAM)) | |
| .release()); | |
| } | |
| void LLVMOrcDisposeMaterializationResponsibility( | |
| LLVMOrcMaterializationResponsibilityRef MR) { | |
| std::unique_ptr<MaterializationResponsibility> TmpMR(unwrap(MR)); | |
| } | |
| LLVMOrcJITDylibRef LLVMOrcMaterializationResponsibilityGetTargetDylib( | |
| LLVMOrcMaterializationResponsibilityRef MR) { | |
| return wrap(&unwrap(MR)->getTargetJITDylib()); | |
| } | |
| LLVMOrcExecutionSessionRef | |
| LLVMOrcMaterializationResponsibilityGetExecutionSession( | |
| LLVMOrcMaterializationResponsibilityRef MR) { | |
| return wrap(&unwrap(MR)->getExecutionSession()); | |
| } | |
| LLVMOrcCSymbolFlagsMapPairs LLVMOrcMaterializationResponsibilityGetSymbols( | |
| LLVMOrcMaterializationResponsibilityRef MR, size_t *NumPairs) { | |
| auto Symbols = unwrap(MR)->getSymbols(); | |
| LLVMOrcCSymbolFlagsMapPairs Result = static_cast<LLVMOrcCSymbolFlagsMapPairs>( | |
| safe_malloc(Symbols.size() * sizeof(LLVMOrcCSymbolFlagsMapPair))); | |
| size_t I = 0; | |
| for (auto const &pair : Symbols) { | |
| auto Name = wrap(SymbolStringPoolEntryUnsafe::from(pair.first)); | |
| auto Flags = pair.second; | |
| Result[I] = {Name, fromJITSymbolFlags(Flags)}; | |
| I++; | |
| } | |
| *NumPairs = Symbols.size(); | |
| return Result; | |
| } | |
| void LLVMOrcDisposeCSymbolFlagsMap(LLVMOrcCSymbolFlagsMapPairs Pairs) { | |
| free(Pairs); | |
| } | |
| LLVMOrcSymbolStringPoolEntryRef | |
| LLVMOrcMaterializationResponsibilityGetInitializerSymbol( | |
| LLVMOrcMaterializationResponsibilityRef MR) { | |
| auto Sym = unwrap(MR)->getInitializerSymbol(); | |
| return wrap(SymbolStringPoolEntryUnsafe::from(Sym)); | |
| } | |
| LLVMOrcSymbolStringPoolEntryRef * | |
| LLVMOrcMaterializationResponsibilityGetRequestedSymbols( | |
| LLVMOrcMaterializationResponsibilityRef MR, size_t *NumSymbols) { | |
| auto Symbols = unwrap(MR)->getRequestedSymbols(); | |
| LLVMOrcSymbolStringPoolEntryRef *Result = | |
| static_cast<LLVMOrcSymbolStringPoolEntryRef *>(safe_malloc( | |
| Symbols.size() * sizeof(LLVMOrcSymbolStringPoolEntryRef))); | |
| size_t I = 0; | |
| for (auto &Name : Symbols) { | |
| Result[I] = wrap(SymbolStringPoolEntryUnsafe::from(Name)); | |
| I++; | |
| } | |
| *NumSymbols = Symbols.size(); | |
| return Result; | |
| } | |
| void LLVMOrcDisposeSymbols(LLVMOrcSymbolStringPoolEntryRef *Symbols) { | |
| free(Symbols); | |
| } | |
| LLVMErrorRef LLVMOrcMaterializationResponsibilityNotifyResolved( | |
| LLVMOrcMaterializationResponsibilityRef MR, LLVMOrcCSymbolMapPairs Symbols, | |
| size_t NumSymbols) { | |
| SymbolMap SM = toSymbolMap(Symbols, NumSymbols); | |
| return wrap(unwrap(MR)->notifyResolved(std::move(SM))); | |
| } | |
| LLVMErrorRef LLVMOrcMaterializationResponsibilityNotifyEmitted( | |
| LLVMOrcMaterializationResponsibilityRef MR, | |
| LLVMOrcCSymbolDependenceGroup *SymbolDepGroups, size_t NumSymbolDepGroups) { | |
| std::vector<SymbolDependenceGroup> SDGs; | |
| SDGs.reserve(NumSymbolDepGroups); | |
| for (size_t I = 0; I != NumSymbolDepGroups; ++I) { | |
| SDGs.push_back(SymbolDependenceGroup()); | |
| auto &SDG = SDGs.back(); | |
| SDG.Symbols = toSymbolNameSet(SymbolDepGroups[I].Symbols); | |
| SDG.Dependencies = toSymbolDependenceMap( | |
| SymbolDepGroups[I].Dependencies, SymbolDepGroups[I].NumDependencies); | |
| } | |
| return wrap(unwrap(MR)->notifyEmitted(SDGs)); | |
| } | |
| LLVMErrorRef LLVMOrcMaterializationResponsibilityDefineMaterializing( | |
| LLVMOrcMaterializationResponsibilityRef MR, | |
| LLVMOrcCSymbolFlagsMapPairs Syms, size_t NumSyms) { | |
| SymbolFlagsMap SFM; | |
| for (size_t I = 0; I != NumSyms; ++I) | |
| SFM[unwrap(Syms[I].Name).moveToSymbolStringPtr()] = | |
| toJITSymbolFlags(Syms[I].Flags); | |
| return wrap(unwrap(MR)->defineMaterializing(std::move(SFM))); | |
| } | |
| LLVMErrorRef LLVMOrcMaterializationResponsibilityReplace( | |
| LLVMOrcMaterializationResponsibilityRef MR, | |
| LLVMOrcMaterializationUnitRef MU) { | |
| std::unique_ptr<MaterializationUnit> TmpMU(unwrap(MU)); | |
| return wrap(unwrap(MR)->replace(std::move(TmpMU))); | |
| } | |
| LLVMErrorRef LLVMOrcMaterializationResponsibilityDelegate( | |
| LLVMOrcMaterializationResponsibilityRef MR, | |
| LLVMOrcSymbolStringPoolEntryRef *Symbols, size_t NumSymbols, | |
| LLVMOrcMaterializationResponsibilityRef *Result) { | |
| SymbolNameSet Syms; | |
| for (size_t I = 0; I != NumSymbols; I++) { | |
| Syms.insert(unwrap(Symbols[I]).moveToSymbolStringPtr()); | |
| } | |
| auto OtherMR = unwrap(MR)->delegate(Syms); | |
| if (!OtherMR) { | |
| return wrap(OtherMR.takeError()); | |
| } | |
| *Result = wrap(OtherMR->release()); | |
| return LLVMErrorSuccess; | |
| } | |
| void LLVMOrcMaterializationResponsibilityFailMaterialization( | |
| LLVMOrcMaterializationResponsibilityRef MR) { | |
| unwrap(MR)->failMaterialization(); | |
| } | |
| void LLVMOrcIRTransformLayerEmit(LLVMOrcIRTransformLayerRef IRLayer, | |
| LLVMOrcMaterializationResponsibilityRef MR, | |
| LLVMOrcThreadSafeModuleRef TSM) { | |
| std::unique_ptr<ThreadSafeModule> TmpTSM(unwrap(TSM)); | |
| unwrap(IRLayer)->emit( | |
| std::unique_ptr<MaterializationResponsibility>(unwrap(MR)), | |
| std::move(*TmpTSM)); | |
| } | |
| LLVMOrcJITDylibRef | |
| LLVMOrcExecutionSessionCreateBareJITDylib(LLVMOrcExecutionSessionRef ES, | |
| const char *Name) { | |
| return wrap(&unwrap(ES)->createBareJITDylib(Name)); | |
| } | |
| LLVMErrorRef | |
| LLVMOrcExecutionSessionCreateJITDylib(LLVMOrcExecutionSessionRef ES, | |
| LLVMOrcJITDylibRef *Result, | |
| const char *Name) { | |
| auto JD = unwrap(ES)->createJITDylib(Name); | |
| if (!JD) | |
| return wrap(JD.takeError()); | |
| *Result = wrap(&*JD); | |
| return LLVMErrorSuccess; | |
| } | |
| LLVMOrcJITDylibRef | |
| LLVMOrcExecutionSessionGetJITDylibByName(LLVMOrcExecutionSessionRef ES, | |
| const char *Name) { | |
| return wrap(unwrap(ES)->getJITDylibByName(Name)); | |
| } | |
| LLVMErrorRef LLVMOrcJITDylibDefine(LLVMOrcJITDylibRef JD, | |
| LLVMOrcMaterializationUnitRef MU) { | |
| std::unique_ptr<MaterializationUnit> TmpMU(unwrap(MU)); | |
| if (auto Err = unwrap(JD)->define(TmpMU)) { | |
| TmpMU.release(); | |
| return wrap(std::move(Err)); | |
| } | |
| return LLVMErrorSuccess; | |
| } | |
| LLVMErrorRef LLVMOrcJITDylibClear(LLVMOrcJITDylibRef JD) { | |
| return wrap(unwrap(JD)->clear()); | |
| } | |
| void LLVMOrcJITDylibAddGenerator(LLVMOrcJITDylibRef JD, | |
| LLVMOrcDefinitionGeneratorRef DG) { | |
| unwrap(JD)->addGenerator(std::unique_ptr<DefinitionGenerator>(unwrap(DG))); | |
| } | |
| LLVMOrcDefinitionGeneratorRef LLVMOrcCreateCustomCAPIDefinitionGenerator( | |
| LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction F, void *Ctx, | |
| LLVMOrcDisposeCAPIDefinitionGeneratorFunction Dispose) { | |
| auto DG = std::make_unique<CAPIDefinitionGenerator>(Dispose, Ctx, F); | |
| return wrap(DG.release()); | |
| } | |
| void LLVMOrcLookupStateContinueLookup(LLVMOrcLookupStateRef S, | |
| LLVMErrorRef Err) { | |
| LookupState LS; | |
| OrcV2CAPIHelper::resetLookupState(LS, ::unwrap(S)); | |
| LS.continueLookup(unwrap(Err)); | |
| } | |
| LLVMErrorRef LLVMOrcCreateDynamicLibrarySearchGeneratorForProcess( | |
| LLVMOrcDefinitionGeneratorRef *Result, char GlobalPrefix, | |
| LLVMOrcSymbolPredicate Filter, void *FilterCtx) { | |
| assert(Result && "Result can not be null"); | |
| assert((Filter || !FilterCtx) && | |
| "if Filter is null then FilterCtx must also be null"); | |
| DynamicLibrarySearchGenerator::SymbolPredicate Pred; | |
| if (Filter) | |
| Pred = [=](const SymbolStringPtr &Name) -> bool { | |
| return Filter(FilterCtx, wrap(SymbolStringPoolEntryUnsafe::from(Name))); | |
| }; | |
| auto ProcessSymsGenerator = | |
| DynamicLibrarySearchGenerator::GetForCurrentProcess(GlobalPrefix, Pred); | |
| if (!ProcessSymsGenerator) { | |
| *Result = nullptr; | |
| return wrap(ProcessSymsGenerator.takeError()); | |
| } | |
| *Result = wrap(ProcessSymsGenerator->release()); | |
| return LLVMErrorSuccess; | |
| } | |
| LLVMErrorRef LLVMOrcCreateDynamicLibrarySearchGeneratorForPath( | |
| LLVMOrcDefinitionGeneratorRef *Result, const char *FileName, | |
| char GlobalPrefix, LLVMOrcSymbolPredicate Filter, void *FilterCtx) { | |
| assert(Result && "Result can not be null"); | |
| assert(FileName && "FileName can not be null"); | |
| assert((Filter || !FilterCtx) && | |
| "if Filter is null then FilterCtx must also be null"); | |
| DynamicLibrarySearchGenerator::SymbolPredicate Pred; | |
| if (Filter) | |
| Pred = [=](const SymbolStringPtr &Name) -> bool { | |
| return Filter(FilterCtx, wrap(SymbolStringPoolEntryUnsafe::from(Name))); | |
| }; | |
| auto LibrarySymsGenerator = | |
| DynamicLibrarySearchGenerator::Load(FileName, GlobalPrefix, Pred); | |
| if (!LibrarySymsGenerator) { | |
| *Result = nullptr; | |
| return wrap(LibrarySymsGenerator.takeError()); | |
| } | |
| *Result = wrap(LibrarySymsGenerator->release()); | |
| return LLVMErrorSuccess; | |
| } | |
| LLVMErrorRef LLVMOrcCreateStaticLibrarySearchGeneratorForPath( | |
| LLVMOrcDefinitionGeneratorRef *Result, LLVMOrcObjectLayerRef ObjLayer, | |
| const char *FileName) { | |
| assert(Result && "Result can not be null"); | |
| assert(FileName && "Filename can not be null"); | |
| assert(ObjLayer && "ObjectLayer can not be null"); | |
| auto LibrarySymsGenerator = | |
| StaticLibraryDefinitionGenerator::Load(*unwrap(ObjLayer), FileName); | |
| if (!LibrarySymsGenerator) { | |
| *Result = nullptr; | |
| return wrap(LibrarySymsGenerator.takeError()); | |
| } | |
| *Result = wrap(LibrarySymsGenerator->release()); | |
| return LLVMErrorSuccess; | |
| } | |
| LLVMOrcThreadSafeContextRef LLVMOrcCreateNewThreadSafeContext(void) { | |
| return wrap(new ThreadSafeContext(std::make_unique<LLVMContext>())); | |
| } | |
| LLVMOrcThreadSafeContextRef | |
| LLVMOrcCreateNewThreadSafeContextFromLLVMContext(LLVMContextRef Ctx) { | |
| return wrap(new ThreadSafeContext(std::unique_ptr<LLVMContext>(unwrap(Ctx)))); | |
| } | |
| void LLVMOrcDisposeThreadSafeContext(LLVMOrcThreadSafeContextRef TSCtx) { | |
| delete unwrap(TSCtx); | |
| } | |
| LLVMErrorRef | |
| LLVMOrcThreadSafeModuleWithModuleDo(LLVMOrcThreadSafeModuleRef TSM, | |
| LLVMOrcGenericIRModuleOperationFunction F, | |
| void *Ctx) { | |
| return wrap(unwrap(TSM)->withModuleDo( | |
| [&](Module &M) { return unwrap(F(Ctx, wrap(&M))); })); | |
| } | |
| LLVMOrcThreadSafeModuleRef | |
| LLVMOrcCreateNewThreadSafeModule(LLVMModuleRef M, | |
| LLVMOrcThreadSafeContextRef TSCtx) { | |
| return wrap( | |
| new ThreadSafeModule(std::unique_ptr<Module>(unwrap(M)), *unwrap(TSCtx))); | |
| } | |
| void LLVMOrcDisposeThreadSafeModule(LLVMOrcThreadSafeModuleRef TSM) { | |
| delete unwrap(TSM); | |
| } | |
| LLVMErrorRef LLVMOrcJITTargetMachineBuilderDetectHost( | |
| LLVMOrcJITTargetMachineBuilderRef *Result) { | |
| assert(Result && "Result can not be null"); | |
| auto JTMB = JITTargetMachineBuilder::detectHost(); | |
| if (!JTMB) { | |
| Result = nullptr; | |
| return wrap(JTMB.takeError()); | |
| } | |
| *Result = wrap(new JITTargetMachineBuilder(std::move(*JTMB))); | |
| return LLVMErrorSuccess; | |
| } | |
| LLVMOrcJITTargetMachineBuilderRef | |
| LLVMOrcJITTargetMachineBuilderCreateFromTargetMachine(LLVMTargetMachineRef TM) { | |
| auto *TemplateTM = unwrap(TM); | |
| auto JTMB = | |
| std::make_unique<JITTargetMachineBuilder>(TemplateTM->getTargetTriple()); | |
| (*JTMB) | |
| .setCPU(TemplateTM->getTargetCPU().str()) | |
| .setRelocationModel(TemplateTM->getRelocationModel()) | |
| .setCodeModel(TemplateTM->getCodeModel()) | |
| .setCodeGenOptLevel(TemplateTM->getOptLevel()) | |
| .setFeatures(TemplateTM->getTargetFeatureString()) | |
| .setOptions(TemplateTM->Options); | |
| LLVMDisposeTargetMachine(TM); | |
| return wrap(JTMB.release()); | |
| } | |
| void LLVMOrcDisposeJITTargetMachineBuilder( | |
| LLVMOrcJITTargetMachineBuilderRef JTMB) { | |
| delete unwrap(JTMB); | |
| } | |
| char *LLVMOrcJITTargetMachineBuilderGetTargetTriple( | |
| LLVMOrcJITTargetMachineBuilderRef JTMB) { | |
| auto Tmp = unwrap(JTMB)->getTargetTriple().str(); | |
| char *TargetTriple = (char *)malloc(Tmp.size() + 1); | |
| strcpy(TargetTriple, Tmp.c_str()); | |
| return TargetTriple; | |
| } | |
| void LLVMOrcJITTargetMachineBuilderSetTargetTriple( | |
| LLVMOrcJITTargetMachineBuilderRef JTMB, const char *TargetTriple) { | |
| unwrap(JTMB)->getTargetTriple() = Triple(TargetTriple); | |
| } | |
| LLVMErrorRef LLVMOrcObjectLayerAddObjectFile(LLVMOrcObjectLayerRef ObjLayer, | |
| LLVMOrcJITDylibRef JD, | |
| LLVMMemoryBufferRef ObjBuffer) { | |
| return wrap(unwrap(ObjLayer)->add( | |
| *unwrap(JD), std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer)))); | |
| } | |
| LLVMErrorRef LLVMOrcObjectLayerAddObjectFileWithRT(LLVMOrcObjectLayerRef ObjLayer, | |
| LLVMOrcResourceTrackerRef RT, | |
| LLVMMemoryBufferRef ObjBuffer) { | |
| return wrap( | |
| unwrap(ObjLayer)->add(ResourceTrackerSP(unwrap(RT)), | |
| std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer)))); | |
| } | |
| void LLVMOrcObjectLayerEmit(LLVMOrcObjectLayerRef ObjLayer, | |
| LLVMOrcMaterializationResponsibilityRef R, | |
| LLVMMemoryBufferRef ObjBuffer) { | |
| unwrap(ObjLayer)->emit( | |
| std::unique_ptr<MaterializationResponsibility>(unwrap(R)), | |
| std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer))); | |
| } | |
| void LLVMOrcDisposeObjectLayer(LLVMOrcObjectLayerRef ObjLayer) { | |
| delete unwrap(ObjLayer); | |
| } | |
| void LLVMOrcIRTransformLayerSetTransform( | |
| LLVMOrcIRTransformLayerRef IRTransformLayer, | |
| LLVMOrcIRTransformLayerTransformFunction TransformFunction, void *Ctx) { | |
| unwrap(IRTransformLayer) | |
| ->setTransform( | |
| [=](ThreadSafeModule TSM, | |
| MaterializationResponsibility &R) -> Expected<ThreadSafeModule> { | |
| LLVMOrcThreadSafeModuleRef TSMRef = | |
| wrap(new ThreadSafeModule(std::move(TSM))); | |
| if (LLVMErrorRef Err = TransformFunction(Ctx, &TSMRef, wrap(&R))) { | |
| assert(!TSMRef && "TSMRef was not reset to null on error"); | |
| return unwrap(Err); | |
| } | |
| assert(TSMRef && "Transform succeeded, but TSMRef was set to null"); | |
| ThreadSafeModule Result = std::move(*unwrap(TSMRef)); | |
| LLVMOrcDisposeThreadSafeModule(TSMRef); | |
| return std::move(Result); | |
| }); | |
| } | |
| void LLVMOrcObjectTransformLayerSetTransform( | |
| LLVMOrcObjectTransformLayerRef ObjTransformLayer, | |
| LLVMOrcObjectTransformLayerTransformFunction TransformFunction, void *Ctx) { | |
| unwrap(ObjTransformLayer) | |
| ->setTransform([TransformFunction, Ctx](std::unique_ptr<MemoryBuffer> Obj) | |
| -> Expected<std::unique_ptr<MemoryBuffer>> { | |
| LLVMMemoryBufferRef ObjBuffer = wrap(Obj.release()); | |
| if (LLVMErrorRef Err = TransformFunction(Ctx, &ObjBuffer)) { | |
| assert(!ObjBuffer && "ObjBuffer was not reset to null on error"); | |
| return unwrap(Err); | |
| } | |
| return std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer)); | |
| }); | |
| } | |
| LLVMOrcDumpObjectsRef LLVMOrcCreateDumpObjects(const char *DumpDir, | |
| const char *IdentifierOverride) { | |
| assert(DumpDir && "DumpDir should not be null"); | |
| assert(IdentifierOverride && "IdentifierOverride should not be null"); | |
| return wrap(new DumpObjects(DumpDir, IdentifierOverride)); | |
| } | |
| void LLVMOrcDisposeDumpObjects(LLVMOrcDumpObjectsRef DumpObjects) { | |
| delete unwrap(DumpObjects); | |
| } | |
| LLVMErrorRef LLVMOrcDumpObjects_CallOperator(LLVMOrcDumpObjectsRef DumpObjects, | |
| LLVMMemoryBufferRef *ObjBuffer) { | |
| std::unique_ptr<MemoryBuffer> OB(unwrap(*ObjBuffer)); | |
| if (auto Result = (*unwrap(DumpObjects))(std::move(OB))) { | |
| *ObjBuffer = wrap(Result->release()); | |
| return LLVMErrorSuccess; | |
| } else { | |
| *ObjBuffer = nullptr; | |
| return wrap(Result.takeError()); | |
| } | |
| } | |
| LLVMOrcLLJITBuilderRef LLVMOrcCreateLLJITBuilder(void) { | |
| return wrap(new LLJITBuilder()); | |
| } | |
| void LLVMOrcDisposeLLJITBuilder(LLVMOrcLLJITBuilderRef Builder) { | |
| delete unwrap(Builder); | |
| } | |
| void LLVMOrcLLJITBuilderSetJITTargetMachineBuilder( | |
| LLVMOrcLLJITBuilderRef Builder, LLVMOrcJITTargetMachineBuilderRef JTMB) { | |
| unwrap(Builder)->setJITTargetMachineBuilder(std::move(*unwrap(JTMB))); | |
| LLVMOrcDisposeJITTargetMachineBuilder(JTMB); | |
| } | |
| void LLVMOrcLLJITBuilderSetObjectLinkingLayerCreator( | |
| LLVMOrcLLJITBuilderRef Builder, | |
| LLVMOrcLLJITBuilderObjectLinkingLayerCreatorFunction F, void *Ctx) { | |
| unwrap(Builder)->setObjectLinkingLayerCreator( | |
| [=](ExecutionSession &ES, | |
| jitlink::JITLinkMemoryManager &MemMgr /* <- Currently ignored */) { | |
| auto TTStr = ES.getTargetTriple().str(); | |
| return std::unique_ptr<ObjectLayer>( | |
| unwrap(F(Ctx, wrap(&ES), TTStr.c_str()))); | |
| }); | |
| } | |
| LLVMErrorRef LLVMOrcCreateLLJIT(LLVMOrcLLJITRef *Result, | |
| LLVMOrcLLJITBuilderRef Builder) { | |
| assert(Result && "Result can not be null"); | |
| if (!Builder) | |
| Builder = LLVMOrcCreateLLJITBuilder(); | |
| auto J = unwrap(Builder)->create(); | |
| LLVMOrcDisposeLLJITBuilder(Builder); | |
| if (!J) { | |
| Result = nullptr; | |
| return wrap(J.takeError()); | |
| } | |
| *Result = wrap(J->release()); | |
| return LLVMErrorSuccess; | |
| } | |
| LLVMErrorRef LLVMOrcDisposeLLJIT(LLVMOrcLLJITRef J) { | |
| delete unwrap(J); | |
| return LLVMErrorSuccess; | |
| } | |
| LLVMOrcExecutionSessionRef LLVMOrcLLJITGetExecutionSession(LLVMOrcLLJITRef J) { | |
| return wrap(&unwrap(J)->getExecutionSession()); | |
| } | |
| LLVMOrcJITDylibRef LLVMOrcLLJITGetMainJITDylib(LLVMOrcLLJITRef J) { | |
| return wrap(&unwrap(J)->getMainJITDylib()); | |
| } | |
| const char *LLVMOrcLLJITGetTripleString(LLVMOrcLLJITRef J) { | |
| return unwrap(J)->getTargetTriple().str().c_str(); | |
| } | |
| char LLVMOrcLLJITGetGlobalPrefix(LLVMOrcLLJITRef J) { | |
| return unwrap(J)->getDataLayout().getGlobalPrefix(); | |
| } | |
| LLVMOrcSymbolStringPoolEntryRef | |
| LLVMOrcLLJITMangleAndIntern(LLVMOrcLLJITRef J, const char *UnmangledName) { | |
| return wrap(SymbolStringPoolEntryUnsafe::take( | |
| unwrap(J)->mangleAndIntern(UnmangledName))); | |
| } | |
| LLVMErrorRef LLVMOrcLLJITAddObjectFile(LLVMOrcLLJITRef J, LLVMOrcJITDylibRef JD, | |
| LLVMMemoryBufferRef ObjBuffer) { | |
| return wrap(unwrap(J)->addObjectFile( | |
| *unwrap(JD), std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer)))); | |
| } | |
| LLVMErrorRef LLVMOrcLLJITAddObjectFileWithRT(LLVMOrcLLJITRef J, | |
| LLVMOrcResourceTrackerRef RT, | |
| LLVMMemoryBufferRef ObjBuffer) { | |
| return wrap(unwrap(J)->addObjectFile( | |
| ResourceTrackerSP(unwrap(RT)), | |
| std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer)))); | |
| } | |
| LLVMErrorRef LLVMOrcLLJITAddLLVMIRModule(LLVMOrcLLJITRef J, | |
| LLVMOrcJITDylibRef JD, | |
| LLVMOrcThreadSafeModuleRef TSM) { | |
| std::unique_ptr<ThreadSafeModule> TmpTSM(unwrap(TSM)); | |
| return wrap(unwrap(J)->addIRModule(*unwrap(JD), std::move(*TmpTSM))); | |
| } | |
| LLVMErrorRef LLVMOrcLLJITAddLLVMIRModuleWithRT(LLVMOrcLLJITRef J, | |
| LLVMOrcResourceTrackerRef RT, | |
| LLVMOrcThreadSafeModuleRef TSM) { | |
| std::unique_ptr<ThreadSafeModule> TmpTSM(unwrap(TSM)); | |
| return wrap(unwrap(J)->addIRModule(ResourceTrackerSP(unwrap(RT)), | |
| std::move(*TmpTSM))); | |
| } | |
| LLVMErrorRef LLVMOrcLLJITLookup(LLVMOrcLLJITRef J, | |
| LLVMOrcJITTargetAddress *Result, | |
| const char *Name) { | |
| assert(Result && "Result can not be null"); | |
| auto Sym = unwrap(J)->lookup(Name); | |
| if (!Sym) { | |
| *Result = 0; | |
| return wrap(Sym.takeError()); | |
| } | |
| *Result = Sym->getValue(); | |
| return LLVMErrorSuccess; | |
| } | |
| LLVMOrcObjectLayerRef LLVMOrcLLJITGetObjLinkingLayer(LLVMOrcLLJITRef J) { | |
| return wrap(&unwrap(J)->getObjLinkingLayer()); | |
| } | |
| LLVMOrcObjectTransformLayerRef | |
| LLVMOrcLLJITGetObjTransformLayer(LLVMOrcLLJITRef J) { | |
| return wrap(&unwrap(J)->getObjTransformLayer()); | |
| } | |
| LLVMErrorRef LLVMOrcCreateObjectLinkingLayerWithInProcessMemoryManager( | |
| LLVMOrcObjectLayerRef *Result, LLVMOrcExecutionSessionRef ES) { | |
| assert(Result && "Result must not be null"); | |
| assert(ES && "ES must not be null"); | |
| auto MM = jitlink::InProcessMemoryManager::Create(); | |
| if (!MM) | |
| return wrap(MM.takeError()); | |
| *Result = wrap(new ObjectLinkingLayer(*unwrap(ES), std::move(*MM))); | |
| return LLVMErrorSuccess; | |
| } | |
| LLVMOrcObjectLayerRef | |
| LLVMOrcCreateRTDyldObjectLinkingLayerWithSectionMemoryManager( | |
| LLVMOrcExecutionSessionRef ES) { | |
| assert(ES && "ES must not be null"); | |
| return wrap( | |
| new RTDyldObjectLinkingLayer(*unwrap(ES), [](const MemoryBuffer &) { | |
| return std::make_unique<SectionMemoryManager>(); | |
| })); | |
| } | |
| LLVMOrcObjectLayerRef | |
| LLVMOrcCreateRTDyldObjectLinkingLayerWithSectionMemoryManagerReserveAlloc( | |
| LLVMOrcExecutionSessionRef ES, LLVMBool ReserveAlloc) { | |
| assert(ES && "ES must not be null"); | |
| return wrap(new RTDyldObjectLinkingLayer( | |
| *unwrap(ES), [ReserveAlloc](const MemoryBuffer &) { | |
| return std::make_unique<SectionMemoryManager>(nullptr, ReserveAlloc); | |
| })); | |
| } | |
| LLVMOrcObjectLayerRef | |
| LLVMOrcCreateRTDyldObjectLinkingLayerWithMCJITMemoryManagerLikeCallbacks( | |
| LLVMOrcExecutionSessionRef ES, void *CreateContextCtx, | |
| LLVMMemoryManagerCreateContextCallback CreateContext, | |
| LLVMMemoryManagerNotifyTerminatingCallback NotifyTerminating, | |
| LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection, | |
| LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection, | |
| LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory, | |
| LLVMMemoryManagerDestroyCallback Destroy) { | |
| struct MCJITMemoryManagerLikeCallbacks { | |
| MCJITMemoryManagerLikeCallbacks() = default; | |
| MCJITMemoryManagerLikeCallbacks( | |
| void *CreateContextCtx, | |
| LLVMMemoryManagerCreateContextCallback CreateContext, | |
| LLVMMemoryManagerNotifyTerminatingCallback NotifyTerminating, | |
| LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection, | |
| LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection, | |
| LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory, | |
| LLVMMemoryManagerDestroyCallback Destroy) | |
| : CreateContextCtx(CreateContextCtx), CreateContext(CreateContext), | |
| NotifyTerminating(NotifyTerminating), | |
| AllocateCodeSection(AllocateCodeSection), | |
| AllocateDataSection(AllocateDataSection), | |
| FinalizeMemory(FinalizeMemory), Destroy(Destroy) {} | |
| MCJITMemoryManagerLikeCallbacks(MCJITMemoryManagerLikeCallbacks &&Other) { | |
| std::swap(CreateContextCtx, Other.CreateContextCtx); | |
| std::swap(CreateContext, Other.CreateContext); | |
| std::swap(NotifyTerminating, Other.NotifyTerminating); | |
| std::swap(AllocateCodeSection, Other.AllocateCodeSection); | |
| std::swap(AllocateDataSection, Other.AllocateDataSection); | |
| std::swap(FinalizeMemory, Other.FinalizeMemory); | |
| std::swap(Destroy, Other.Destroy); | |
| } | |
| ~MCJITMemoryManagerLikeCallbacks() { | |
| if (NotifyTerminating) | |
| NotifyTerminating(CreateContextCtx); | |
| } | |
| void *CreateContextCtx = nullptr; | |
| LLVMMemoryManagerCreateContextCallback CreateContext = nullptr; | |
| LLVMMemoryManagerNotifyTerminatingCallback NotifyTerminating = nullptr; | |
| LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection = nullptr; | |
| LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection = nullptr; | |
| LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory = nullptr; | |
| LLVMMemoryManagerDestroyCallback Destroy = nullptr; | |
| }; | |
| class MCJITMemoryManagerLikeCallbacksMemMgr : public RTDyldMemoryManager { | |
| public: | |
| MCJITMemoryManagerLikeCallbacksMemMgr( | |
| const MCJITMemoryManagerLikeCallbacks &CBs) | |
| : CBs(CBs) { | |
| Opaque = CBs.CreateContext(CBs.CreateContextCtx); | |
| } | |
| ~MCJITMemoryManagerLikeCallbacksMemMgr() override { CBs.Destroy(Opaque); } | |
| uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, | |
| unsigned SectionID, | |
| StringRef SectionName) override { | |
| return CBs.AllocateCodeSection(Opaque, Size, Alignment, SectionID, | |
| SectionName.str().c_str()); | |
| } | |
| uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, | |
| unsigned SectionID, StringRef SectionName, | |
| bool isReadOnly) override { | |
| return CBs.AllocateDataSection(Opaque, Size, Alignment, SectionID, | |
| SectionName.str().c_str(), isReadOnly); | |
| } | |
| bool finalizeMemory(std::string *ErrMsg) override { | |
| char *ErrMsgCString = nullptr; | |
| bool Result = CBs.FinalizeMemory(Opaque, &ErrMsgCString); | |
| assert((Result || !ErrMsgCString) && | |
| "Did not expect an error message if FinalizeMemory succeeded"); | |
| if (ErrMsgCString) { | |
| if (ErrMsg) | |
| *ErrMsg = ErrMsgCString; | |
| free(ErrMsgCString); | |
| } | |
| return Result; | |
| } | |
| private: | |
| const MCJITMemoryManagerLikeCallbacks &CBs; | |
| void *Opaque = nullptr; | |
| }; | |
| assert(ES && "ES must not be null"); | |
| assert(CreateContext && "CreateContext must not be null"); | |
| assert(NotifyTerminating && "NotifyTerminating must not be null"); | |
| assert(AllocateCodeSection && "AllocateCodeSection must not be null"); | |
| assert(AllocateDataSection && "AllocateDataSection must not be null"); | |
| assert(FinalizeMemory && "FinalizeMemory must not be null"); | |
| assert(Destroy && "Destroy must not be null"); | |
| MCJITMemoryManagerLikeCallbacks CBs( | |
| CreateContextCtx, CreateContext, NotifyTerminating, AllocateCodeSection, | |
| AllocateDataSection, FinalizeMemory, Destroy); | |
| return wrap(new RTDyldObjectLinkingLayer( | |
| *unwrap(ES), [CBs = std::move(CBs)](const MemoryBuffer &) { | |
| return std::make_unique<MCJITMemoryManagerLikeCallbacksMemMgr>(CBs); | |
| })); | |
| return nullptr; | |
| } | |
| void LLVMOrcRTDyldObjectLinkingLayerRegisterJITEventListener( | |
| LLVMOrcObjectLayerRef RTDyldObjLinkingLayer, | |
| LLVMJITEventListenerRef Listener) { | |
| assert(RTDyldObjLinkingLayer && "RTDyldObjLinkingLayer must not be null"); | |
| assert(Listener && "Listener must not be null"); | |
| reinterpret_cast<RTDyldObjectLinkingLayer *>(unwrap(RTDyldObjLinkingLayer)) | |
| ->registerJITEventListener(*unwrap(Listener)); | |
| } | |
| LLVMOrcIRTransformLayerRef LLVMOrcLLJITGetIRTransformLayer(LLVMOrcLLJITRef J) { | |
| return wrap(&unwrap(J)->getIRTransformLayer()); | |
| } | |
| const char *LLVMOrcLLJITGetDataLayoutStr(LLVMOrcLLJITRef J) { | |
| return unwrap(J)->getDataLayout().getStringRepresentation().c_str(); | |
| } | |
| LLVMOrcIndirectStubsManagerRef | |
| LLVMOrcCreateLocalIndirectStubsManager(const char *TargetTriple) { | |
| auto builder = createLocalIndirectStubsManagerBuilder(Triple(TargetTriple)); | |
| return wrap(builder().release()); | |
| } | |
| void LLVMOrcDisposeIndirectStubsManager(LLVMOrcIndirectStubsManagerRef ISM) { | |
| std::unique_ptr<IndirectStubsManager> TmpISM(unwrap(ISM)); | |
| } | |
| LLVMErrorRef LLVMOrcCreateLocalLazyCallThroughManager( | |
| const char *TargetTriple, LLVMOrcExecutionSessionRef ES, | |
| LLVMOrcJITTargetAddress ErrorHandlerAddr, | |
| LLVMOrcLazyCallThroughManagerRef *Result) { | |
| auto LCTM = createLocalLazyCallThroughManager( | |
| Triple(TargetTriple), *unwrap(ES), ExecutorAddr(ErrorHandlerAddr)); | |
| if (!LCTM) | |
| return wrap(LCTM.takeError()); | |
| *Result = wrap(LCTM->release()); | |
| return LLVMErrorSuccess; | |
| } | |
| void LLVMOrcDisposeLazyCallThroughManager( | |
| LLVMOrcLazyCallThroughManagerRef LCM) { | |
| std::unique_ptr<LazyCallThroughManager> TmpLCM(unwrap(LCM)); | |
| } |