public static Instruction FindObjectInstance(this CilBody body, Instruction methodInvokeInstruction) { if (body == null) { throw new ArgumentNullException(nameof(body)); } if (methodInvokeInstruction == null) { throw new ArgumentNullException(nameof(methodInvokeInstruction)); } if (!(methodInvokeInstruction.Operand is IMethodDefOrRef target) || !target.MethodSig.HasThis) { throw new ArgumentOutOfRangeException(nameof(methodInvokeInstruction)); } // instance type is the declaring type when `HasThis` bit is set to true var type = target.DeclaringType; var instructions = body.Instructions; for (var index = instructions.IndexOf(methodInvokeInstruction); index > 0; index--) { var instruction = instructions[index]; if (instruction.OpCode == OpCodes.Call && instruction.Operand is IMethodDefOrRef method) { if (method.MethodSig.RetType.ToTypeDefOrRef() == type) { return(instruction); } } else if (instruction.IsLdloc()) { var local = instruction.GetLocal(body.Variables); if (local.Type.ToTypeDefOrRef() == type) { var src = body.FindSource(local, instruction); if (src != null) { return(src); } } } } return(null); }