From 8383eb440f68461b18de15027cf6ffe076c24d2d Mon Sep 17 00:00:00 2001 From: Juergen Graf Date: Mon, 5 Nov 2012 21:30:59 +0100 Subject: [PATCH] make mutable cfg an actual control flow graph --- .../ibm/wala/cfg/exc/intra/MutableCFG.java | 115 +++++++++++++++++- 1 file changed, 112 insertions(+), 3 deletions(-) diff --git a/com.ibm.wala.core/src/com/ibm/wala/cfg/exc/intra/MutableCFG.java b/com.ibm.wala.core/src/com/ibm/wala/cfg/exc/intra/MutableCFG.java index 8927c7cef..bd880b7c3 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/cfg/exc/intra/MutableCFG.java +++ b/com.ibm.wala.core/src/com/ibm/wala/cfg/exc/intra/MutableCFG.java @@ -1,8 +1,16 @@ package com.ibm.wala.cfg.exc.intra; +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + import com.ibm.wala.cfg.ControlFlowGraph; import com.ibm.wala.cfg.IBasicBlock; +import com.ibm.wala.classLoader.IMethod; import com.ibm.wala.util.graph.impl.SparseNumberedGraph; +import com.ibm.wala.util.intset.BitVector; +import com.ibm.wala.util.intset.IntSet; /** * A modifiable control flow graph. @@ -10,13 +18,16 @@ import com.ibm.wala.util.graph.impl.SparseNumberedGraph; * @author Juergen Graf * */ -public class MutableCFG> extends SparseNumberedGraph { +public class MutableCFG> extends SparseNumberedGraph implements ControlFlowGraph { - private MutableCFG() { + private final ControlFlowGraph orig; + + private MutableCFG(final ControlFlowGraph orig) { + this.orig = orig; } public static > MutableCFG copyFrom(ControlFlowGraph cfg) { - MutableCFG mutable = new MutableCFG(); + MutableCFG mutable = new MutableCFG(cfg); for (T node : cfg) { mutable.addNode(node); @@ -34,5 +45,103 @@ public class MutableCFG> extends SparseNumberedGraph return mutable; } + + public T entry() { + return orig.entry(); + } + + public T exit() { + return orig.exit(); + } + + // slow + public BitVector getCatchBlocks() { + final BitVector bvOrig = orig.getCatchBlocks(); + final BitVector bvThis = new BitVector(); + + for (final T block : this) { + bvThis.set(block.getNumber()); + } + + bvThis.and(bvOrig); + + return bvThis; + } + + public T getBlockForInstruction(int index) { + final T block = orig.getBlockForInstruction(index); + + return (containsNode(block) ? block : null); + } + + public X[] getInstructions() { + return orig.getInstructions(); + } + + public int getProgramCounter(int index) { + return orig.getProgramCounter(index); + } + + public IMethod getMethod() { + return orig.getMethod(); + } + + public List getExceptionalSuccessors(T b) { + final List origSucc = orig.getExceptionalSuccessors(b); + final IntSet allSuccs = this.getSuccNodeNumbers(b); + final List thisSuccs = new LinkedList(); + + for (final T block : origSucc) { + if (allSuccs.contains(block.getNumber())) { + thisSuccs.add(block); + } + } + + return thisSuccs; + } + + public Collection getNormalSuccessors(T b) { + final List excSuccs = getExceptionalSuccessors(b); + final List thisSuccs = new LinkedList(); + + final Iterator succs = getSuccNodes(b); + while (succs.hasNext()) { + final T succ = succs.next(); + if (!excSuccs.contains(succ)) { + thisSuccs.add(succ); + } + } + + return thisSuccs; + } + + public Collection getExceptionalPredecessors(T b) { + final Collection origPreds = orig.getExceptionalPredecessors(b); + final IntSet allPreds = this.getPredNodeNumbers(b); + final List thisPreds = new LinkedList(); + + for (final T block : origPreds) { + if (allPreds.contains(block.getNumber())) { + thisPreds.add(block); + } + } + + return thisPreds; + } + + public Collection getNormalPredecessors(T b) { + final Collection excPreds = getExceptionalPredecessors(b); + final List thisPreds = new LinkedList(); + + final Iterator preds = getPredNodes(b); + while (preds.hasNext()) { + final T pred = preds.next(); + if (!excPreds.contains(pred)) { + thisPreds.add(pred); + } + } + + return thisPreds; + } } \ No newline at end of file