/// <summary>
        /// Clone a source method body to a target method definition.
        /// Field/Method/Type references are corrected
        /// </summary>
        /// <param name="source">Source method definition</param>
        /// <param name="target">Target method definition</param>
        public static void CloneMethodBody(MethodDefinition source, MethodDefinition target)
        {
            var newBody = CloneMethodBody(source.Body, source, target);
            target.Body = newBody;

            target.Body.ComputeOffsets();
        }
        /// <summary>
        /// Clone a source method body to a target method definition. Optimze and fix IL code.
        /// Field/Method/Type references are corrected
        /// </summary>
        /// <param name="source">Source method definition</param>
        /// <param name="target">Target method definition</param>
        public static void CloneMethodBody(MethodDefinition source, MethodDefinition target, bool OptimizeAndFixIL)
        {
            var newBody = CloneMethodBody(source.Body, source, target);
            target.Body = newBody;

            if (OptimizeAndFixIL)
            {
                // this will also call ComputeOffsets
                target.Body.SimplifyMacros();
                target.Body.OptimizeMacros();
            }
            else
            {
                target.Body.ComputeOffsets();
            }
        }
        public static ParameterDefinition CloneParameterDefinition(ParameterDefinition param, MethodDefinition owner)
        {
            var context = owner.Module;
            var np = new ParameterDefinition(
                param.Name,
                param.Attributes,
                context.Import(param.ParameterType));

            if (param.HasConstant)
                np.Constant = param.Constant;

            if (param.MarshalInfo != null)
                np.MarshalInfo = new MarshalInfo(param.MarshalInfo.NativeType);

            foreach (var ca in param.CustomAttributes)
                np.CustomAttributes.Add(CustomAttribute.Clone(ca, context));

            return np;
        }
 public bool TryGetOverrideMapping(MethodDefinition method, out MetadataToken[] mapping)
 {
     return Overrides.TryGetValue(method.token.RID, out mapping);
 }
 public void RemoveOverrideMapping(MethodDefinition method)
 {
     Overrides.Remove(method.token.RID);
 }
 public void AddMethodDefinition(MethodDefinition method)
 {
     Methods[method.token.RID - 1] = method;
 }
        private static TypeReference FixTypeImport(ModuleDefinition context, MethodDefinition source, MethodDefinition target,
            TypeReference type)
        {
            if (type.FullName == source.DeclaringType.FullName)
                return target.DeclaringType;

            return context.Import(type);
        }
        private static MethodReference FixMethodImport(ModuleDefinition context, MethodDefinition source,
            MethodDefinition target, MethodReference method)
        {
            if (method.DeclaringType.FullName == source.DeclaringType.FullName)
                return FindMatchingMethod(target.DeclaringType, method);

            return context.Import(method);
        }
        private static FieldReference FixFieldImport(ModuleDefinition context, MethodDefinition source,
            MethodDefinition target, FieldReference field)
        {
            if (field.DeclaringType.FullName == source.DeclaringType.FullName)
                return FindMatchingField(target.DeclaringType, field);

            return context.Import(field);
        }
Esempio n. 10
0
        private static MethodBody CloneMethodBody(MethodBody body, MethodDefinition source, MethodDefinition target)
        {
            var context = target.DeclaringType.Module;
            var nb = new MethodBody(target)
            {
                MaxStackSize = body.MaxStackSize,
                InitLocals = body.InitLocals,
                CodeSize = body.CodeSize
            };

            var worker = nb.GetILProcessor();

            foreach (var var in body.Variables)
                nb.Variables.Add(new VariableDefinition(
                    var.Name, FixTypeImport(context, source, target, var.VariableType)));

            foreach (var instr in body.Instructions)
            {
                var ni = new Instruction(instr.OpCode, OpCodes.Nop);

                switch (instr.OpCode.OperandType)
                {
                    case OperandType.InlineArg:
                    case OperandType.ShortInlineArg:
                        if (instr.Operand == body.ThisParameter)
                            ni.Operand = nb.ThisParameter;
                        else
                        {
                            var param = body.Method.Parameters.IndexOf((ParameterDefinition)instr.Operand);
                            ni.Operand = target.Parameters[param];
                        }
                        break;
                    case OperandType.InlineVar:
                    case OperandType.ShortInlineVar:
                        var var = body.Variables.IndexOf((VariableDefinition)instr.Operand);
                        ni.Operand = nb.Variables[var];
                        break;
                    case OperandType.InlineField:
                        ni.Operand = FixFieldImport(context, source, target, (FieldReference)instr.Operand);
                        break;
                    case OperandType.InlineMethod:
                        ni.Operand = FixMethodImport(context, source, target, (MethodReference)instr.Operand);
                        break;
                    case OperandType.InlineType:
                        ni.Operand = FixTypeImport(context, source, target, (TypeReference)instr.Operand);
                        break;
                    case OperandType.InlineTok:
                        if ((instr.Operand) is TypeReference)
                            ni.Operand = FixTypeImport(context, source, target, (TypeReference)instr.Operand);
                        else if ((instr.Operand) is FieldReference)
                            ni.Operand = FixFieldImport(context, source, target, (FieldReference)instr.Operand);
                        else if ((instr.Operand) is MethodReference)
                            ni.Operand = FixMethodImport(context, source, target, (MethodReference)instr.Operand);
                        break;
                    case OperandType.ShortInlineBrTarget:
                    case OperandType.InlineBrTarget:
                    case OperandType.InlineSwitch:
                        break;
                    default:
                        ni.Operand = instr.Operand;
                        break;
                }

                worker.Append(ni);
            }

            for (var i = 0; i < body.Instructions.Count; i++)
            {
                var instr = nb.Instructions[i];
                var oldi = body.Instructions[i];

                switch (instr.OpCode.OperandType)
                {
                    case OperandType.InlineSwitch:
                        {
                            var olds = (Instruction[])oldi.Operand;
                            var targets = new Instruction[olds.Length];

                            for (var j = 0; j < targets.Length; j++)
                                targets[j] = GetInstruction(body, nb, olds[j]);

                            instr.Operand = targets;
                        }
                        break;
                    case OperandType.InlineBrTarget:
                    case OperandType.ShortInlineBrTarget:
                        instr.Operand = GetInstruction(body, nb, (Instruction)oldi.Operand);
                        break;
                }
            }

            foreach (var eh in body.ExceptionHandlers)
            {
                var neh = new ExceptionHandler(eh.HandlerType)
                {
                    TryStart = GetInstruction(body, nb, eh.TryStart),
                    TryEnd = GetInstruction(body, nb, eh.TryEnd),
                    HandlerStart = GetInstruction(body, nb, eh.HandlerStart),
                    HandlerEnd = GetInstruction(body, nb, eh.HandlerEnd)
                };

                switch (eh.HandlerType)
                {
                    case ExceptionHandlerType.Catch:
                        neh.CatchType = FixTypeImport(context, source, target, eh.CatchType);
                        break;
                    case ExceptionHandlerType.Filter:
                        neh.FilterStart = GetInstruction(body, nb, eh.FilterStart);
                        break;
                }

                nb.ExceptionHandlers.Add(neh);
            }

            return nb;
        }
        static Collection<ParameterDefinition> MirrorParameters(MethodDefinition method, int bound)
        {
            var parameters = new Collection<ParameterDefinition>();
            if (!method.HasParameters)
                return parameters;

            var original_parameters = method.Parameters;
            var end = original_parameters.Count - bound;

            for (int i = 0; i < end; i++)
                parameters.Add(original_parameters[i]);

            return parameters;
        }