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 | static InProgressLookupState *(LookupState &LS) { |
31 | return LS.IPLS.release(); |
32 | } |
33 | |
34 | static void resetLookupState(LookupState &LS, InProgressLookupState *IPLS) { |
35 | return LS.reset(IPLS); |
36 | } |
37 | }; |
38 | |
39 | } // namespace orc |
40 | } // namespace llvm |
41 | |
42 | inline LLVMOrcSymbolStringPoolEntryRef wrap(SymbolStringPoolEntryUnsafe E) { |
43 | return reinterpret_cast<LLVMOrcSymbolStringPoolEntryRef>(E.rawPtr()); |
44 | } |
45 | |
46 | inline SymbolStringPoolEntryUnsafe unwrap(LLVMOrcSymbolStringPoolEntryRef E) { |
47 | return reinterpret_cast<SymbolStringPoolEntryUnsafe::PoolEntry *>(E); |
48 | } |
49 | |
50 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ExecutionSession, LLVMOrcExecutionSessionRef) |
51 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SymbolStringPool, LLVMOrcSymbolStringPoolRef) |
52 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MaterializationUnit, |
53 | LLVMOrcMaterializationUnitRef) |
54 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MaterializationResponsibility, |
55 | LLVMOrcMaterializationResponsibilityRef) |
56 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(JITDylib, LLVMOrcJITDylibRef) |
57 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ResourceTracker, LLVMOrcResourceTrackerRef) |
58 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DefinitionGenerator, |
59 | LLVMOrcDefinitionGeneratorRef) |
60 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(InProgressLookupState, LLVMOrcLookupStateRef) |
61 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ThreadSafeContext, |
62 | LLVMOrcThreadSafeContextRef) |
63 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ThreadSafeModule, LLVMOrcThreadSafeModuleRef) |
64 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(JITTargetMachineBuilder, |
65 | LLVMOrcJITTargetMachineBuilderRef) |
66 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ObjectLayer, LLVMOrcObjectLayerRef) |
67 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IRTransformLayer, LLVMOrcIRTransformLayerRef) |
68 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ObjectTransformLayer, |
69 | LLVMOrcObjectTransformLayerRef) |
70 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DumpObjects, LLVMOrcDumpObjectsRef) |
71 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IndirectStubsManager, |
72 | LLVMOrcIndirectStubsManagerRef) |
73 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LazyCallThroughManager, |
74 | LLVMOrcLazyCallThroughManagerRef) |
75 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLJITBuilder, LLVMOrcLLJITBuilderRef) |
76 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLJIT, LLVMOrcLLJITRef) |
77 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef) |
78 | |
79 | namespace { |
80 | |
81 | class OrcCAPIMaterializationUnit : public llvm::orc::MaterializationUnit { |
82 | public: |
83 | OrcCAPIMaterializationUnit( |
84 | std::string Name, SymbolFlagsMap InitialSymbolFlags, |
85 | SymbolStringPtr InitSymbol, void *Ctx, |
86 | LLVMOrcMaterializationUnitMaterializeFunction Materialize, |
87 | LLVMOrcMaterializationUnitDiscardFunction Discard, |
88 | LLVMOrcMaterializationUnitDestroyFunction Destroy) |
89 | : llvm::orc::MaterializationUnit( |
90 | Interface(std::move(InitialSymbolFlags), std::move(InitSymbol))), |
91 | Name(std::move(Name)), Ctx(Ctx), Materialize(Materialize), |
92 | Discard(Discard), Destroy(Destroy) {} |
93 | |
94 | ~OrcCAPIMaterializationUnit() { |
95 | if (Ctx) |
96 | Destroy(Ctx); |
97 | } |
98 | |
99 | StringRef getName() const override { return Name; } |
100 | |
101 | void materialize(std::unique_ptr<MaterializationResponsibility> R) override { |
102 | void *Tmp = Ctx; |
103 | Ctx = nullptr; |
104 | Materialize(Tmp, wrap(P: R.release())); |
105 | } |
106 | |
107 | private: |
108 | void discard(const JITDylib &JD, const SymbolStringPtr &Name) override { |
109 | Discard(Ctx, wrap(P: &JD), wrap(E: SymbolStringPoolEntryUnsafe::from(S: Name))); |
110 | } |
111 | |
112 | std::string Name; |
113 | void *Ctx = nullptr; |
114 | LLVMOrcMaterializationUnitMaterializeFunction Materialize = nullptr; |
115 | LLVMOrcMaterializationUnitDiscardFunction Discard = nullptr; |
116 | LLVMOrcMaterializationUnitDestroyFunction Destroy = nullptr; |
117 | }; |
118 | |
119 | static JITSymbolFlags toJITSymbolFlags(LLVMJITSymbolFlags F) { |
120 | |
121 | JITSymbolFlags JSF; |
122 | |
123 | if (F.GenericFlags & LLVMJITSymbolGenericFlagsExported) |
124 | JSF |= JITSymbolFlags::Exported; |
125 | if (F.GenericFlags & LLVMJITSymbolGenericFlagsWeak) |
126 | JSF |= JITSymbolFlags::Weak; |
127 | if (F.GenericFlags & LLVMJITSymbolGenericFlagsCallable) |
128 | JSF |= JITSymbolFlags::Callable; |
129 | if (F.GenericFlags & LLVMJITSymbolGenericFlagsMaterializationSideEffectsOnly) |
130 | JSF |= JITSymbolFlags::MaterializationSideEffectsOnly; |
131 | |
132 | JSF.getTargetFlags() = F.TargetFlags; |
133 | |
134 | return JSF; |
135 | } |
136 | |
137 | static LLVMJITSymbolFlags fromJITSymbolFlags(JITSymbolFlags JSF) { |
138 | LLVMJITSymbolFlags F = {.GenericFlags: 0, .TargetFlags: 0}; |
139 | if (JSF & JITSymbolFlags::Exported) |
140 | F.GenericFlags |= LLVMJITSymbolGenericFlagsExported; |
141 | if (JSF & JITSymbolFlags::Weak) |
142 | F.GenericFlags |= LLVMJITSymbolGenericFlagsWeak; |
143 | if (JSF & JITSymbolFlags::Callable) |
144 | F.GenericFlags |= LLVMJITSymbolGenericFlagsCallable; |
145 | if (JSF & JITSymbolFlags::MaterializationSideEffectsOnly) |
146 | F.GenericFlags |= LLVMJITSymbolGenericFlagsMaterializationSideEffectsOnly; |
147 | |
148 | F.TargetFlags = JSF.getTargetFlags(); |
149 | |
150 | return F; |
151 | } |
152 | |
153 | static SymbolNameSet toSymbolNameSet(LLVMOrcCSymbolsList Symbols) { |
154 | SymbolNameSet Result; |
155 | Result.reserve(Size: Symbols.Length); |
156 | for (size_t I = 0; I != Symbols.Length; ++I) |
157 | Result.insert(V: unwrap(E: Symbols.Symbols[I]).moveToSymbolStringPtr()); |
158 | return Result; |
159 | } |
160 | |
161 | static SymbolMap toSymbolMap(LLVMOrcCSymbolMapPairs Syms, size_t NumPairs) { |
162 | SymbolMap SM; |
163 | for (size_t I = 0; I != NumPairs; ++I) { |
164 | JITSymbolFlags Flags = toJITSymbolFlags(F: Syms[I].Sym.Flags); |
165 | SM[unwrap(E: Syms[I].Name).moveToSymbolStringPtr()] = { |
166 | ExecutorAddr(Syms[I].Sym.Address), Flags}; |
167 | } |
168 | return SM; |
169 | } |
170 | |
171 | static SymbolDependenceMap |
172 | toSymbolDependenceMap(LLVMOrcCDependenceMapPairs Pairs, size_t NumPairs) { |
173 | SymbolDependenceMap SDM; |
174 | for (size_t I = 0; I != NumPairs; ++I) { |
175 | JITDylib *JD = unwrap(P: Pairs[I].JD); |
176 | SymbolNameSet Names; |
177 | |
178 | for (size_t J = 0; J != Pairs[I].Names.Length; ++J) { |
179 | auto Sym = Pairs[I].Names.Symbols[J]; |
180 | Names.insert(V: unwrap(E: Sym).moveToSymbolStringPtr()); |
181 | } |
182 | SDM[JD] = Names; |
183 | } |
184 | return SDM; |
185 | } |
186 | |
187 | static LookupKind toLookupKind(LLVMOrcLookupKind K) { |
188 | switch (K) { |
189 | case LLVMOrcLookupKindStatic: |
190 | return LookupKind::Static; |
191 | case LLVMOrcLookupKindDLSym: |
192 | return LookupKind::DLSym; |
193 | } |
194 | llvm_unreachable("unrecognized LLVMOrcLookupKind value" ); |
195 | } |
196 | |
197 | static LLVMOrcLookupKind fromLookupKind(LookupKind K) { |
198 | switch (K) { |
199 | case LookupKind::Static: |
200 | return LLVMOrcLookupKindStatic; |
201 | case LookupKind::DLSym: |
202 | return LLVMOrcLookupKindDLSym; |
203 | } |
204 | llvm_unreachable("unrecognized LookupKind value" ); |
205 | } |
206 | |
207 | static JITDylibLookupFlags |
208 | toJITDylibLookupFlags(LLVMOrcJITDylibLookupFlags LF) { |
209 | switch (LF) { |
210 | case LLVMOrcJITDylibLookupFlagsMatchExportedSymbolsOnly: |
211 | return JITDylibLookupFlags::MatchExportedSymbolsOnly; |
212 | case LLVMOrcJITDylibLookupFlagsMatchAllSymbols: |
213 | return JITDylibLookupFlags::MatchAllSymbols; |
214 | } |
215 | llvm_unreachable("unrecognized LLVMOrcJITDylibLookupFlags value" ); |
216 | } |
217 | |
218 | static LLVMOrcJITDylibLookupFlags |
219 | fromJITDylibLookupFlags(JITDylibLookupFlags LF) { |
220 | switch (LF) { |
221 | case JITDylibLookupFlags::MatchExportedSymbolsOnly: |
222 | return LLVMOrcJITDylibLookupFlagsMatchExportedSymbolsOnly; |
223 | case JITDylibLookupFlags::MatchAllSymbols: |
224 | return LLVMOrcJITDylibLookupFlagsMatchAllSymbols; |
225 | } |
226 | llvm_unreachable("unrecognized JITDylibLookupFlags value" ); |
227 | } |
228 | |
229 | static SymbolLookupFlags toSymbolLookupFlags(LLVMOrcSymbolLookupFlags SLF) { |
230 | switch (SLF) { |
231 | case LLVMOrcSymbolLookupFlagsRequiredSymbol: |
232 | return SymbolLookupFlags::RequiredSymbol; |
233 | case LLVMOrcSymbolLookupFlagsWeaklyReferencedSymbol: |
234 | return SymbolLookupFlags::WeaklyReferencedSymbol; |
235 | } |
236 | llvm_unreachable("unrecognized LLVMOrcSymbolLookupFlags value" ); |
237 | } |
238 | |
239 | static LLVMOrcSymbolLookupFlags fromSymbolLookupFlags(SymbolLookupFlags SLF) { |
240 | switch (SLF) { |
241 | case SymbolLookupFlags::RequiredSymbol: |
242 | return LLVMOrcSymbolLookupFlagsRequiredSymbol; |
243 | case SymbolLookupFlags::WeaklyReferencedSymbol: |
244 | return LLVMOrcSymbolLookupFlagsWeaklyReferencedSymbol; |
245 | } |
246 | llvm_unreachable("unrecognized SymbolLookupFlags value" ); |
247 | } |
248 | |
249 | static LLVMJITEvaluatedSymbol |
250 | fromExecutorSymbolDef(const ExecutorSymbolDef &S) { |
251 | return {.Address: S.getAddress().getValue(), .Flags: fromJITSymbolFlags(JSF: S.getFlags())}; |
252 | } |
253 | |
254 | } // end anonymous namespace |
255 | |
256 | namespace llvm { |
257 | namespace orc { |
258 | |
259 | class CAPIDefinitionGenerator final : public DefinitionGenerator { |
260 | public: |
261 | CAPIDefinitionGenerator( |
262 | LLVMOrcDisposeCAPIDefinitionGeneratorFunction Dispose, void *Ctx, |
263 | LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction TryToGenerate) |
264 | : Dispose(Dispose), Ctx(Ctx), TryToGenerate(TryToGenerate) {} |
265 | |
266 | ~CAPIDefinitionGenerator() { |
267 | if (Dispose) |
268 | Dispose(Ctx); |
269 | } |
270 | |
271 | Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD, |
272 | JITDylibLookupFlags JDLookupFlags, |
273 | const SymbolLookupSet &LookupSet) override { |
274 | |
275 | // Take the lookup state. |
276 | LLVMOrcLookupStateRef LSR = ::wrap(P: OrcV2CAPIHelper::extractLookupState(LS)); |
277 | |
278 | // Translate the lookup kind. |
279 | LLVMOrcLookupKind CLookupKind = fromLookupKind(K); |
280 | |
281 | // Translate the JITDylibLookupFlags. |
282 | LLVMOrcJITDylibLookupFlags CJDLookupFlags = |
283 | fromJITDylibLookupFlags(LF: JDLookupFlags); |
284 | |
285 | // Translate the lookup set. |
286 | std::vector<LLVMOrcCLookupSetElement> CLookupSet; |
287 | CLookupSet.reserve(n: LookupSet.size()); |
288 | for (auto &KV : LookupSet) { |
289 | LLVMOrcSymbolStringPoolEntryRef Name = |
290 | ::wrap(E: SymbolStringPoolEntryUnsafe::from(S: KV.first)); |
291 | LLVMOrcSymbolLookupFlags SLF = fromSymbolLookupFlags(SLF: KV.second); |
292 | CLookupSet.push_back(x: {.Name: Name, .LookupFlags: SLF}); |
293 | } |
294 | |
295 | // Run the C TryToGenerate function. |
296 | auto Err = unwrap(ErrRef: TryToGenerate(::wrap(P: this), Ctx, &LSR, CLookupKind, |
297 | ::wrap(P: &JD), CJDLookupFlags, |
298 | CLookupSet.data(), CLookupSet.size())); |
299 | |
300 | // Restore the lookup state. |
301 | OrcV2CAPIHelper::resetLookupState(LS, IPLS: ::unwrap(P: LSR)); |
302 | |
303 | return Err; |
304 | } |
305 | |
306 | private: |
307 | LLVMOrcDisposeCAPIDefinitionGeneratorFunction Dispose; |
308 | void *Ctx; |
309 | LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction TryToGenerate; |
310 | }; |
311 | |
312 | } // end namespace orc |
313 | } // end namespace llvm |
314 | |
315 | void LLVMOrcExecutionSessionSetErrorReporter( |
316 | LLVMOrcExecutionSessionRef ES, LLVMOrcErrorReporterFunction ReportError, |
317 | void *Ctx) { |
318 | unwrap(P: ES)->setErrorReporter( |
319 | [=](Error Err) { ReportError(Ctx, wrap(Err: std::move(Err))); }); |
320 | } |
321 | |
322 | LLVMOrcSymbolStringPoolRef |
323 | LLVMOrcExecutionSessionGetSymbolStringPool(LLVMOrcExecutionSessionRef ES) { |
324 | return wrap( |
325 | P: unwrap(P: ES)->getExecutorProcessControl().getSymbolStringPool().get()); |
326 | } |
327 | |
328 | void LLVMOrcSymbolStringPoolClearDeadEntries(LLVMOrcSymbolStringPoolRef SSP) { |
329 | unwrap(P: SSP)->clearDeadEntries(); |
330 | } |
331 | |
332 | LLVMOrcSymbolStringPoolEntryRef |
333 | LLVMOrcExecutionSessionIntern(LLVMOrcExecutionSessionRef ES, const char *Name) { |
334 | return wrap(E: SymbolStringPoolEntryUnsafe::take(S: unwrap(P: ES)->intern(SymName: Name))); |
335 | } |
336 | |
337 | void LLVMOrcExecutionSessionLookup( |
338 | LLVMOrcExecutionSessionRef ES, LLVMOrcLookupKind K, |
339 | LLVMOrcCJITDylibSearchOrder SearchOrder, size_t SearchOrderSize, |
340 | LLVMOrcCLookupSet Symbols, size_t SymbolsSize, |
341 | LLVMOrcExecutionSessionLookupHandleResultFunction HandleResult, void *Ctx) { |
342 | assert(ES && "ES cannot be null" ); |
343 | assert(SearchOrder && "SearchOrder cannot be null" ); |
344 | assert(Symbols && "Symbols cannot be null" ); |
345 | assert(HandleResult && "HandleResult cannot be null" ); |
346 | |
347 | JITDylibSearchOrder SO; |
348 | for (size_t I = 0; I != SearchOrderSize; ++I) |
349 | SO.push_back(x: {unwrap(P: SearchOrder[I].JD), |
350 | toJITDylibLookupFlags(LF: SearchOrder[I].JDLookupFlags)}); |
351 | |
352 | SymbolLookupSet SLS; |
353 | for (size_t I = 0; I != SymbolsSize; ++I) |
354 | SLS.add(Name: unwrap(E: Symbols[I].Name).moveToSymbolStringPtr(), |
355 | Flags: toSymbolLookupFlags(SLF: Symbols[I].LookupFlags)); |
356 | |
357 | unwrap(P: ES)->lookup( |
358 | K: toLookupKind(K), SearchOrder: SO, Symbols: std::move(SLS), RequiredState: SymbolState::Ready, |
359 | NotifyComplete: [HandleResult, Ctx](Expected<SymbolMap> Result) { |
360 | if (Result) { |
361 | SmallVector<LLVMOrcCSymbolMapPair> CResult; |
362 | for (auto &KV : *Result) |
363 | CResult.push_back(Elt: LLVMOrcCSymbolMapPair{ |
364 | .Name: wrap(E: SymbolStringPoolEntryUnsafe::from(S: KV.first)), |
365 | .Sym: fromExecutorSymbolDef(S: KV.second)}); |
366 | HandleResult(LLVMErrorSuccess, CResult.data(), CResult.size(), Ctx); |
367 | } else |
368 | HandleResult(wrap(Err: Result.takeError()), nullptr, 0, Ctx); |
369 | }, |
370 | RegisterDependencies: NoDependenciesToRegister); |
371 | } |
372 | |
373 | void LLVMOrcRetainSymbolStringPoolEntry(LLVMOrcSymbolStringPoolEntryRef S) { |
374 | unwrap(E: S).retain(); |
375 | } |
376 | |
377 | void LLVMOrcReleaseSymbolStringPoolEntry(LLVMOrcSymbolStringPoolEntryRef S) { |
378 | unwrap(E: S).release(); |
379 | } |
380 | |
381 | const char *LLVMOrcSymbolStringPoolEntryStr(LLVMOrcSymbolStringPoolEntryRef S) { |
382 | return unwrap(E: S).rawPtr()->getKey().data(); |
383 | } |
384 | |
385 | LLVMOrcResourceTrackerRef |
386 | LLVMOrcJITDylibCreateResourceTracker(LLVMOrcJITDylibRef JD) { |
387 | auto RT = unwrap(P: JD)->createResourceTracker(); |
388 | // Retain the pointer for the C API client. |
389 | RT->Retain(); |
390 | return wrap(P: RT.get()); |
391 | } |
392 | |
393 | LLVMOrcResourceTrackerRef |
394 | LLVMOrcJITDylibGetDefaultResourceTracker(LLVMOrcJITDylibRef JD) { |
395 | auto RT = unwrap(P: JD)->getDefaultResourceTracker(); |
396 | // Retain the pointer for the C API client. |
397 | return wrap(P: RT.get()); |
398 | } |
399 | |
400 | void LLVMOrcReleaseResourceTracker(LLVMOrcResourceTrackerRef RT) { |
401 | ResourceTrackerSP TmpRT(unwrap(P: RT)); |
402 | TmpRT->Release(); |
403 | } |
404 | |
405 | void LLVMOrcResourceTrackerTransferTo(LLVMOrcResourceTrackerRef SrcRT, |
406 | LLVMOrcResourceTrackerRef DstRT) { |
407 | ResourceTrackerSP TmpRT(unwrap(P: SrcRT)); |
408 | TmpRT->transferTo(DstRT&: *unwrap(P: DstRT)); |
409 | } |
410 | |
411 | LLVMErrorRef LLVMOrcResourceTrackerRemove(LLVMOrcResourceTrackerRef RT) { |
412 | ResourceTrackerSP TmpRT(unwrap(P: RT)); |
413 | return wrap(Err: TmpRT->remove()); |
414 | } |
415 | |
416 | void LLVMOrcDisposeDefinitionGenerator(LLVMOrcDefinitionGeneratorRef DG) { |
417 | std::unique_ptr<DefinitionGenerator> TmpDG(unwrap(P: DG)); |
418 | } |
419 | |
420 | void LLVMOrcDisposeMaterializationUnit(LLVMOrcMaterializationUnitRef MU) { |
421 | std::unique_ptr<MaterializationUnit> TmpMU(unwrap(P: MU)); |
422 | } |
423 | |
424 | LLVMOrcMaterializationUnitRef LLVMOrcCreateCustomMaterializationUnit( |
425 | const char *Name, void *Ctx, LLVMOrcCSymbolFlagsMapPairs Syms, |
426 | size_t NumSyms, LLVMOrcSymbolStringPoolEntryRef InitSym, |
427 | LLVMOrcMaterializationUnitMaterializeFunction Materialize, |
428 | LLVMOrcMaterializationUnitDiscardFunction Discard, |
429 | LLVMOrcMaterializationUnitDestroyFunction Destroy) { |
430 | SymbolFlagsMap SFM; |
431 | for (size_t I = 0; I != NumSyms; ++I) |
432 | SFM[unwrap(E: Syms[I].Name).moveToSymbolStringPtr()] = |
433 | toJITSymbolFlags(F: Syms[I].Flags); |
434 | |
435 | auto IS = unwrap(E: InitSym).moveToSymbolStringPtr(); |
436 | |
437 | return wrap(P: new OrcCAPIMaterializationUnit( |
438 | Name, std::move(SFM), std::move(IS), Ctx, Materialize, Discard, Destroy)); |
439 | } |
440 | |
441 | LLVMOrcMaterializationUnitRef |
442 | LLVMOrcAbsoluteSymbols(LLVMOrcCSymbolMapPairs Syms, size_t NumPairs) { |
443 | SymbolMap SM = toSymbolMap(Syms, NumPairs); |
444 | return wrap(P: absoluteSymbols(Symbols: std::move(SM)).release()); |
445 | } |
446 | |
447 | LLVMOrcMaterializationUnitRef LLVMOrcLazyReexports( |
448 | LLVMOrcLazyCallThroughManagerRef LCTM, LLVMOrcIndirectStubsManagerRef ISM, |
449 | LLVMOrcJITDylibRef SourceJD, LLVMOrcCSymbolAliasMapPairs CallableAliases, |
450 | size_t NumPairs) { |
451 | |
452 | SymbolAliasMap SAM; |
453 | for (size_t I = 0; I != NumPairs; ++I) { |
454 | auto pair = CallableAliases[I]; |
455 | JITSymbolFlags Flags = toJITSymbolFlags(F: pair.Entry.Flags); |
456 | SymbolStringPtr Name = unwrap(E: pair.Entry.Name).moveToSymbolStringPtr(); |
457 | SAM[unwrap(E: pair.Name).moveToSymbolStringPtr()] = |
458 | SymbolAliasMapEntry(Name, Flags); |
459 | } |
460 | |
461 | return wrap(P: lazyReexports(LCTManager&: *unwrap(P: LCTM), ISManager&: *unwrap(P: ISM), SourceJD&: *unwrap(P: SourceJD), |
462 | CallableAliases: std::move(SAM)) |
463 | .release()); |
464 | } |
465 | |
466 | void LLVMOrcDisposeMaterializationResponsibility( |
467 | LLVMOrcMaterializationResponsibilityRef MR) { |
468 | std::unique_ptr<MaterializationResponsibility> TmpMR(unwrap(P: MR)); |
469 | } |
470 | |
471 | LLVMOrcJITDylibRef LLVMOrcMaterializationResponsibilityGetTargetDylib( |
472 | LLVMOrcMaterializationResponsibilityRef MR) { |
473 | return wrap(P: &unwrap(P: MR)->getTargetJITDylib()); |
474 | } |
475 | |
476 | LLVMOrcExecutionSessionRef |
477 | LLVMOrcMaterializationResponsibilityGetExecutionSession( |
478 | LLVMOrcMaterializationResponsibilityRef MR) { |
479 | return wrap(P: &unwrap(P: MR)->getExecutionSession()); |
480 | } |
481 | |
482 | LLVMOrcCSymbolFlagsMapPairs LLVMOrcMaterializationResponsibilityGetSymbols( |
483 | LLVMOrcMaterializationResponsibilityRef MR, size_t *NumPairs) { |
484 | |
485 | auto Symbols = unwrap(P: MR)->getSymbols(); |
486 | LLVMOrcCSymbolFlagsMapPairs Result = static_cast<LLVMOrcCSymbolFlagsMapPairs>( |
487 | safe_malloc(Sz: Symbols.size() * sizeof(LLVMOrcCSymbolFlagsMapPair))); |
488 | size_t I = 0; |
489 | for (auto const &pair : Symbols) { |
490 | auto Name = wrap(E: SymbolStringPoolEntryUnsafe::from(S: pair.first)); |
491 | auto Flags = pair.second; |
492 | Result[I] = {.Name: Name, .Flags: fromJITSymbolFlags(JSF: Flags)}; |
493 | I++; |
494 | } |
495 | *NumPairs = Symbols.size(); |
496 | return Result; |
497 | } |
498 | |
499 | void LLVMOrcDisposeCSymbolFlagsMap(LLVMOrcCSymbolFlagsMapPairs Pairs) { |
500 | free(ptr: Pairs); |
501 | } |
502 | |
503 | LLVMOrcSymbolStringPoolEntryRef |
504 | LLVMOrcMaterializationResponsibilityGetInitializerSymbol( |
505 | LLVMOrcMaterializationResponsibilityRef MR) { |
506 | auto Sym = unwrap(P: MR)->getInitializerSymbol(); |
507 | return wrap(E: SymbolStringPoolEntryUnsafe::from(S: Sym)); |
508 | } |
509 | |
510 | LLVMOrcSymbolStringPoolEntryRef * |
511 | LLVMOrcMaterializationResponsibilityGetRequestedSymbols( |
512 | LLVMOrcMaterializationResponsibilityRef MR, size_t *NumSymbols) { |
513 | |
514 | auto Symbols = unwrap(P: MR)->getRequestedSymbols(); |
515 | LLVMOrcSymbolStringPoolEntryRef *Result = |
516 | static_cast<LLVMOrcSymbolStringPoolEntryRef *>(safe_malloc( |
517 | Sz: Symbols.size() * sizeof(LLVMOrcSymbolStringPoolEntryRef))); |
518 | size_t I = 0; |
519 | for (auto &Name : Symbols) { |
520 | Result[I] = wrap(E: SymbolStringPoolEntryUnsafe::from(S: Name)); |
521 | I++; |
522 | } |
523 | *NumSymbols = Symbols.size(); |
524 | return Result; |
525 | } |
526 | |
527 | void LLVMOrcDisposeSymbols(LLVMOrcSymbolStringPoolEntryRef *Symbols) { |
528 | free(ptr: Symbols); |
529 | } |
530 | |
531 | LLVMErrorRef LLVMOrcMaterializationResponsibilityNotifyResolved( |
532 | LLVMOrcMaterializationResponsibilityRef MR, LLVMOrcCSymbolMapPairs Symbols, |
533 | size_t NumSymbols) { |
534 | SymbolMap SM = toSymbolMap(Syms: Symbols, NumPairs: NumSymbols); |
535 | return wrap(Err: unwrap(P: MR)->notifyResolved(Symbols: std::move(SM))); |
536 | } |
537 | |
538 | LLVMErrorRef LLVMOrcMaterializationResponsibilityNotifyEmitted( |
539 | LLVMOrcMaterializationResponsibilityRef MR, |
540 | LLVMOrcCSymbolDependenceGroup *SymbolDepGroups, size_t NumSymbolDepGroups) { |
541 | std::vector<SymbolDependenceGroup> SDGs; |
542 | SDGs.reserve(n: NumSymbolDepGroups); |
543 | for (size_t I = 0; I != NumSymbolDepGroups; ++I) { |
544 | SDGs.push_back(x: SymbolDependenceGroup()); |
545 | auto &SDG = SDGs.back(); |
546 | SDG.Symbols = toSymbolNameSet(Symbols: SymbolDepGroups[I].Symbols); |
547 | SDG.Dependencies = toSymbolDependenceMap( |
548 | Pairs: SymbolDepGroups[I].Dependencies, NumPairs: SymbolDepGroups[I].NumDependencies); |
549 | } |
550 | return wrap(Err: unwrap(P: MR)->notifyEmitted(EmittedDeps: SDGs)); |
551 | } |
552 | |
553 | LLVMErrorRef LLVMOrcMaterializationResponsibilityDefineMaterializing( |
554 | LLVMOrcMaterializationResponsibilityRef MR, |
555 | LLVMOrcCSymbolFlagsMapPairs Syms, size_t NumSyms) { |
556 | SymbolFlagsMap SFM; |
557 | for (size_t I = 0; I != NumSyms; ++I) |
558 | SFM[unwrap(E: Syms[I].Name).moveToSymbolStringPtr()] = |
559 | toJITSymbolFlags(F: Syms[I].Flags); |
560 | |
561 | return wrap(Err: unwrap(P: MR)->defineMaterializing(SymbolFlags: std::move(SFM))); |
562 | } |
563 | |
564 | LLVMErrorRef LLVMOrcMaterializationResponsibilityReplace( |
565 | LLVMOrcMaterializationResponsibilityRef MR, |
566 | LLVMOrcMaterializationUnitRef MU) { |
567 | std::unique_ptr<MaterializationUnit> TmpMU(unwrap(P: MU)); |
568 | return wrap(Err: unwrap(P: MR)->replace(MU: std::move(TmpMU))); |
569 | } |
570 | |
571 | LLVMErrorRef LLVMOrcMaterializationResponsibilityDelegate( |
572 | LLVMOrcMaterializationResponsibilityRef MR, |
573 | LLVMOrcSymbolStringPoolEntryRef *Symbols, size_t NumSymbols, |
574 | LLVMOrcMaterializationResponsibilityRef *Result) { |
575 | SymbolNameSet Syms; |
576 | for (size_t I = 0; I != NumSymbols; I++) { |
577 | Syms.insert(V: unwrap(E: Symbols[I]).moveToSymbolStringPtr()); |
578 | } |
579 | auto OtherMR = unwrap(P: MR)->delegate(Symbols: Syms); |
580 | |
581 | if (!OtherMR) { |
582 | return wrap(Err: OtherMR.takeError()); |
583 | } |
584 | *Result = wrap(P: OtherMR->release()); |
585 | return LLVMErrorSuccess; |
586 | } |
587 | |
588 | void LLVMOrcMaterializationResponsibilityFailMaterialization( |
589 | LLVMOrcMaterializationResponsibilityRef MR) { |
590 | unwrap(P: MR)->failMaterialization(); |
591 | } |
592 | |
593 | void LLVMOrcIRTransformLayerEmit(LLVMOrcIRTransformLayerRef IRLayer, |
594 | LLVMOrcMaterializationResponsibilityRef MR, |
595 | LLVMOrcThreadSafeModuleRef TSM) { |
596 | std::unique_ptr<ThreadSafeModule> TmpTSM(unwrap(P: TSM)); |
597 | unwrap(P: IRLayer)->emit( |
598 | R: std::unique_ptr<MaterializationResponsibility>(unwrap(P: MR)), |
599 | TSM: std::move(*TmpTSM)); |
600 | } |
601 | |
602 | LLVMOrcJITDylibRef |
603 | LLVMOrcExecutionSessionCreateBareJITDylib(LLVMOrcExecutionSessionRef ES, |
604 | const char *Name) { |
605 | return wrap(P: &unwrap(P: ES)->createBareJITDylib(Name)); |
606 | } |
607 | |
608 | LLVMErrorRef |
609 | LLVMOrcExecutionSessionCreateJITDylib(LLVMOrcExecutionSessionRef ES, |
610 | LLVMOrcJITDylibRef *Result, |
611 | const char *Name) { |
612 | auto JD = unwrap(P: ES)->createJITDylib(Name); |
613 | if (!JD) |
614 | return wrap(Err: JD.takeError()); |
615 | *Result = wrap(P: &*JD); |
616 | return LLVMErrorSuccess; |
617 | } |
618 | |
619 | LLVMOrcJITDylibRef |
620 | LLVMOrcExecutionSessionGetJITDylibByName(LLVMOrcExecutionSessionRef ES, |
621 | const char *Name) { |
622 | return wrap(P: unwrap(P: ES)->getJITDylibByName(Name)); |
623 | } |
624 | |
625 | LLVMErrorRef LLVMOrcJITDylibDefine(LLVMOrcJITDylibRef JD, |
626 | LLVMOrcMaterializationUnitRef MU) { |
627 | std::unique_ptr<MaterializationUnit> TmpMU(unwrap(P: MU)); |
628 | |
629 | if (auto Err = unwrap(P: JD)->define(MU&: TmpMU)) { |
630 | TmpMU.release(); |
631 | return wrap(Err: std::move(Err)); |
632 | } |
633 | return LLVMErrorSuccess; |
634 | } |
635 | |
636 | LLVMErrorRef LLVMOrcJITDylibClear(LLVMOrcJITDylibRef JD) { |
637 | return wrap(Err: unwrap(P: JD)->clear()); |
638 | } |
639 | |
640 | void LLVMOrcJITDylibAddGenerator(LLVMOrcJITDylibRef JD, |
641 | LLVMOrcDefinitionGeneratorRef DG) { |
642 | unwrap(P: JD)->addGenerator(DefGenerator: std::unique_ptr<DefinitionGenerator>(unwrap(P: DG))); |
643 | } |
644 | |
645 | LLVMOrcDefinitionGeneratorRef LLVMOrcCreateCustomCAPIDefinitionGenerator( |
646 | LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction F, void *Ctx, |
647 | LLVMOrcDisposeCAPIDefinitionGeneratorFunction Dispose) { |
648 | auto DG = std::make_unique<CAPIDefinitionGenerator>(args&: Dispose, args&: Ctx, args&: F); |
649 | return wrap(P: DG.release()); |
650 | } |
651 | |
652 | void LLVMOrcLookupStateContinueLookup(LLVMOrcLookupStateRef S, |
653 | LLVMErrorRef Err) { |
654 | LookupState LS; |
655 | OrcV2CAPIHelper::resetLookupState(LS, IPLS: ::unwrap(P: S)); |
656 | LS.continueLookup(Err: unwrap(ErrRef: Err)); |
657 | } |
658 | |
659 | LLVMErrorRef LLVMOrcCreateDynamicLibrarySearchGeneratorForProcess( |
660 | LLVMOrcDefinitionGeneratorRef *Result, char GlobalPrefix, |
661 | LLVMOrcSymbolPredicate Filter, void *FilterCtx) { |
662 | assert(Result && "Result can not be null" ); |
663 | assert((Filter || !FilterCtx) && |
664 | "if Filter is null then FilterCtx must also be null" ); |
665 | |
666 | DynamicLibrarySearchGenerator::SymbolPredicate Pred; |
667 | if (Filter) |
668 | Pred = [=](const SymbolStringPtr &Name) -> bool { |
669 | return Filter(FilterCtx, wrap(E: SymbolStringPoolEntryUnsafe::from(S: Name))); |
670 | }; |
671 | |
672 | auto ProcessSymsGenerator = |
673 | DynamicLibrarySearchGenerator::GetForCurrentProcess(GlobalPrefix, Allow: Pred); |
674 | |
675 | if (!ProcessSymsGenerator) { |
676 | *Result = nullptr; |
677 | return wrap(Err: ProcessSymsGenerator.takeError()); |
678 | } |
679 | |
680 | *Result = wrap(P: ProcessSymsGenerator->release()); |
681 | return LLVMErrorSuccess; |
682 | } |
683 | |
684 | LLVMErrorRef LLVMOrcCreateDynamicLibrarySearchGeneratorForPath( |
685 | LLVMOrcDefinitionGeneratorRef *Result, const char *FileName, |
686 | char GlobalPrefix, LLVMOrcSymbolPredicate Filter, void *FilterCtx) { |
687 | assert(Result && "Result can not be null" ); |
688 | assert(FileName && "FileName can not be null" ); |
689 | assert((Filter || !FilterCtx) && |
690 | "if Filter is null then FilterCtx must also be null" ); |
691 | |
692 | DynamicLibrarySearchGenerator::SymbolPredicate Pred; |
693 | if (Filter) |
694 | Pred = [=](const SymbolStringPtr &Name) -> bool { |
695 | return Filter(FilterCtx, wrap(E: SymbolStringPoolEntryUnsafe::from(S: Name))); |
696 | }; |
697 | |
698 | auto LibrarySymsGenerator = |
699 | DynamicLibrarySearchGenerator::Load(FileName, GlobalPrefix, Allow: Pred); |
700 | |
701 | if (!LibrarySymsGenerator) { |
702 | *Result = nullptr; |
703 | return wrap(Err: LibrarySymsGenerator.takeError()); |
704 | } |
705 | |
706 | *Result = wrap(P: LibrarySymsGenerator->release()); |
707 | return LLVMErrorSuccess; |
708 | } |
709 | |
710 | LLVMErrorRef LLVMOrcCreateStaticLibrarySearchGeneratorForPath( |
711 | LLVMOrcDefinitionGeneratorRef *Result, LLVMOrcObjectLayerRef ObjLayer, |
712 | const char *FileName) { |
713 | assert(Result && "Result can not be null" ); |
714 | assert(FileName && "Filename can not be null" ); |
715 | assert(ObjLayer && "ObjectLayer can not be null" ); |
716 | |
717 | auto LibrarySymsGenerator = |
718 | StaticLibraryDefinitionGenerator::Load(L&: *unwrap(P: ObjLayer), FileName); |
719 | if (!LibrarySymsGenerator) { |
720 | *Result = nullptr; |
721 | return wrap(Err: LibrarySymsGenerator.takeError()); |
722 | } |
723 | *Result = wrap(P: LibrarySymsGenerator->release()); |
724 | return LLVMErrorSuccess; |
725 | } |
726 | |
727 | LLVMOrcThreadSafeContextRef LLVMOrcCreateNewThreadSafeContext(void) { |
728 | return wrap(P: new ThreadSafeContext(std::make_unique<LLVMContext>())); |
729 | } |
730 | |
731 | LLVMContextRef |
732 | LLVMOrcThreadSafeContextGetContext(LLVMOrcThreadSafeContextRef TSCtx) { |
733 | return wrap(P: unwrap(P: TSCtx)->getContext()); |
734 | } |
735 | |
736 | void LLVMOrcDisposeThreadSafeContext(LLVMOrcThreadSafeContextRef TSCtx) { |
737 | delete unwrap(P: TSCtx); |
738 | } |
739 | |
740 | LLVMErrorRef |
741 | LLVMOrcThreadSafeModuleWithModuleDo(LLVMOrcThreadSafeModuleRef TSM, |
742 | LLVMOrcGenericIRModuleOperationFunction F, |
743 | void *Ctx) { |
744 | return wrap(Err: unwrap(P: TSM)->withModuleDo( |
745 | F: [&](Module &M) { return unwrap(ErrRef: F(Ctx, wrap(P: &M))); })); |
746 | } |
747 | |
748 | LLVMOrcThreadSafeModuleRef |
749 | LLVMOrcCreateNewThreadSafeModule(LLVMModuleRef M, |
750 | LLVMOrcThreadSafeContextRef TSCtx) { |
751 | return wrap( |
752 | P: new ThreadSafeModule(std::unique_ptr<Module>(unwrap(P: M)), *unwrap(P: TSCtx))); |
753 | } |
754 | |
755 | void LLVMOrcDisposeThreadSafeModule(LLVMOrcThreadSafeModuleRef TSM) { |
756 | delete unwrap(P: TSM); |
757 | } |
758 | |
759 | LLVMErrorRef LLVMOrcJITTargetMachineBuilderDetectHost( |
760 | LLVMOrcJITTargetMachineBuilderRef *Result) { |
761 | assert(Result && "Result can not be null" ); |
762 | |
763 | auto JTMB = JITTargetMachineBuilder::detectHost(); |
764 | if (!JTMB) { |
765 | Result = nullptr; |
766 | return wrap(Err: JTMB.takeError()); |
767 | } |
768 | |
769 | *Result = wrap(P: new JITTargetMachineBuilder(std::move(*JTMB))); |
770 | return LLVMErrorSuccess; |
771 | } |
772 | |
773 | LLVMOrcJITTargetMachineBuilderRef |
774 | LLVMOrcJITTargetMachineBuilderCreateFromTargetMachine(LLVMTargetMachineRef TM) { |
775 | auto *TemplateTM = unwrap(P: TM); |
776 | |
777 | auto JTMB = |
778 | std::make_unique<JITTargetMachineBuilder>(args: TemplateTM->getTargetTriple()); |
779 | |
780 | (*JTMB) |
781 | .setCPU(TemplateTM->getTargetCPU().str()) |
782 | .setRelocationModel(TemplateTM->getRelocationModel()) |
783 | .setCodeModel(TemplateTM->getCodeModel()) |
784 | .setCodeGenOptLevel(TemplateTM->getOptLevel()) |
785 | .setFeatures(TemplateTM->getTargetFeatureString()) |
786 | .setOptions(TemplateTM->Options); |
787 | |
788 | LLVMDisposeTargetMachine(T: TM); |
789 | |
790 | return wrap(P: JTMB.release()); |
791 | } |
792 | |
793 | void LLVMOrcDisposeJITTargetMachineBuilder( |
794 | LLVMOrcJITTargetMachineBuilderRef JTMB) { |
795 | delete unwrap(P: JTMB); |
796 | } |
797 | |
798 | char *LLVMOrcJITTargetMachineBuilderGetTargetTriple( |
799 | LLVMOrcJITTargetMachineBuilderRef JTMB) { |
800 | auto Tmp = unwrap(P: JTMB)->getTargetTriple().str(); |
801 | char *TargetTriple = (char *)malloc(size: Tmp.size() + 1); |
802 | strcpy(dest: TargetTriple, src: Tmp.c_str()); |
803 | return TargetTriple; |
804 | } |
805 | |
806 | void LLVMOrcJITTargetMachineBuilderSetTargetTriple( |
807 | LLVMOrcJITTargetMachineBuilderRef JTMB, const char *TargetTriple) { |
808 | unwrap(P: JTMB)->getTargetTriple() = Triple(TargetTriple); |
809 | } |
810 | |
811 | LLVMErrorRef LLVMOrcObjectLayerAddObjectFile(LLVMOrcObjectLayerRef ObjLayer, |
812 | LLVMOrcJITDylibRef JD, |
813 | LLVMMemoryBufferRef ObjBuffer) { |
814 | return wrap(Err: unwrap(P: ObjLayer)->add( |
815 | JD&: *unwrap(P: JD), O: std::unique_ptr<MemoryBuffer>(unwrap(P: ObjBuffer)))); |
816 | } |
817 | |
818 | LLVMErrorRef LLVMOrcObjectLayerAddObjectFileWithRT(LLVMOrcObjectLayerRef ObjLayer, |
819 | LLVMOrcResourceTrackerRef RT, |
820 | LLVMMemoryBufferRef ObjBuffer) { |
821 | return wrap( |
822 | Err: unwrap(P: ObjLayer)->add(RT: ResourceTrackerSP(unwrap(P: RT)), |
823 | O: std::unique_ptr<MemoryBuffer>(unwrap(P: ObjBuffer)))); |
824 | } |
825 | |
826 | void LLVMOrcObjectLayerEmit(LLVMOrcObjectLayerRef ObjLayer, |
827 | LLVMOrcMaterializationResponsibilityRef R, |
828 | LLVMMemoryBufferRef ObjBuffer) { |
829 | unwrap(P: ObjLayer)->emit( |
830 | R: std::unique_ptr<MaterializationResponsibility>(unwrap(P: R)), |
831 | O: std::unique_ptr<MemoryBuffer>(unwrap(P: ObjBuffer))); |
832 | } |
833 | |
834 | void LLVMOrcDisposeObjectLayer(LLVMOrcObjectLayerRef ObjLayer) { |
835 | delete unwrap(P: ObjLayer); |
836 | } |
837 | |
838 | void LLVMOrcIRTransformLayerSetTransform( |
839 | LLVMOrcIRTransformLayerRef IRTransformLayer, |
840 | LLVMOrcIRTransformLayerTransformFunction TransformFunction, void *Ctx) { |
841 | unwrap(P: IRTransformLayer) |
842 | ->setTransform( |
843 | [=](ThreadSafeModule TSM, |
844 | MaterializationResponsibility &R) -> Expected<ThreadSafeModule> { |
845 | LLVMOrcThreadSafeModuleRef TSMRef = |
846 | wrap(P: new ThreadSafeModule(std::move(TSM))); |
847 | if (LLVMErrorRef Err = TransformFunction(Ctx, &TSMRef, wrap(P: &R))) { |
848 | assert(!TSMRef && "TSMRef was not reset to null on error" ); |
849 | return unwrap(ErrRef: Err); |
850 | } |
851 | assert(TSMRef && "Transform succeeded, but TSMRef was set to null" ); |
852 | ThreadSafeModule Result = std::move(*unwrap(P: TSMRef)); |
853 | LLVMOrcDisposeThreadSafeModule(TSM: TSMRef); |
854 | return std::move(Result); |
855 | }); |
856 | } |
857 | |
858 | void LLVMOrcObjectTransformLayerSetTransform( |
859 | LLVMOrcObjectTransformLayerRef ObjTransformLayer, |
860 | LLVMOrcObjectTransformLayerTransformFunction TransformFunction, void *Ctx) { |
861 | unwrap(P: ObjTransformLayer) |
862 | ->setTransform([TransformFunction, Ctx](std::unique_ptr<MemoryBuffer> Obj) |
863 | -> Expected<std::unique_ptr<MemoryBuffer>> { |
864 | LLVMMemoryBufferRef ObjBuffer = wrap(P: Obj.release()); |
865 | if (LLVMErrorRef Err = TransformFunction(Ctx, &ObjBuffer)) { |
866 | assert(!ObjBuffer && "ObjBuffer was not reset to null on error" ); |
867 | return unwrap(ErrRef: Err); |
868 | } |
869 | return std::unique_ptr<MemoryBuffer>(unwrap(P: ObjBuffer)); |
870 | }); |
871 | } |
872 | |
873 | LLVMOrcDumpObjectsRef LLVMOrcCreateDumpObjects(const char *DumpDir, |
874 | const char *IdentifierOverride) { |
875 | assert(DumpDir && "DumpDir should not be null" ); |
876 | assert(IdentifierOverride && "IdentifierOverride should not be null" ); |
877 | return wrap(P: new DumpObjects(DumpDir, IdentifierOverride)); |
878 | } |
879 | |
880 | void LLVMOrcDisposeDumpObjects(LLVMOrcDumpObjectsRef DumpObjects) { |
881 | delete unwrap(P: DumpObjects); |
882 | } |
883 | |
884 | LLVMErrorRef LLVMOrcDumpObjects_CallOperator(LLVMOrcDumpObjectsRef DumpObjects, |
885 | LLVMMemoryBufferRef *ObjBuffer) { |
886 | std::unique_ptr<MemoryBuffer> OB(unwrap(P: *ObjBuffer)); |
887 | if (auto Result = (*unwrap(P: DumpObjects))(std::move(OB))) { |
888 | *ObjBuffer = wrap(P: Result->release()); |
889 | return LLVMErrorSuccess; |
890 | } else { |
891 | *ObjBuffer = nullptr; |
892 | return wrap(Err: Result.takeError()); |
893 | } |
894 | } |
895 | |
896 | LLVMOrcLLJITBuilderRef LLVMOrcCreateLLJITBuilder(void) { |
897 | return wrap(P: new LLJITBuilder()); |
898 | } |
899 | |
900 | void LLVMOrcDisposeLLJITBuilder(LLVMOrcLLJITBuilderRef Builder) { |
901 | delete unwrap(P: Builder); |
902 | } |
903 | |
904 | void LLVMOrcLLJITBuilderSetJITTargetMachineBuilder( |
905 | LLVMOrcLLJITBuilderRef Builder, LLVMOrcJITTargetMachineBuilderRef JTMB) { |
906 | unwrap(P: Builder)->setJITTargetMachineBuilder(std::move(*unwrap(P: JTMB))); |
907 | LLVMOrcDisposeJITTargetMachineBuilder(JTMB); |
908 | } |
909 | |
910 | void LLVMOrcLLJITBuilderSetObjectLinkingLayerCreator( |
911 | LLVMOrcLLJITBuilderRef Builder, |
912 | LLVMOrcLLJITBuilderObjectLinkingLayerCreatorFunction F, void *Ctx) { |
913 | unwrap(P: Builder)->setObjectLinkingLayerCreator( |
914 | [=](ExecutionSession &ES, const Triple &TT) { |
915 | auto TTStr = TT.str(); |
916 | return std::unique_ptr<ObjectLayer>( |
917 | unwrap(P: F(Ctx, wrap(P: &ES), TTStr.c_str()))); |
918 | }); |
919 | } |
920 | |
921 | LLVMErrorRef LLVMOrcCreateLLJIT(LLVMOrcLLJITRef *Result, |
922 | LLVMOrcLLJITBuilderRef Builder) { |
923 | assert(Result && "Result can not be null" ); |
924 | |
925 | if (!Builder) |
926 | Builder = LLVMOrcCreateLLJITBuilder(); |
927 | |
928 | auto J = unwrap(P: Builder)->create(); |
929 | LLVMOrcDisposeLLJITBuilder(Builder); |
930 | |
931 | if (!J) { |
932 | Result = nullptr; |
933 | return wrap(Err: J.takeError()); |
934 | } |
935 | |
936 | *Result = wrap(P: J->release()); |
937 | return LLVMErrorSuccess; |
938 | } |
939 | |
940 | LLVMErrorRef LLVMOrcDisposeLLJIT(LLVMOrcLLJITRef J) { |
941 | delete unwrap(P: J); |
942 | return LLVMErrorSuccess; |
943 | } |
944 | |
945 | LLVMOrcExecutionSessionRef LLVMOrcLLJITGetExecutionSession(LLVMOrcLLJITRef J) { |
946 | return wrap(P: &unwrap(P: J)->getExecutionSession()); |
947 | } |
948 | |
949 | LLVMOrcJITDylibRef LLVMOrcLLJITGetMainJITDylib(LLVMOrcLLJITRef J) { |
950 | return wrap(P: &unwrap(P: J)->getMainJITDylib()); |
951 | } |
952 | |
953 | const char *LLVMOrcLLJITGetTripleString(LLVMOrcLLJITRef J) { |
954 | return unwrap(P: J)->getTargetTriple().str().c_str(); |
955 | } |
956 | |
957 | char LLVMOrcLLJITGetGlobalPrefix(LLVMOrcLLJITRef J) { |
958 | return unwrap(P: J)->getDataLayout().getGlobalPrefix(); |
959 | } |
960 | |
961 | LLVMOrcSymbolStringPoolEntryRef |
962 | LLVMOrcLLJITMangleAndIntern(LLVMOrcLLJITRef J, const char *UnmangledName) { |
963 | return wrap(E: SymbolStringPoolEntryUnsafe::take( |
964 | S: unwrap(P: J)->mangleAndIntern(UnmangledName))); |
965 | } |
966 | |
967 | LLVMErrorRef LLVMOrcLLJITAddObjectFile(LLVMOrcLLJITRef J, LLVMOrcJITDylibRef JD, |
968 | LLVMMemoryBufferRef ObjBuffer) { |
969 | return wrap(Err: unwrap(P: J)->addObjectFile( |
970 | JD&: *unwrap(P: JD), Obj: std::unique_ptr<MemoryBuffer>(unwrap(P: ObjBuffer)))); |
971 | } |
972 | |
973 | LLVMErrorRef LLVMOrcLLJITAddObjectFileWithRT(LLVMOrcLLJITRef J, |
974 | LLVMOrcResourceTrackerRef RT, |
975 | LLVMMemoryBufferRef ObjBuffer) { |
976 | return wrap(Err: unwrap(P: J)->addObjectFile( |
977 | RT: ResourceTrackerSP(unwrap(P: RT)), |
978 | Obj: std::unique_ptr<MemoryBuffer>(unwrap(P: ObjBuffer)))); |
979 | } |
980 | |
981 | LLVMErrorRef LLVMOrcLLJITAddLLVMIRModule(LLVMOrcLLJITRef J, |
982 | LLVMOrcJITDylibRef JD, |
983 | LLVMOrcThreadSafeModuleRef TSM) { |
984 | std::unique_ptr<ThreadSafeModule> TmpTSM(unwrap(P: TSM)); |
985 | return wrap(Err: unwrap(P: J)->addIRModule(JD&: *unwrap(P: JD), TSM: std::move(*TmpTSM))); |
986 | } |
987 | |
988 | LLVMErrorRef LLVMOrcLLJITAddLLVMIRModuleWithRT(LLVMOrcLLJITRef J, |
989 | LLVMOrcResourceTrackerRef RT, |
990 | LLVMOrcThreadSafeModuleRef TSM) { |
991 | std::unique_ptr<ThreadSafeModule> TmpTSM(unwrap(P: TSM)); |
992 | return wrap(Err: unwrap(P: J)->addIRModule(RT: ResourceTrackerSP(unwrap(P: RT)), |
993 | TSM: std::move(*TmpTSM))); |
994 | } |
995 | |
996 | LLVMErrorRef LLVMOrcLLJITLookup(LLVMOrcLLJITRef J, |
997 | LLVMOrcJITTargetAddress *Result, |
998 | const char *Name) { |
999 | assert(Result && "Result can not be null" ); |
1000 | |
1001 | auto Sym = unwrap(P: J)->lookup(UnmangledName: Name); |
1002 | if (!Sym) { |
1003 | *Result = 0; |
1004 | return wrap(Err: Sym.takeError()); |
1005 | } |
1006 | |
1007 | *Result = Sym->getValue(); |
1008 | return LLVMErrorSuccess; |
1009 | } |
1010 | |
1011 | LLVMOrcObjectLayerRef LLVMOrcLLJITGetObjLinkingLayer(LLVMOrcLLJITRef J) { |
1012 | return wrap(P: &unwrap(P: J)->getObjLinkingLayer()); |
1013 | } |
1014 | |
1015 | LLVMOrcObjectTransformLayerRef |
1016 | LLVMOrcLLJITGetObjTransformLayer(LLVMOrcLLJITRef J) { |
1017 | return wrap(P: &unwrap(P: J)->getObjTransformLayer()); |
1018 | } |
1019 | |
1020 | LLVMOrcObjectLayerRef |
1021 | LLVMOrcCreateRTDyldObjectLinkingLayerWithSectionMemoryManager( |
1022 | LLVMOrcExecutionSessionRef ES) { |
1023 | assert(ES && "ES must not be null" ); |
1024 | return wrap(P: new RTDyldObjectLinkingLayer( |
1025 | *unwrap(P: ES), [] { return std::make_unique<SectionMemoryManager>(); })); |
1026 | } |
1027 | |
1028 | LLVMOrcObjectLayerRef |
1029 | LLVMOrcCreateRTDyldObjectLinkingLayerWithMCJITMemoryManagerLikeCallbacks( |
1030 | LLVMOrcExecutionSessionRef ES, void *CreateContextCtx, |
1031 | LLVMMemoryManagerCreateContextCallback CreateContext, |
1032 | LLVMMemoryManagerNotifyTerminatingCallback NotifyTerminating, |
1033 | LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection, |
1034 | LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection, |
1035 | LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory, |
1036 | LLVMMemoryManagerDestroyCallback Destroy) { |
1037 | |
1038 | struct MCJITMemoryManagerLikeCallbacks { |
1039 | MCJITMemoryManagerLikeCallbacks() = default; |
1040 | MCJITMemoryManagerLikeCallbacks( |
1041 | void *CreateContextCtx, |
1042 | LLVMMemoryManagerCreateContextCallback CreateContext, |
1043 | LLVMMemoryManagerNotifyTerminatingCallback NotifyTerminating, |
1044 | LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection, |
1045 | LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection, |
1046 | LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory, |
1047 | LLVMMemoryManagerDestroyCallback Destroy) |
1048 | : CreateContextCtx(CreateContextCtx), CreateContext(CreateContext), |
1049 | NotifyTerminating(NotifyTerminating), |
1050 | AllocateCodeSection(AllocateCodeSection), |
1051 | AllocateDataSection(AllocateDataSection), |
1052 | FinalizeMemory(FinalizeMemory), Destroy(Destroy) {} |
1053 | |
1054 | MCJITMemoryManagerLikeCallbacks(MCJITMemoryManagerLikeCallbacks &&Other) { |
1055 | std::swap(a&: CreateContextCtx, b&: Other.CreateContextCtx); |
1056 | std::swap(a&: CreateContext, b&: Other.CreateContext); |
1057 | std::swap(a&: NotifyTerminating, b&: Other.NotifyTerminating); |
1058 | std::swap(a&: AllocateCodeSection, b&: Other.AllocateCodeSection); |
1059 | std::swap(a&: AllocateDataSection, b&: Other.AllocateDataSection); |
1060 | std::swap(a&: FinalizeMemory, b&: Other.FinalizeMemory); |
1061 | std::swap(a&: Destroy, b&: Other.Destroy); |
1062 | } |
1063 | |
1064 | ~MCJITMemoryManagerLikeCallbacks() { |
1065 | if (NotifyTerminating) |
1066 | NotifyTerminating(CreateContextCtx); |
1067 | } |
1068 | |
1069 | void *CreateContextCtx = nullptr; |
1070 | LLVMMemoryManagerCreateContextCallback CreateContext = nullptr; |
1071 | LLVMMemoryManagerNotifyTerminatingCallback NotifyTerminating = nullptr; |
1072 | LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection = nullptr; |
1073 | LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection = nullptr; |
1074 | LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory = nullptr; |
1075 | LLVMMemoryManagerDestroyCallback Destroy = nullptr; |
1076 | }; |
1077 | |
1078 | class MCJITMemoryManagerLikeCallbacksMemMgr : public RTDyldMemoryManager { |
1079 | public: |
1080 | MCJITMemoryManagerLikeCallbacksMemMgr( |
1081 | const MCJITMemoryManagerLikeCallbacks &CBs) |
1082 | : CBs(CBs) { |
1083 | Opaque = CBs.CreateContext(CBs.CreateContextCtx); |
1084 | } |
1085 | ~MCJITMemoryManagerLikeCallbacksMemMgr() override { CBs.Destroy(Opaque); } |
1086 | |
1087 | uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, |
1088 | unsigned SectionID, |
1089 | StringRef SectionName) override { |
1090 | return CBs.AllocateCodeSection(Opaque, Size, Alignment, SectionID, |
1091 | SectionName.str().c_str()); |
1092 | } |
1093 | |
1094 | uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, |
1095 | unsigned SectionID, StringRef SectionName, |
1096 | bool isReadOnly) override { |
1097 | return CBs.AllocateDataSection(Opaque, Size, Alignment, SectionID, |
1098 | SectionName.str().c_str(), isReadOnly); |
1099 | } |
1100 | |
1101 | bool finalizeMemory(std::string *ErrMsg) override { |
1102 | char *ErrMsgCString = nullptr; |
1103 | bool Result = CBs.FinalizeMemory(Opaque, &ErrMsgCString); |
1104 | assert((Result || !ErrMsgCString) && |
1105 | "Did not expect an error message if FinalizeMemory succeeded" ); |
1106 | if (ErrMsgCString) { |
1107 | if (ErrMsg) |
1108 | *ErrMsg = ErrMsgCString; |
1109 | free(ptr: ErrMsgCString); |
1110 | } |
1111 | return Result; |
1112 | } |
1113 | |
1114 | private: |
1115 | const MCJITMemoryManagerLikeCallbacks &CBs; |
1116 | void *Opaque = nullptr; |
1117 | }; |
1118 | |
1119 | assert(ES && "ES must not be null" ); |
1120 | assert(CreateContext && "CreateContext must not be null" ); |
1121 | assert(NotifyTerminating && "NotifyTerminating must not be null" ); |
1122 | assert(AllocateCodeSection && "AllocateCodeSection must not be null" ); |
1123 | assert(AllocateDataSection && "AllocateDataSection must not be null" ); |
1124 | assert(FinalizeMemory && "FinalizeMemory must not be null" ); |
1125 | assert(Destroy && "Destroy must not be null" ); |
1126 | |
1127 | MCJITMemoryManagerLikeCallbacks CBs( |
1128 | CreateContextCtx, CreateContext, NotifyTerminating, AllocateCodeSection, |
1129 | AllocateDataSection, FinalizeMemory, Destroy); |
1130 | |
1131 | return wrap(P: new RTDyldObjectLinkingLayer(*unwrap(P: ES), [CBs = std::move(CBs)] { |
1132 | return std::make_unique<MCJITMemoryManagerLikeCallbacksMemMgr>(args: CBs); |
1133 | })); |
1134 | |
1135 | return nullptr; |
1136 | } |
1137 | |
1138 | void LLVMOrcRTDyldObjectLinkingLayerRegisterJITEventListener( |
1139 | LLVMOrcObjectLayerRef RTDyldObjLinkingLayer, |
1140 | LLVMJITEventListenerRef Listener) { |
1141 | assert(RTDyldObjLinkingLayer && "RTDyldObjLinkingLayer must not be null" ); |
1142 | assert(Listener && "Listener must not be null" ); |
1143 | reinterpret_cast<RTDyldObjectLinkingLayer *>(unwrap(P: RTDyldObjLinkingLayer)) |
1144 | ->registerJITEventListener(L&: *unwrap(P: Listener)); |
1145 | } |
1146 | |
1147 | LLVMOrcIRTransformLayerRef LLVMOrcLLJITGetIRTransformLayer(LLVMOrcLLJITRef J) { |
1148 | return wrap(P: &unwrap(P: J)->getIRTransformLayer()); |
1149 | } |
1150 | |
1151 | const char *LLVMOrcLLJITGetDataLayoutStr(LLVMOrcLLJITRef J) { |
1152 | return unwrap(P: J)->getDataLayout().getStringRepresentation().c_str(); |
1153 | } |
1154 | |
1155 | LLVMOrcIndirectStubsManagerRef |
1156 | LLVMOrcCreateLocalIndirectStubsManager(const char *TargetTriple) { |
1157 | auto builder = createLocalIndirectStubsManagerBuilder(T: Triple(TargetTriple)); |
1158 | return wrap(P: builder().release()); |
1159 | } |
1160 | |
1161 | void LLVMOrcDisposeIndirectStubsManager(LLVMOrcIndirectStubsManagerRef ISM) { |
1162 | std::unique_ptr<IndirectStubsManager> TmpISM(unwrap(P: ISM)); |
1163 | } |
1164 | |
1165 | LLVMErrorRef LLVMOrcCreateLocalLazyCallThroughManager( |
1166 | const char *TargetTriple, LLVMOrcExecutionSessionRef ES, |
1167 | LLVMOrcJITTargetAddress ErrorHandlerAddr, |
1168 | LLVMOrcLazyCallThroughManagerRef *Result) { |
1169 | auto LCTM = createLocalLazyCallThroughManager( |
1170 | T: Triple(TargetTriple), ES&: *unwrap(P: ES), ErrorHandlerAddr: ExecutorAddr(ErrorHandlerAddr)); |
1171 | |
1172 | if (!LCTM) |
1173 | return wrap(Err: LCTM.takeError()); |
1174 | *Result = wrap(P: LCTM->release()); |
1175 | return LLVMErrorSuccess; |
1176 | } |
1177 | |
1178 | void LLVMOrcDisposeLazyCallThroughManager( |
1179 | LLVMOrcLazyCallThroughManagerRef LCM) { |
1180 | std::unique_ptr<LazyCallThroughManager> TmpLCM(unwrap(P: LCM)); |
1181 | } |
1182 | |