Search in sources :

Example 91 with InsnNode

use of jadx.core.dex.nodes.InsnNode in project jadx by skylot.

the class RegisterArg method getPhiAssignInsn.

public InsnNode getPhiAssignInsn() {
    PhiInsn usePhi = sVar.getUsedInPhi();
    if (usePhi != null) {
        return usePhi;
    }
    InsnNode parent = sVar.getAssign().getParentInsn();
    if (parent != null && parent.getType() == InsnType.PHI) {
        return parent;
    }
    return null;
}
Also used : InsnNode(jadx.core.dex.nodes.InsnNode) PhiInsn(jadx.core.dex.instructions.PhiInsn)

Example 92 with InsnNode

use of jadx.core.dex.nodes.InsnNode in project jadx by skylot.

the class CodeShrinker method inline.

private static boolean inline(RegisterArg arg, InsnNode insn, BlockNode block) {
    InsnNode parentInsn = arg.getParentInsn();
    if (parentInsn != null && parentInsn.getType() == InsnType.RETURN) {
        parentInsn.setSourceLine(insn.getSourceLine());
    }
    boolean replaced = arg.wrapInstruction(insn) != null;
    if (replaced) {
        InsnList.remove(block, insn);
    }
    return replaced;
}
Also used : InsnNode(jadx.core.dex.nodes.InsnNode)

Example 93 with InsnNode

use of jadx.core.dex.nodes.InsnNode in project jadx by skylot.

the class CodeShrinker method shrinkBlock.

private static void shrinkBlock(MethodNode mth, BlockNode block) {
    if (block.getInstructions().isEmpty()) {
        return;
    }
    InsnList insnList = new InsnList(block.getInstructions());
    int insnCount = insnList.size();
    List<ArgsInfo> argsList = new ArrayList<ArgsInfo>(insnCount);
    for (int i = 0; i < insnCount; i++) {
        argsList.add(new ArgsInfo(insnList.get(i), argsList, i));
    }
    List<WrapInfo> wrapList = new ArrayList<WrapInfo>();
    for (ArgsInfo argsInfo : argsList) {
        List<RegisterArg> args = argsInfo.getArgs();
        if (args.isEmpty()) {
            continue;
        }
        ListIterator<RegisterArg> it = args.listIterator(args.size());
        while (it.hasPrevious()) {
            RegisterArg arg = it.previous();
            //				if (arg.getName() != null) {
            //					continue;
            //				}
            SSAVar sVar = arg.getSVar();
            // allow inline only one use arg or 'this'
            if (sVar == null || sVar.getVariableUseCount() != 1 && !arg.isThis() || sVar.contains(AFlag.DONT_INLINE)) {
                continue;
            }
            InsnNode assignInsn = sVar.getAssign().getParentInsn();
            if (assignInsn == null || assignInsn.contains(AFlag.DONT_INLINE)) {
                continue;
            }
            int assignPos = insnList.getIndex(assignInsn);
            if (assignPos != -1) {
                WrapInfo wrapInfo = argsInfo.checkInline(assignPos, arg);
                if (wrapInfo != null) {
                    wrapList.add(wrapInfo);
                }
            } else {
                // another block
                BlockNode assignBlock = BlockUtils.getBlockByInsn(mth, assignInsn);
                if (assignBlock != null && assignInsn != arg.getParentInsn() && canMoveBetweenBlocks(assignInsn, assignBlock, block, argsInfo.getInsn())) {
                    inline(arg, assignInsn, assignBlock);
                }
            }
        }
    }
    if (!wrapList.isEmpty()) {
        for (WrapInfo wrapInfo : wrapList) {
            inline(wrapInfo.getArg(), wrapInfo.getInsn(), block);
        }
    }
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) ArrayList(java.util.ArrayList) InsnList(jadx.core.utils.InsnList) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) SSAVar(jadx.core.dex.instructions.args.SSAVar)

Example 94 with InsnNode

use of jadx.core.dex.nodes.InsnNode in project jadx by skylot.

the class ConstInlineVisitor method replaceConst.

