Skip to content

Commit

Permalink
moved buildtraps API to JimplePrinter
Browse files Browse the repository at this point in the history
  • Loading branch information
sahilagichani14 committed Nov 9, 2024
1 parent 13388a1 commit a295490
Show file tree
Hide file tree
Showing 10 changed files with 91 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,6 @@ public Iterator<Stmt> iterator() {
return backingGraph.iterator();
}

@Nonnull
@Override
public List<Trap> buildTraps() {
return backingGraph.buildTraps();
}

@Override
public void removeExceptionalFlowFromAllBlocks(
@Nonnull ClassType exceptionType, @Nonnull Stmt exceptionHandlerStmt) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,6 @@ public boolean hasEdgeConnecting(@Nonnull Stmt source, @Nonnull Stmt target) {
throw new UnsupportedOperationException("Not implemented yet!");
}

@Nonnull
@Override
public List<Trap> buildTraps() {
throw new UnsupportedOperationException("Not implemented yet!");
}

@Override
public void removeExceptionalFlowFromAllBlocks(ClassType classType, Stmt exceptionHandlerStmt) {
throw new UnsupportedOperationException("Not implemented yet!");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1596,39 +1596,6 @@ public boolean hasEdgeConnecting(@Nonnull Stmt source, @Nonnull Stmt target) {
}
}

/** Comparator which sorts the trap output in getTraps() */
public Comparator<Trap> getTrapComparator(@Nonnull Map<Stmt, Integer> stmtsBlockIdx) {
return (a, b) ->
ComparisonChain.start()
.compare(stmtsBlockIdx.get(a.getBeginStmt()), stmtsBlockIdx.get(b.getBeginStmt()))
.compare(stmtsBlockIdx.get(a.getEndStmt()), stmtsBlockIdx.get(b.getEndStmt()))
// [ms] would be nice to have the traps ordered by exception hierarchy as well
.compare(a.getExceptionType().toString(), b.getExceptionType().toString())
.result();
}

/** hint: little expensive getter - its more of a build/create - currently no overlaps */
@Override
public List<Trap> buildTraps() {
// [ms] try to incorporate it into the serialisation of jimple printing so the other half of
// iteration information is not wasted..
BlockGraphIteratorAndTrapAggregator it =
new BlockGraphIteratorAndTrapAggregator(new MutableBasicBlockImpl());
// it.getTraps() is valid/completely build when the iterator is done.
Map<Stmt, Integer> stmtsBlockIdx = new IdentityHashMap<>();
int i = 0;
// collect BlockIdx positions to sort the traps according to the numbering
while (it.hasNext()) {
final BasicBlock<?> nextBlock = it.next();
stmtsBlockIdx.put(nextBlock.getHead(), i);
stmtsBlockIdx.put(nextBlock.getTail(), i);
i++;
}
final List<Trap> traps = it.getTraps();
traps.sort(getTrapComparator(stmtsBlockIdx));
return traps;
}

