Search in sources :

Example 56 with Local

use of com.googlecode.dex2jar.ir.expr.Local in project dex2jar by pxb1988.

the class AggTransformerTest method t001.

@Test
public void t001() {
    Local a = addLocal("a");
    addStmt(nAssign(a, nNewIntArray(nInt(5))));
    addStmt(nReturn(a));
    transform();
    Assert.assertEquals("only `return new int[5]` should left.", 1, stmts.getSize());
    Assert.assertEquals("no local should left", 0, locals.size());
}
Also used : Local(com.googlecode.dex2jar.ir.expr.Local) Test(org.junit.Test)

Example 57 with Local

use of com.googlecode.dex2jar.ir.expr.Local in project dex2jar by pxb1988.

the class ConstTransformerTest method test02.

@Test
public void test02() {
    // test local loop
    IrMethod jm = new IrMethod();
    Local a = nLocal("a");
    Local p = nLocal("p");
    Local q = nLocal("q");
    jm.locals.add(a);
    jm.locals.add(p);
    jm.locals.add(q);
    jm.stmts.add(nAssign(a, nString("a String")));
    jm.stmts.add(nAssign(p, Exprs.nPhi(a, q)));
    jm.stmts.add(nAssign(q, Exprs.nPhi(p)));
    UnopStmt retStmt = nReturn(q);
    jm.stmts.add(retStmt);
    new ConstTransformer().transform(jm);
    Assert.assertTrue(jm.locals.size() == 3);
    Assert.assertTrue(jm.stmts.getSize() == 4);
    Assert.assertEquals("a String", ((Constant) retStmt.op.trim()).value);
}
Also used : ConstTransformer(com.googlecode.dex2jar.ir.ts.ConstTransformer) Exprs.nLocal(com.googlecode.dex2jar.ir.expr.Exprs.nLocal) Local(com.googlecode.dex2jar.ir.expr.Local) IrMethod(com.googlecode.dex2jar.ir.IrMethod) UnopStmt(com.googlecode.dex2jar.ir.stmt.UnopStmt) Test(org.junit.Test)

Example 58 with Local

use of com.googlecode.dex2jar.ir.expr.Local in project dex2jar by pxb1988.

the class UnSSATransformer method insertAssignPath.

private void insertAssignPath(StmtList stmts, Stmt from, LabelStmt labelStmt, List<AssignStmt> buff) {
    boolean insertBeforeFromStmt;
    if (from.exceptionHandlers != null && from.exceptionHandlers.contains(labelStmt)) {
        insertBeforeFromStmt = true;
    } else {
        switch(from.st) {
            case GOTO:
            case IF:
                JumpStmt jumpStmt = (JumpStmt) from;
                //
                insertBeforeFromStmt = jumpStmt.getTarget().equals(labelStmt);
                break;
            case TABLE_SWITCH:
            case LOOKUP_SWITCH:
                insertBeforeFromStmt = true;
                break;
            default:
                insertBeforeFromStmt = false;
                break;
        }
    }
    if (insertBeforeFromStmt) {
        for (AssignStmt as : buff) {
            stmts.insertBefore(from, as);
        }
    } else {
        for (AssignStmt as : buff) {
            stmts.insertAfter(from, as);
        }
    }
    LiveV[] frame = (LiveV[]) from.frame;
    List<LiveV> newLiveVs = new ArrayList<>(buff.size());
    for (AssignStmt as : buff) {
        Local left = (Local) as.getOp1();
        {
            LiveV liveV = new LiveV();
            liveV.local = left;
            liveV.used = true;
            newLiveVs.add(liveV);
        }
        RegAssign leftRegAssign = (RegAssign) left.tag;
        Local right = (Local) as.getOp2();
        int toSkip = right._ls_index;
        for (int i = 0; i < frame.length; i++) {
            if (i == toSkip) {
                continue;
            }
            LiveV v = frame[i];
            if (v != null && v.used) {
                RegAssign assign = (RegAssign) v.local.tag;
                assign.excludes.add(leftRegAssign);
                leftRegAssign.excludes.add(assign);
            }
        }
        for (AssignStmt as2 : buff) {
            RegAssign assign = (RegAssign) ((Local) as2.getOp1()).tag;
            assign.excludes.add(leftRegAssign);
            leftRegAssign.excludes.add(assign);
        }
    }
    LiveV[] newFrame = new LiveV[frame.length + newLiveVs.size()];
    System.arraycopy(frame, 0, newFrame, 0, frame.length);
    for (int i = 0; i < newLiveVs.size(); i++) {
        newFrame[i + frame.length] = newLiveVs.get(i);
    }
}
Also used : JumpStmt(com.googlecode.dex2jar.ir.stmt.JumpStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) ArrayList(java.util.ArrayList) Local(com.googlecode.dex2jar.ir.expr.Local)

