public void SetMethodInfo(MMethod methodInfo) { this.methodInfo = methodInfo; methodReturnType = ResolverUtils.GetReturnType(methodInfo.methodBase); methodParameters = GetMethodParameterTypes(methodInfo.methodBase); delegateType = Utils.GetDelegateType(methodReturnType, methodParameters); }
public RewrittenMethod CreateDelegate(MethodBase realMethod) { var newMethodInfo = realMethodToNewMethod[realMethod]; if (newMethodInfo.rewrittenMethod != null) { return(newMethodInfo.rewrittenMethod); } var dm = new DynamicMethod(newMethodInfo.rewrittenMethodName, typeof(object), new Type[] { GetType(), typeof(object[]) }, newMethodInfo.oldMethod.Module, true); var ilg = dm.GetILGenerator(); ilg.Emit(ROpCodes.Ldarg_0); ilg.Emit(ROpCodes.Ldc_I4, newMethodInfo.delegateIndex); ilg.Emit(ROpCodes.Call, GetType().GetMethod("RtGetDelegateInstance", BindingFlags.DeclaredOnly | BindingFlags.NonPublic | BindingFlags.Instance)); ilg.Emit(ROpCodes.Castclass, newMethodInfo.delegateType); var args = newMethodInfo.oldMethod.GetParameters(); for (int i = 0; i < args.Length; i++) { var arg = args[i].ParameterType; ilg.Emit(ROpCodes.Ldarg_1); ilg.Emit(ROpCodes.Ldc_I4, i); ilg.Emit(ROpCodes.Ldelem_Ref); if (arg.IsValueType) { ilg.Emit(ROpCodes.Unbox_Any, arg); } else { ilg.Emit(ROpCodes.Castclass, arg); } } ilg.Emit(ROpCodes.Ldarg_0); var flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance; var invokeMethod = newMethodInfo.delegateType.GetMethod("Invoke", flags); ilg.Emit(ROpCodes.Call, invokeMethod); if (ResolverUtils.GetReturnType(newMethodInfo.oldMethod) == typeof(void)) { ilg.Emit(ROpCodes.Ldnull); } ilg.Emit(ROpCodes.Ret); newMethodInfo.rewrittenMethod = (RewrittenMethod)dm.CreateDelegate(typeof(RewrittenMethod), this); return(newMethodInfo.rewrittenMethod); }