/* This file is part of the db4o object database http://www.db4o.com Copyright (C) 2004 - 2011 Versant Corporation http://www.versant.com db4o is free software; you can redistribute it and/or modify it under the terms of version 3 of the GNU General Public License as published by the Free Software Foundation. db4o is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. */ package EDU.purdue.cs.bloat.cfg; import java.util.*; import EDU.purdue.cs.bloat.tree.*; /** * <tt>ReplaceTarget</tt> replaces the block that is the target of a * <tt>JumpStmt</tt>, <tt>JsrStmt</tt>, <tt>RetStmt</tt>, * <tt>GotoStmt</tt>, <tt>SwitchStmt</tt>, or <tt>IfStmt</tt> with * another <tt>Block</tt>. */ public class ReplaceTarget extends TreeVisitor { Block oldDst; Block newDst; public ReplaceTarget(final Block oldDst, final Block newDst) { this.oldDst = oldDst; this.newDst = newDst; } public void visitTree(final Tree tree) { final Stmt last = tree.lastStmt(); if (last instanceof JumpStmt) { final JumpStmt stmt = (JumpStmt) last; if (FlowGraph.DEBUG) { System.out.println(" Replacing " + oldDst + " with " + newDst + " in " + stmt); } if (stmt.catchTargets().remove(oldDst)) { stmt.catchTargets().add(newDst); } stmt.visit(this); } } public void visitJsrStmt(final JsrStmt stmt) { if (stmt.sub().entry() == oldDst) { if (FlowGraph.DEBUG) { System.out.print(" replacing " + stmt); } stmt.block().graph().setSubEntry(stmt.sub(), newDst); if (FlowGraph.DEBUG) { System.out.println(" with " + stmt); } } } public void visitRetStmt(final RetStmt stmt) { final Iterator paths = stmt.sub().paths().iterator(); while (paths.hasNext()) { final Block[] path = (Block[]) paths.next(); if (FlowGraph.DEBUG) { System.out.println(" path = " + path[0] + " " + path[1]); } if (path[1] == oldDst) { if (FlowGraph.DEBUG) { System.out.println(" replacing ret to " + oldDst + " with ret to " + newDst); } path[1] = newDst; ((JsrStmt) path[0].tree().lastStmt()).setFollow(newDst); } } } public void visitGotoStmt(final GotoStmt stmt) { if (stmt.target() == oldDst) { if (FlowGraph.DEBUG) { System.out.print(" replacing " + stmt); } stmt.setTarget(newDst); if (FlowGraph.DEBUG) { System.out.println(" with " + stmt); } } } public void visitSwitchStmt(final SwitchStmt stmt) { if (stmt.defaultTarget() == oldDst) { if (FlowGraph.DEBUG) { System.out.print(" replacing " + stmt); } stmt.setDefaultTarget(newDst); if (FlowGraph.DEBUG) { System.out.println(" with " + stmt); } } final Block[] targets = stmt.targets(); for (int i = 0; i < targets.length; i++) { if (targets[i] == oldDst) { if (FlowGraph.DEBUG) { System.out.print(" replacing " + stmt); } targets[i] = newDst; if (FlowGraph.DEBUG) { System.out.println(" with " + stmt); } } } } public void visitIfStmt(final IfStmt stmt) { if (stmt.trueTarget() == oldDst) { if (FlowGraph.DEBUG) { System.out.print(" replacing " + stmt); } stmt.setTrueTarget(newDst); if (FlowGraph.DEBUG) { System.out.println(" with " + stmt); } } if (stmt.falseTarget() == oldDst) { if (FlowGraph.DEBUG) { System.out.print(" replacing " + stmt); } stmt.setFalseTarget(newDst); if (FlowGraph.DEBUG) { System.out.println(" with " + stmt); } } } }