/// <summary> /// Gets the instructions that generate the arguments for the call in the given instructions. /// </summary> public static Instruction[] GetCallArguments(this Instruction call, ILSequence sequence, bool includeThis) { var method = (MethodReference)call.Operand; var count = method.Parameters.Count; if (includeThis && method.HasThis) { count++; } var result = new Instruction[count]; var current = call; var height = count; for (int i = count - 1; i >= 0; i--) { // Look for the starting instruction where stack height is i while (result[i] == null) { var prevIndex = sequence.IndexOf(current); var prev = (prevIndex >= 1) ? sequence[prevIndex - 1] : null; if (prev == null) { throw new ArgumentException(string.Format("Cannot find arguments for call to {0}", method)); } height -= prev.GetPushDelta(); if (height == i) { result[i] = prev; } height += prev.GetPopDelta(0, true); current = prev; } } return(result); }
/// <summary> /// Insert this sequence just after the given instruction in of the given target collection. /// </summary> public void InsertToAfter(Instruction prev, ILSequence target) { InsertTo(target.IndexOf(prev) + 1, target); }
/// <summary> /// Insert this sequence to at the given index of the given target collection. /// </summary> public void InsertTo(int index, ILSequence target) { target.instructions.InsertRange(index, instructions); }
/// <summary> /// Insert this sequence just before the given instruction in of the given target collection. /// </summary> public void InsertToBefore(Instruction next, ILSequence target) { InsertTo(target.IndexOf(next), target); }
/// <summary> /// Add this sequence to the end of the given target collection. /// </summary> public void AppendTo(ILSequence target) { target.instructions.AddRange(instructions); }