private static boolean replaceConst(MethodNode mth, InsnNode constInsn, long literal) {
    SSAVar sVar = constInsn.getResult().getSVar();
    List<RegisterArg> use = new ArrayList<RegisterArg>(sVar.getUseList());
    int replaceCount = 0;
    for (RegisterArg arg : use) {
        InsnNode useInsn = arg.getParentInsn();
        if (useInsn == null || useInsn.getType() == InsnType.PHI || useInsn.getType() == InsnType.MERGE) {
            continue;
        }
        LiteralArg litArg;
        ArgType argType = arg.getType();
        if (argType.isObject() && literal != 0) {
            argType = ArgType.NARROW_NUMBERS;
        }
        if (use.size() == 1 || arg.isTypeImmutable()) {
            // arg used only in one place
            litArg = InsnArg.lit(literal, argType);
        } else if (useInsn.getType() == InsnType.MOVE && !useInsn.getResult().getType().isTypeKnown()) {
            // save type for 'move' instructions (hard to find type in chains of 'move')
            litArg = InsnArg.lit(literal, argType);
        } else {
            // in most cases type not equal arg.getType()
            // just set unknown type and run type fixer
            litArg = InsnArg.lit(literal, ArgType.UNKNOWN);
        }
        if (useInsn.replaceArg(arg, litArg)) {
            fixTypes(mth, useInsn, litArg);
            replaceCount++;
            if (useInsn.getType() == InsnType.RETURN) {
                useInsn.setSourceLine(constInsn.getSourceLine());
            }
            FieldNode f = null;
            ArgType litArgType = litArg.getType();
            if (litArgType.isTypeKnown()) {
                f = mth.getParentClass().getConstFieldByLiteralArg(litArg);
            } else if (litArgType.contains(PrimitiveType.INT)) {
                f = mth.getParentClass().getConstField((int) literal, false);
            }
            if (f != null) {
                litArg.wrapInstruction(new IndexInsnNode(InsnType.SGET, f.getFieldInfo(), 0));
            }
        }
    }
    return replaceCount == use.size();
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) SSAVar(jadx.core.dex.instructions.args.SSAVar) FieldNode(jadx.core.dex.nodes.FieldNode) ArrayList(java.util.ArrayList) LiteralArg(jadx.core.dex.instructions.args.LiteralArg) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode)

Example 95 with InsnNode

use of jadx.core.dex.nodes.InsnNode in project jadx by skylot.

the class ConstInlineVisitor method visit.

@Override
public void visit(MethodNode mth) throws JadxException {
    if (mth.isNoCode()) {
        return;
    }
    List<InsnNode> toRemove = new ArrayList<InsnNode>();
    for (BlockNode block : mth.getBasicBlocks()) {
        toRemove.clear();
        for (InsnNode insn : block.getInstructions()) {
            if (checkInsn(mth, insn)) {
                toRemove.add(insn);
            }
        }
        InstructionRemover.removeAll(mth, block, toRemove);
    }
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) ArrayList(java.util.ArrayList)

Aggregations

InsnNode (jadx.core.dex.nodes.InsnNode)123 BlockNode (jadx.core.dex.nodes.BlockNode)41 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)39 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)35 InsnArg (jadx.core.dex.instructions.args.InsnArg)32 InsnWrapArg (jadx.core.dex.instructions.args.InsnWrapArg)19 SSAVar (jadx.core.dex.instructions.args.SSAVar)16 ArrayList (java.util.ArrayList)14 ArgType (jadx.core.dex.instructions.args.ArgType)11 PhiInsn (jadx.core.dex.instructions.PhiInsn)10 FieldNode (jadx.core.dex.nodes.FieldNode)10 JadxRuntimeException (jadx.core.utils.exceptions.JadxRuntimeException)8 LiteralArg (jadx.core.dex.instructions.args.LiteralArg)7 ClassNode (jadx.core.dex.nodes.ClassNode)7 MethodNode (jadx.core.dex.nodes.MethodNode)7 FieldInfo (jadx.core.dex.info.FieldInfo)6 ArithNode (jadx.core.dex.instructions.ArithNode)6 ConstructorInsn (jadx.core.dex.instructions.mods.ConstructorInsn)6 InsnType (jadx.core.dex.instructions.InsnType)5 IContainer (jadx.core.dex.nodes.IContainer)5