Skip to content

Commit 6dc6ad1

Browse files
committed
Merge branch 'develop' of github.com:soot-oss/soot into develop
2 parents 7bb46b9 + 06750f0 commit 6dc6ad1

File tree

4 files changed

+122
-22
lines changed

4 files changed

+122
-22
lines changed

src/main/java/soot/jimple/spark/solver/TopoSorter.java

+17-12
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222
* #L%
2323
*/
2424

25-
import java.util.ArrayList;
2625
import java.util.HashSet;
27-
import java.util.List;
26+
import java.util.Set;
27+
import java.util.Stack;
2828

2929
import soot.jimple.spark.pag.Node;
3030
import soot.jimple.spark.pag.PAG;
@@ -61,26 +61,31 @@ public TopoSorter(PAG pag, boolean ignoreTypes) {
6161
protected HashSet<VarNode> visited;
6262

6363
protected void dfsVisit(VarNode n) {
64-
if (visited.contains(n)) {
64+
if (!visited.add(n)) {
6565
return;
6666
}
67-
List<VarNode> stack = new ArrayList<>();
68-
List<VarNode> all = new ArrayList<>();
67+
68+
Stack<VarNode> stack = new Stack<>();
69+
Set<VarNode> visitedSuccessors = new HashSet<>();
6970
stack.add(n);
71+
7072
while (!stack.isEmpty()) {
71-
VarNode s = stack.remove(stack.size() - 1);
72-
if (visited.add(s)) {
73-
all.add(s);
73+
VarNode s = stack.peek();
74+
75+
if (visitedSuccessors.add(s)) {
7476
Node[] succs = pag.simpleLookup(s);
7577
for (Node element : succs) {
7678
if (ignoreTypes || pag.getTypeManager().castNeverFails(n.getType(), element.getType())) {
77-
stack.add((VarNode) element);
79+
if (visited.add((VarNode) element)) {
80+
stack.push((VarNode) element);
81+
}
7882
}
7983
}
84+
85+
} else {
86+
stack.pop();
87+
s.setFinishingNumber(nextFinishNumber++);
8088
}
8189
}
82-
for (int i = all.size() - 1; i >= 0; i--) {
83-
all.get(i).setFinishingNumber(nextFinishNumber++);
84-
}
8590
}
8691
}

src/main/java/soot/toDex/DexPrinter.java

+10-10
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010
* it under the terms of the GNU Lesser General Public License as
1111
* published by the Free Software Foundation, either version 2.1 of the
1212
* License, or (at your option) any later version.
13-
*
13+
*
1414
* This program is distributed in the hope that it will be useful,
1515
* but WITHOUT ANY WARRANTY; without even the implied warranty of
1616
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1717
* GNU General Lesser Public License for more details.
18-
*
18+
*
1919
* You should have received a copy of the GNU General Lesser Public
2020
* License along with this program. If not, see
2121
* <http://www.gnu.org/licenses/lgpl-2.1.html>.
@@ -313,7 +313,7 @@ private void printZip() throws IOException {
313313
}
314314

315315
if (Options.v().output_jar()) {
316-
// if we create JAR file, MANIFEST.MF is preferred
316+
// if we create JAR file, MANIFEST.MF is preferred.
317317
addManifest(outputZip, files);
318318
}
319319

@@ -404,8 +404,8 @@ private void addManifest(ZipOutputStream destination, Collection<File> dexFiles)
404404
try (BufferedOutputStream bufOut = new BufferedOutputStream(destination)) {
405405
manifest.write(bufOut);
406406
bufOut.flush();
407+
destination.closeEntry();
407408
}
408-
destination.closeEntry();
409409
}
410410

411411
/**
@@ -1116,7 +1116,7 @@ protected Collection<Method> toMethods(SootClass clazz) {
11161116

11171117
/**
11181118
* Checks whether the given method shall be ignored, i.e., not written out to dex
1119-
*
1119+
*
11201120
* @param sm
11211121
* The method to check
11221122
* @return True to ignore the method while writing the dex file, false to write it out as normal
@@ -1127,7 +1127,7 @@ protected boolean isIgnored(SootMethod sm) {
11271127

11281128
/**
11291129
* Checks whether the given field shall be ignored, i.e., not written out to dex
1130-
*
1130+
*
11311131
* @param sf
11321132
* The field to check
11331133
* @return True to ignore the field while writing the dex file, false to write it out as normal
@@ -1293,9 +1293,9 @@ protected MethodImplementation toMethodImplementation(SootMethod m) {
12931293

12941294
/**
12951295
* Creates a statement visitor to build code for each statement.
1296-
*
1296+
*
12971297
* Allows subclasses to use own implementations
1298-
*
1298+
*
12991299
* @param belongingMethod
13001300
* the method
13011301
* @param arrayInitDetector
@@ -1308,7 +1308,7 @@ protected StmtVisitor buildStmtVisitor(SootMethod belongingMethod, DexArrayInitD
13081308

13091309
/**
13101310
* Writes out the information stored in the tags associated with the given statement
1311-
*
1311+
*
13121312
* @param builder
13131313
* The builder used to generate the Dalvik method implementation
13141314
* @param stmt
@@ -1397,7 +1397,7 @@ private void fixLongJumps(List<BuilderInstruction> instructions, LabelAssigner l
13971397
/*
13981398
* Assuming every instruction between this instruction and the jump target is a CONST_STRING instruction, how
13991399
* much could the distance increase?
1400-
*
1400+
*
14011401
* Because we only spend the effort to count the number of CONST_STRING instructions if there is a real
14021402
* chance that it changes the distance to overflow the allowed maximum.
14031403
*/

src/test/java/soot/PackManagerTest.java

+33
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,31 @@
2020
* <http://www.gnu.org/licenses/lgpl-2.1.html>.
2121
* #L%
2222
*/
23+
24+
import com.google.common.io.Files;
2325
import org.junit.Test;
2426
import soot.options.Options;
2527

28+
import java.io.File;
2629
import java.nio.file.Path;
2730
import java.nio.file.Paths;
2831
import java.util.ArrayList;
2932
import java.util.Collections;
33+
import java.util.Enumeration;
3034
import java.util.List;
3135
import java.util.stream.Collectors;
3236
import java.util.stream.Stream;
37+
import java.util.zip.ZipEntry;
38+
import java.util.zip.ZipFile;
3339

3440
import static org.junit.Assert.assertEquals;
41+
import static org.junit.Assert.assertTrue;
42+
import static org.junit.Assert.fail;
3543

3644

3745
/**
3846
* Some tests to disable jb transformers.
47+
*
3948
* @author Linghui Luo
4049
*/
4150
public class PackManagerTest {
@@ -122,6 +131,30 @@ public void testDisableUnusedLocalEliminatorInJBPhase() {
122131
}
123132
}
124133

134+
@Test
135+
public void testWritingToJar() throws Exception {
136+
setup();
137+
File tempDir = Files.createTempDir();
138+
Options.v().set_output_jar(true);
139+
Options.v().set_output_dir(tempDir.getAbsolutePath());
140+
Options.v().set_output_format(Options.output_format_dex);
141+
Scene.v().loadNecessaryClasses();
142+
PackManager.v().runBodyPacks();
143+
PackManager.v().writeOutput();
144+
assertEquals(1, tempDir.listFiles().length);
145+
File targetJar = tempDir.listFiles()[0];
146+
ZipFile jarRead = new ZipFile(targetJar.getAbsolutePath());
147+
Enumeration<? extends ZipEntry> entries = jarRead.entries();
148+
while (entries.hasMoreElements()) {
149+
ZipEntry entry = entries.nextElement();
150+
if (entry.getName().toLowerCase().endsWith("manifest.mf")) {
151+
assertTrue(entry.getSize() > 0);
152+
return;
153+
}
154+
}
155+
fail("No Manifest entry found in " + targetJar.getAbsolutePath());
156+
}
157+
125158
public static List<String> expectedBody(String... jimpleLines) {
126159
return Stream.of(jimpleLines).collect(Collectors.toList());
127160
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package soot.jimple.spark.solver;
2+
3+
/*-
4+
* #%L
5+
* Soot - a J*va Optimization Framework
6+
* %%
7+
* Copyright (C) 1997 - 2018 Raja Vallée-Rai and others
8+
* %%
9+
* This program is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU Lesser General Public License as
11+
* published by the Free Software Foundation, either version 2.1 of the
12+
* License, or (at your option) any later version.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU General Lesser Public License for more details.
18+
*
19+
* You should have received a copy of the GNU General Lesser Public
20+
* License along with this program. If not, see
21+
* <http://www.gnu.org/licenses/lgpl-2.1.html>.
22+
* #L%
23+
*/
24+
25+
import java.util.Collections;
26+
27+
import org.junit.Test;
28+
29+
import static org.junit.Assert.assertEquals;
30+
31+
import soot.Scene;
32+
import soot.Type;
33+
import soot.jimple.spark.pag.PAG;
34+
import soot.jimple.spark.pag.VarNode;
35+
import soot.options.SparkOptions;
36+
37+
public class SCCCollapserTest {
38+
39+
@Test
40+
public void testSeparateComponents() {
41+
Scene.v().loadBasicClasses();
42+
Type type = Scene.v().getObjectType();
43+
44+
SparkOptions sparkOptions = new SparkOptions(Collections.emptyMap());
45+
PAG pag = new PAG(sparkOptions);
46+
47+
VarNode a = pag.makeGlobalVarNode("a", type);
48+
VarNode b = pag.makeGlobalVarNode("b", type);
49+
VarNode c = pag.makeGlobalVarNode("c", type);
50+
pag.addEdge(a, b);
51+
pag.addEdge(a, c);
52+
pag.addEdge(b, c);
53+
54+
SCCCollapser sccCollapser = new SCCCollapser(pag, false);
55+
sccCollapser.collapse();
56+
pag.cleanUpMerges();
57+
58+
assertEquals(a, a.getReplacement());
59+
assertEquals(b, b.getReplacement());
60+
assertEquals(c, c.getReplacement());
61+
}
62+
}

0 commit comments

Comments
 (0)