From 790ff7674b9e25181004f3f04251e4609f1a7e55 Mon Sep 17 00:00:00 2001 From: zunhoho Date: Tue, 5 Nov 2024 16:37:52 +0100 Subject: [PATCH] fix ssa with trap --- .../core/graph/BlockAnalysisDirection.java | 15 +- .../core/graph/PostOrderBlockIterator.java | 7 +- .../StaticSingleAssignmentFormerTest.java | 200 +++++++++--------- 3 files changed, 112 insertions(+), 110 deletions(-) diff --git a/sootup.core/src/main/java/sootup/core/graph/BlockAnalysisDirection.java b/sootup.core/src/main/java/sootup/core/graph/BlockAnalysisDirection.java index dfbf54411f..8860ab897c 100644 --- a/sootup.core/src/main/java/sootup/core/graph/BlockAnalysisDirection.java +++ b/sootup.core/src/main/java/sootup/core/graph/BlockAnalysisDirection.java @@ -23,14 +23,19 @@ import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; import javax.annotation.Nonnull; public enum BlockAnalysisDirection { POSTORDERBACKWARD { @Override @Nonnull - List> getPredecessors(BasicBlock block) { - return block.getSuccessors(); + List> getPredecessors(BasicBlock block) { + List> esuccs = + block.getExceptionalSuccessors().values().stream().collect(Collectors.toList()); + List> succs = (List>) block.getSuccessors(); + succs.addAll(esuccs); + return succs; } @Nonnull @@ -42,8 +47,8 @@ List> getSortedBlocks(StmtGraph blockGraph) { REVERSEPOSTORDERFORWARD { @Override @Nonnull - List> getPredecessors(BasicBlock block) { - return block.getPredecessors(); + List> getPredecessors(BasicBlock block) { + return (List>) block.getPredecessors(); } @Nonnull @@ -55,7 +60,7 @@ List> getSortedBlocks(StmtGraph blockGraph) { }; @Nonnull - abstract List> getPredecessors(BasicBlock block); + abstract List> getPredecessors(BasicBlock block); @Nonnull abstract List> getSortedBlocks(StmtGraph blockGraph); diff --git a/sootup.core/src/main/java/sootup/core/graph/PostOrderBlockIterator.java b/sootup.core/src/main/java/sootup/core/graph/PostOrderBlockIterator.java index d314282e24..67540bcfc6 100644 --- a/sootup.core/src/main/java/sootup/core/graph/PostOrderBlockIterator.java +++ b/sootup.core/src/main/java/sootup/core/graph/PostOrderBlockIterator.java @@ -22,6 +22,7 @@ */ import java.util.*; +import java.util.stream.Collectors; import javax.annotation.Nonnull; public class PostOrderBlockIterator implements BlockIterator { @@ -53,7 +54,11 @@ public BasicBlock next() { if (frame.succIterator.hasNext()) { BasicBlock succ = frame.succIterator.next(); if (visitNode(succ)) { - stack.push(new Frame(succ, ((List>) succ.getSuccessors()).iterator())); + List> esuccs = + succ.getExceptionalSuccessors().values().stream().collect(Collectors.toList()); + List> succs = (List>) succ.getSuccessors(); + succs.addAll(esuccs); + stack.push(new Frame(succ, succs.iterator())); } } else { stack.pop(); diff --git a/sootup.java.bytecode.frontend/src/test/java/sootup/java/bytecode/frontend/interceptors/StaticSingleAssignmentFormerTest.java b/sootup.java.bytecode.frontend/src/test/java/sootup/java/bytecode/frontend/interceptors/StaticSingleAssignmentFormerTest.java index fa6b9eec74..20e17bb269 100644 --- a/sootup.java.bytecode.frontend/src/test/java/sootup/java/bytecode/frontend/interceptors/StaticSingleAssignmentFormerTest.java +++ b/sootup.java.bytecode.frontend/src/test/java/sootup/java/bytecode/frontend/interceptors/StaticSingleAssignmentFormerTest.java @@ -3,12 +3,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import categories.TestCategories; - import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; import java.util.*; - import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -39,7 +37,10 @@ public class StaticSingleAssignmentFormerTest { JavaIdentifierFactory factory = JavaIdentifierFactory.getInstance(); StmtPositionInfo noStmtPositionInfo = StmtPositionInfo.getNoStmtPositionInfo(); JavaJimple javaJimple = JavaJimple.getInstance(); - final String location = Paths.get(System.getProperty("user.dir")).getParent() + File.separator + "shared-test-resources/bugfixes/"; + final String location = + Paths.get(System.getProperty("user.dir")).getParent() + + File.separator + + "shared-test-resources/bugfixes/"; JavaClassType intType = factory.getClassType("int"); JavaClassType classType = factory.getClassType("Test"); @@ -85,11 +86,9 @@ public class StaticSingleAssignmentFormerTest { FallsThroughStmt handlerStmt = JavaJimple.newIdentityStmt(stack4, caughtExceptionRef, noStmtPositionInfo); - JAssignStmt l2eq2 = - JavaJimple.newAssignStmt(l2, IntConstant.getInstance(2), noStmtPositionInfo); + JAssignStmt l2eq2 = JavaJimple.newAssignStmt(l2, IntConstant.getInstance(2), noStmtPositionInfo); JGotoStmt gotoStmt = JavaJimple.newGotoStmt(noStmtPositionInfo); - @Test public void testSSA() { StaticSingleAssignmentFormer ssa = new StaticSingleAssignmentFormer(); @@ -138,98 +137,112 @@ public void testSSA() { } @Test - public void testSSA2(){ + public void testSSA2() { ClassType clazzType = factory.getClassType("TrapSSA"); - MethodSignature methodSignature = factory.getMethodSignature(clazzType, "main", "void", Collections.singletonList("java.lang.String[]")); - final Path path = Paths.get(location+"TrapSSA.class"); - PathBasedAnalysisInputLocation inputLocation = new PathBasedAnalysisInputLocation.ClassFileBasedAnalysisInputLocation(path, "", SourceType.Application); - PathBasedAnalysisInputLocation inputLocationWithSSA = new PathBasedAnalysisInputLocation.ClassFileBasedAnalysisInputLocation(path, "", SourceType.Application, Collections.singletonList(new StaticSingleAssignmentFormer())); + MethodSignature methodSignature = + factory.getMethodSignature( + clazzType, "main", "void", Collections.singletonList("java.lang.String[]")); + final Path path = Paths.get(location + "TrapSSA.class"); + PathBasedAnalysisInputLocation inputLocation = + new PathBasedAnalysisInputLocation.ClassFileBasedAnalysisInputLocation( + path, "", SourceType.Application); + PathBasedAnalysisInputLocation inputLocationWithSSA = + new PathBasedAnalysisInputLocation.ClassFileBasedAnalysisInputLocation( + path, + "", + SourceType.Application, + Collections.singletonList(new StaticSingleAssignmentFormer())); JavaView view = new JavaView(inputLocationWithSSA); System.out.println(view.getMethod(methodSignature).get().getBody()); } @Test - public void testSSA3(){ + public void testSSA3() { ClassType clazzType = factory.getClassType("ForLoopSSA"); - MethodSignature methodSignature = factory.getMethodSignature(clazzType, "main", "void", Collections.singletonList("java.lang.String[]")); - final Path path = Paths.get(location+"ForLoopSSA.class"); - PathBasedAnalysisInputLocation inputLocation = new PathBasedAnalysisInputLocation.ClassFileBasedAnalysisInputLocation(path, "", SourceType.Application); - PathBasedAnalysisInputLocation inputLocationWithSSA = new PathBasedAnalysisInputLocation.ClassFileBasedAnalysisInputLocation(path, "", SourceType.Application, Collections.singletonList(new StaticSingleAssignmentFormer())); + MethodSignature methodSignature = + factory.getMethodSignature( + clazzType, "main", "void", Collections.singletonList("java.lang.String[]")); + final Path path = Paths.get(location + "ForLoopSSA.class"); + PathBasedAnalysisInputLocation inputLocation = + new PathBasedAnalysisInputLocation.ClassFileBasedAnalysisInputLocation( + path, "", SourceType.Application); + PathBasedAnalysisInputLocation inputLocationWithSSA = + new PathBasedAnalysisInputLocation.ClassFileBasedAnalysisInputLocation( + path, + "", + SourceType.Application, + Collections.singletonList(new StaticSingleAssignmentFormer())); JavaView view = new JavaView(inputLocationWithSSA); System.out.println(view.getMethod(methodSignature).get().getBody()); } - @Disabled("ms: Which Trap body?") @Test public void testTrappedSSA() { StaticSingleAssignmentFormer ssa = new StaticSingleAssignmentFormer(); Body.BodyBuilder builder = createTrapBody(); ssa.interceptBody(builder, new JavaView(Collections.emptyList())); - String expectedBodyString = "{\n" - + " int l0, l1, l2, l3, l0#0, l1#1, l2#2, l3#3, l3#4, l2#5, l2#6, l3#7, l2#8, l2#10, l2#11, l3#12, l3#13, l2#14;\n" - + " ref stack4, stack4#9;\n" + + " Test l0, l0#0;\n" + + " int l1, l1#1, l2, l2#11, l2#13, l2#2, l2#4, l2#6, l2#8, l2#9, l3, l3#10, l3#12, l3#14, l3#3, l3#5;\n" + + " ref stack4, stack4#7;\n" + "\n" + "\n" + " l0#0 := @this: Test;\n" - + "\n" + " l1#1 = 1;\n" - + "\n" - + " l2#2 = 1;\n" - + "\n" + + " l2#2 = 2;\n" + " l3#3 = 0;\n" + "\n" + " label1:\n" - + " l3#4 = phi(l3#3, l3#13);\n" - + "\n" - + " l2#5 = phi(l2#2, l2#14);\n" + + " l2#4 = phi(l2#2, l2#13);\n" + + " l3#5 = phi(l3#3, l3#14);\n" + "\n" - + " if l3#4 < 100 goto label6;\n" + + " if l3#5 < 100 goto label2;\n" + "\n" - + " if l2#5 < 20 goto label5;\n" + + " return l2#4;\n" + "\n" + " label2:\n" - + " l2#8 = l1#1;\n" - + "\n" - + " label3:\n" - + " l2#11 = phi(l2#8, l2#10);\n" - + "\n" - + " l3#12 = l3#4 + 1;\n" - + "\n" - + " l3#13 = phi(l3#7, l3#12);\n" + + " if l2#4 < 20 goto label3;\n" + + " l2#11 = l3#5;\n" + + " l3#12 = l3#5 + 2;\n" + "\n" - + " l2#14 = phi(l2#6, l2#11);\n" + + " goto label6;\n" + "\n" - + " goto label1;\n" + + " label3:\n" + + " l2#6 = l1#1;\n" + "\n" + " label4:\n" - + " stack4#9 := @caughtexception;\n" + + " l2#9 = phi(l2#6, l2#8);\n" + + " l3#10 = l3#5 + 1;\n" + "\n" - + " l2#10 = 0;\n" - + "\n" - + " goto label3;\n" + + " goto label6;\n" + "\n" + " label5:\n" - + " l2#6 = l3#4;\n" + + " stack4#7 := @caughtexception;\n" + + " l2#8 = 2;\n" + "\n" - + " l3#7 = l3#4 + 2;\n" + + " goto label4;\n" + "\n" + " label6:\n" - + " return l2#5;\n" + + " l2#13 = phi(l2#9, l2#11);\n" + + " l3#14 = phi(l3#10, l3#12);\n" + "\n" - + " catch Exception from label2 to label3 with label4;\n" + + " goto label1;\n" + + "\n" + + " catch Exception from label3 to label4 with label5;\n" + "}\n"; assertEquals(expectedBodyString, builder.build().toString()); } /** + * + * *
    *    l0 := @this Test
    *    l1 = 1
-   *    l2 = 1
+   *    l2 = 2
    *    l3 = 0
    * label1:
    *    if l3 < 100 goto label2
@@ -250,22 +263,22 @@ public void testTrappedSSA() {
   private Body.BodyBuilder createBody() {
     MutableBlockStmtGraph graph = new MutableBlockStmtGraph();
 
-    // Block0
+    // Block 0
     graph.setStartingStmt(startingStmt);
     graph.putEdge(startingStmt, assign1tol1);
     graph.putEdge(assign1tol1, assign1tol2);
     graph.putEdge(assign1tol2, assign0tol3);
 
-    // block1
+    // block 1
     graph.putEdge(assign0tol3, ifStmt);
 
-    // block2
+    // block 2
     graph.putEdge(ifStmt, JIfStmt.TRUE_BRANCH_IDX, ifStmt2);
 
-    // block3
+    // block 3
     graph.putEdge(ifStmt, JIfStmt.FALSE_BRANCH_IDX, returnStmt);
 
-    // block4
+    // block 4
     graph.putEdge(ifStmt2, JIfStmt.TRUE_BRANCH_IDX, assignl1tol2);
     graph.putEdge(assignl1tol2, assignl3plus1tol3);
     graph.putEdge(assignl3plus1tol3, gotoStmt1);
@@ -287,23 +300,6 @@ private Body.BodyBuilder createBody() {
     Set locals = ImmutableUtils.immutableSet(l0, l1, l2, l3);
     builder.setLocals(locals);
 
-    // todo: how to use initializeWith?
-    /*Map> successorMap = new HashMap<>();
-    successorMap.put(ifStmt, Arrays.asList(ifStmt2, returnStmt));
-    successorMap.put(ifStmt2, Arrays.asList(assignl1tol2, assignl3tol2));
-    successorMap.put(goTo, Collections.singletonList(ifStmt));
-    graph.initializeWith(
-        Arrays.asList(
-            Arrays.asList(startingStmt, assign1tol1, assign1tol2, assign0tol3),
-            Collections.singletonList(ifStmt),
-            Collections.singletonList(ifStmt2),
-            Arrays.asList(assignl1tol2, assignl3plus1tol3, gotoStmt1),
-            Arrays.asList(assignl3tol2, assignl3plus2tol3, gotoStmt2),
-            Arrays.asList(goTo),
-            Collections.singletonList(returnStmt)),
-        successorMap,
-        Collections.emptyList());*/
-
     return builder;
   }
 
@@ -313,71 +309,72 @@ private Body.BodyBuilder createBody() {
    * 
    *    l0 := @this Test
    *    l1 = 1
-   *    l2 = 1
+   *    l2 = 2
    *    l3 = 0
    * label1:
-   *    if l3 < 100 goto label6
-   *    if l2 < 20 goto label5
+   *    if l3 < 100 goto label2
+   *    return l2
    * label2:
-   *    l2 = l1
+   *    if l2 < 20 goto label3
+   *    l2 = l3
+   *    l3 = l3 + 2
+   *    goto label6
    * label3:
-   *    l3 = l3 + 1
-   *    goto label1;
+   *    l2 = l1
    * label4:
-   *    stack4 := @caughtexception
-   *    l2 = 0;
-   *    goto label3;
+   *    l3 = l3 + 1
+   *    goto label6
    * label5:
-   *    l2 = l3
-   *    l3 = l3 + 2
+   *    stack4 := @caughtexception
+   *    l2 = 2
+   *    goto label4
    * label6:
-   *    return l2
+   *    goto label1
    *
-   * catch Exception from label2 to label3 with label4;
+   * catch Exception from label3 to label5 with label5
    * 
*/ private Body.BodyBuilder createTrapBody() { MutableBlockStmtGraph graph = new MutableBlockStmtGraph(); - // Block0 + // Block 0 graph.setStartingStmt(startingStmt); graph.putEdge(startingStmt, assign1tol1); graph.putEdge(assign1tol1, assign1tol2); graph.putEdge(assign1tol2, assign0tol3); - // block1 + // block 1 graph.putEdge(assign0tol3, ifStmt); - // block2 + // block 2 graph.putEdge(ifStmt, JIfStmt.TRUE_BRANCH_IDX, ifStmt2); - // block3 + // block 3 graph.putEdge(ifStmt, JIfStmt.FALSE_BRANCH_IDX, returnStmt); - // block4 + // block 4 graph.putEdge(ifStmt2, JIfStmt.TRUE_BRANCH_IDX, assignl1tol2); - graph.addExceptionalEdge(assignl1tol2, exceptionType, handlerStmt); + + // block 5 exceptional block + graph.addNode(assignl1tol2, Collections.singletonMap(exceptionType, handlerStmt)); + graph.putEdge(handlerStmt, l2eq2); + graph.putEdge(l2eq2, gotoStmt3); + + // block 6 + graph.putEdge(gotoStmt3, JGotoStmt.BRANCH_IDX, assignl3plus1tol3); graph.putEdge(assignl1tol2, assignl3plus1tol3); graph.putEdge(assignl3plus1tol3, gotoStmt1); - // block 5 + // block 7 graph.putEdge(ifStmt2, JIfStmt.FALSE_BRANCH_IDX, assignl3tol2); graph.putEdge(assignl3tol2, assignl3plus2tol3); graph.putEdge(assignl3plus2tol3, gotoStmt2); - // block 6 + // block 8 graph.putEdge(gotoStmt1, JGotoStmt.BRANCH_IDX, gotoStmt); graph.putEdge(gotoStmt2, JGotoStmt.BRANCH_IDX, gotoStmt); graph.putEdge(gotoStmt, JGotoStmt.BRANCH_IDX, ifStmt); - // add exception - - - graph.putEdge(handlerStmt, l2eq2); - graph.putEdge(l2eq2, gotoStmt3); - graph.putEdge(gotoStmt3, JGotoStmt.BRANCH_IDX, assignl3plus1tol3); - graph.buildTraps(); - Body.BodyBuilder builder = Body.builder(graph); builder.setMethodSignature(methodSignature); @@ -387,9 +384,4 @@ private Body.BodyBuilder createTrapBody() { return builder; } - - - - - }