- fixed the IndexOutOfBoundsException exception when decompiling

FastStringBuffer   
- fixed typo in LITERALS_AS_IS definition
- some helper stuff
This commit is contained in:
Stiver 2014-05-29 18:13:17 +02:00
parent 1119499562
commit c286d42c5b
7 changed files with 50 additions and 15 deletions

View File

@ -28,7 +28,7 @@ public interface IFernflowerPreferences {
public static final String NO_EXCEPTIONS_RETURN = "ner"; public static final String NO_EXCEPTIONS_RETURN = "ner";
public static final String DECOMPILE_ENUM = "den"; public static final String DECOMPILE_ENUM = "den";
public static final String REMOVE_GETCLASS_NEW = "rgn"; 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 BOOLEAN_TRUE_ONE = "bto";
public static final String SYNTHETIC_NOT_SET = "nns"; public static final String SYNTHETIC_NOT_SET = "nns";
public static final String UNDEFINED_PARAM_TYPE_OBJECT = "uto"; public static final String UNDEFINED_PARAM_TYPE_OBJECT = "uto";

View File

@ -186,7 +186,7 @@ public class MethodProcessorThread implements Runnable {
StackVarsProcessor stackproc = new StackVarsProcessor(); StackVarsProcessor stackproc = new StackVarsProcessor();
stackproc.simplifyStackVars(root, mt, cl); stackproc.simplifyStackVars(root, mt, cl);
// System.out.println("~~~~~~~~~~~~~~~~~~~~~~ \r\n"+root.toJava()); //System.out.println("~~~~~~~~~~~~~~~~~~~~~~ \r\n"+root.toJava());
varproc.setVarVersions(root); varproc.setVarVersions(root);
@ -216,14 +216,15 @@ public class MethodProcessorThread implements Runnable {
if(DecompilerContext.getOption(IFernflowerPreferences.IDEA_NOT_NULL_ANNOTATION)) { if(DecompilerContext.getOption(IFernflowerPreferences.IDEA_NOT_NULL_ANNOTATION)) {
IdeaNotNullHelper.removeHardcodedChecks(root, mt); if(IdeaNotNullHelper.removeHardcodedChecks(root, mt)) {
SequenceHelper.condenseSequences(root); SequenceHelper.condenseSequences(root);
StackVarsProcessor stackproc = new StackVarsProcessor(); StackVarsProcessor stackproc = new StackVarsProcessor();
stackproc.simplifyStackVars(root, mt, cl); stackproc.simplifyStackVars(root, mt, cl);
varproc.setVarVersions(root); varproc.setVarVersions(root);
}
} }
LabelHelper.identifyLabels(root); LabelHelper.identifyLabels(root);

View File

@ -36,13 +36,21 @@ import de.fernflower.util.VBStyleCollection;
public class IdeaNotNullHelper { 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 // 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 // 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) { private static boolean findAndRemoveParameterCheck(Statement stat, StructMethod mt) {

View File

@ -33,6 +33,7 @@ import de.fernflower.modules.decompiler.sforms.DirectNode;
import de.fernflower.modules.decompiler.sforms.FlattenStatementsHelper; import de.fernflower.modules.decompiler.sforms.FlattenStatementsHelper;
import de.fernflower.modules.decompiler.sforms.SSAConstructorSparseEx; import de.fernflower.modules.decompiler.sforms.SSAConstructorSparseEx;
import de.fernflower.modules.decompiler.sforms.SSAUConstructorSparseEx; 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.RootStatement;
import de.fernflower.modules.decompiler.stats.Statement; import de.fernflower.modules.decompiler.stats.Statement;
import de.fernflower.modules.decompiler.vars.VarVersionEdge; import de.fernflower.modules.decompiler.vars.VarVersionEdge;
@ -218,6 +219,21 @@ public class StackVarsProcessor {
stack.add(ndx); stack.add(ndx);
stackMaps.add(new HashMap<VarVersionPaar, Exprent>(mapVarValues)); 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; return res;

View File

@ -419,6 +419,9 @@ public class SSAUConstructorSparseEx {
FastSparseSet<Integer> versCopy = vers.getCopy(); FastSparseSet<Integer> versCopy = vers.getCopy();
HashSet<Integer> phiVers = new HashSet<Integer>(); 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 // ssu graph
VarVersionNode phinode = ssuversions.nodes.getWithKey(phivar); VarVersionNode phinode = ssuversions.nodes.getWithKey(phivar);
List<VarVersionEdge> lstPreds = new ArrayList<VarVersionEdge>(phinode.preds); List<VarVersionEdge> lstPreds = new ArrayList<VarVersionEdge>(phinode.preds);
@ -430,7 +433,7 @@ public class SSAUConstructorSparseEx {
} else { } else {
for(VarVersionEdge edge: lstPreds) { for(VarVersionEdge edge: lstPreds) {
int verssrc = edge.source.preds.iterator().next().source.version; int verssrc = edge.source.preds.iterator().next().source.version;
if(!vers.contains(verssrc)) { if(!vers.contains(verssrc) && verssrc != ppvers) {
edge.source.removeSuccessor(edge); edge.source.removeSuccessor(edge);
phinode.removePredecessor(edge); phinode.removePredecessor(edge);
} else { } else {

View File

@ -51,6 +51,9 @@ public class VarVersionEdge { // FIXME: can be removed?
return hashCode; return hashCode;
} }
@Override
public String toString() {
return source.toString() + " ->" + type + "-> " + dest.toString();
}
} }

View File

@ -150,6 +150,10 @@ public class DotExporter {
private static String directBlockIdToDot(String id) { private static String directBlockIdToDot(String id) {
id = id.replaceAll("_try", "999"); id = id.replaceAll("_try", "999");
id = id.replaceAll("_tail", "888"); id = id.replaceAll("_tail", "888");
id = id.replaceAll("_init", "111");
id = id.replaceAll("_cond", "222");
id = id.replaceAll("_inc", "333");
return id; return id;
} }