Search in sources :

Example 1 with ArithOp

use of jadx.core.dex.instructions.ArithOp in project jadx by skylot.

the class PrepareForCodeGen method checkInsn.

/**
	 * Remove parenthesis for wrapped insn  in arith '+' or '-'
	 * ('(a + b) +c' => 'a + b + c')
	 */
private static void checkInsn(InsnNode insn) {
    if (insn.getType() == InsnType.ARITH) {
        ArithNode arith = (ArithNode) insn;
        ArithOp op = arith.getOp();
        if (op == ArithOp.ADD || op == ArithOp.SUB) {
            for (int i = 0; i < 2; i++) {
                InsnArg arg = arith.getArg(i);
                if (arg.isInsnWrap()) {
                    InsnNode wrapInsn = ((InsnWrapArg) arg).getWrapInsn();
                    wrapInsn.add(AFlag.DONT_WRAP);
                    checkInsn(wrapInsn);
                }
            }
        }
    } else {
        for (InsnArg arg : insn.getArguments()) {
            if (arg.isInsnWrap()) {
                InsnNode wrapInsn = ((InsnWrapArg) arg).getWrapInsn();
                checkInsn(wrapInsn);
            }
        }
    }
}
Also used : InsnNode(jadx.core.dex.nodes.InsnNode) InsnArg(jadx.core.dex.instructions.args.InsnArg) ArithOp(jadx.core.dex.instructions.ArithOp) InsnWrapArg(jadx.core.dex.instructions.args.InsnWrapArg) ArithNode(jadx.core.dex.instructions.ArithNode)

Example 2 with ArithOp

use of jadx.core.dex.instructions.ArithOp in project jadx by skylot.

the class InsnGen method makeArithOneArg.

private void makeArithOneArg(ArithNode insn, ICodeWriter code) throws CodegenException {
    ArithOp op = insn.getOp();
    InsnArg resArg = insn.getArg(0);
    InsnArg arg = insn.getArg(1);
    // "++" or "--"
    if (arg.isLiteral() && (op == ArithOp.ADD || op == ArithOp.SUB)) {
        LiteralArg lit = (LiteralArg) arg;
        if (lit.getLiteral() == 1 && lit.isInteger()) {
            addArg(code, resArg, false);
            String opSymbol = op.getSymbol();
            code.add(opSymbol).add(opSymbol);
            return;
        }
    }
    // +=, -=, ...
    addArg(code, resArg, false);
    code.add(' ').add(op.getSymbol()).add("= ");
    addArg(code, arg, false);
}
Also used : InsnArg(jadx.core.dex.instructions.args.InsnArg) ArithOp(jadx.core.dex.instructions.ArithOp) LiteralArg(jadx.core.dex.instructions.args.LiteralArg)

Example 3 with ArithOp

use of jadx.core.dex.instructions.ArithOp in project jadx by skylot.

the class PrepareForCodeGen method removeParenthesis.

/**
 * Remove parenthesis for wrapped insn in arith '+' or '-'
 * ('(a + b) +c' => 'a + b + c')
 */
private static void removeParenthesis(InsnNode insn) {
    if (insn.getType() == InsnType.ARITH) {
        ArithNode arith = (ArithNode) insn;
        ArithOp op = arith.getOp();
        if (op == ArithOp.ADD || op == ArithOp.MUL || op == ArithOp.AND || op == ArithOp.OR) {
            for (int i = 0; i < 2; i++) {
                InsnArg arg = arith.getArg(i);
                if (arg.isInsnWrap()) {
                    InsnNode wrapInsn = ((InsnWrapArg) arg).getWrapInsn();
                    if (wrapInsn.getType() == InsnType.ARITH && ((ArithNode) wrapInsn).getOp() == op) {
                        wrapInsn.add(AFlag.DONT_WRAP);
                    }
                    removeParenthesis(wrapInsn);
                }
            }
        }
    } else {
        if (insn.getType() == InsnType.TERNARY) {
            removeParenthesis(((TernaryInsn) insn).getCondition());
        }
        for (InsnArg arg : insn.getArguments()) {
            if (arg.isInsnWrap()) {
                InsnNode wrapInsn = ((InsnWrapArg) arg).getWrapInsn();
                removeParenthesis(wrapInsn);
            }
        }
    }
}
Also used : InsnNode(jadx.core.dex.nodes.InsnNode) InsnArg(jadx.core.dex.instructions.args.InsnArg) ArithOp(jadx.core.dex.instructions.ArithOp) InsnWrapArg(jadx.core.dex.instructions.args.InsnWrapArg) ArithNode(jadx.core.dex.instructions.ArithNode)

