コード例 #1
0
ファイル: ManagedJit.cs プロジェクト: FenixDan/Jitex
        private void ResolveToken(IntPtr thisHandle, IntPtr pResolvedToken)
        {
            _tokenTls ??= new TokenTls();
            _tokenTls.EnterCount++;

            if (thisHandle == IntPtr.Zero)
            {
                return;
            }

            try
            {
                if (_tokenTls.EnterCount == 1 && _tokenResolvers != null)
                {
                    IEnumerable <Delegate> resolvers = _tokenResolvers.GetInvocationList();

                    if (!resolvers.Any())
                    {
                        CEEInfo.ResolveToken(thisHandle, pResolvedToken);
                        return;
                    }

                    //Capture method who trying resolve that token.
                    _tokenTls.Source = _tokenTls.GetSource();

                    ResolvedToken resolvedToken = new ResolvedToken(pResolvedToken);
                    TokenContext  context       = new TokenContext(ref resolvedToken, _tokenTls.Source);

                    foreach (TokenResolverHandler resolver in resolvers)
                    {
                        resolver(context);
                    }
                }

                CEEInfo.ResolveToken(thisHandle, pResolvedToken);
            }
            finally
            {
                _tokenTls.EnterCount--;
            }
        }
コード例 #2
0
ファイル: ManagedJit.cs プロジェクト: FenixDan/Jitex
        /// <summary>
        ///     Wrap delegate to compileMethod from ICorJitCompiler.
        /// </summary>
        /// <param name="thisPtr">this parameter (pointer to CILJIT).</param>
        /// <param name="comp">(IN) - Pointer to ICorJitInfo.</param>
        /// <param name="info">(IN) - Pointer to CORINFO_METHOD_INFO.</param>
        /// <param name="flags">(IN) - Pointer to CorJitFlag.</param>
        /// <param name="nativeEntry">(OUT) - Pointer to NativeEntry.</param>
        /// <param name="nativeSizeOfCode">(OUT) - Size of NativeEntry.</param>
        private CorJitResult CompileMethod(IntPtr thisPtr, IntPtr comp, IntPtr info, uint flags, out IntPtr nativeEntry, out ulong nativeSizeOfCode)
        {
            if (thisPtr == default)
            {
                nativeEntry      = IntPtr.Zero;
                nativeSizeOfCode = 0;
                return(0);
            }

            _compileTls ??= new CompileTls();
            _compileTls.EnterCount++;

            try
            {
                MethodContext?methodContext = null;
                IntPtr        sigAddress    = IntPtr.Zero;
                IntPtr        ilAddress     = IntPtr.Zero;

                if (_compileTls.EnterCount == 1 && _methodResolvers != null)
                {
                    IEnumerable <Delegate> resolvers = _methodResolvers.GetInvocationList();

                    if (resolvers.Any())
                    {
                        MethodInfo methodInfo = new MethodInfo(info);

                        lock (JitLock)
                        {
                            if (_framework.CEEInfoVTable == IntPtr.Zero)
                            {
                                _framework.ReadICorJitInfoVTable(comp);

                                _hookManager.InjectHook(CEEInfo.ResolveTokenIndex, _resolveToken);
                                _hookManager.InjectHook(CEEInfo.ConstructStringLiteralIndex, _constructStringLiteral);
                            }
                        }

                        if (methodInfo.Module != null)
                        {
                            uint       methodToken = CEEInfo.GetMethodDefFromMethod(methodInfo.MethodDesc);
                            MethodBase methodFound = methodInfo.Module.ResolveMethod((int)methodToken);
                            _tokenTls = new TokenTls {
                                Root = methodFound
                            };

                            methodContext = new MethodContext(methodFound);
                            foreach (MethodResolverHandler resolver in resolvers)
                            {
                                resolver(methodContext);

                                if (methodContext.IsResolved)
                                {
                                    break;
                                }
                            }
                        }

                        if (methodContext != null && methodContext.IsResolved)
                        {
                            int ilLength;

                            if (methodContext.Mode == MethodContext.ResolveMode.IL)
                            {
                                MethodBody methodBody = methodContext.MethodBody;

                                ilLength = methodBody.IL.Length;

                                ilAddress = methodBody.IL.ToPointer();

                                if (methodBody.HasLocalVariable)
                                {
                                    byte[] signatureVariables = methodBody.GetSignatureVariables();
                                    sigAddress = signatureVariables.ToPointer();

                                    methodInfo.Locals.Signature = sigAddress + 1;
                                    methodInfo.Locals.Args      = sigAddress + 3;
                                    methodInfo.Locals.NumArgs   = (ushort)methodBody.LocalVariables.Count;
                                }

                                methodInfo.MaxStack = methodBody.MaxStackSize;
                            }
                            else
                            {
                                (ilAddress, ilLength) = PrepareIL(methodContext);

                                if (methodInfo.MaxStack < 8)
                                {
                                    methodInfo.MaxStack = 8;
                                }
                            }

                            methodInfo.EHCount    = methodContext.MethodBody.EHCount;
                            methodInfo.ILCode     = ilAddress;
                            methodInfo.ILCodeSize = (uint)ilLength;
                        }
                    }
                }

                CorJitResult result = _framework.CompileMethod(thisPtr, comp, info, flags, out nativeEntry, out nativeSizeOfCode);

                if (ilAddress != IntPtr.Zero && methodContext !.Mode == MethodContext.ResolveMode.IL)
                {
                    Marshal.FreeHGlobal(ilAddress);
                }

                if (sigAddress != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(sigAddress);
                }

                if (methodContext?.Mode == MethodContext.ResolveMode.NATIVE)
                {
                    Marshal.Copy(methodContext.NativeCode !, 0, nativeEntry, methodContext.NativeCode !.Length);
                }

                return(result);
            }
            finally
            {
                _compileTls.EnterCount--;
            }
        }