Ejemplo n.º 1
0
        /// <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( ));
            }
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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);
Ejemplo n.º 5
0
        /// <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);
        }
Ejemplo n.º 6
0
        /// <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);
        }
Ejemplo n.º 7
0
        /// <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);
        }