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/Orc.h" 10 #include "llvm-c/TargetMachine.h" 11 12 #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h" 13 #include "llvm/ExecutionEngine/Orc/LLJIT.h" 14 15 using namespace llvm; 16 using namespace llvm::orc; 17 18 namespace llvm { 19 namespace orc { 20 21 class OrcV2CAPIHelper { 22 public: 23 using PoolEntry = SymbolStringPtr::PoolEntry; 24 using PoolEntryPtr = SymbolStringPtr::PoolEntryPtr; 25 26 static PoolEntryPtr releaseSymbolStringPtr(SymbolStringPtr S) { 27 PoolEntryPtr Result = nullptr; 28 std::swap(Result, S.S); 29 return Result; 30 } 31 32 static PoolEntryPtr getRawPoolEntryPtr(const SymbolStringPtr &S) { 33 return S.S; 34 } 35 36 static void releasePoolEntry(PoolEntryPtr P) { 37 SymbolStringPtr S; 38 S.S = P; 39 } 40 }; 41 42 } // end namespace orc 43 } // end namespace llvm 44 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) 58 59 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef) 60 61 LLVMOrcSymbolStringPoolEntryRef 62 LLVMOrcExecutionSessionIntern(LLVMOrcExecutionSessionRef ES, const char *Name) { 63 return wrap( 64 OrcV2CAPIHelper::releaseSymbolStringPtr(unwrap(ES)->intern(Name))); 65 } 66 67 void LLVMOrcReleaseSymbolStringPoolEntry(LLVMOrcSymbolStringPoolEntryRef S) { 68 OrcV2CAPIHelper::releasePoolEntry(unwrap(S)); 69 } 70 71 void LLVMOrcDisposeJITDylibDefinitionGenerator( 72 LLVMOrcJITDylibDefinitionGeneratorRef DG) { 73 delete unwrap(DG); 74 } 75 76 void LLVMOrcJITDylibAddGenerator(LLVMOrcJITDylibRef JD, 77 LLVMOrcJITDylibDefinitionGeneratorRef DG) { 78 unwrap(JD)->addGenerator( 79 std::unique_ptr<JITDylib::DefinitionGenerator>(unwrap(DG))); 80 } 81 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"); 88 89 DynamicLibrarySearchGenerator::SymbolPredicate Pred; 90 if (Filter) 91 Pred = [=](const SymbolStringPtr &Name) -> bool { 92 return Filter(wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(Name)), FilterCtx); 93 }; 94 95 auto ProcessSymsGenerator = 96 DynamicLibrarySearchGenerator::GetForCurrentProcess(GlobalPrefix, Pred); 97 98 if (!ProcessSymsGenerator) { 99 *Result = 0; 100 return wrap(ProcessSymsGenerator.takeError()); 101 } 102 103 *Result = wrap(ProcessSymsGenerator->release()); 104 return LLVMErrorSuccess; 105 } 106 107 LLVMOrcThreadSafeContextRef LLVMOrcCreateNewThreadSafeContext(void) { 108 return wrap(new ThreadSafeContext(std::make_unique<LLVMContext>())); 109 } 110 111 LLVMContextRef 112 LLVMOrcThreadSafeContextGetContext(LLVMOrcThreadSafeContextRef TSCtx) { 113 return wrap(unwrap(TSCtx)->getContext()); 114 } 115 116 void LLVMOrcDisposeThreadSafeContext(LLVMOrcThreadSafeContextRef TSCtx) { 117 delete unwrap(TSCtx); 118 } 119 120 LLVMOrcThreadSafeModuleRef 121 LLVMOrcCreateNewThreadSafeModule(LLVMModuleRef M, 122 LLVMOrcThreadSafeContextRef TSCtx) { 123 return wrap( 124 new ThreadSafeModule(std::unique_ptr<Module>(unwrap(M)), *unwrap(TSCtx))); 125 } 126 127 void LLVMOrcDisposeThreadSafeModule(LLVMOrcThreadSafeModuleRef TSM) { 128 delete unwrap(TSM); 129 } 130 131 LLVMErrorRef LLVMOrcJITTargetMachineBuilderDetectHost( 132 LLVMOrcJITTargetMachineBuilderRef *Result) { 133 assert(Result && "Result can not be null"); 134 135 auto JTMB = JITTargetMachineBuilder::detectHost(); 136 if (!JTMB) { 137 Result = 0; 138 return wrap(JTMB.takeError()); 139 } 140 141 *Result = wrap(new JITTargetMachineBuilder(std::move(*JTMB))); 142 return LLVMErrorSuccess; 143 } 144 145 LLVMOrcJITTargetMachineBuilderRef 146 LLVMOrcJITTargetMachineBuilderFromTargetMachine(LLVMTargetMachineRef TM) { 147 auto *TemplateTM = unwrap(TM); 148 149 auto JTMB = 150 std::make_unique<JITTargetMachineBuilder>(TemplateTM->getTargetTriple()); 151 152 (*JTMB) 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); 159 160 LLVMDisposeTargetMachine(TM); 161 162 return wrap(JTMB.release()); 163 } 164 165 void LLVMOrcDisposeJITTargetMachineBuilder( 166 LLVMOrcJITTargetMachineBuilderRef JTMB) { 167 delete unwrap(JTMB); 168 } 169 170 LLVMOrcLLJITBuilderRef LLVMOrcCreateLLJITBuilder(void) { 171 return wrap(new LLJITBuilder()); 172 } 173 174 void LLVMOrcDisposeLLJITBuilder(LLVMOrcLLJITBuilderRef Builder) { 175 delete unwrap(Builder); 176 } 177 178 void LLVMOrcLLJITBuilderSetJITTargetMachineBuilder( 179 LLVMOrcLLJITBuilderRef Builder, LLVMOrcJITTargetMachineBuilderRef JTMB) { 180 unwrap(Builder)->setJITTargetMachineBuilder(*unwrap(JTMB)); 181 } 182 183 LLVMErrorRef LLVMOrcCreateLLJIT(LLVMOrcLLJITRef *Result, 184 LLVMOrcLLJITBuilderRef Builder) { 185 assert(Result && "Result can not be null"); 186 187 if (!Builder) 188 Builder = LLVMOrcCreateLLJITBuilder(); 189 190 auto J = unwrap(Builder)->create(); 191 LLVMOrcDisposeLLJITBuilder(Builder); 192 193 if (!J) { 194 Result = 0; 195 return wrap(J.takeError()); 196 } 197 198 *Result = wrap(J->release()); 199 return LLVMErrorSuccess; 200 } 201 202 LLVMErrorRef LLVMOrcDisposeLLJIT(LLVMOrcLLJITRef J) { 203 delete unwrap(J); 204 return LLVMErrorSuccess; 205 } 206 207 LLVMOrcExecutionSessionRef LLVMOrcLLJITGetExecutionSession(LLVMOrcLLJITRef J) { 208 return wrap(&unwrap(J)->getExecutionSession()); 209 } 210 211 LLVMOrcJITDylibRef LLVMOrcLLJITGetMainJITDylib(LLVMOrcLLJITRef J) { 212 return wrap(&unwrap(J)->getMainJITDylib()); 213 } 214 215 const char *LLVMOrcLLJITGetTripleString(LLVMOrcLLJITRef J) { 216 return unwrap(J)->getTargetTriple().str().c_str(); 217 } 218 219 char LLVMOrcLLJITGetGlobalPrefix(LLVMOrcLLJITRef J) { 220 return unwrap(J)->getDataLayout().getGlobalPrefix(); 221 } 222 223 LLVMOrcSymbolStringPoolEntryRef 224 LLVMOrcLLJITMangleAndIntern(LLVMOrcLLJITRef J, const char *UnmangledName) { 225 return wrap(OrcV2CAPIHelper::releaseSymbolStringPtr( 226 unwrap(J)->mangleAndIntern(UnmangledName))); 227 } 228 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)))); 233 } 234 235 LLVMErrorRef LLVMOrcLLJITAddLLVMIRModule(LLVMOrcLLJITRef J, 236 LLVMOrcJITDylibRef JD, 237 LLVMOrcThreadSafeModuleRef TSM) { 238 return wrap(unwrap(J)->addIRModule(*unwrap(JD), std::move(*unwrap(TSM)))); 239 } 240 241 LLVMErrorRef LLVMOrcLLJITLookup(LLVMOrcLLJITRef J, 242 LLVMOrcJITTargetAddress *Result, 243 const char *Name) { 244 assert(Result && "Result can not be null"); 245 246 auto Sym = unwrap(J)->lookup(Name); 247 if (!Sym) { 248 *Result = 0; 249 return wrap(Sym.takeError()); 250 } 251 252 *Result = Sym->getAddress(); 253 return LLVMErrorSuccess; 254 } 255