private void CloneInstructions(CilMethodBody body, CilMethodBody newBody) { var branchInstructions = new List <CilInstruction>(); var switchInstructions = new List <CilInstruction>(); foreach (var instruction in body.Instructions) { object operand = instruction.Operand; if (operand is IMemberReference) { operand = _importer.ImportReference((IMemberReference)operand); } var newInstruction = new CilInstruction(instruction.Offset, instruction.OpCode, operand); newBody.Instructions.Add(newInstruction); switch (instruction.OpCode.OperandType) { case CilOperandType.InlineBrTarget: case CilOperandType.ShortInlineBrTarget: branchInstructions.Add(newInstruction); break; case CilOperandType.InlineSwitch: switchInstructions.Add(newInstruction); break; } } foreach (var branch in branchInstructions) { branch.Operand = newBody.GetInstructionByOffset(((CilInstruction)branch.Operand).Offset); } foreach (var @switch in switchInstructions) { var targets = (IEnumerable <CilInstruction>)@switch.Operand; var newTargets = new List <CilInstruction>(); foreach (var target in targets) { newTargets.Add(newBody.GetInstructionByOffset(target.Offset)); } @switch.Operand = newTargets; } }
private void CloneExceptionHandlers(CilMethodBody body, CilMethodBody newBody) { foreach (var handler in body.ExceptionHandlers) { var newHandler = new ExceptionHandler(handler.HandlerType) { TryStart = newBody.GetInstructionByOffset(handler.TryStart.Offset), TryEnd = newBody.GetInstructionByOffset(handler.TryEnd.Offset), HandlerStart = newBody.GetInstructionByOffset(handler.HandlerStart.Offset), HandlerEnd = newBody.GetInstructionByOffset(handler.HandlerEnd.Offset), }; if (handler.FilterStart != null) { newHandler.FilterStart = newBody.GetInstructionByOffset(handler.FilterStart.Offset); } if (handler.CatchType != null) { newHandler.CatchType = _importer.ImportType(handler.CatchType); } newBody.ExceptionHandlers.Add(newHandler); } }