Example #1
0
        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());
        }
Example #3
0
        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));
        }