Пример #1
0
        /// <inheritdoc/>
        public ulong DefaultSymbolResolver(string name, IntPtr ctx)
        {
            try
            {
                // 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  err          = LibLLVMOrcGetSymbolAddress(JitStackHandle, out ulong retAddr, name, exportedOnly);
                if (!err.IsInvalid)
                {
                    throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resources.Unresolved_Symbol_0_1, name, LLVMOrcGetErrorMsg(JitStackHandle)));
                }

                if (retAddr != 0)
                {
                    return(retAddr);
                }

                return(GlobalInteropFunctions.TryGetValue(name, out WrappedNativeCallback callBack) ? ( ulong )callBack.ToIntPtr( ).ToInt64( ) : 0);
            }
#pragma warning disable CA1031 // Do not catch general exception types
            catch
            {
                // Allowing exceptions outside this call is not helpful as the LLVM
                // native JIT engine is what calls this function and it doesn't know
                // how to deal with a managed exception. Any exceptions are at least
                // logged in a debugger before being swallowed here.
                return(0);
            }
#pragma warning restore CA1031 // Do not catch general exception types
        }
Пример #2
0
        /// <summary>Adds or replaces an interop callback for a global symbol</summary>
        /// <typeparam name="T">Delegate type for the callback</typeparam>
        /// <param name="symbolName">Symbol name of the global</param>
        /// <param name="delegate">Delegate for the callback</param>
        /// <remarks>
        /// <note type="warning">
        /// The delegate is made available to native code as a callback, and therefore it
        /// must have a lifetime that is at least as long as the callback is registered or
        /// the lifetime of the JIT engine itself. The direct delegate and any instance
        /// it may be a member of are handled automatically in the internal implementation
        /// of this function. However, any data the delegate may rely on is not. (e.g. if
        /// the object the delegate is a method on a class implementing IDisposable and the
        /// Dispose method was called on that instance, then the callback could end up operating
        /// on a disposed object)
        /// </note>
        /// <note type="warning">
        /// The callback **MUST NOT** throw any exceptions out of the callback, as the
        /// JIT engine doesn't know how to handle them and neither does the JIT'd code.
        /// </note>
        /// </remarks>
        public void AddInteropCallback <T>(string symbolName, T @delegate)
            where T : Delegate
        {
            LLVMOrcGetMangledSymbol(JitStackHandle, out string mangledName, symbolName);
            if (GlobalInteropFunctions.TryGetValue(mangledName, out WrappedNativeCallback existingCallback))
            {
                GlobalInteropFunctions.Remove(mangledName);
                existingCallback.Dispose( );
            }

            GlobalInteropFunctions.Add(mangledName, new WrappedNativeCallback <T>(@delegate));
        }