public DynamicMethod CreateCopy(MethodBase method) { MethodBody body = method.GetMethodBody(); if (body == null) { throw new InvalidOperationException("P/Invoke methods cannot be copied!"); } ParameterInfo[] args = method.GetParameters(); Type[] argTypes; if (!method.IsStatic) { argTypes = new Type[args.Length + 1]; argTypes[0] = method.DeclaringType; for (int i = 0; i < args.Length; i++) { argTypes[i + 1] = args[i].ParameterType; } } else { argTypes = new Type[args.Length]; for (int i = 0; i < args.Length; i++) { argTypes[i] = args[i].ParameterType; } } DynamicMethod dm = new DynamicMethod( $"orig_{method.Name}", // method.Attributes, method.CallingConvention, // DynamicMethod only supports public, static and standard (method as MethodInfo)?.ReturnType ?? typeof(void), argTypes, method.DeclaringType, false ); ILGenerator il = dm.GetILGenerator(); // TODO: Move away from using Harmony's ILCopying code in MonoMod... List <Label> endLabels = new List <Label>(); List <Harmony.ILCopying.ExceptionBlock> endBlocks = new List <Harmony.ILCopying.ExceptionBlock>(); Harmony.ILCopying.MethodCopier copier = new Harmony.ILCopying.MethodCopier(method, il); copier.Finalize(endLabels, endBlocks); foreach (Label label in endLabels) { il.MarkLabel(label); } foreach (Harmony.ILCopying.ExceptionBlock block in endBlocks) { Harmony.ILCopying.Emitter.MarkBlockAfter(il, block); } return(dm.Pin()); }
public DynamicMethod CreateCopy(MethodBase method) { MethodBody body; try { body = method.GetMethodBody(); } catch (InvalidOperationException) { body = null; } if (body == null) { throw new InvalidOperationException("P/Invoke methods cannot be copied!"); } ParameterInfo[] args = method.GetParameters(); Type[] argTypes; if (!method.IsStatic) { argTypes = new Type[args.Length + 1]; argTypes[0] = method.DeclaringType; for (int i = 0; i < args.Length; i++) { argTypes[i + 1] = args[i].ParameterType; } } else { argTypes = new Type[args.Length]; for (int i = 0; i < args.Length; i++) { argTypes[i] = args[i].ParameterType; } } DynamicMethod dm = new DynamicMethod( $"orig_{method.Name}", // method.Attributes, method.CallingConvention, // DynamicMethod only supports public, static and standard (method as MethodInfo)?.ReturnType ?? typeof(void), argTypes, method.DeclaringType, false ); ILGenerator il = dm.GetILGenerator(); // TODO: Move away from using Harmony's ILCopying code in MonoMod... using (Harmony.ILCopying.MethodCopier copier = new Harmony.ILCopying.MethodCopier(method, il)) { copier.Copy(); } return(dm.Pin()); }
public static HarmonyDelegate Clone(MethodInfo source, TranspilerImpl transpiler = null) { var types = new List <Type>(source.GetParameters().Select(p => p.ParameterType)); if (source.IsStatic == false) { types.Insert(0, source.DeclaringType); } var dm = new System.Reflection.Emit.DynamicMethod("", source.ReturnType, types.ToArray()); var copier = new Harmony.ILCopying.MethodCopier(source, dm); copier.AddTranspiler(transpiler); copier.Emit(null); types.Add(source.ReturnType); // Use Expression to create Delegate type var delegateType = System.Linq.Expressions.Expression.GetDelegateType(types.ToArray()); var __delegate = dm.CreateDelegate(delegateType); return(new HarmonyDelegate(__delegate)); }