private void SaveInvocationInfo(CilWorker IL, MethodReference targetMethod, ModuleDefinition module, TypeReference returnType) { // If the target method is an instance method, then the remaining item on the stack // will be the target object instance // Put all the method arguments into the argument stack foreach (ParameterReference param in targetMethod.Parameters) { // Save the current argument var parameterType = param.ParameterType; if (parameterType.IsValueType || parameterType is GenericParameter) IL.Emit(OpCodes.Box, parameterType); IL.Emit(OpCodes.Stloc, _currentArgument); IL.Emit(OpCodes.Ldloc, _currentArguments); IL.Emit(OpCodes.Ldloc, _currentArgument); IL.Emit(OpCodes.Callvirt, _pushMethod); } // Static methods will always have a null reference as the target if (!targetMethod.HasThis) IL.Emit(OpCodes.Ldnull); // Box the target, if necessary var declaringType = targetMethod.GetDeclaringType(); if (targetMethod.HasThis && (declaringType.IsValueType || declaringType is GenericParameter)) IL.Emit(OpCodes.Box, declaringType); // Save the target IL.Emit(OpCodes.Stloc, _target); IL.Emit(OpCodes.Ldloc, _target); // Push the current method IL.PushMethod(targetMethod, module); // Push the stack trace PushStackTrace(IL, module); var systemType = module.Import(typeof(Type)); // Save the parameter types var parameterCount = targetMethod.Parameters.Count; IL.Emit(OpCodes.Ldc_I4, parameterCount); IL.Emit(OpCodes.Newarr, systemType); IL.Emit(OpCodes.Stloc, _parameterTypes); IL.SaveParameterTypes(targetMethod, module, _parameterTypes); IL.Emit(OpCodes.Ldloc, _parameterTypes); // Save the type arguments var genericParameterCount = targetMethod.GenericParameters.Count; IL.Emit(OpCodes.Ldc_I4, genericParameterCount); IL.Emit(OpCodes.Newarr, systemType); IL.Emit(OpCodes.Stloc, _typeArguments); IL.PushGenericArguments(targetMethod, module, _typeArguments); IL.Emit(OpCodes.Ldloc, _typeArguments); // Push the return type IL.PushType(returnType, module); // Save the method arguments IL.Emit(OpCodes.Ldloc, _currentArguments); IL.Emit(OpCodes.Callvirt, _toArray); IL.Emit(OpCodes.Newobj, _invocationInfoCtor); IL.Emit(OpCodes.Stloc, _invocationInfo); }