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--; } }
/// <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--; } }