Search in sources :

Example 1 with LabelStmt

use of com.googlecode.dex2jar.ir.stmt.LabelStmt in project dex2jar by pxb1988.

the class DeadCodeTransformer method transform.

@Override
public void transform(IrMethod method) {
    Cfg.createCFG(method);
    Cfg.dfsVisit(method, null);
    if (method.traps != null) {
        for (Iterator<Trap> it = method.traps.iterator(); it.hasNext(); ) {
            Trap t = it.next();
            boolean allNotThrow = true;
            for (Stmt p = t.start; p != t.end; p = p.getNext()) {
                if (p.visited && Cfg.isThrow(p)) {
                    allNotThrow = false;
                    break;
                }
            }
            if (allNotThrow) {
                it.remove();
                continue;
            }
            boolean allNotVisited = true;
            boolean allVisited = true;
            for (LabelStmt labelStmt : t.handlers) {
                if (labelStmt.visited) {
                    allNotVisited = false;
                } else {
                    allVisited = false;
                }
            }
            if (allNotVisited) {
                it.remove();
            } else {
                // keep start and end
                t.start.visited = true;
                t.end.visited = true;
                if (!allVisited) {
                    // part visited
                    List<String> types = new ArrayList<>(t.handlers.length);
                    List<LabelStmt> labelStmts = new ArrayList<>(t.handlers.length);
                    for (int i = 0; i < t.handlers.length; i++) {
                        labelStmts.add(t.handlers[i]);
                        types.add(t.types[i]);
                    }
                    t.handlers = labelStmts.toArray(new LabelStmt[labelStmts.size()]);
                    t.types = types.toArray(new String[types.size()]);
                }
            }
        }
    }
    Set<Local> definedLocals = new HashSet<>();
    for (Iterator<Stmt> it = method.stmts.iterator(); it.hasNext(); ) {
        Stmt p = it.next();
        if (!p.visited) {
            it.remove();
            continue;
        }
        if (p.st == Stmt.ST.ASSIGN || p.st == Stmt.ST.IDENTITY) {
            if (p.getOp1().vt == Value.VT.LOCAL) {
                definedLocals.add((Local) p.getOp1());
            }
        }
    }
    if (method.phiLabels != null) {
        for (Iterator<LabelStmt> it = method.phiLabels.iterator(); it.hasNext(); ) {
            LabelStmt labelStmt = it.next();
            if (!labelStmt.visited) {
                it.remove();
                continue;
            }
            if (labelStmt.phis != null) {
                for (AssignStmt phi : labelStmt.phis) {
                    definedLocals.add((Local) phi.getOp1());
                }
            }
        }
    }
    method.locals.clear();
    method.locals.addAll(definedLocals);
    Set<Value> tmp = new HashSet<>();
    if (method.phiLabels != null) {
        for (Iterator<LabelStmt> it = method.phiLabels.iterator(); it.hasNext(); ) {
            LabelStmt labelStmt = it.next();
            if (labelStmt.phis != null) {
                for (AssignStmt phi : labelStmt.phis) {
                    PhiExpr phiExpr = (PhiExpr) phi.getOp2();
                    boolean needRebuild = false;
                    for (Value v : phiExpr.getOps()) {
                        if (!definedLocals.contains(v)) {
                            needRebuild = true;
                            break;
                        }
                    }
                    if (needRebuild) {
                        for (Value v : phiExpr.getOps()) {
                            if (definedLocals.contains(v)) {
                                tmp.add(v);
                            }
                        }
                        phiExpr.setOps(tmp.toArray(new Value[tmp.size()]));
                        tmp.clear();
                    }
                }
            }
        }
    }
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Local(com.googlecode.dex2jar.ir.expr.Local) Trap(com.googlecode.dex2jar.ir.Trap) LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Stmt(com.googlecode.dex2jar.ir.stmt.Stmt) PhiExpr(com.googlecode.dex2jar.ir.expr.PhiExpr) Value(com.googlecode.dex2jar.ir.expr.Value)

Example 2 with LabelStmt

use of com.googlecode.dex2jar.ir.stmt.LabelStmt in project dex2jar by pxb1988.

the class IrMethod method clone.

public IrMethod clone() {
    IrMethod n = new IrMethod();
    LabelAndLocalMapper mapper = new LabelAndLocalMapper();
    n.name = name;
    n.args = args;
    n.isStatic = isStatic;
    n.owner = owner;
    n.ret = ret;
    n.stmts = stmts.clone(mapper);
    for (Trap trap : traps) {
        n.traps.add(trap.clone(mapper));
    }
    for (LocalVar var : vars) {
        n.vars.add(var.clone(mapper));
    }
    if (phiLabels != null) {
        List<LabelStmt> nPhiLabels = new ArrayList<>(phiLabels.size());
        for (LabelStmt labelStmt : phiLabels) {
            nPhiLabels.add(labelStmt.clone(mapper));
        }
        n.phiLabels = nPhiLabels;
    }
    for (Local local : locals) {
        n.locals.add((Local) local.clone(mapper));
    }
    return n;
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) ArrayList(java.util.ArrayList) Local(com.googlecode.dex2jar.ir.expr.Local)

Example 3 with LabelStmt

use of com.googlecode.dex2jar.ir.stmt.LabelStmt in project dex2jar by pxb1988.

the class LabelAndLocalMapper method map.

public LabelStmt map(LabelStmt label) {
    LabelStmt nTarget = labels.get(label);
    if (nTarget == null) {
        nTarget = Stmts.nLabel();
        labels.put(label, nTarget);
    }
    return nTarget;
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt)

Example 4 with LabelStmt

use of com.googlecode.dex2jar.ir.stmt.LabelStmt in project dex2jar by pxb1988.

the class RemoveLocalFromSSA method replacePhi.

private void replacePhi(List<LabelStmt> phiLabels, Map<Local, Local> toReplace, Set<Value> set) {
    if (phiLabels != null) {
        for (LabelStmt labelStmt : phiLabels) {
            for (AssignStmt phi : labelStmt.phis) {
                Value[] ops = phi.getOp2().getOps();
                for (Value op : ops) {
                    Value n = toReplace.get(op);
                    if (n != null) {
                        set.add(n);
                    } else {
                        set.add(op);
                    }
                }
                set.remove(phi.getOp1());
                phi.getOp2().setOps(set.toArray(new Value[set.size()]));
                set.clear();
            }
        }
    }
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Value(com.googlecode.dex2jar.ir.expr.Value)

Example 5 with LabelStmt

use of com.googlecode.dex2jar.ir.stmt.LabelStmt in project dex2jar by pxb1988.

the class RemoveLocalFromSSA method removeLoopFromPhi.

private boolean removeLoopFromPhi(List<LabelStmt> phiLabels, Map<Local, Local> toReplace) {
    boolean changed = false;
    if (phiLabels != null) {
        Set<Local> toDeletePhiAssign = new HashSet<>();
        Map<Local, PhiObject> phis;
        // detect loop init in phi
        phis = collectPhiObjects(phiLabels);
        Queue<PhiObject> q = new UniqueQueue<>();
        q.addAll(phis.values());
        while (!q.isEmpty()) {
            PhiObject po = q.poll();
            for (PhiObject child : po.children) {
                if (child.isInitByPhi) {
                    if (child.parent.addAll(po.parent)) {
                        q.add(child);
                    }
                }
            }
        }
        for (PhiObject po : phis.values()) {
            if (po.isInitByPhi) {
                Local local = null;
                for (PhiObject p : po.parent) {
                    if (!p.isInitByPhi) {
                        if (local == null) {
                            // the first non-phi value
                            local = p.local;
                        } else {
                            local = null;
                            break;
                        }
                    }
                }
                if (local != null) {
                    toReplace.put(po.local, local);
                    toDeletePhiAssign.add(po.local);
                    changed = true;
                }
            }
        }
        for (Iterator<LabelStmt> itLabel = phiLabels.iterator(); itLabel.hasNext(); ) {
            LabelStmt labelStmt = itLabel.next();
            for (Iterator<AssignStmt> it = labelStmt.phis.iterator(); it.hasNext(); ) {
                AssignStmt phi = it.next();
                if (toDeletePhiAssign.contains(phi.getOp1())) {
                    it.remove();
                }
            }
            if (labelStmt.phis.size() == 0) {
                labelStmt.phis = null;
                itLabel.remove();
            }
        }
    }
    return changed;
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Local(com.googlecode.dex2jar.ir.expr.Local)

Aggregations

LabelStmt (com.googlecode.dex2jar.ir.stmt.LabelStmt)39 Local (com.googlecode.dex2jar.ir.expr.Local)26 Stmt (com.googlecode.dex2jar.ir.stmt.Stmt)22 AssignStmt (com.googlecode.dex2jar.ir.stmt.AssignStmt)17 Test (org.junit.Test)14 Value (com.googlecode.dex2jar.ir.expr.Value)8 ArrayList (java.util.ArrayList)7 Trap (com.googlecode.dex2jar.ir.Trap)4 JumpStmt (com.googlecode.dex2jar.ir.stmt.JumpStmt)4 StmtList (com.googlecode.dex2jar.ir.stmt.StmtList)4 List (java.util.List)3 StmtTraveler (com.googlecode.dex2jar.ir.StmtTraveler)2 PhiExpr (com.googlecode.dex2jar.ir.expr.PhiExpr)2 Cfg (com.googlecode.dex2jar.ir.ts.Cfg)2 HashSet (java.util.HashSet)2 IR2JConverter (com.googlecode.d2j.converter.IR2JConverter)1 DexFileNode (com.googlecode.d2j.node.DexFileNode)1 DexMethodNode (com.googlecode.d2j.node.DexMethodNode)1 IrMethod (com.googlecode.dex2jar.ir.IrMethod)1 LabelAndLocalMapper (com.googlecode.dex2jar.ir.LabelAndLocalMapper)1