/// <summary> /// Steps back a single instruction. Throws a HistoryEmptyRuntimeException /// if the history of the VM is empty. /// </summary> public void StepBack() { if (!VirtualMachine.Data.Uncommit()) { throw new HistoryEmptyRuntimeException(new ushort[] { 0 }, VirtualMachine.Data.DirectPC); } DataDelta uncommited = VirtualMachine.Data.Delta; VirtualMachine.Data.Rollback(); // The breakpoint checker executes an instruction in advance to determine // whether it will trigger any breakpoints. // Since we are undoing an instruction, we already know its effect, // so we are informing the checker here. BreakpointChecker.SetNextDelta(uncommited, VirtualMachine.Data.DirectPC); }
/// <summary> /// Calculates the effects of the next instruction. /// </summary> /// <remarks> /// This calculation in advance allows breakpoints to be hit BEFORE the /// actual execution. /// </remarks> /// <returns>A value holding the effects of the instruction.</returns> protected DataDelta CalculateNextDelta() { Data data = Target.VirtualMachine.Data; if (_processor == null || _processor.Data != data) { _processor = new Processor(data, _nullDevice); } data.Commit(); // Commits any previous changes try { _processor.Step(); } // Execute next instruction (breakpoint probe). catch (Exception) { } DataDelta result = data.Delta; // Delta object holds the changes made by the probe if (!data.Uncommit()) // Uncommit restores previous Delta object from history and discards the probe changes. { // If uncommit fails, we need to manually discard probe changes by calling Rollback(). data.Rollback(); } return(result); }
/// <summary> /// Sets the NextDelta and the corresponding PC. /// </summary> /// <remarks> /// This method should be used when stepping back to avoid /// reexecuting the undone instruction in CalculateNextDelta. /// </remarks> /// <param name="nextDelta">The Delta of the next instruction</param> /// <param name="pc">The address of the instruction</param> public void SetNextDelta(DataDelta nextDelta, ushort pc) { _nextDelta = nextDelta; _nextDeltaPC = pc; }