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/RTDyldObjectLinkingLayer.h"
17 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
18 
19 using namespace llvm;
20 using namespace llvm::orc;
21 
22 namespace llvm {
23 namespace orc {
24 
25 class InProgressLookupState;
26 
27 class OrcV2CAPIHelper {
28 public:
29   using PoolEntry = SymbolStringPtr::PoolEntry;
30   using PoolEntryPtr = SymbolStringPtr::PoolEntryPtr;
31 
32   // Move from SymbolStringPtr to PoolEntryPtr (no change in ref count).
33   static PoolEntryPtr moveFromSymbolStringPtr(SymbolStringPtr S) {
34     PoolEntryPtr Result = nullptr;
35     std::swap(Result, S.S);
36     return Result;
37   }
38 
39   // Move from a PoolEntryPtr to a SymbolStringPtr (no change in ref count).
40   static SymbolStringPtr moveToSymbolStringPtr(PoolEntryPtr P) {
41     SymbolStringPtr S;
42     S.S = P;
43     return S;
44   }
45 
46   // Copy a pool entry to a SymbolStringPtr (increments ref count).
47   static SymbolStringPtr copyToSymbolStringPtr(PoolEntryPtr P) {
48     return SymbolStringPtr(P);
49   }
50 
51   static PoolEntryPtr getRawPoolEntryPtr(const SymbolStringPtr &S) {
52     return S.S;
53   }
54 
55   static void retainPoolEntry(PoolEntryPtr P) {
56     SymbolStringPtr S(P);
57     S.S = nullptr;
58   }
59 
60   static void releasePoolEntry(PoolEntryPtr P) {
61     SymbolStringPtr S;
62     S.S = P;
63   }
64 
65   static InProgressLookupState *extractLookupState(LookupState &LS) {
66     return LS.IPLS.release();
67   }
68 
69   static void resetLookupState(LookupState &LS, InProgressLookupState *IPLS) {
70     return LS.reset(IPLS);
71   }
72 };
73 
74 } // namespace orc
75 } // namespace llvm
76 
77 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ExecutionSession, LLVMOrcExecutionSessionRef)
78 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SymbolStringPool, LLVMOrcSymbolStringPoolRef)
79 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcV2CAPIHelper::PoolEntry,
80                                    LLVMOrcSymbolStringPoolEntryRef)
81 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MaterializationUnit,
82                                    LLVMOrcMaterializationUnitRef)
83 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MaterializationResponsibility,
84                                    LLVMOrcMaterializationResponsibilityRef)
85 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(JITDylib, LLVMOrcJITDylibRef)
86 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ResourceTracker, LLVMOrcResourceTrackerRef)
87 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DefinitionGenerator,
88                                    LLVMOrcDefinitionGeneratorRef)
89 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(InProgressLookupState, LLVMOrcLookupStateRef)
90 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ThreadSafeContext,
91                                    LLVMOrcThreadSafeContextRef)
92 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ThreadSafeModule, LLVMOrcThreadSafeModuleRef)
93 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(JITTargetMachineBuilder,
94                                    LLVMOrcJITTargetMachineBuilderRef)
95 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ObjectLayer, LLVMOrcObjectLayerRef)
96 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLJITBuilder, LLVMOrcLLJITBuilderRef)
97 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLJIT, LLVMOrcLLJITRef)
98 
99 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
100 
101 namespace llvm {
102 namespace orc {
103 
104 class CAPIDefinitionGenerator final : public DefinitionGenerator {
105 public:
106   CAPIDefinitionGenerator(
107       void *Ctx,
108       LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction TryToGenerate)
109       : Ctx(Ctx), TryToGenerate(TryToGenerate) {}
110 
111   Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
112                       JITDylibLookupFlags JDLookupFlags,
113                       const SymbolLookupSet &LookupSet) override {
114 
115     // Take the lookup state.
116     LLVMOrcLookupStateRef LSR = ::wrap(OrcV2CAPIHelper::extractLookupState(LS));
117 
118     // Translate the lookup kind.
119     LLVMOrcLookupKind CLookupKind;
120     switch (K) {
121     case LookupKind::Static:
122       CLookupKind = LLVMOrcLookupKindStatic;
123       break;
124     case LookupKind::DLSym:
125       CLookupKind = LLVMOrcLookupKindDLSym;
126       break;
127     }
128 
129     // Translate the JITDylibSearchFlags.
130     LLVMOrcJITDylibLookupFlags CJDLookupFlags;
131     switch (JDLookupFlags) {
132     case JITDylibLookupFlags::MatchExportedSymbolsOnly:
133       CJDLookupFlags = LLVMOrcJITDylibLookupFlagsMatchExportedSymbolsOnly;
134       break;
135     case JITDylibLookupFlags::MatchAllSymbols:
136       CJDLookupFlags = LLVMOrcJITDylibLookupFlagsMatchAllSymbols;
137       break;
138     }
139 
140     // Translate the lookup set.
141     std::vector<LLVMOrcCLookupSetElement> CLookupSet;
142     CLookupSet.reserve(LookupSet.size());
143     for (auto &KV : LookupSet) {
144       LLVMOrcSymbolLookupFlags SLF;
145       LLVMOrcSymbolStringPoolEntryRef Name =
146         ::wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(KV.first));
147       switch (KV.second) {
148       case SymbolLookupFlags::RequiredSymbol:
149         SLF = LLVMOrcSymbolLookupFlagsRequiredSymbol;
150         break;
151       case SymbolLookupFlags::WeaklyReferencedSymbol:
152         SLF = LLVMOrcSymbolLookupFlagsWeaklyReferencedSymbol;
153         break;
154       }
155       CLookupSet.push_back({Name, SLF});
156     }
157 
158     // Run the C TryToGenerate function.
159     auto Err = unwrap(TryToGenerate(::wrap(this), Ctx, &LSR, CLookupKind,
160                                     ::wrap(&JD), CJDLookupFlags,
161                                     CLookupSet.data(), CLookupSet.size()));
162 
163     // Restore the lookup state.
164     OrcV2CAPIHelper::resetLookupState(LS, ::unwrap(LSR));
165 
166     return Err;
167   }
168 
169 private:
170   void *Ctx;
171   LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction TryToGenerate;
172 };
173 
174 } // end namespace orc
175 } // end namespace llvm
176 
177 namespace {
178 
179 class OrcCAPIMaterializationUnit : public llvm::orc::MaterializationUnit {
180 public:
181   OrcCAPIMaterializationUnit(
182       std::string Name, SymbolFlagsMap InitialSymbolFlags,
183       SymbolStringPtr InitSymbol, void *Ctx,
184       LLVMOrcMaterializationUnitMaterializeFunction Materialize,
185       LLVMOrcMaterializationUnitDiscardFunction Discard,
186       LLVMOrcMaterializationUnitDestroyFunction Destroy)
187       : llvm::orc::MaterializationUnit(std::move(InitialSymbolFlags),
188                                        std::move(InitSymbol)),
189         Name(std::move(Name)), Ctx(Ctx), Materialize(Materialize),
190         Discard(Discard), Destroy(Destroy) {}
191 
192   ~OrcCAPIMaterializationUnit() {
193     if (Ctx)
194       Destroy(Ctx);
195   }
196 
197   StringRef getName() const override { return Name; }
198 
199   void materialize(std::unique_ptr<MaterializationResponsibility> R) override {
200     void *Tmp = Ctx;
201     Ctx = nullptr;
202     Materialize(Tmp, wrap(R.release()));
203   }
204 
205 private:
206   void discard(const JITDylib &JD, const SymbolStringPtr &Name) override {
207     Discard(Ctx, wrap(&JD), wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(Name)));
208   }
209 
210   std::string Name;
211   void *Ctx = nullptr;
212   LLVMOrcMaterializationUnitMaterializeFunction Materialize = nullptr;
213   LLVMOrcMaterializationUnitDiscardFunction Discard = nullptr;
214   LLVMOrcMaterializationUnitDestroyFunction Destroy = nullptr;
215 };
216 
217 static JITSymbolFlags toJITSymbolFlags(LLVMJITSymbolFlags F) {
218 
219   JITSymbolFlags JSF;
220 
221   if (F.GenericFlags & LLVMJITSymbolGenericFlagsExported)
222     JSF |= JITSymbolFlags::Exported;
223   if (F.GenericFlags & LLVMJITSymbolGenericFlagsWeak)
224     JSF |= JITSymbolFlags::Weak;
225   if (F.GenericFlags & LLVMJITSymbolGenericFlagsCallable)
226     JSF |= JITSymbolFlags::Callable;
227   if (F.GenericFlags & LLVMJITSymbolGenericFlagsMaterializationSideEffectsOnly)
228     JSF |= JITSymbolFlags::MaterializationSideEffectsOnly;
229 
230   JSF.getTargetFlags() = F.TargetFlags;
231 
232   return JSF;
233 }
234 
235 } // end anonymous namespace
236 
237 void LLVMOrcExecutionSessionSetErrorReporter(
238     LLVMOrcExecutionSessionRef ES, LLVMOrcErrorReporterFunction ReportError,
239     void *Ctx) {
240   unwrap(ES)->setErrorReporter(
241       [=](Error Err) { ReportError(Ctx, wrap(std::move(Err))); });
242 }
243 
244 LLVMOrcSymbolStringPoolRef
245 LLVMOrcExecutionSessionGetSymbolStringPool(LLVMOrcExecutionSessionRef ES) {
246   return wrap(unwrap(ES)->getSymbolStringPool().get());
247 }
248 
249 void LLVMOrcSymbolStringPoolClearDeadEntries(LLVMOrcSymbolStringPoolRef SSP) {
250   unwrap(SSP)->clearDeadEntries();
251 }
252 
253 LLVMOrcSymbolStringPoolEntryRef
254 LLVMOrcExecutionSessionIntern(LLVMOrcExecutionSessionRef ES, const char *Name) {
255   return wrap(
256       OrcV2CAPIHelper::moveFromSymbolStringPtr(unwrap(ES)->intern(Name)));
257 }
258 
259 void LLVMOrcRetainSymbolStringPoolEntry(LLVMOrcSymbolStringPoolEntryRef S) {
260   OrcV2CAPIHelper::retainPoolEntry(unwrap(S));
261 }
262 
263 void LLVMOrcReleaseSymbolStringPoolEntry(LLVMOrcSymbolStringPoolEntryRef S) {
264   OrcV2CAPIHelper::releasePoolEntry(unwrap(S));
265 }
266 
267 const char *LLVMOrcSymbolStringPoolEntryStr(LLVMOrcSymbolStringPoolEntryRef S) {
268   return unwrap(S)->getKey().data();
269 }
270 
271 LLVMOrcResourceTrackerRef
272 LLVMOrcJITDylibCreateResourceTracker(LLVMOrcJITDylibRef JD) {
273   auto RT = unwrap(JD)->createResourceTracker();
274   // Retain the pointer for the C API client.
275   RT->Retain();
276   return wrap(RT.get());
277 }
278 
279 LLVMOrcResourceTrackerRef
280 LLVMOrcJITDylibGetDefaultResourceTracker(LLVMOrcJITDylibRef JD) {
281   auto RT = unwrap(JD)->getDefaultResourceTracker();
282   // Retain the pointer for the C API client.
283   return wrap(RT.get());
284 }
285 
286 void LLVMOrcReleaseResourceTracker(LLVMOrcResourceTrackerRef RT) {
287   ResourceTrackerSP TmpRT(unwrap(RT));
288   TmpRT->Release();
289 }
290 
291 void LLVMOrcResourceTrackerTransferTo(LLVMOrcResourceTrackerRef SrcRT,
292                                       LLVMOrcResourceTrackerRef DstRT) {
293   ResourceTrackerSP TmpRT(unwrap(SrcRT));
294   TmpRT->transferTo(*unwrap(DstRT));
295 }
296 
297 LLVMErrorRef LLVMOrcResourceTrackerRemove(LLVMOrcResourceTrackerRef RT) {
298   ResourceTrackerSP TmpRT(unwrap(RT));
299   return wrap(TmpRT->remove());
300 }
301 
302 void LLVMOrcDisposeDefinitionGenerator(LLVMOrcDefinitionGeneratorRef DG) {
303   std::unique_ptr<DefinitionGenerator> TmpDG(unwrap(DG));
304 }
305 
306 void LLVMOrcDisposeMaterializationUnit(LLVMOrcMaterializationUnitRef MU) {
307   std::unique_ptr<MaterializationUnit> TmpMU(unwrap(MU));
308 }
309 
310 LLVMOrcMaterializationUnitRef LLVMOrcCreateCustomMaterializationUnit(
311     const char *Name, void *Ctx, LLVMOrcCSymbolFlagsMapPairs Syms,
312     size_t NumSyms, LLVMOrcSymbolStringPoolEntryRef InitSym,
313     LLVMOrcMaterializationUnitMaterializeFunction Materialize,
314     LLVMOrcMaterializationUnitDiscardFunction Discard,
315     LLVMOrcMaterializationUnitDestroyFunction Destroy) {
316   SymbolFlagsMap SFM;
317   for (size_t I = 0; I != NumSyms; ++I)
318     SFM[OrcV2CAPIHelper::moveToSymbolStringPtr(unwrap(Syms[I].Name))] =
319         toJITSymbolFlags(Syms[I].Flags);
320 
321   auto IS = OrcV2CAPIHelper::moveToSymbolStringPtr(unwrap(InitSym));
322 
323   return wrap(new OrcCAPIMaterializationUnit(
324       Name, std::move(SFM), std::move(IS), Ctx, Materialize, Discard, Destroy));
325 }
326 
327 LLVMOrcMaterializationUnitRef
328 LLVMOrcAbsoluteSymbols(LLVMOrcCSymbolMapPairs Syms, size_t NumPairs) {
329   SymbolMap SM;
330   for (size_t I = 0; I != NumPairs; ++I) {
331     JITSymbolFlags Flags = toJITSymbolFlags(Syms[I].Sym.Flags);
332     SM[OrcV2CAPIHelper::moveToSymbolStringPtr(unwrap(Syms[I].Name))] =
333         JITEvaluatedSymbol(Syms[I].Sym.Address, Flags);
334   }
335 
336   return wrap(absoluteSymbols(std::move(SM)).release());
337 }
338 
339 LLVMOrcJITDylibRef
340 LLVMOrcExecutionSessionCreateBareJITDylib(LLVMOrcExecutionSessionRef ES,
341                                           const char *Name) {
342   return wrap(&unwrap(ES)->createBareJITDylib(Name));
343 }
344 
345 LLVMErrorRef
346 LLVMOrcExecutionSessionCreateJITDylib(LLVMOrcExecutionSessionRef ES,
347                                       LLVMOrcJITDylibRef *Result,
348                                       const char *Name) {
349   auto JD = unwrap(ES)->createJITDylib(Name);
350   if (!JD)
351     return wrap(JD.takeError());
352   *Result = wrap(&*JD);
353   return LLVMErrorSuccess;
354 }
355 
356 LLVMOrcJITDylibRef
357 LLVMOrcExecutionSessionGetJITDylibByName(LLVMOrcExecutionSessionRef ES,
358                                          const char *Name) {
359   return wrap(unwrap(ES)->getJITDylibByName(Name));
360 }
361 
362 LLVMErrorRef LLVMOrcJITDylibDefine(LLVMOrcJITDylibRef JD,
363                                    LLVMOrcMaterializationUnitRef MU) {
364   std::unique_ptr<MaterializationUnit> TmpMU(unwrap(MU));
365 
366   if (auto Err = unwrap(JD)->define(TmpMU)) {
367     TmpMU.release();
368     return wrap(std::move(Err));
369   }
370   return LLVMErrorSuccess;
371 }
372 
373 LLVMErrorRef LLVMOrcJITDylibClear(LLVMOrcJITDylibRef JD) {
374   return wrap(unwrap(JD)->clear());
375 }
376 
377 void LLVMOrcJITDylibAddGenerator(LLVMOrcJITDylibRef JD,
378                                  LLVMOrcDefinitionGeneratorRef DG) {
379   unwrap(JD)->addGenerator(std::unique_ptr<DefinitionGenerator>(unwrap(DG)));
380 }
381 
382 LLVMOrcDefinitionGeneratorRef LLVMOrcCreateCustomCAPIDefinitionGenerator(
383     LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction F, void *Ctx) {
384   auto DG = std::make_unique<CAPIDefinitionGenerator>(Ctx, F);
385   return wrap(DG.release());
386 }
387 
388 LLVMErrorRef LLVMOrcCreateDynamicLibrarySearchGeneratorForProcess(
389     LLVMOrcDefinitionGeneratorRef *Result, char GlobalPrefix,
390     LLVMOrcSymbolPredicate Filter, void *FilterCtx) {
391   assert(Result && "Result can not be null");
392   assert((Filter || !FilterCtx) &&
393          "if Filter is null then FilterCtx must also be null");
394 
395   DynamicLibrarySearchGenerator::SymbolPredicate Pred;
396   if (Filter)
397     Pred = [=](const SymbolStringPtr &Name) -> bool {
398       return Filter(FilterCtx, wrap(OrcV2CAPIHelper::getRawPoolEntryPtr(Name)));
399     };
400 
401   auto ProcessSymsGenerator =
402       DynamicLibrarySearchGenerator::GetForCurrentProcess(GlobalPrefix, Pred);
403 
404   if (!ProcessSymsGenerator) {
405     *Result = 0;
406     return wrap(ProcessSymsGenerator.takeError());
407   }
408 
409   *Result = wrap(ProcessSymsGenerator->release());
410   return LLVMErrorSuccess;
411 }
412 
413 LLVMOrcThreadSafeContextRef LLVMOrcCreateNewThreadSafeContext(void) {
414   return wrap(new ThreadSafeContext(std::make_unique<LLVMContext>()));
415 }
416 
417 LLVMContextRef
418 LLVMOrcThreadSafeContextGetContext(LLVMOrcThreadSafeContextRef TSCtx) {
419   return wrap(unwrap(TSCtx)->getContext());
420 }
421 
422 void LLVMOrcDisposeThreadSafeContext(LLVMOrcThreadSafeContextRef TSCtx) {
423   delete unwrap(TSCtx);
424 }
425 
426 LLVMOrcThreadSafeModuleRef
427 LLVMOrcCreateNewThreadSafeModule(LLVMModuleRef M,
428                                  LLVMOrcThreadSafeContextRef TSCtx) {
429   return wrap(
430       new ThreadSafeModule(std::unique_ptr<Module>(unwrap(M)), *unwrap(TSCtx)));
431 }
432 
433 void LLVMOrcDisposeThreadSafeModule(LLVMOrcThreadSafeModuleRef TSM) {
434   delete unwrap(TSM);
435 }
436 
437 LLVMErrorRef LLVMOrcJITTargetMachineBuilderDetectHost(
438     LLVMOrcJITTargetMachineBuilderRef *Result) {
439   assert(Result && "Result can not be null");
440 
441   auto JTMB = JITTargetMachineBuilder::detectHost();
442   if (!JTMB) {
443     Result = 0;
444     return wrap(JTMB.takeError());
445   }
446 
447   *Result = wrap(new JITTargetMachineBuilder(std::move(*JTMB)));
448   return LLVMErrorSuccess;
449 }
450 
451 LLVMOrcJITTargetMachineBuilderRef
452 LLVMOrcJITTargetMachineBuilderCreateFromTargetMachine(LLVMTargetMachineRef TM) {
453   auto *TemplateTM = unwrap(TM);
454 
455   auto JTMB =
456       std::make_unique<JITTargetMachineBuilder>(TemplateTM->getTargetTriple());
457 
458   (*JTMB)
459       .setCPU(TemplateTM->getTargetCPU().str())
460       .setRelocationModel(TemplateTM->getRelocationModel())
461       .setCodeModel(TemplateTM->getCodeModel())
462       .setCodeGenOptLevel(TemplateTM->getOptLevel())
463       .setFeatures(TemplateTM->getTargetFeatureString())
464       .setOptions(TemplateTM->Options);
465 
466   LLVMDisposeTargetMachine(TM);
467 
468   return wrap(JTMB.release());
469 }
470 
471 void LLVMOrcDisposeJITTargetMachineBuilder(
472     LLVMOrcJITTargetMachineBuilderRef JTMB) {
473   delete unwrap(JTMB);
474 }
475 
476 char *LLVMOrcJITTargetMachineBuilderGetTargetTriple(
477     LLVMOrcJITTargetMachineBuilderRef JTMB) {
478   auto Tmp = unwrap(JTMB)->getTargetTriple().str();
479   char *TargetTriple = (char *)malloc(Tmp.size() + 1);
480   strcpy(TargetTriple, Tmp.c_str());
481   return TargetTriple;
482 }
483 
484 void LLVMOrcJITTargetMachineBuilderSetTargetTriple(
485     LLVMOrcJITTargetMachineBuilderRef JTMB, const char *TargetTriple) {
486   unwrap(JTMB)->getTargetTriple() = Triple(TargetTriple);
487 }
488 
489 void LLVMOrcJITTargetMachineBuilderDisposeTargetTriple(
490     LLVMOrcJITTargetMachineBuilderRef JTMB, char *TargetTriple) {
491   free(TargetTriple);
492 }
493 
494 void LLVMOrcObjectLayerEmit(LLVMOrcObjectLayerRef ObjLayer,
495                             LLVMOrcMaterializationResponsibilityRef R,
496                             LLVMMemoryBufferRef ObjBuffer) {
497   unwrap(ObjLayer)->emit(
498       std::unique_ptr<MaterializationResponsibility>(unwrap(R)),
499       std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer)));
500 }
501 
502 void LLVMOrcDisposeObjectLayer(LLVMOrcObjectLayerRef ObjLayer) {
503   delete unwrap(ObjLayer);
504 }
505 
506 LLVMOrcLLJITBuilderRef LLVMOrcCreateLLJITBuilder(void) {
507   return wrap(new LLJITBuilder());
508 }
509 
510 void LLVMOrcDisposeLLJITBuilder(LLVMOrcLLJITBuilderRef Builder) {
511   delete unwrap(Builder);
512 }
513 
514 void LLVMOrcLLJITBuilderSetJITTargetMachineBuilder(
515     LLVMOrcLLJITBuilderRef Builder, LLVMOrcJITTargetMachineBuilderRef JTMB) {
516   unwrap(Builder)->setJITTargetMachineBuilder(std::move(*unwrap(JTMB)));
517   LLVMOrcDisposeJITTargetMachineBuilder(JTMB);
518 }
519 
520 void LLVMOrcLLJITBuilderSetObjectLinkingLayerCreator(
521     LLVMOrcLLJITBuilderRef Builder,
522     LLVMOrcLLJITBuilderObjectLinkingLayerCreatorFunction F, void *Ctx) {
523   unwrap(Builder)->setObjectLinkingLayerCreator(
524       [=](ExecutionSession &ES, const Triple &TT) {
525         auto TTStr = TT.str();
526         return std::unique_ptr<ObjectLayer>(
527             unwrap(F(Ctx, wrap(&ES), TTStr.c_str())));
528       });
529 }
530 
531 LLVMErrorRef LLVMOrcCreateLLJIT(LLVMOrcLLJITRef *Result,
532                                 LLVMOrcLLJITBuilderRef Builder) {
533   assert(Result && "Result can not be null");
534 
535   if (!Builder)
536     Builder = LLVMOrcCreateLLJITBuilder();
537 
538   auto J = unwrap(Builder)->create();
539   LLVMOrcDisposeLLJITBuilder(Builder);
540 
541   if (!J) {
542     Result = 0;
543     return wrap(J.takeError());
544   }
545 
546   *Result = wrap(J->release());
547   return LLVMErrorSuccess;
548 }
549 
550 LLVMErrorRef LLVMOrcDisposeLLJIT(LLVMOrcLLJITRef J) {
551   delete unwrap(J);
552   return LLVMErrorSuccess;
553 }
554 
555 LLVMOrcExecutionSessionRef LLVMOrcLLJITGetExecutionSession(LLVMOrcLLJITRef J) {
556   return wrap(&unwrap(J)->getExecutionSession());
557 }
558 
559 LLVMOrcJITDylibRef LLVMOrcLLJITGetMainJITDylib(LLVMOrcLLJITRef J) {
560   return wrap(&unwrap(J)->getMainJITDylib());
561 }
562 
563 const char *LLVMOrcLLJITGetTripleString(LLVMOrcLLJITRef J) {
564   return unwrap(J)->getTargetTriple().str().c_str();
565 }
566 
567 char LLVMOrcLLJITGetGlobalPrefix(LLVMOrcLLJITRef J) {
568   return unwrap(J)->getDataLayout().getGlobalPrefix();
569 }
570 
571 LLVMOrcSymbolStringPoolEntryRef
572 LLVMOrcLLJITMangleAndIntern(LLVMOrcLLJITRef J, const char *UnmangledName) {
573   return wrap(OrcV2CAPIHelper::moveFromSymbolStringPtr(
574       unwrap(J)->mangleAndIntern(UnmangledName)));
575 }
576 
577 LLVMErrorRef LLVMOrcLLJITAddObjectFile(LLVMOrcLLJITRef J, LLVMOrcJITDylibRef JD,
578                                        LLVMMemoryBufferRef ObjBuffer) {
579   return wrap(unwrap(J)->addObjectFile(
580       *unwrap(JD), std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer))));
581 }
582 
583 LLVMErrorRef LLVMOrcLLJITAddObjectFileWithRT(LLVMOrcLLJITRef J,
584                                              LLVMOrcResourceTrackerRef RT,
585                                              LLVMMemoryBufferRef ObjBuffer) {
586   return wrap(unwrap(J)->addObjectFile(
587       ResourceTrackerSP(unwrap(RT)),
588       std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer))));
589 }
590 
591 LLVMErrorRef LLVMOrcLLJITAddLLVMIRModule(LLVMOrcLLJITRef J,
592                                          LLVMOrcJITDylibRef JD,
593                                          LLVMOrcThreadSafeModuleRef TSM) {
594   std::unique_ptr<ThreadSafeModule> TmpTSM(unwrap(TSM));
595   return wrap(unwrap(J)->addIRModule(*unwrap(JD), std::move(*TmpTSM)));
596 }
597 
598 LLVMErrorRef LLVMOrcLLJITAddLLVMIRModuleWithRT(LLVMOrcLLJITRef J,
599                                                LLVMOrcResourceTrackerRef RT,
600                                                LLVMOrcThreadSafeModuleRef TSM) {
601   std::unique_ptr<ThreadSafeModule> TmpTSM(unwrap(TSM));
602   return wrap(unwrap(J)->addIRModule(ResourceTrackerSP(unwrap(RT)),
603                                      std::move(*TmpTSM)));
604 }
605 
606 LLVMErrorRef LLVMOrcLLJITLookup(LLVMOrcLLJITRef J,
607                                 LLVMOrcJITTargetAddress *Result,
608                                 const char *Name) {
609   assert(Result && "Result can not be null");
610 
611   auto Sym = unwrap(J)->lookup(Name);
612   if (!Sym) {
613     *Result = 0;
614     return wrap(Sym.takeError());
615   }
616 
617   *Result = Sym->getAddress();
618   return LLVMErrorSuccess;
619 }
620 
621 LLVMOrcObjectLayerRef LLVMOrcLLJITGetObjLinkingLayer(LLVMOrcLLJITRef J) {
622   return wrap(&unwrap(J)->getObjLinkingLayer());
623 }
624 
625 LLVMOrcObjectLayerRef
626 LLVMOrcCreateRTDyldObjectLinkingLayerWithSectionMemoryManager(
627     LLVMOrcExecutionSessionRef ES) {
628   assert(ES && "ES must not be null");
629   return wrap(new RTDyldObjectLinkingLayer(
630       *unwrap(ES), [] { return std::make_unique<SectionMemoryManager>(); }));
631 }
632 
633 void LLVMOrcRTDyldObjectLinkingLayerRegisterJITEventListener(
634     LLVMOrcObjectLayerRef RTDyldObjLinkingLayer,
635     LLVMJITEventListenerRef Listener) {
636   assert(RTDyldObjLinkingLayer && "RTDyldObjLinkingLayer must not be null");
637   assert(Listener && "Listener must not be null");
638   reinterpret_cast<RTDyldObjectLinkingLayer *>(unwrap(RTDyldObjLinkingLayer))
639       ->registerJITEventListener(*unwrap(Listener));
640 }
641