private RegisterGroup(RegisterGroup toClone) { // Construct a new RegisterGroup from a $toClone by taking a deep copy of all the registers it contains. // If there was no deep copy, C# would shallow copy by default. This would mean that changing a register in $toClone // would change that register in $this, because they point to the same array in memory. // E.g // Without DeepCopy(), // $toClone = new byte[8] // $toClone[0] = 0x1 // $myRegGroup = $toClone // $myRegGroup[0] = 0x2 // Now $toClone[0] == 0x2 // With DeepCopy(), // $toClone = new byte[8] // $toClone[0] = 0x1 // $myRegGroup = $toClone.DeepCopy(); // $myRegGroup[0] = 0x2 // $toClone[0] == 0x1 // To put this in context, the Disassembler class takes a DeepCopy of the VM context, if it took a ShallowCopy, (such as $myRegGroup = $toClone), if a register changed in the // disassembler context, it would change in the VM context, exactly like in the example above. for (int i = 0; i < toClone.Registers.Length; i++) { Registers[i] = toClone.Registers[i].DeepCopy(); } }
private Context(Context toClone) { // Create a deep copy of each member in the context // This means that each variable will have a different instance, but with the same data as that of $toClone // If this wasn't used, changing addresses in $this.Memory would change the same addresses in $toClone.Memory // as with $Breakpoints and $Registers. However this isn't necessary for $Flags and $InstructionPointer because // they are value types--a deep copy is taken regardless. Flags = toClone.Flags; InstructionPointer = toClone.InstructionPointer; Memory = toClone.Memory.DeepCopy(); Breakpoints = toClone.Breakpoints.DeepCopy(); Registers = toClone.Registers.DeepCopy(); }