Search in sources :

Example 1 with TravelCallBack

use of com.googlecode.dex2jar.ir.ts.Cfg.TravelCallBack in project dex2jar by pxb1988.

the class SSATransformer method prepare.

private boolean prepare(final IrMethod method) {
    int index = Cfg.reIndexLocal(method);
    final int[] readCounts = new int[index];
    final int[] writeCounts = new int[index];
    Cfg.travel(method.stmts, new TravelCallBack() {

        @Override
        public Value onAssign(Local v, AssignStmt as) {
            writeCounts[v._ls_index]++;
            return v;
        }

        @Override
        public Value onUse(Local v) {
            readCounts[v._ls_index]++;
            return v;
        }
    }, true);
    boolean needTravel = false;
    boolean needSSAAnalyze = false;
    index = 0;
    List<Local> oldLocals = method.locals;
    List<Local> locals = new ArrayList<>(oldLocals);
    oldLocals.clear();
    for (Local local : locals) {
        int idx = local._ls_index;
        int read = readCounts[idx];
        int write = writeCounts[idx];
        if (read > 0 && write == 0) {
        // TODO if we need throw exception ?
        // or the code is dead?
        }
        if (read == 0 && write == 0) {
        // ignore the local
        } else {
            if (write <= 1) {
                // no phi require
                local._ls_index = -1;
                oldLocals.add(local);
            } else if (read == 0) {
                local._ls_index = -2;
                needTravel = true;
            // we are going to duplicate each usage of the local and add to method.locals,
            // so not add the original local to method.locals
            } else {
                needSSAAnalyze = true;
                local._ls_index = index++;
                oldLocals.add(local);
            }
        }
    }
    if (needSSAAnalyze || needTravel) {
        Cfg.travelMod(method.stmts, new TravelCallBack() {

            @Override
            public Value onAssign(Local v, AssignStmt as) {
                if (v._ls_index == -1) {
                    return v;
                } else if (v._ls_index == -2) {
                    Local n = (Local) v.clone();
                    method.locals.add(n);
                    return n;
                }
                // others
                return v.clone();
            }

            @Override
            public Value onUse(Local v) {
                if (v._ls_index == -1) {
                    return v;
                }
                return v.clone();
            }
        }, true);
    }
    return needSSAAnalyze;
}
Also used : TravelCallBack(com.googlecode.dex2jar.ir.ts.Cfg.TravelCallBack) Value(com.googlecode.dex2jar.ir.expr.Value) AnalyzeValue(com.googlecode.dex2jar.ir.ts.an.AnalyzeValue) Local(com.googlecode.dex2jar.ir.expr.Local)

Example 2 with TravelCallBack

use of com.googlecode.dex2jar.ir.ts.Cfg.TravelCallBack in project dex2jar by pxb1988.

the class SSATransformer method replaceLocalsWithSSA.

private void replaceLocalsWithSSA(final IrMethod method) {
    final List<Local> locals = method.locals;
    locals.clear();
    StmtList stmts = method.stmts;
    TravelCallBack tcb = new TravelCallBack() {

        @Override
        public Value onAssign(Local a, AssignStmt as) {
            if (a._ls_index < 0) {
                locals.add(a);
                return a;
            }
            SSAValue lsv = (SSAValue) a.tag;
            Local b = lsv.local;
            locals.add(b);
            return b;
        }

        @Override
        public Value onUse(Local a) {
            if (a._ls_index < 0) {
                return a;
            }
            SSAValue lsv = (SSAValue) a.tag;
            Local b = lsv.local;
            return b;
        }
    };
    Set<Value> froms = new HashSet<>();
    List<LabelStmt> phiLabels = new ArrayList<>();
    // 2. we are looking for Phis and insert Phi node to the code
    for (Stmt p = stmts.getFirst(); p != null; p = p.getNext()) {
        if (p.st == ST.LABEL) {
            LabelStmt labelStmt = (LabelStmt) p;
            List<AssignStmt> phis = null;
            SSAValue[] frame = (SSAValue[]) p.frame;
            if (frame != null) {
                for (SSAValue v : frame) {
                    if (v == null || !v.used) {
                        continue;
                    }
                    if (v.parent != null) {
                        froms.add(v.parent.local);
                    }
                    if (v.otherParents != null) {
                        for (SSAValue parent : v.otherParents) {
                            froms.add(parent.local);
                        }
                    }
                    froms.remove(v.local);
                    if (phis == null) {
                        phis = new ArrayList<>();
                    }
                    locals.add(v.local);
                    phis.add(Stmts.nAssign(v.local, Exprs.nPhi(froms.toArray(new Value[froms.size()]))));
                    froms.clear();
                }
            }
            labelStmt.phis = phis;
            if (phis != null) {
                phiLabels.add(labelStmt);
            }
        } else {
            Cfg.travelMod(p, tcb, true);
        }
        p.frame = null;
    }
    if (phiLabels.size() > 0) {
        method.phiLabels = phiLabels;
    }
}
Also used : TravelCallBack(com.googlecode.dex2jar.ir.ts.Cfg.TravelCallBack) Local(com.googlecode.dex2jar.ir.expr.Local) Value(com.googlecode.dex2jar.ir.expr.Value) AnalyzeValue(com.googlecode.dex2jar.ir.ts.an.AnalyzeValue)

Aggregations

Local (com.googlecode.dex2jar.ir.expr.Local)2 Value (com.googlecode.dex2jar.ir.expr.Value)2 TravelCallBack (com.googlecode.dex2jar.ir.ts.Cfg.TravelCallBack)2 AnalyzeValue (com.googlecode.dex2jar.ir.ts.an.AnalyzeValue)2