Example 4 with ArithOp

use of jadx.core.dex.instructions.ArithOp in project jadx by skylot.

the class IfCondition method simplifyCmpOp.

private static IfCondition simplifyCmpOp(Compare c) {
    if (!c.getA().isInsnWrap()) {
        return null;
    }
    if (!c.getB().isLiteral()) {
        return null;
    }
    long lit = ((LiteralArg) c.getB()).getLiteral();
    if (lit != 0 && lit != 1) {
        return null;
    }
    InsnNode wrapInsn = ((InsnWrapArg) c.getA()).getWrapInsn();
    switch(wrapInsn.getType()) {
        case CMP_L:
        case CMP_G:
            if (lit == 0) {
                IfNode insn = c.getInsn();
                insn.changeCondition(insn.getOp(), wrapInsn.getArg(0), wrapInsn.getArg(1));
            }
            break;
        case ARITH:
            if (c.getB().getType() == ArgType.BOOLEAN) {
                ArithOp arithOp = ((ArithNode) wrapInsn).getOp();
                if (arithOp == ArithOp.OR || arithOp == ArithOp.AND) {
                    IfOp ifOp = c.getInsn().getOp();
                    boolean isTrue = ifOp == IfOp.NE && lit == 0 || ifOp == IfOp.EQ && lit == 1;
                    IfOp op = isTrue ? IfOp.NE : IfOp.EQ;
                    Mode mode = isTrue && arithOp == ArithOp.OR || !isTrue && arithOp == ArithOp.AND ? Mode.OR : Mode.AND;
                    IfNode if1 = new IfNode(op, -1, wrapInsn.getArg(0), LiteralArg.litFalse());
                    IfNode if2 = new IfNode(op, -1, wrapInsn.getArg(1), LiteralArg.litFalse());
                    return new IfCondition(mode, Arrays.asList(new IfCondition(new Compare(if1)), new IfCondition(new Compare(if2))));
                }
            }
            break;
        default:
            break;
    }
    return null;
}
Also used : InsnNode(jadx.core.dex.nodes.InsnNode) ArithOp(jadx.core.dex.instructions.ArithOp) LiteralArg(jadx.core.dex.instructions.args.LiteralArg) InsnWrapArg(jadx.core.dex.instructions.args.InsnWrapArg) IfNode(jadx.core.dex.instructions.IfNode) ArithNode(jadx.core.dex.instructions.ArithNode) IfOp(jadx.core.dex.instructions.IfOp)

Example 5 with ArithOp

use of jadx.core.dex.instructions.ArithOp in project jadx by skylot.

the class InsnGen method makeArithOneArg.

private void makeArithOneArg(ArithNode insn, CodeWriter code) throws CodegenException {
    ArithOp op = insn.getOp();
    InsnArg arg = insn.getArg(1);
    // "++" or "--"
    if (arg.isLiteral() && (op == ArithOp.ADD || op == ArithOp.SUB)) {
        LiteralArg lit = (LiteralArg) arg;
        if (lit.isInteger() && lit.getLiteral() == 1) {
            assignVar(code, insn);
            String opSymbol = op.getSymbol();
            code.add(opSymbol).add(opSymbol);
            return;
        }
    }
    // +=, -= ...
    assignVar(code, insn);
    code.add(' ').add(op.getSymbol()).add("= ");
    addArg(code, arg, false);
}
Also used : InsnArg(jadx.core.dex.instructions.args.InsnArg) ArithOp(jadx.core.dex.instructions.ArithOp) LiteralArg(jadx.core.dex.instructions.args.LiteralArg)

Aggregations

ArithOp (jadx.core.dex.instructions.ArithOp)5 InsnArg (jadx.core.dex.instructions.args.InsnArg)4 ArithNode (jadx.core.dex.instructions.ArithNode)3 InsnWrapArg (jadx.core.dex.instructions.args.InsnWrapArg)3 LiteralArg (jadx.core.dex.instructions.args.LiteralArg)3 InsnNode (jadx.core.dex.nodes.InsnNode)3 IfNode (jadx.core.dex.instructions.IfNode)1 IfOp (jadx.core.dex.instructions.IfOp)1