/// <inheritdoc/> public void AddLazyFunctionGenerator(string name, LazyFunctionCompiler generator, IntPtr context) { LLVMOrcGetMangledSymbol(JitStackHandle, out string mangledName, name); // wrap the provided generator function for a safe native callback UInt64 CompileAction(LLVMOrcJITStackRef jitStackHandle, IntPtr ctx) { try { (string implName, BitcodeModule module) = generator( ); if (module == null) { return(0); } AddEagerlyCompiledModule(module, DefaultSymbolResolver); // Workaround OrcJit+Windows/COFF bug/limitation where functions in the generated obj are // not marked as exported, so the official llvm-c API doesn't see the symbol to get the address // LibLLVM variant takes the additional bool so that is used on Windows to find non-exported symbols. bool exportedOnly = Environment.OSVersion.Platform != PlatformID.Win32NT; var e = LibLLVMOrcGetSymbolAddress(JitStackHandle, out UInt64 implAddr, name, exportedOnly); if (!e.IsInvalid) { throw new LlvmException(e.ToString()); } e = LLVMOrcSetIndirectStubPointer(JitStackHandle, mangledName, implAddr); if (!e.IsInvalid) { throw new LlvmException(e.ToString()); } LazyFunctionGenerators.Remove(mangledName); return(implAddr); } #pragma warning disable CA1031 // Do not catch general exception types catch { // native callback - MUST NOT leak exceptions out of this call. return(0); } #pragma warning restore CA1031 // Do not catch general exception types } var callbackAction = new WrappedNativeCallback <LLVMOrcLazyCompileCallbackFn>(CompileAction); LazyFunctionGenerators.Add(mangledName, callbackAction); var err = LLVMOrcCreateLazyCompileCallback(JitStackHandle, out UInt64 stubAddr, callbackAction, context); if (!err.IsInvalid) { throw new LlvmException(err.ToString()); } err = LLVMOrcCreateIndirectStub(JitStackHandle, mangledName, stubAddr); if (!err.IsInvalid) { throw new LlvmException(err.ToString( )); } }
internal ValueCache(Context context) { Context = context; // methods used as cross P/Invoke callbacks so the delegates must remain alive for duration WrappedOnDeleted = new WrappedNativeCallback <LibLLVMValueCacheItemDeletedCallback>(OnItemDeleted); WrappedOnReplaced = new WrappedNativeCallback <LibLLVMValueCacheItemReplacedCallback>(OnItemReplaced); Handle = LibLLVMCreateValueCache(WrappedOnDeleted, WrappedOnReplaced); }
private Context(LLVMContextRef contextRef) { ContextHandle = contextRef; lock ( ContextCache ) { ContextCache.Add(contextRef, this); } ActiveHandler = new WrappedNativeCallback(new LLVMDiagnosticHandler(DiagnosticHandler)); NativeMethods.ContextSetDiagnosticHandler(ContextHandle, ActiveHandler.GetFuncPointer( ), IntPtr.Zero); }
internal Context(LLVMContextRef contextRef) { if (contextRef.Handle == default) { throw new ArgumentNullException(nameof(contextRef)); } this.ContextHandle = contextRef; this.activeHandler = new WrappedNativeCallback <LLVMDiagnosticHandler>(DiagnosticHandler); this.valueCache = new Value.InterningFactory(this); this.moduleCache = new BitcodeModule.InterningFactory(this); this.typeCache = new TypeRef.InterningFactory(this); this.attributeValueCache = new AttributeValue.InterningFactory(this); LLVM.ContextSetDiagnosticHandler(this.ContextHandle, this.activeHandler, (void *)default);
/// <summary>Create and add the internalize pass to the given pass manager with the provided preservation callback.</summary> /// <typeparam name="T">Type of PassManager</typeparam> /// <param name="passManager">PassManager to add the pass to</param> /// <param name="predicate">predicate to callback on each invocation</param> /// <returns>The input <paramref name="passManager"/></returns> /// <remarks> /// <para>Any instance that <paramref name="predicate"/> is a member of (if not static) MUST outlive the /// lifetime of <paramref name="passManager"/> or unpredictable results will occur (usually a crash). /// This is especially important for disposable types as calling Dispose on them can invalidate the /// predicate function.</para> /// <para>Additionally, the predicate function MUST NOT throw, or allow any exceptions to bubble out /// of the function as it is called by native code that has no idea what to do with a managed code /// exception. (Again, likely resulting in a crash)</para> /// </remarks> public static T AddInternalizePassWithMustPreservePredicate <T>([ValidatedNotNull] this T passManager , Predicate <Value> predicate ) where T : PassManager { passManager.ValidateNotNull(nameof(passManager)); predicate.ValidateNotNull(nameof(predicate)); var wrappedCallBack = new WrappedNativeCallback <Predicate <Value> >(predicate); passManager.NativeCallBacks.Add(wrappedCallBack); LLVMAddInternalizePassWithMustPreservePredicate(passManager.Handle, IntPtr.Zero, wrappedCallBack.ToIntPtr( )); return(passManager); }
/// <inheritdoc/> public ulong AddLazyCompiledModule(BitcodeModule bitcodeModule, LLVMOrcSymbolResolverFn resolver) { LLVMModuleRef moduleHandle = bitcodeModule.Detach( ); var wrappedResolver = new WrappedNativeCallback <LLVMOrcSymbolResolverFn>(resolver); var err = LLVMOrcAddLazilyCompiledIR(JitStackHandle, out ulong retHandle, moduleHandle, wrappedResolver, IntPtr.Zero); moduleHandle.SetHandleAsInvalid( ); if (!err.IsInvalid) { throw new LlvmException(err.ToString( )); } // keep resolver delegate alive as native code needs to call it after this function exits SymbolResolvers.Add(retHandle, wrappedResolver); return(retHandle); }
/// <inheritdoc/> public ulong AddEagerlyCompiledModule(BitcodeModule bitcodeModule, LLVMOrcSymbolResolverFn resolver) { bitcodeModule.ValidateNotNull(nameof(bitcodeModule)); resolver.ValidateNotNull(nameof(resolver)); // detach the module before providing to JIT as JIT takes ownership LLVMModuleRef moduleHandle = bitcodeModule.Detach( ); var wrappedResolver = new WrappedNativeCallback <LLVMOrcSymbolResolverFn>(resolver); var err = LLVMOrcAddEagerlyCompiledIR(JitStackHandle, out ulong retHandle, moduleHandle, wrappedResolver, IntPtr.Zero); moduleHandle.SetHandleAsInvalid( ); if (!err.IsInvalid) { throw new LlvmException(err.ToString( )); } // keep resolver delegate alive as native code needs to call it after this function exits SymbolResolvers.Add(retHandle, wrappedResolver); return(retHandle); }