Search in sources :

Example 1 with E2Stmt

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

the class ConstTransformer method collect.

private void collect(IrMethod m) {
    for (Stmt p = m.stmts.getFirst(); p != null; p = p.getNext()) {
        if (p.st == ST.ASSIGN || p.st == ST.IDENTITY) {
            E2Stmt e2 = (E2Stmt) p;
            Value op1 = e2.op1.trim();
            Value op2 = e2.op2.trim();
            if (op1.vt == VT.LOCAL) {
                ConstAnalyzeValue cav = (ConstAnalyzeValue) ((Local) op1).tag;
                if (op2.vt == VT.CONSTANT) {
                    Constant c = (Constant) op2;
                    cav.isConst = true;
                    cav.cst = c.value;
                } else if (op2.vt == VT.LOCAL) {
                    Local local2 = (Local) op2;
                    ConstAnalyzeValue zaf2 = (ConstAnalyzeValue) local2.tag;
                    cav.assignFrom.add(zaf2);
                    zaf2.assignTo.add(cav);
                } else if (op2.vt == VT.PHI) {
                    PhiExpr pe = (PhiExpr) op2;
                    for (Value v : pe.ops) {
                        ConstAnalyzeValue zaf2 = (ConstAnalyzeValue) ((Local) v.trim()).tag;
                        cav.assignFrom.add(zaf2);
                        zaf2.assignTo.add(cav);
                    }
                } else {
                    cav.isConst = Boolean.FALSE;
                }
            }
        }
    }
}
Also used : E2Stmt(com.googlecode.dex2jar.ir.stmt.Stmt.E2Stmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Stmt(com.googlecode.dex2jar.ir.stmt.Stmt) E2Stmt(com.googlecode.dex2jar.ir.stmt.Stmt.E2Stmt)

Example 2 with E2Stmt

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

the class ArrayNullPointerTransformer method replaceNPE.

private void replaceNPE(StmtList stmts, List<Local> locals, Stmt p) {
    List<Value> values = new ArrayList<Value>();
    switch(p.et) {
        case E1:
            tryAdd(((E1Stmt) p).op.trim(), values);
            break;
        case E2:
            E2Stmt e2 = (E2Stmt) p;
            switch(e2.op1.trim().vt) {
                case LOCAL:
                    tryAdd(e2.op2.trim(), values);
                    break;
                case ARRAY:
                    ArrayExpr ae = (ArrayExpr) e2.op1.trim();
                    if (tryAdd(ae.op1.trim(), values)) {
                        if (tryAdd(ae.op2.trim(), values)) {
                            tryAdd(e2.op2.trim(), values);
                        }
                    }
                    break;
                case // putfield
                FIELD:
                    FieldExpr fe = (FieldExpr) e2.op1.trim();
                    if (fe.op == null || fe.op.trim() == null || tryAdd(fe.op.trim(), values)) {
                        tryAdd(e2.op2.trim(), values);
                    }
                    break;
                default:
                    if (tryAdd(e2.op2.trim(), values)) {
                        tryAdd(e2.op1.trim(), values);
                    }
            }
        default:
    }
    for (Value value : values) {
        switch(value.vt) {
            case CONSTANT:
            case LOCAL:
                break;
            default:
                Local n = Exprs.nLocal("xxx");
                locals.add(n);
                stmts.insertBefore(p, Stmts.nAssign(n, value));
        }
    }
    stmts.insertBefore(p, Stmts.nThrow(Exprs.nInvokeNew(new Value[0], new String[0], "Ljava/lang/NullPointerException;")));
    stmts.remove(p);
}
Also used : ArrayExpr(com.googlecode.dex2jar.ir.expr.ArrayExpr) E2Stmt(com.googlecode.dex2jar.ir.stmt.Stmt.E2Stmt) ArrayList(java.util.ArrayList) Value(com.googlecode.dex2jar.ir.expr.Value) Local(com.googlecode.dex2jar.ir.expr.Local) FieldExpr(com.googlecode.dex2jar.ir.expr.FieldExpr) E1Stmt(com.googlecode.dex2jar.ir.stmt.Stmt.E1Stmt)

Example 3 with E2Stmt

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

the class IR2JConverter method reBuildInstructions.

private void reBuildInstructions(IrMethod ir, MethodVisitor asm) {
    asm = new LdcOptimizeAdapter(asm);
    int maxLocalIndex = 0;
    for (Local local : ir.locals) {
        maxLocalIndex = Math.max(maxLocalIndex, local._ls_index);
    }
    Map<String, Integer> lockMap = new HashMap<String, Integer>();
    for (Stmt st : ir.stmts) {
        switch(st.st) {
            case LABEL:
                LabelStmt labelStmt = (LabelStmt) st;
                Label label = (Label) labelStmt.tag;
                asm.visitLabel(label);
                if (labelStmt.lineNumber >= 0) {
                    asm.visitLineNumber(labelStmt.lineNumber, label);
                }
                break;
            case ASSIGN:
                {
                    E2Stmt e2 = (E2Stmt) st;
                    Value v1 = e2.op1;
                    Value v2 = e2.op2;
                    switch(v1.vt) {
                        case LOCAL:
                            Local local = ((Local) v1);
                            int i = local._ls_index;
                            boolean skipOrg = false;
                            if (v2.vt == VT.LOCAL && (i == ((Local) v2)._ls_index)) {
                                // check for a=a
                                skipOrg = true;
                            } else if (v1.valueType.charAt(0) == 'I') {
                                // check for IINC
                                if (v2.vt == VT.ADD) {
                                    if (isLocalWithIndex(v2.getOp1(), i) && v2.getOp2().vt == VT.CONSTANT) {
                                        // a=a+1;
                                        int increment = (Integer) ((Constant) v2.getOp2()).value;
                                        if (increment >= Short.MIN_VALUE && increment <= Short.MAX_VALUE) {
                                            asm.visitIincInsn(i, increment);
                                            skipOrg = true;
                                        }
                                    } else if (isLocalWithIndex(v2.getOp2(), i) && v2.getOp1().vt == VT.CONSTANT) {
                                        // a=1+a;
                                        int increment = (Integer) ((Constant) v2.getOp1()).value;
                                        if (increment >= Short.MIN_VALUE && increment <= Short.MAX_VALUE) {
                                            asm.visitIincInsn(i, increment);
                                            skipOrg = true;
                                        }
                                    }
                                } else if (v2.vt == VT.SUB) {
                                    if (isLocalWithIndex(v2.getOp1(), i) && v2.getOp2().vt == VT.CONSTANT) {
                                        // a=a-1;
                                        int increment = -(Integer) ((Constant) v2.getOp2()).value;
                                        if (increment >= Short.MIN_VALUE && increment <= Short.MAX_VALUE) {
                                            asm.visitIincInsn(i, increment);
                                            skipOrg = true;
                                        }
                                    }
                                }
                            }
                            if (!skipOrg) {
                                accept(v2, asm);
                                if (i >= 0) {
                                    asm.visitVarInsn(getOpcode(v1, ISTORE), i);
                                } else if (!v1.valueType.equals("V")) {
                                    // skip void type locals
                                    switch(v1.valueType.charAt(0)) {
                                        case 'J':
                                        case 'D':
                                            asm.visitInsn(POP2);
                                            break;
                                        default:
                                            asm.visitInsn(POP);
                                            break;
                                    }
                                }
                            }
                            break;
                        case STATIC_FIELD:
                            {
                                StaticFieldExpr fe = (StaticFieldExpr) v1;
                                accept(v2, asm);
                                insertI2x(v2.valueType, fe.type, asm);
                                asm.visitFieldInsn(PUTSTATIC, toInternal(fe.owner), fe.name, fe.type);
                                break;
                            }
                        case FIELD:
                            {
                                FieldExpr fe = (FieldExpr) v1;
                                accept(fe.op, asm);
                                accept(v2, asm);
                                insertI2x(v2.valueType, fe.type, asm);
                                asm.visitFieldInsn(PUTFIELD, toInternal(fe.owner), fe.name, fe.type);
                                break;
                            }
                        case ARRAY:
                            ArrayExpr ae = (ArrayExpr) v1;
                            accept(ae.op1, asm);
                            accept(ae.op2, asm);
                            accept(v2, asm);
                            String tp1 = ae.op1.valueType;
                            String tp2 = ae.valueType;
                            if (tp1.charAt(0) == '[') {
                                String arrayElementType = tp1.substring(1);
                                insertI2x(v2.valueType, arrayElementType, asm);
                                asm.visitInsn(getOpcode(arrayElementType, IASTORE));
                            } else {
                                asm.visitInsn(getOpcode(tp2, IASTORE));
                            }
                            break;
                    }
                }
                break;
            case IDENTITY:
                {
                    E2Stmt e2 = (E2Stmt) st;
                    if (e2.op2.vt == VT.EXCEPTION_REF) {
                        int index = ((Local) e2.op1)._ls_index;
                        if (index >= 0) {
                            asm.visitVarInsn(ASTORE, index);
                        } else {
                            asm.visitInsn(POP);
                        }
                    }
                }
                break;
            case FILL_ARRAY_DATA:
                {
                    E2Stmt e2 = (E2Stmt) st;
                    if (e2.getOp2().vt == VT.CONSTANT) {
                        Object arrayData = ((Constant) e2.getOp2()).value;
                        int arraySize = Array.getLength(arrayData);
                        String arrayValueType = e2.getOp1().valueType;
                        String elementType;
                        if (arrayValueType.charAt(0) == '[') {
                            elementType = arrayValueType.substring(1);
                        } else {
                            elementType = "I";
                        }
                        int iastoreOP = getOpcode(elementType, IASTORE);
                        accept(e2.getOp1(), asm);
                        for (int i = 0; i < arraySize; i++) {
                            asm.visitInsn(DUP);
                            asm.visitLdcInsn(i);
                            asm.visitLdcInsn(Array.get(arrayData, i));
                            asm.visitInsn(iastoreOP);
                        }
                        asm.visitInsn(POP);
                    } else {
                        FilledArrayExpr filledArrayExpr = (FilledArrayExpr) e2.getOp2();
                        int arraySize = filledArrayExpr.ops.length;
                        String arrayValueType = e2.getOp1().valueType;
                        String elementType;
                        if (arrayValueType.charAt(0) == '[') {
                            elementType = arrayValueType.substring(1);
                        } else {
                            elementType = "I";
                        }
                        int iastoreOP = getOpcode(elementType, IASTORE);
                        accept(e2.getOp1(), asm);
                        for (int i = 0; i < arraySize; i++) {
                            asm.visitInsn(DUP);
                            asm.visitLdcInsn(i);
                            accept(filledArrayExpr.ops[i], asm);
                            asm.visitInsn(iastoreOP);
                        }
                        asm.visitInsn(POP);
                    }
                }
                break;
            case GOTO:
                asm.visitJumpInsn(GOTO, (Label) ((GotoStmt) st).target.tag);
                break;
            case IF:
                reBuildJumpInstructions((IfStmt) st, asm);
                break;
            case LOCK:
                {
                    Value v = ((UnopStmt) st).op;
                    accept(v, asm);
                    if (optimizeSynchronized) {
                        switch(v.vt) {
                            case LOCAL:
                            // break;
                            case CONSTANT:
                                {
                                    String key;
                                    if (v.vt == VT.LOCAL) {
                                        key = "L" + ((Local) v)._ls_index;
                                    } else {
                                        key = "C" + ((Constant) v).value;
                                    }
                                    Integer integer = lockMap.get(key);
                                    int nIndex = integer != null ? integer : ++maxLocalIndex;
                                    asm.visitInsn(DUP);
                                    asm.visitVarInsn(getOpcode(v, ISTORE), nIndex);
                                    lockMap.put(key, nIndex);
                                }
                                break;
                            default:
                                throw new RuntimeException();
                        }
                    }
                    asm.visitInsn(MONITORENTER);
                }
                break;
            case UNLOCK:
                {
                    Value v = ((UnopStmt) st).op;
                    if (optimizeSynchronized) {
                        switch(v.vt) {
                            case LOCAL:
                            case CONSTANT:
                                {
                                    String key;
                                    if (v.vt == VT.LOCAL) {
                                        key = "L" + ((Local) v)._ls_index;
                                    } else {
                                        key = "C" + ((Constant) v).value;
                                    }
                                    Integer integer = lockMap.get(key);
                                    if (integer != null) {
                                        asm.visitVarInsn(getOpcode(v, ILOAD), integer);
                                    } else {
                                        accept(v, asm);
                                    }
                                }
                                break;
                            // TODO other
                            default:
                                {
                                    accept(v, asm);
                                    break;
                                }
                        }
                    } else {
                        accept(v, asm);
                    }
                    asm.visitInsn(MONITOREXIT);
                }
                break;
            case NOP:
                break;
            case RETURN:
                {
                    Value v = ((UnopStmt) st).op;
                    accept(v, asm);
                    insertI2x(v.valueType, ir.ret, asm);
                    asm.visitInsn(getOpcode(v, IRETURN));
                }
                break;
            case RETURN_VOID:
                asm.visitInsn(RETURN);
                break;
            case LOOKUP_SWITCH:
                {
                    LookupSwitchStmt lss = (LookupSwitchStmt) st;
                    accept(lss.op, asm);
                    Label[] targets = new Label[lss.targets.length];
                    for (int i = 0; i < targets.length; i++) {
                        targets[i] = (Label) lss.targets[i].tag;
                    }
                    asm.visitLookupSwitchInsn((Label) lss.defaultTarget.tag, lss.lookupValues, targets);
                }
                break;
            case TABLE_SWITCH:
                {
                    TableSwitchStmt tss = (TableSwitchStmt) st;
                    accept(tss.op, asm);
                    Label[] targets = new Label[tss.targets.length];
                    for (int i = 0; i < targets.length; i++) {
                        targets[i] = (Label) tss.targets[i].tag;
                    }
                    asm.visitTableSwitchInsn(tss.lowIndex, tss.lowIndex + targets.length - 1, (Label) tss.defaultTarget.tag, targets);
                }
                break;
            case THROW:
                accept(((UnopStmt) st).op, asm);
                asm.visitInsn(ATHROW);
                break;
            case VOID_INVOKE:
                Value op = st.getOp();
                accept(op, asm);
                String ret = op.valueType;
                if (op.vt == VT.INVOKE_NEW) {
                    asm.visitInsn(POP);
                } else if (!"V".equals(ret)) {
                    switch(ret.charAt(0)) {
                        case 'J':
                        case 'D':
                            asm.visitInsn(POP2);
                            break;
                        default:
                            asm.visitInsn(POP);
                            break;
                    }
                }
                break;
            default:
                throw new RuntimeException("not support st: " + st.st);
        }
    }
}
Also used : LdcOptimizeAdapter(com.googlecode.d2j.asm.LdcOptimizeAdapter) HashMap(java.util.HashMap) Label(org.objectweb.asm.Label) E2Stmt(com.googlecode.dex2jar.ir.stmt.Stmt.E2Stmt) E2Stmt(com.googlecode.dex2jar.ir.stmt.Stmt.E2Stmt)

Aggregations

E2Stmt (com.googlecode.dex2jar.ir.stmt.Stmt.E2Stmt)3 LdcOptimizeAdapter (com.googlecode.d2j.asm.LdcOptimizeAdapter)1 ArrayExpr (com.googlecode.dex2jar.ir.expr.ArrayExpr)1 FieldExpr (com.googlecode.dex2jar.ir.expr.FieldExpr)1 Local (com.googlecode.dex2jar.ir.expr.Local)1 Value (com.googlecode.dex2jar.ir.expr.Value)1 AssignStmt (com.googlecode.dex2jar.ir.stmt.AssignStmt)1 Stmt (com.googlecode.dex2jar.ir.stmt.Stmt)1 E1Stmt (com.googlecode.dex2jar.ir.stmt.Stmt.E1Stmt)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 Label (org.objectweb.asm.Label)1