diff options
Diffstat (limited to 'src/org/jetbrains/java/decompiler/modules/decompiler/PPandMMHelper.java')
-rw-r--r-- | src/org/jetbrains/java/decompiler/modules/decompiler/PPandMMHelper.java | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/PPandMMHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/PPandMMHelper.java new file mode 100644 index 0000000..be90625 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/PPandMMHelper.java @@ -0,0 +1,153 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.modules.decompiler; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; + +import org.jetbrains.java.decompiler.modules.decompiler.exps.AssignmentExprent; +import org.jetbrains.java.decompiler.modules.decompiler.exps.ConstExprent; +import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent; +import org.jetbrains.java.decompiler.modules.decompiler.exps.FunctionExprent; +import org.jetbrains.java.decompiler.modules.decompiler.sforms.DirectGraph; +import org.jetbrains.java.decompiler.modules.decompiler.sforms.DirectNode; +import org.jetbrains.java.decompiler.modules.decompiler.sforms.FlattenStatementsHelper; +import org.jetbrains.java.decompiler.modules.decompiler.stats.RootStatement; +import org.jetbrains.java.decompiler.struct.gen.VarType; + +public class PPandMMHelper { + + private boolean exprentReplaced; + + public boolean findPPandMM(RootStatement root) { + + FlattenStatementsHelper flatthelper = new FlattenStatementsHelper(); + DirectGraph dgraph = flatthelper.buildDirectGraph(root); + + LinkedList<DirectNode> stack = new LinkedList<DirectNode>(); + stack.add(dgraph.first); + + HashSet<DirectNode> setVisited = new HashSet<DirectNode>(); + + boolean res = false; + + while(!stack.isEmpty()) { + + DirectNode node = stack.removeFirst(); + + if(setVisited.contains(node)) { + continue; + } + setVisited.add(node); + + res |= processExprentList(node.exprents); + + stack.addAll(node.succs); + } + + return res; + } + + private boolean processExprentList(List<Exprent> lst) { + + boolean result = false; + + for(int i=0;i<lst.size();i++) { + Exprent exprent = lst.get(i); + exprentReplaced = false; + + Exprent retexpr = processExprentRecursive(exprent); + if(retexpr != null) { + lst.set(i, retexpr); + + result = true; + i--; // process the same exprent again + } + + result |= exprentReplaced; + } + + return result; + } + + private Exprent processExprentRecursive(Exprent exprent) { + + boolean replaced = true; + while(replaced) { + replaced = false; + + for(Exprent expr: exprent.getAllExprents()) { + Exprent retexpr = processExprentRecursive(expr); + if(retexpr != null) { + exprent.replaceExprent(expr, retexpr); + replaced = true; + exprentReplaced = true; + break; + } + } + } + + if(exprent.type == Exprent.EXPRENT_ASSIGNMENT) { + AssignmentExprent as = (AssignmentExprent)exprent; + + if(as.getRight().type == Exprent.EXPRENT_FUNCTION) { + FunctionExprent func = (FunctionExprent)as.getRight(); + + VarType midlayer = null; + if(func.getFunctype() >= FunctionExprent.FUNCTION_I2L && + func.getFunctype() <= FunctionExprent.FUNCTION_I2S) { + midlayer = func.getSimpleCastType(); + if(func.getLstOperands().get(0).type == Exprent.EXPRENT_FUNCTION) { + func = (FunctionExprent)func.getLstOperands().get(0); + } else { + return null; + } + } + + if(func.getFunctype() == FunctionExprent.FUNCTION_ADD || + func.getFunctype() == FunctionExprent.FUNCTION_SUB) { + Exprent econd = func.getLstOperands().get(0); + Exprent econst = func.getLstOperands().get(1); + + if(econst.type != Exprent.EXPRENT_CONST && econd.type == Exprent.EXPRENT_CONST && + func.getFunctype() == FunctionExprent.FUNCTION_ADD) { + econd = econst; + econst = func.getLstOperands().get(0); + } + + if(econst.type == Exprent.EXPRENT_CONST && ((ConstExprent)econst).hasValueOne()) { + Exprent left = as.getLeft(); + + VarType condtype = econd.getExprType(); + if(left.equals(econd) && (midlayer == null || midlayer.equals(condtype))) { + FunctionExprent ret = new FunctionExprent( + func.getFunctype() == FunctionExprent.FUNCTION_ADD?FunctionExprent.FUNCTION_PPI:FunctionExprent.FUNCTION_MMI, + Arrays.asList(new Exprent[]{econd})); + ret.setImplicitType(condtype); + + exprentReplaced = true; + return ret; + } + } + } + } + } + + return null; + } + +} |