public bool DoPatch(Queue <CodeInstruction> buffer, int origPos, int written) { if (buffer.Count < match.Length) { return(false); } if (QuickPatcher.StartsWith(buffer, match)) { //match! if (Target == null) { throw new Exception("Can't steal labels, target not set!"); } var enumr = buffer.GetEnumerator(); for (int i = 0; i < markOffset; i++) { enumr.MoveNext(); } enumr.MoveNext(); var mark = enumr.Current; if (mark.labels.Count == 0) { throw new Exception("Can't steal labels, mark didn't have any labels to steal!"); } foreach (var label in mark.labels) { Target.labels.Add(label); } mark.labels.Clear(); PatchedOriginalLocation = origPos; PatchedWrittenLocation = written; if (DebugVerbosity >= 1) { Debug.Log(string.Format("PATCH: Stole {6} labels from [{2} {3}], gave them to [{4} {5}] at {0} / {1} ", PatchedOriginalLocation, PatchedWrittenLocation, mark.opcode, mark.operand, Target.opcode, Target.operand, Target.labels.Count)); } return(true); } return(false); }
public bool DoPatch(Queue <CodeInstruction> buffer, int origPos, int written) { if (buffer.Count < match.Length) { return(false); } if (QuickPatcher.StartsWith(buffer, match)) { //match! if (insert != null) { //Debug.Log("Before: \n" + string.Join("\n", new List<string>(buffer.Select(i => i.ToString())).ToArray() ) ); if (!after) { //Ugh. C#'s Queue class kinda sucks. //This is like, the worst way to do this, but Queue's interface is so strict we don't have a choice. CodeInstruction[] orig = buffer.ToArray(); buffer.Clear(); foreach (var e in insert) { buffer.Enqueue(e); } foreach (var e in orig) { buffer.Enqueue(e); } } else { CodeInstruction[] orig = null; //If the buffer is exactly the size of the match, we can cheat, we *only* need to append the patch. if (buffer.Count != match.Length) { //Otherwise, we have to split the Queue to make sure our patch is inserted only after the match. orig = buffer.ToArray(); buffer.Clear(); //clear the buffer //Enqueue the match again. for (int i = 0; i < match.Length; i++) { buffer.Enqueue(orig[i]); } } //Enqueue the patch. foreach (var e in insert) { buffer.Enqueue(e); } //Append what's left of the buffer if necessary if (orig != null) { for (int i = match.Length; i < orig.Length; i++) { buffer.Enqueue(orig[i]); } } } //Debug.Log("After: \n" + string.Join("\n", new List<string>(buffer.Select(i => i.ToString())).ToArray())); } //else Null patch PatchedOriginalLocation = !after ? origPos : origPos + match.Length; PatchedWrittenLocation = !after ? written : written + match.Length; if (DebugVerbosity >= 1) { Debug.Log(string.Format("PATCH: Inserted patch ({2} instructions) at {0} / {1} ", PatchedOriginalLocation, PatchedWrittenLocation, insert == null ? 0 : insert.Length)); } return(true); } return(false); }