コード例 #1
0
        private static void PatchDistributedUpdate(PatchContext ctx, MethodBase callerMethod)
        {
            var foundAnyIterate = false;
            var msil            = PatchUtilities.ReadInstructions(callerMethod).ToList();

            for (var i = 0; i < msil.Count; i++)
            {
                var insn = msil[i];
                if ((insn.OpCode != OpCodes.Callvirt && insn.OpCode != OpCodes.Call) ||
                    !IsDistributedIterate((insn.Operand as MsilOperandInline <MethodBase>)?.Value as MethodInfo))
                {
                    continue;
                }

                foundAnyIterate = true;
                // Call to Iterate().  Backtrace up the instruction stack to find the statement creating the delegate.
                var foundNewDel = false;
                for (var j = i - 1; j >= 1; j--)
                {
                    var insn2 = msil[j];
                    if (insn2.OpCode != OpCodes.Newobj)
                    {
                        continue;
                    }
                    var ctorType = (insn2.Operand as MsilOperandInline <MethodBase>)?.Value?.DeclaringType;
                    if (ctorType == null || !ctorType.IsGenericType || ctorType.GetGenericTypeDefinition() != typeof(Action <>))
                    {
                        continue;
                    }
                    foundNewDel = true;
                    // Find the instruction loading the function pointer this delegate is created with
                    var ldftn = msil[j - 1];
                    if (ldftn.OpCode != OpCodes.Ldftn ||
                        !(ldftn.Operand is MsilOperandInline <MethodBase> targetMethod))
                    {
                        Log.Error(
                            $"Unable to find ldftn instruction for call to Iterate in {callerMethod.DeclaringType}#{callerMethod}");
                    }
                    else
                    {
                        Log.Debug(
                            $"Patching {targetMethod.Value.DeclaringType}#{targetMethod.Value} for {callerMethod.DeclaringType}#{callerMethod}");
                        PatchDistUpdateDel(ctx, targetMethod.Value);
                    }

                    break;
                }

                if (!foundNewDel)
                {
                    Log.Error(
                        $"Unable to find new Action() call for Iterate in {callerMethod.DeclaringType}#{callerMethod}");
                }
            }

            if (!foundAnyIterate)
            {
                Log.Error($"Unable to find any calls to {_distributedUpdaterIterate} in {callerMethod.DeclaringType}#{callerMethod}");
            }
        }
コード例 #2
0
ファイル: FixedLoop_Run.cs プロジェクト: HnZGaming/Profiler
        static MethodBase FindAction(MethodBase caller)
        {
            var msil = PatchUtilities.ReadInstructions(caller).ToList();

            for (var i = 0; i < msil.Count; i++)
            {
                Log.Trace($"insn: {i} {msil[i]}");

                var newobj = msil[i];
                if (newobj.OpCode != OpCodes.Newobj)
                {
                    continue;
                }

                Log.Trace("newobj found");

                var newobjType = (newobj.Operand as MsilOperandInline <MethodBase>)?.Value?.DeclaringType;
                if (newobjType == null)
                {
                    continue;
                }
                if (newobjType != typeof(GenericLoop.VoidAction))
                {
                    continue;
                }

                var ldftn = msil[i - 1];
                Log.Trace($"ldftn found: {ldftn}");

                if (ldftn.OpCode != OpCodes.Ldftn)
                {
                    continue;
                }
                if (!(ldftn.Operand is MsilOperandInline <MethodBase> action))
                {
                    continue;
                }

                return(action.Value);
            }

            throw new Exception("Failed to patch: action not found in FixedLoop.Run()");
        }