1 //===--------------- OrcV2CBindings.cpp - C bindings OrcV2 APIs -----------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm-c/Orc.h"
10 #include "llvm-c/TargetMachine.h"
12 #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
13 #include "llvm/ExecutionEngine/Orc/LLJIT.h"
16 using namespace llvm::orc;
21 class OrcV2CAPIHelper {
23 using PoolEntry = SymbolStringPtr::PoolEntry;
24 using PoolEntryPtr = SymbolStringPtr::PoolEntryPtr;
26 static PoolEntryPtr releaseSymbolStringPtr(SymbolStringPtr S) {
27 PoolEntryPtr Result = nullptr;
28 std::swap(Result, S.S);
32 static PoolEntryPtr getRawPoolEntryPtr(const SymbolStringPtr &S) {
36 static void releasePoolEntry(PoolEntryPtr P) {
42 } // end namespace orc
43 } // end namespace llvm
45 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ExecutionSession, LLVMOrcExecutionSessionRef)
46 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcV2CAPIHelper::PoolEntry,
47 LLVMOrcSymbolStringPoolEntryRef)
48 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(JITDylib, LLVMOrcJITDylibRef)
49 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(JITDylib::DefinitionGenerator,
50 LLVMOrcJITDylibDefinitionGeneratorRef)
51 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ThreadSafeContext,
52 LLVMOrcThreadSafeContextRef)
53 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ThreadSafeModule, LLVMOrcThreadSafeModuleRef)
54 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(JITTargetMachineBuilder,
55 LLVMOrcJITTargetMachineBuilderRef)
56 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLJITBuilder, LLVMOrcLLJITBuilderRef)
57 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLJIT, LLVMOrcLLJITRef)
59 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
61 LLVMOrcSymbolStringPoolEntryRef
62 LLVMOrcExecutionSessionIntern(LLVMOrcExecutionSessionRef ES, const char *Name) {
64 OrcV2CAPIHelper::releaseSymbolStringPtr(unwrap(ES)->intern(Name)));
67 void LLVMOrcReleaseSymbolStringPoolEntry(LLVMOrcSymbolStringPoolEntryRef S) {
68 OrcV2CAPIHelper::releasePoolEntry(unwrap(S));
71 void LLVMOrcDisposeJITDylibDefinitionGenerator(
72 LLVMOrcJITDylibDefinitionGeneratorRef DG) {
76 void LLVMOrcJITDylibAddGenerator(LLVMOrcJITDylibRef JD,
77 LLVMOrcJITDylibDefinitionGeneratorRef DG) {
78 unwrap(JD)->addGenerator(
79 std::unique_ptr<JITDylib::DefinitionGenerator>(unwrap(DG)));
82 LLVMErrorRef LLVMOrcCreateDynamicLibrarySearchGeneratorForProcess(
83 LLVMOrcJITDylibDefinitionGeneratorRef *Result, char GlobalPrefix,
84 LLVMOrcSymbolPredicate Filter, void *FilterCtx) {
85 assert(Result && "Result can not be null");
86 assert((Filter || !FilterCtx) &&
87 "if Filter is null then FilterCtx must also be null");
89 DynamicLibrarySearchGenerator::SymbolPredicate Pred;
91 Pred = [=](const SymbolStringPtr &Name) -> bool {
92 return Filter(wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(Name)), FilterCtx);
95 auto ProcessSymsGenerator =
96 DynamicLibrarySearchGenerator::GetForCurrentProcess(GlobalPrefix, Pred);
98 if (!ProcessSymsGenerator) {
100 return wrap(ProcessSymsGenerator.takeError());
103 *Result = wrap(ProcessSymsGenerator->release());
104 return LLVMErrorSuccess;
107 LLVMOrcThreadSafeContextRef LLVMOrcCreateNewThreadSafeContext(void) {
108 return wrap(new ThreadSafeContext(std::make_unique<LLVMContext>()));
112 LLVMOrcThreadSafeContextGetContext(LLVMOrcThreadSafeContextRef TSCtx) {
113 return wrap(unwrap(TSCtx)->getContext());
116 void LLVMOrcDisposeThreadSafeContext(LLVMOrcThreadSafeContextRef TSCtx) {
117 delete unwrap(TSCtx);
120 LLVMOrcThreadSafeModuleRef
121 LLVMOrcCreateNewThreadSafeModule(LLVMModuleRef M,
122 LLVMOrcThreadSafeContextRef TSCtx) {
124 new ThreadSafeModule(std::unique_ptr<Module>(unwrap(M)), *unwrap(TSCtx)));
127 void LLVMOrcDisposeThreadSafeModule(LLVMOrcThreadSafeModuleRef TSM) {
131 LLVMErrorRef LLVMOrcJITTargetMachineBuilderDetectHost(
132 LLVMOrcJITTargetMachineBuilderRef *Result) {
133 assert(Result && "Result can not be null");
135 auto JTMB = JITTargetMachineBuilder::detectHost();
138 return wrap(JTMB.takeError());
141 *Result = wrap(new JITTargetMachineBuilder(std::move(*JTMB)));
142 return LLVMErrorSuccess;
145 LLVMOrcJITTargetMachineBuilderRef
146 LLVMOrcJITTargetMachineBuilderFromTargetMachine(LLVMTargetMachineRef TM) {
147 auto *TemplateTM = unwrap(TM);
150 std::make_unique<JITTargetMachineBuilder>(TemplateTM->getTargetTriple());
153 .setCPU(TemplateTM->getTargetCPU().str())
154 .setRelocationModel(TemplateTM->getRelocationModel())
155 .setCodeModel(TemplateTM->getCodeModel())
156 .setCodeGenOptLevel(TemplateTM->getOptLevel())
157 .setFeatures(TemplateTM->getTargetFeatureString())
158 .setOptions(TemplateTM->Options);
160 LLVMDisposeTargetMachine(TM);
162 return wrap(JTMB.release());
165 void LLVMOrcDisposeJITTargetMachineBuilder(
166 LLVMOrcJITTargetMachineBuilderRef JTMB) {
170 LLVMOrcLLJITBuilderRef LLVMOrcCreateLLJITBuilder(void) {
171 return wrap(new LLJITBuilder());
174 void LLVMOrcDisposeLLJITBuilder(LLVMOrcLLJITBuilderRef Builder) {
175 delete unwrap(Builder);
178 void LLVMOrcLLJITBuilderSetJITTargetMachineBuilder(
179 LLVMOrcLLJITBuilderRef Builder, LLVMOrcJITTargetMachineBuilderRef JTMB) {
180 unwrap(Builder)->setJITTargetMachineBuilder(*unwrap(JTMB));
183 LLVMErrorRef LLVMOrcCreateLLJIT(LLVMOrcLLJITRef *Result,
184 LLVMOrcLLJITBuilderRef Builder) {
185 assert(Result && "Result can not be null");
188 Builder = LLVMOrcCreateLLJITBuilder();
190 auto J = unwrap(Builder)->create();
191 LLVMOrcDisposeLLJITBuilder(Builder);
195 return wrap(J.takeError());
198 *Result = wrap(J->release());
199 return LLVMErrorSuccess;
202 LLVMErrorRef LLVMOrcDisposeLLJIT(LLVMOrcLLJITRef J) {
204 return LLVMErrorSuccess;
207 LLVMOrcExecutionSessionRef LLVMOrcLLJITGetExecutionSession(LLVMOrcLLJITRef J) {
208 return wrap(&unwrap(J)->getExecutionSession());
211 LLVMOrcJITDylibRef LLVMOrcLLJITGetMainJITDylib(LLVMOrcLLJITRef J) {
212 return wrap(&unwrap(J)->getMainJITDylib());
215 const char *LLVMOrcLLJITGetTripleString(LLVMOrcLLJITRef J) {
216 return unwrap(J)->getTargetTriple().str().c_str();
219 char LLVMOrcLLJITGetGlobalPrefix(LLVMOrcLLJITRef J) {
220 return unwrap(J)->getDataLayout().getGlobalPrefix();
223 LLVMOrcSymbolStringPoolEntryRef
224 LLVMOrcLLJITMangleAndIntern(LLVMOrcLLJITRef J, const char *UnmangledName) {
225 return wrap(OrcV2CAPIHelper::releaseSymbolStringPtr(
226 unwrap(J)->mangleAndIntern(UnmangledName)));
229 LLVMErrorRef LLVMOrcLLJITAddObjectFile(LLVMOrcLLJITRef J, LLVMOrcJITDylibRef JD,
230 LLVMMemoryBufferRef ObjBuffer) {
231 return wrap(unwrap(J)->addObjectFile(
232 *unwrap(JD), std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer))));
235 LLVMErrorRef LLVMOrcLLJITAddLLVMIRModule(LLVMOrcLLJITRef J,
236 LLVMOrcJITDylibRef JD,
237 LLVMOrcThreadSafeModuleRef TSM) {
238 return wrap(unwrap(J)->addIRModule(*unwrap(JD), std::move(*unwrap(TSM))));
241 LLVMErrorRef LLVMOrcLLJITLookup(LLVMOrcLLJITRef J,
242 LLVMOrcJITTargetAddress *Result,
244 assert(Result && "Result can not be null");
246 auto Sym = unwrap(J)->lookup(Name);
249 return wrap(Sym.takeError());
252 *Result = Sym->getAddress();
253 return LLVMErrorSuccess;