// // Copyright (C) 2006 United States Government as represented by the // Administrator of the National Aeronautics and Space Administration // (NASA). All Rights Reserved. // // This software is distributed under the NASA Open Source Agreement // (NOSA), version 1.3. The NOSA has been approved by the Open Source // Initiative. See the file NOSA-1.3-JPF at the top of the distribution // directory tree for the complete NOSA document. // // THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY // KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT // LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO // SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR // A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT // THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT // DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. // package gov.nasa.jpf.vm; import gov.nasa.jpf.util.ImmutableList; public class DefaultBacktracker<KState> implements Backtracker { /** where we keep the saved KernelState head */ protected ImmutableList<KState> kstack; /** and that adds the SystemState specifics */ protected ImmutableList<Object> sstack; protected SystemState ss; protected StateRestorer<KState> restorer; public void attach(VM vm) { ss = vm.getSystemState(); restorer = vm.getRestorer(); } //--- the backtrack support (depth first only) protected void backtrackKernelState() { KState data = kstack.head; kstack = kstack.tail; restorer.restore(data); } protected void backtrackSystemState() { Object o = sstack.head; sstack = sstack.tail; ss.backtrackTo(o); } /** * Moves one step backward. This method and forward() are the main methods * used by the search object. * Note this is called with the state that caused the backtrack still being on * the stack, so we have to remove that one first (i.e. popping two states * and restoring the second one) */ @Override public boolean backtrack () { if (sstack != null) { backtrackKernelState(); backtrackSystemState(); return true; } else { // we are back to the top of where we can backtrack to return false; } } /** * Saves the state of the system. */ @Override public void pushKernelState () { kstack = new ImmutableList<KState>(restorer.getRestorableData(),kstack); } /** * Saves the backtracking information. */ @Override public void pushSystemState () { sstack = new ImmutableList<Object>(ss.getBacktrackData(),sstack); } //--- the restore support // <2do> this saves both the backtrack and the restore data - too redundant class RestorableStateImpl implements RestorableState { final ImmutableList<KState> savedKstack; final ImmutableList<Object> savedSstack; final KState kcur; final Object scur; RestorableStateImpl() { savedKstack = kstack; savedSstack = sstack; kcur = restorer.getRestorableData(); scur = ss.getRestoreData(); } void restore() { kstack = savedKstack; sstack = savedSstack; restorer.restore(kcur); ss.restoreTo(scur); } } @SuppressWarnings("unchecked") @Override public void restoreState (RestorableState state) { ((RestorableStateImpl) state).restore(); } @Override public RestorableState getRestorableState() { return new RestorableStateImpl(); } }