/// <summary> /// Creates a new <see cref="InstructionCloner"/>. /// </summary> /// <param name="parent">Method body cloner associated with new instruction cloner.</param> /// <param name="previous">Cloner for the previous instruction, if any.</param> /// <param name="possiblyReferencedVariables">Collection of variables that may be referenced by the source instruction.</param> /// <param name="source">Cloning source.</param> /// <param name="referencedVariableIndexTranslation">Optional translation that should be applied to the possible variable reference due to added or removed variables.</param> /// <param name="argumentIndexTranslation">Optional translation that should be applied to possible argment references, e.g. to add or remove <c>this</c> parameter in translation to or from <c>static</c> methods</param> /// <param name="instructionInsertAction">Override default instruction add behavior by sending a custom action.</param> /// <remarks> /// By default, an instruction is inserted after the previous instruction, and an instruction with no previous instruction, as /// specified by <paramref name="previous"/>, will be appended to the end of the target method. If a delegate is supplied in /// in <paramref name="instructionInsertAction"/>, then the delegate will be run instead. /// </remarks> public InstructionCloner( ICloneToMethodBody <object> parent, InstructionCloner previous, Instruction source, IEnumerable <VariableDefinition> possiblyReferencedVariables = null, int referencedVariableIndexTranslation = 0, int argumentIndexTranslation = 0, Action <ILProcessor, ICloneToMethodBody <object>, InstructionCloner, Instruction, Instruction> instructionInsertAction = null) : base(parent.CloningContext, source) { Contract.Requires(parent != null); Contract.Requires(parent.CloningContext != null); Contract.Requires(source != null); Contract.Ensures(this.Parent != null); Contract.Ensures(this.PossiblyReferencedVariables != null); Contract.Ensures(this.InstructionInsertAction != null); Contract.Ensures(this.TargetInstructionCreator != null); Contract.Ensures(this.OperandImporter != null); this.Parent = parent; this.Previous = previous; this.PossiblyReferencedVariables = possiblyReferencedVariables ?? new VariableDefinition[0]; this.ReferencedVariableIndexTranslation = referencedVariableIndexTranslation; this.ArgumentIndexTranslation = argumentIndexTranslation; this.InstructionInsertAction = instructionInsertAction ?? InstructionCloner.DefaultInstructionInsertAction; this.TargetInstructionCreator = new InstructionCreateDispatcher(parent.CloningContext); this.OperandImporter = new OperandImportDispatcher( parent.CloningContext, this.Parent.SourceThisParameter, this.Parent.Target.ThisParameter); }
/// <summary> /// Default action for inserting the target instruction. /// </summary> /// <param name="ilProcessor">IL processor to use in inserting the instruction.</param> /// <param name="parent">Cloner for the method body containing the instruction being cloned.</param> /// <param name="previous">Cloner for the previous instruction being cloned, if any.</param> /// <param name="source">Source instruction.</param> /// <param name="target">Target instruction</param> public static void DefaultInstructionInsertAction( ILProcessor ilProcessor, ICloneToMethodBody <object> parent, InstructionCloner previous, Instruction source, Instruction target) { if (previous == null) { ilProcessor.Append(target); } else { ilProcessor.InsertAfter(previous.Target, target); } }
/// <summary> /// Action for inserting the target instruction in such a way that cloned instructions appear before any existing /// instructions in the target method body. /// </summary> /// <param name="ilProcessor">IL processor to use in inserting the instruction.</param> /// <param name="parent">Cloner for the method body containing the instruction being cloned.</param> /// <param name="previous">Cloner for the previous instruction being cloned, if any.</param> /// <param name="source">Source instruction.</param> /// <param name="target">Target instruction</param> public static void InsertBeforeExistingInstructionInsertAction( ILProcessor ilProcessor, ICloneToMethodBody <object> parent, InstructionCloner previous, Instruction source, Instruction target) { if (previous == null) { if (parent.Target.Instructions.Count == 0) { ilProcessor.Append(target); } else { ilProcessor.InsertBefore(parent.Target.Instructions[0], target); } } else { ilProcessor.InsertAfter(previous.Target, target); } }