예제 #1
0
        /// <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);
        }
예제 #2
0
 /// <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);
     }
 }
예제 #3
0
 /// <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);
     }
 }