Example 59 with Local

use of com.googlecode.dex2jar.ir.expr.Local in project dex2jar by pxb1988.

the class UnSSATransformer method transform.

@Override
public void transform(IrMethod method) {
    if (method.phiLabels == null || method.phiLabels.size() == 0) {
        return;
    }
    // 1. Live analyze the method,
    // a. remove Phi,
    // b. record parameter reference
    LiveA liveA = new LiveA(method);
    liveA.analyze();
    genRegGraph(method, liveA);
    // 2. insert x=y
    fixPhi(method, method.phiLabels);
    insertAssignPath(method, method.phiLabels);
    // 4. clean up
    for (Local local : method.locals) {
        local.tag = null;
    }
    for (Stmt stmt : method.stmts) {
        stmt.frame = null;
    }
    for (LabelStmt labelStmt : method.phiLabels) {
        labelStmt.phis = null;
    }
    method.phiLabels = null;
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) Local(com.googlecode.dex2jar.ir.expr.Local) LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) JumpStmt(com.googlecode.dex2jar.ir.stmt.JumpStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Stmt(com.googlecode.dex2jar.ir.stmt.Stmt)

Example 60 with Local

use of com.googlecode.dex2jar.ir.expr.Local in project dex2jar by pxb1988.

the class UnSSATransformer method fixPhi.

/**
     * there is somewhere both a and its possible x is both live, insert a=x, will change the meaning for example
     * 
     * <pre>
     *                      L0:
     *                      a = phi(b, ... )
     *                      b = 234;
     *                      if a>0 goto L0: // a, b both live here
     *                      ...
     * </pre>
     * 
     * after insert a=b before the if stmt, the programe change to
     * 
     * <pre>
     *                      L0:
     *                      // a = phi(b, ... )
     *                      b = 234;
     *                      a = b
     *                      if a>0 goto L0:
     *                      ...
     * </pre>
     * 
     * the solution is by introduce a new local x
     * 
     * <pre>
     *                      L0:
     *                      x = phi(b, ... )
     *                      a = x
     *                      b = 234;
     *                      if a>0 goto L0: // a, b both live here
     *                      ...
     * </pre>
     * 
     * insert x = b is ok now
     * 
     * <pre>
     *                      L0:
     *                      // x = phi(b, ... )
     *                      a = x
     *                      b = 234;
     *                      x = b
     *                      if a>0 goto L0: // a, b both live here
     *                      ...
     * </pre>
     * 
     * @param phiLabels
     */
private void fixPhi(IrMethod method, Collection<LabelStmt> phiLabels) {
    for (LabelStmt labelStmt : phiLabels) {
        List<AssignStmt> phis = (List<AssignStmt>) labelStmt.phis;
        for (AssignStmt phi : phis) {
            Local a = (Local) phi.getOp1();
            PhiExpr b = (PhiExpr) phi.getOp2();
            boolean introduceNewLocal = false;
            RegAssign aReg = (RegAssign) a.tag;
            for (Value op : b.getOps()) {
                RegAssign bReg = (RegAssign) ((Local) op).tag;
                if (aReg.excludes.contains(bReg)) {
                    introduceNewLocal = true;
                    break;
                }
            }
            if (introduceNewLocal) {
                Local newLocal = (Local) a.clone();
                if (DEBUG) {
                    newLocal.debugName = "x" + method.locals.size();
                }
                phi.op1 = newLocal;
                RegAssign newRegAssign = new RegAssign();
                newLocal.tag = newRegAssign;
                method.locals.add(newLocal);
                Stmt newAssigStmt = Stmts.nAssign(a, newLocal);
                Stmt next = labelStmt.getNext();
                if (next != null && next.st == ST.IDENTITY && next.getOp2().vt == VT.EXCEPTION_REF) {
                    // it's a handler, insert after the exception ref
                    method.stmts.insertAfter(next, newAssigStmt);
                } else {
                    method.stmts.insertAfter(labelStmt, newAssigStmt);
                }
                LiveV[] frame = (LiveV[]) labelStmt.frame;
                if (DEBUG) {
                    LiveV[] copy = frame.clone();
                    LiveV n = new LiveV();
                    n.local = a;
                    n.used = true;
                    copy[a._ls_index] = new LiveV();
                    newAssigStmt.frame = copy;
                }
                LiveV thePhi = frame[a._ls_index];
                thePhi.local = newLocal;
                for (LiveV v : frame) {
                    if (v != null && v.used) {
                        RegAssign s = (RegAssign) v.local.tag;
                        s.excludes.add(newRegAssign);
                        newRegAssign.excludes.add(s);
                    }
                }
            }
        }
    }
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) PhiExpr(com.googlecode.dex2jar.ir.expr.PhiExpr) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Value(com.googlecode.dex2jar.ir.expr.Value) AnalyzeValue(com.googlecode.dex2jar.ir.ts.an.AnalyzeValue) Local(com.googlecode.dex2jar.ir.expr.Local) StmtList(com.googlecode.dex2jar.ir.stmt.StmtList) ArrayList(java.util.ArrayList) List(java.util.List) LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) JumpStmt(com.googlecode.dex2jar.ir.stmt.JumpStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Stmt(com.googlecode.dex2jar.ir.stmt.Stmt)

Aggregations

Local (com.googlecode.dex2jar.ir.expr.Local)86 Test (org.junit.Test)44 LabelStmt (com.googlecode.dex2jar.ir.stmt.LabelStmt)28 Stmt (com.googlecode.dex2jar.ir.stmt.Stmt)23 Value (com.googlecode.dex2jar.ir.expr.Value)19 AssignStmt (com.googlecode.dex2jar.ir.stmt.AssignStmt)15 ArrayList (java.util.ArrayList)8 IrMethod (com.googlecode.dex2jar.ir.IrMethod)6 Exprs.nLocal (com.googlecode.dex2jar.ir.expr.Exprs.nLocal)6 UnopStmt (com.googlecode.dex2jar.ir.stmt.UnopStmt)6 JumpStmt (com.googlecode.dex2jar.ir.stmt.JumpStmt)5 ConstTransformer (com.googlecode.dex2jar.ir.ts.ConstTransformer)5 Exprs.nString (com.googlecode.dex2jar.ir.expr.Exprs.nString)4 StmtList (com.googlecode.dex2jar.ir.stmt.StmtList)4 Trap (com.googlecode.dex2jar.ir.Trap)3 Exprs.nArrayValue (com.googlecode.dex2jar.ir.expr.Exprs.nArrayValue)3 AnalyzeValue (com.googlecode.dex2jar.ir.ts.an.AnalyzeValue)3 List (java.util.List)3 DexLabel (com.googlecode.d2j.DexLabel)2 Op (com.googlecode.d2j.reader.Op)2