/// <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); }
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; }