Exemplo 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( ));
            }
        }
Exemplo n.º 2
0
 /// <summary>Add a lazy function generator</summary>
 /// <param name="jit">JIT to add the module to</param>
 /// <param name="name">name of the function</param>
 /// <param name="generator">Generator that will generate the bit-code module for the function on demand</param>
 /// <remarks>
 /// A lazy function generator is an engine callback that is called when the JIT engine first encounters
 /// a symbol name during execution. If the function is never called, then the code is never generated (e.g.
 /// this is the real "JIT" part of a JIT engine.)
 /// <para>The <paramref name="generator"/> generates the IR module for the function. For this overload, the generator
 /// must contain everything necessary to generate the <see cref="BitcodeModule"/> for the function. Typically, this is
 /// a closure that captured the AST for the language and generates the IR from that state.</para>
 /// </remarks>
 public static void AddLazyFunctionGenerator([ValidatedNotNull] this ILazyCompileExecutionEngine jit, string name, LazyFunctionCompiler generator)
 {
     jit.ValidateNotNull(nameof(jit));
     jit.AddLazyFunctionGenerator(name, generator, IntPtr.Zero);
 }
 /// <summary>Add a lazy function generator</summary>
 /// <param name="jit">JIT to add the module to</param>
 /// <param name="name">name of the function</param>
 /// <param name="generator">Generator that will generate the bit-code module for the function on demand</param>
 /// <remarks>
 /// A lazy function generator is an engine callback that is called when the JIT engine first encounters
 /// a symbol name during execution. If the function is never called, then the code is never generated (e.g.
 /// this is the real "JIT" part of a JIT engine.)
 /// <para>The <paramref name="generator"/> generates the IR module for the function. For this overload, the generator
 /// must contain everything necessary to generate the <see cref="BitcodeModule"/> for the function. Typically, this is
 /// a closure that captured the AST for the language and generates the IR from that state.</para>
 /// </remarks>
 public static void AddLazyFunctionGenerator(this ILazyCompileExecutionEngine jit, string name, LazyFunctionCompiler generator)
 {
     jit.AddLazyFunctionGenerator(name, generator, IntPtr.Zero);
 }