@Override
public void removeExceptionalFlowFromAllBlocks(
@Nonnull ClassType exceptionType, @Nonnull Stmt exceptionHandlerStmt) {
Expand Down
33 changes: 18 additions & 15 deletions sootup.core/src/main/java/sootup/core/graph/StmtGraph.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
*/
public abstract class StmtGraph<V extends BasicBlock<V>> implements Iterable<Stmt> {

public final JimplePrinter jimplePrinter = new JimplePrinter();

public abstract Stmt getStartingStmt();

public abstract BasicBlock<?> getStartingStmtBlock();
Expand Down Expand Up @@ -148,15 +150,6 @@ public int degree(@Nonnull Stmt node) {
*/
public abstract boolean hasEdgeConnecting(@Nonnull Stmt source, @Nonnull Stmt target);

/**
* returns a (reconstructed) list of traps like the traptable in the bytecode
*
* <p>Note: if you need exceptionional flow information in more augmented with the affected
* blocks/stmts and not just a (reconstructed, possibly more verbose) traptable - have a look at
* BasicBlock.getExceptionalSuccessor()
*/
public abstract List<Trap> buildTraps();

/**
* Removes the specified exceptional flow from all blocks.
*
Expand Down Expand Up @@ -206,15 +199,25 @@ public Collection<Stmt> getEntrypoints() {
/** validates whether the each Stmt has the correct amount of outgoing flows. */
public void validateStmtConnectionsInGraph() {
try {
List<Stmt> handlerStmts = new ArrayList<>();
for (Stmt stmt: getNodes()){
if (stmt instanceof JIdentityStmt) {
//JThrowStmt?
IdentityRef rightOp = ((JIdentityStmt) stmt).getRightOp();
if (rightOp instanceof JCaughtExceptionRef) {
handlerStmts.add(stmt);
}
}
}

for (Stmt stmt : getNodes()) {
final List<Stmt> successors = successors(stmt);
final int successorCount = successors.size();

if (predecessors(stmt).isEmpty()) {

if (!(stmt == getStartingStmt()
|| buildTraps().stream()
.map(Trap::getHandlerStmt)
|| handlerStmts.stream()
.anyMatch(handler -> handler == stmt))) {
throw new IllegalStateException(
"Stmt '"
Expand Down Expand Up @@ -353,7 +356,7 @@ public boolean equals(Object o) {
return false;
}

if (!buildTraps().equals(otherGraph.buildTraps())) {
if (!jimplePrinter.buildTraps(this).equals(jimplePrinter.buildTraps(otherGraph))) {
return false;
}

Expand Down Expand Up @@ -517,7 +520,7 @@ public List<Trap> getTraps() {
}

/** Iterates over the blocks */
protected class BlockGraphIterator implements Iterator<BasicBlock<?>> {
public class BlockGraphIterator implements Iterator<BasicBlock<?>> {

@Nonnull private final ArrayDeque<BasicBlock<?>> trapHandlerBlocks = new ArrayDeque<>();

Expand Down Expand Up @@ -717,7 +720,7 @@ public Collection<Stmt> getLabeledStmts() {
}
}

for (Trap trap : buildTraps()) {
for (Trap trap : jimplePrinter.buildTraps(this)) {
stmtList.add(trap.getBeginStmt());
stmtList.add(trap.getEndStmt());
stmtList.add(trap.getHandlerStmt());
Expand All @@ -730,7 +733,7 @@ public Collection<Stmt> getLabeledStmts() {
public String toString() {
StringWriter writer = new StringWriter();
try (PrintWriter writerOut = new PrintWriter(new EscapedWriter(writer))) {
new JimplePrinter().printTo(this, writerOut);
jimplePrinter.printTo(this, writerOut);
}
return writer.toString();
}
Expand Down
2 changes: 1 addition & 1 deletion sootup.core/src/main/java/sootup/core/model/Body.java
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ public Set<Local> getLocals() {
@Nonnull
@Deprecated()
public List<Trap> getTraps() {
return graph.buildTraps();
return new JimplePrinter().buildTraps(graph);
}

/** Return unit containing the \@this-assignment * */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,8 @@
* #L%
*/

import java.io.PrintWriter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import sootup.core.graph.StmtGraph;
import com.google.common.collect.ComparisonChain;
import sootup.core.graph.*;
import sootup.core.jimple.Jimple;
import sootup.core.jimple.basic.Local;
import sootup.core.jimple.basic.Trap;
Expand All @@ -38,6 +35,12 @@
import sootup.core.types.ClassType;
import sootup.core.types.Type;

import javax.annotation.Nonnull;
import java.io.PrintWriter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
* Prints out a class and all its methods.
*
Expand Down Expand Up @@ -297,6 +300,44 @@ public void printTo(StmtGraph<?> graph, PrintWriter out, LabeledStmtPrinter prin
out.print(printer);
}

/**
* returns a (reconstructed) list of traps like the traptable in the bytecode
*
* <p>Note: if you need exceptionional flow information in more augmented with the affected
* blocks/stmts and not just a (reconstructed, possibly more verbose) traptable - have a look at
* BasicBlock.getExceptionalSuccessor()
*/
/** hint: little expensive getter - its more of a build/create - currently no overlaps */
public List<Trap> buildTraps(StmtGraph stmtGraph) {
// [ms] try to incorporate it into the serialisation of jimple printing so the other half of
// iteration information is not wasted..
StmtGraph<MutableBasicBlock>.BlockGraphIteratorAndTrapAggregator it = stmtGraph.new BlockGraphIteratorAndTrapAggregator(new MutableBasicBlockImpl());
// it.getTraps() is valid/completely build when the iterator is done.
Map<Stmt, Integer> stmtsBlockIdx = new IdentityHashMap<>();
int i = 0;
// collect BlockIdx positions to sort the traps according to the numbering
while (it.hasNext()) {
final BasicBlock<?> nextBlock = it.next();
stmtsBlockIdx.put(nextBlock.getHead(), i);
stmtsBlockIdx.put(nextBlock.getTail(), i);
i++;
}
final List<Trap> traps = it.getTraps();
traps.sort(getTrapComparator(stmtsBlockIdx));
return traps;
}

/** Comparator which sorts the trap output in getTraps() */
public Comparator<Trap> getTrapComparator(@Nonnull Map<Stmt, Integer> stmtsBlockIdx) {
return (a, b) ->
ComparisonChain.start()
.compare(stmtsBlockIdx.get(a.getBeginStmt()), stmtsBlockIdx.get(b.getBeginStmt()))
.compare(stmtsBlockIdx.get(a.getEndStmt()), stmtsBlockIdx.get(b.getEndStmt()))
// [ms] would be nice to have the traps ordered by exception hierarchy as well
.compare(a.getExceptionType().toString(), b.getExceptionType().toString())
.result();
}

/**
* Prints out the method corresponding to b Body, (declaration and body), in the textual format
* corresponding to the IR used to encode b body.
Expand Down Expand Up @@ -380,7 +421,7 @@ private void printStmts(StmtGraph<?> stmtGraph, LabeledStmtPrinter printer) {

// Print out exceptions
{
Iterator<Trap> trapIt = stmtGraph.buildTraps().iterator();
Iterator<Trap> trapIt = buildTraps(stmtGraph).iterator();

if (trapIt.hasNext()) {
printer.newline();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public Iterable<Stmt> initializeSootMethod(@Nonnull StmtGraph<?> stmtGraph) {
@Nonnull
public List<Stmt> getStmts(@Nonnull StmtGraph<?> stmtGraph) {
final Collection<Stmt> targetStmtsOfBranches = stmtGraph.getLabeledStmts();
final List<Trap> traps = stmtGraph.buildTraps();
final List<Trap> traps = new JimplePrinter().buildTraps(stmtGraph);

final int maxEstimatedSize = targetStmtsOfBranches.size() + traps.size() * 3;
labels = new HashMap<>(maxEstimatedSize, 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@
import sootup.core.types.ClassType;
import sootup.core.types.PrimitiveType;
import sootup.core.types.UnknownType;
import sootup.core.util.printer.JimplePrinter;

@Tag("Java8")
public class MutableBlockStmtGraphTest {

public JimplePrinter jimplePrinter = new JimplePrinter();

BranchingStmt firstGoto = new JGotoStmt(StmtPositionInfo.getNoStmtPositionInfo());
JNopStmt firstNop = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo());
JNopStmt secondNop = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo());
Expand Down Expand Up @@ -621,7 +624,7 @@ public PackageName getPackageName() {
graph0.putEdge(stmt2, 0, returnStmt);

{
final List<Trap> traps = graph0.buildTraps();
final List<Trap> traps = jimplePrinter.buildTraps(graph0);
assertEquals(2, traps.size()); // as @caughtexception gets currently in their way.
assertEquals(stmt2, traps.get(1).getBeginStmt());
assertEquals(returnStmt, traps.get(1).getEndStmt());
Expand Down Expand Up @@ -659,7 +662,7 @@ public PackageName getPackageName() {
graph2.putEdge(stmt2, JGotoStmt.BRANCH_IDX, returnStmt);
{
assertEquals(5, graph2.getBlocks().size());
final List<Trap> traps = graph2.buildTraps();
final List<Trap> traps = jimplePrinter.buildTraps(graph2);
assertEquals(2, traps.size());
}

Expand All @@ -675,7 +678,7 @@ public PackageName getPackageName() {
graph3.putEdge(stmt3, JGotoStmt.BRANCH_IDX, returnStmt);

{
final List<Trap> traps = graph3.buildTraps();
final List<Trap> traps = jimplePrinter.buildTraps(graph3);
assertEquals(5, graph2.getBlocks().size());
assertEquals(2, traps.size());
}
Expand All @@ -698,7 +701,7 @@ public PackageName getPackageName() {
graph4.putEdge(stmt2, JGotoStmt.BRANCH_IDX, stmt3);
graph4.putEdge(stmt3, JGotoStmt.BRANCH_IDX, returnStmt);

assertEquals(3, graph4.buildTraps().size());
assertEquals(3, jimplePrinter.buildTraps(graph4).size());

// mixed 2
MutableBlockStmtGraph graph5 = new MutableBlockStmtGraph();
Expand Down Expand Up @@ -733,7 +736,7 @@ public PackageName getPackageName() {
graph5.putEdge(stmt3, JGotoStmt.BRANCH_IDX, returnStmt);

{
final List<Trap> traps = graph5.buildTraps();
final List<Trap> traps = jimplePrinter.buildTraps(graph5);
assertEquals(6, traps.size());
assertEquals(6, graph5.getBlocks().size());
}
Expand Down Expand Up @@ -769,7 +772,7 @@ public PackageName getPackageName() {
graph6.putEdge(stmt2, JGotoStmt.BRANCH_IDX, stmt3);
graph6.putEdge(stmt3, JGotoStmt.BRANCH_IDX, returnStmt);
{
final List<Trap> traps = graph6.buildTraps();
final List<Trap> traps = jimplePrinter.buildTraps(graph6);
assertEquals(5, traps.size());
assertEquals(6, graph6.getBlocks().size());
assertEquals(
Expand Down Expand Up @@ -1030,6 +1033,7 @@ public void simpleInsertion() {
assertTrue(graph.successors(stmt1).contains(stmt2));
}

// It is an invalid graph, just for the test
@Test
public void testRemoveSingleTrap() {
MutableBlockStmtGraph graph = new MutableBlockStmtGraph();
Expand All @@ -1052,7 +1056,7 @@ public void testRemoveSingleTrap() {
graph.addExceptionalEdge(stmt1, throwableSig, handlerStmt);

// Verify the trap is present
List<Trap> traps = graph.buildTraps();
List<Trap> traps = jimplePrinter.buildTraps(graph);
assertEquals(1, traps.size());
assertEquals(stmt1, traps.get(0).getBeginStmt());
assertEquals(handlerStmt, traps.get(0).getHandlerStmt());
Expand All @@ -1061,7 +1065,7 @@ public void testRemoveSingleTrap() {
Trap trapToRemove = traps.get(0);
graph.removeExceptionalFlowFromAllBlocks(
trapToRemove.getExceptionType(), trapToRemove.getHandlerStmt());
traps = graph.buildTraps();
traps = jimplePrinter.buildTraps(graph);
assertEquals(0, traps.size());
}

Expand Down Expand Up @@ -1095,7 +1099,7 @@ public void testRemoveMultipleTrapsWithDifferentExceptionTypes() {
graph.addExceptionalEdge(stmt2, ioExceptionSig, handlerStmt2);

// Verify both traps are present
List<Trap> traps = graph.buildTraps();
List<Trap> traps = jimplePrinter.buildTraps(graph);
assertEquals(2, traps.size());

// Remove one trap and verify the remaining
Expand All @@ -1104,7 +1108,7 @@ public void testRemoveMultipleTrapsWithDifferentExceptionTypes() {

graph.removeExceptionalFlowFromAllBlocks(
trapToRemove.getExceptionType(), trapToRemove.getHandlerStmt());
traps = graph.buildTraps();
traps = jimplePrinter.buildTraps(graph);
assertEquals(1, traps.size());
assertEquals(stmt2, trapToKeep.getBeginStmt());
assertEquals(handlerStmt2, trapToKeep.getHandlerStmt());
Expand Down
Loading

0 comments on commit a295490

Please sign in to comment.