summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/de/fernflower/main/extern/IFernflowerPreferences.java2
-rw-r--r--src/de/fernflower/main/rels/MethodProcessorThread.java17
-rw-r--r--src/de/fernflower/modules/decompiler/IdeaNotNullHelper.java14
-rw-r--r--src/de/fernflower/modules/decompiler/StackVarsProcessor.java16
-rw-r--r--src/de/fernflower/modules/decompiler/sforms/SSAUConstructorSparseEx.java7
-rw-r--r--src/de/fernflower/modules/decompiler/vars/VarVersionEdge.java5
-rw-r--r--test/test/util/DotExporter.java4
7 files changed, 50 insertions, 15 deletions
diff --git a/src/de/fernflower/main/extern/IFernflowerPreferences.java b/src/de/fernflower/main/extern/IFernflowerPreferences.java
index 5037107..3b923e7 100644
--- a/src/de/fernflower/main/extern/IFernflowerPreferences.java
+++ b/src/de/fernflower/main/extern/IFernflowerPreferences.java
@@ -28,7 +28,7 @@ public interface IFernflowerPreferences {
public static final String NO_EXCEPTIONS_RETURN = "ner";
public static final String DECOMPILE_ENUM = "den";
public static final String REMOVE_GETCLASS_NEW = "rgn";
- public static final String LITERALS_AS_IS = "bto";
+ public static final String LITERALS_AS_IS = "lit";
public static final String BOOLEAN_TRUE_ONE = "bto";
public static final String SYNTHETIC_NOT_SET = "nns";
public static final String UNDEFINED_PARAM_TYPE_OBJECT = "uto";
diff --git a/src/de/fernflower/main/rels/MethodProcessorThread.java b/src/de/fernflower/main/rels/MethodProcessorThread.java
index 3ec6db9..df5c925 100644
--- a/src/de/fernflower/main/rels/MethodProcessorThread.java
+++ b/src/de/fernflower/main/rels/MethodProcessorThread.java
@@ -186,7 +186,7 @@ public class MethodProcessorThread implements Runnable {
StackVarsProcessor stackproc = new StackVarsProcessor();
stackproc.simplifyStackVars(root, mt, cl);
-// System.out.println("~~~~~~~~~~~~~~~~~~~~~~ \r\n"+root.toJava());
+ //System.out.println("~~~~~~~~~~~~~~~~~~~~~~ \r\n"+root.toJava());
varproc.setVarVersions(root);
@@ -216,14 +216,15 @@ public class MethodProcessorThread implements Runnable {
if(DecompilerContext.getOption(IFernflowerPreferences.IDEA_NOT_NULL_ANNOTATION)) {
- IdeaNotNullHelper.removeHardcodedChecks(root, mt);
-
- SequenceHelper.condenseSequences(root);
+ if(IdeaNotNullHelper.removeHardcodedChecks(root, mt)) {
- StackVarsProcessor stackproc = new StackVarsProcessor();
- stackproc.simplifyStackVars(root, mt, cl);
-
- varproc.setVarVersions(root);
+ SequenceHelper.condenseSequences(root);
+
+ StackVarsProcessor stackproc = new StackVarsProcessor();
+ stackproc.simplifyStackVars(root, mt, cl);
+
+ varproc.setVarVersions(root);
+ }
}
LabelHelper.identifyLabels(root);
diff --git a/src/de/fernflower/modules/decompiler/IdeaNotNullHelper.java b/src/de/fernflower/modules/decompiler/IdeaNotNullHelper.java
index b5bb113..98035d3 100644
--- a/src/de/fernflower/modules/decompiler/IdeaNotNullHelper.java
+++ b/src/de/fernflower/modules/decompiler/IdeaNotNullHelper.java
@@ -36,13 +36,21 @@ import de.fernflower.util.VBStyleCollection;
public class IdeaNotNullHelper {
- public static void removeHardcodedChecks(Statement root, StructMethod mt) {
+ public static boolean removeHardcodedChecks(Statement root, StructMethod mt) {
+ boolean checks_removed = false;
+
// parameter @NotNull annotations
- while(findAndRemoveParameterCheck(root, mt)); // iterate until nothing found. Each invocation removes one parameter check.
+ while(findAndRemoveParameterCheck(root, mt)) { // iterate until nothing found. Each invocation removes one parameter check.
+ checks_removed = true;
+ }
// method @NotNull annotation
- while(findAndRemoveReturnCheck(root, mt)); // iterate until nothing found. Each invocation handles one method exit check.
+ while(findAndRemoveReturnCheck(root, mt)) { // iterate until nothing found. Each invocation handles one method exit check.
+ checks_removed = true;
+ }
+
+ return checks_removed;
}
private static boolean findAndRemoveParameterCheck(Statement stat, StructMethod mt) {
diff --git a/src/de/fernflower/modules/decompiler/StackVarsProcessor.java b/src/de/fernflower/modules/decompiler/StackVarsProcessor.java
index 1632355..a76229f 100644
--- a/src/de/fernflower/modules/decompiler/StackVarsProcessor.java
+++ b/src/de/fernflower/modules/decompiler/StackVarsProcessor.java
@@ -33,6 +33,7 @@ import de.fernflower.modules.decompiler.sforms.DirectNode;
import de.fernflower.modules.decompiler.sforms.FlattenStatementsHelper;
import de.fernflower.modules.decompiler.sforms.SSAConstructorSparseEx;
import de.fernflower.modules.decompiler.sforms.SSAUConstructorSparseEx;
+import de.fernflower.modules.decompiler.stats.DoStatement;
import de.fernflower.modules.decompiler.stats.RootStatement;
import de.fernflower.modules.decompiler.stats.Statement;
import de.fernflower.modules.decompiler.vars.VarVersionEdge;
@@ -218,6 +219,21 @@ public class StackVarsProcessor {
stack.add(ndx);
stackMaps.add(new HashMap<VarVersionPaar, Exprent>(mapVarValues));
}
+
+ // make sure the 3 special exprent lists in a loop (init, condition, increment) are not empty
+ // change loop type if necessary
+ if(nd.exprents.isEmpty() &&
+ (nd.type == DirectNode.NODE_INIT || nd.type == DirectNode.NODE_CONDITION || nd.type == DirectNode.NODE_INCREMENT)) {
+ nd.exprents.add(null);
+
+ if(nd.statement.type == Statement.TYPE_DO) {
+ DoStatement loop = (DoStatement)nd.statement;
+
+ if(nd.type == DirectNode.NODE_INCREMENT && loop.getLooptype() == DoStatement.LOOP_FOR) { // "downgrade" loop to 'while'
+ loop.setLooptype(DoStatement.LOOP_WHILE);
+ }
+ }
+ }
}
return res;
diff --git a/src/de/fernflower/modules/decompiler/sforms/SSAUConstructorSparseEx.java b/src/de/fernflower/modules/decompiler/sforms/SSAUConstructorSparseEx.java
index ef51e90..0fdcd47 100644
--- a/src/de/fernflower/modules/decompiler/sforms/SSAUConstructorSparseEx.java
+++ b/src/de/fernflower/modules/decompiler/sforms/SSAUConstructorSparseEx.java
@@ -418,7 +418,10 @@ public class SSAUConstructorSparseEx {
FastSparseSet<Integer> versCopy = vers.getCopy();
HashSet<Integer> phiVers = new HashSet<Integer>();
-
+
+ // take into account the corresponding mm/pp node if existing
+ int ppvers = phantomppnodes.containsKey(phivar) ? phantomppnodes.get(phivar).version : -1;
+
// ssu graph
VarVersionNode phinode = ssuversions.nodes.getWithKey(phivar);
List<VarVersionEdge> lstPreds = new ArrayList<VarVersionEdge>(phinode.preds);
@@ -430,7 +433,7 @@ public class SSAUConstructorSparseEx {
} else {
for(VarVersionEdge edge: lstPreds) {
int verssrc = edge.source.preds.iterator().next().source.version;
- if(!vers.contains(verssrc)) {
+ if(!vers.contains(verssrc) && verssrc != ppvers) {
edge.source.removeSuccessor(edge);
phinode.removePredecessor(edge);
} else {
diff --git a/src/de/fernflower/modules/decompiler/vars/VarVersionEdge.java b/src/de/fernflower/modules/decompiler/vars/VarVersionEdge.java
index 2fa7f03..aaedb2d 100644
--- a/src/de/fernflower/modules/decompiler/vars/VarVersionEdge.java
+++ b/src/de/fernflower/modules/decompiler/vars/VarVersionEdge.java
@@ -51,6 +51,9 @@ public class VarVersionEdge { // FIXME: can be removed?
return hashCode;
}
-
+ @Override
+ public String toString() {
+ return source.toString() + " ->" + type + "-> " + dest.toString();
+ }
}
diff --git a/test/test/util/DotExporter.java b/test/test/util/DotExporter.java
index 88b9320..61ee5eb 100644
--- a/test/test/util/DotExporter.java
+++ b/test/test/util/DotExporter.java
@@ -150,6 +150,10 @@ public class DotExporter {
private static String directBlockIdToDot(String id) {
id = id.replaceAll("_try", "999");
id = id.replaceAll("_tail", "888");
+
+ id = id.replaceAll("_init", "111");
+ id = id.replaceAll("_cond", "222");
+ id = id.replaceAll("_inc", "333");
return id;
}