Search in sources :

Example 46 with RegisterArg

use of jadx.core.dex.instructions.args.RegisterArg in project jadx by skylot.

the class InsnGen method generateMethodArguments.

void generateMethodArguments(CodeWriter code, InsnNode insn, int startArgNum, @Nullable MethodNode callMth) throws CodegenException {
    int k = startArgNum;
    if (callMth != null && callMth.contains(AFlag.SKIP_FIRST_ARG)) {
        k++;
    }
    int argsCount = insn.getArgsCount();
    code.add('(');
    boolean firstArg = true;
    if (k < argsCount) {
        boolean overloaded = callMth != null && callMth.isArgsOverload();
        for (int i = k; i < argsCount; i++) {
            InsnArg arg = insn.getArg(i);
            if (arg.contains(AFlag.SKIP_ARG)) {
                continue;
            }
            RegisterArg callArg = getCallMthArg(callMth, i - startArgNum);
            if (callArg != null && callArg.contains(AFlag.SKIP_ARG)) {
                continue;
            }
            if (!firstArg) {
                code.add(", ");
            }
            boolean cast = overloaded && processOverloadedArg(code, callMth, arg, i - startArgNum);
            if (!cast && i == argsCount - 1 && processVarArg(code, callMth, arg)) {
                continue;
            }
            addArg(code, arg, false);
            firstArg = false;
        }
    }
    code.add(')');
}
Also used : RegisterArg(jadx.core.dex.instructions.args.RegisterArg) InsnArg(jadx.core.dex.instructions.args.InsnArg)

Example 47 with RegisterArg

use of jadx.core.dex.instructions.args.RegisterArg in project jadx by skylot.

the class MethodGen method addMethodArguments.

private void addMethodArguments(CodeWriter argsCode, List<RegisterArg> args) {
    MethodParameters paramsAnnotation = mth.get(AType.ANNOTATION_MTH_PARAMETERS);
    int i = 0;
    for (Iterator<RegisterArg> it = args.iterator(); it.hasNext(); ) {
        RegisterArg arg = it.next();
        // add argument annotation
        if (paramsAnnotation != null) {
            annotationGen.addForParameter(argsCode, paramsAnnotation, i);
        }
        SSAVar argSVar = arg.getSVar();
        if (argSVar != null && argSVar.contains(AFlag.FINAL)) {
            argsCode.add("final ");
        }
        if (!it.hasNext() && mth.getAccessFlags().isVarArgs()) {
            // change last array argument to varargs
            ArgType type = arg.getType();
            if (type.isArray()) {
                ArgType elType = type.getArrayElement();
                classGen.useType(argsCode, elType);
                argsCode.add("...");
            } else {
                LOG.warn(ErrorsCounter.formatErrorMsg(mth, "Last argument in varargs method not array"));
                classGen.useType(argsCode, arg.getType());
            }
        } else {
            classGen.useType(argsCode, arg.getType());
        }
        argsCode.add(' ');
        argsCode.add(nameGen.assignArg(arg));
        i++;
        if (it.hasNext()) {
            argsCode.add(", ");
        }
    }
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) SSAVar(jadx.core.dex.instructions.args.SSAVar) MethodParameters(jadx.core.dex.attributes.annotations.MethodParameters)

Example 48 with RegisterArg

use of jadx.core.dex.instructions.args.RegisterArg in project jadx by skylot.

the class ModVisitor method processInvoke.

private static void processInvoke(MethodNode mth, BlockNode block, int insnNumber, InstructionRemover remover) {
    ClassNode parentClass = mth.getParentClass();
    InsnNode insn = block.getInstructions().get(insnNumber);
    InvokeNode inv = (InvokeNode) insn;
    MethodInfo callMth = inv.getCallMth();
    if (!callMth.isConstructor()) {
        return;
    }
    InsnNode instArgAssignInsn = ((RegisterArg) inv.getArg(0)).getAssignInsn();
    ConstructorInsn co = new ConstructorInsn(mth, inv);
    boolean remove = false;
    if (co.isSuper() && (co.getArgsCount() == 0 || parentClass.isEnum())) {
        remove = true;
    } else if (co.isThis() && co.getArgsCount() == 0) {
        MethodNode defCo = parentClass.searchMethodByName(callMth.getShortId());
        if (defCo == null || defCo.isNoCode()) {
            // default constructor not implemented
            remove = true;
        }
    }
    // remove super() call in instance initializer
    if (parentClass.isAnonymous() && mth.isDefaultConstructor() && co.isSuper()) {
        remove = true;
    }
    if (remove) {
        remover.add(insn);
        return;
    }
    if (co.isNewInstance()) {
        InsnNode newInstInsn = removeAssignChain(instArgAssignInsn, remover, InsnType.NEW_INSTANCE);
        if (newInstInsn != null) {
            RegisterArg instArg = newInstInsn.getResult();
            RegisterArg resultArg = co.getResult();
            if (!resultArg.equals(instArg)) {
                // replace all usages of 'instArg' with result of this constructor instruction
                for (RegisterArg useArg : new ArrayList<RegisterArg>(instArg.getSVar().getUseList())) {
                    RegisterArg dup = resultArg.duplicate();
                    InsnNode parentInsn = useArg.getParentInsn();
                    parentInsn.replaceArg(useArg, dup);
                    dup.setParentInsn(parentInsn);
                    resultArg.getSVar().use(dup);
                }
            }
        }
    }
    ConstructorInsn replace = processConstructor(mth, co);
    if (replace != null) {
        co = replace;
    }
    replaceInsn(block, insnNumber, co);
    processAnonymousConstructor(mth, co);
}
Also used : ClassNode(jadx.core.dex.nodes.ClassNode) ConstClassNode(jadx.core.dex.instructions.ConstClassNode) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) MethodNode(jadx.core.dex.nodes.MethodNode) InvokeNode(jadx.core.dex.instructions.InvokeNode) ArrayList(java.util.ArrayList) MethodInfo(jadx.core.dex.info.MethodInfo) ConstructorInsn(jadx.core.dex.instructions.mods.ConstructorInsn)

Example 49 with RegisterArg

use of jadx.core.dex.instructions.args.RegisterArg in project jadx by skylot.

the class ExtractFieldInit method checkInsn.

private static boolean checkInsn(InsnNode insn) {
    InsnArg arg = insn.getArg(0);
    if (arg.isInsnWrap()) {
        InsnNode wrapInsn = ((InsnWrapArg) arg).getWrapInsn();
        if (!wrapInsn.canReorderRecursive() && insn.contains(AType.CATCH_BLOCK)) {
            return false;
        }
    } else {
        return arg.isLiteral() || arg.isThis();
    }
    Set<RegisterArg> regs = new HashSet<RegisterArg>();
    insn.getRegisterArgs(regs);
    if (!regs.isEmpty()) {
        for (RegisterArg reg : regs) {
            if (!reg.isThis()) {
                return false;
            }
        }
    }
    return true;
}
Also used : IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) InsnArg(jadx.core.dex.instructions.args.InsnArg) InsnWrapArg(jadx.core.dex.instructions.args.InsnWrapArg) HashSet(java.util.HashSet)

Example 50 with RegisterArg

use of jadx.core.dex.instructions.args.RegisterArg in project jadx by skylot.

the class MethodInlineVisitor method inlineMth.

private static void inlineMth(MethodNode mth, BlockNode firstBlock, BlockNode returnBlock) {
    List<InsnNode> insnList = firstBlock.getInstructions();
    if (insnList.isEmpty()) {
        // synthetic field getter
        BlockNode block = mth.getBasicBlocks().get(1);
        InsnNode insn = block.getInstructions().get(0);
        // set arg from 'return' instruction
        addInlineAttr(mth, InsnNode.wrapArg(insn.getArg(0)));
        return;
    }
    // synthetic field setter or method invoke
    if (insnList.size() == 1) {
        addInlineAttr(mth, insnList.get(0));
        return;
    }
    // other field operations
    if (insnList.size() == 2 && returnBlock.getInstructions().size() == 1 && !mth.getReturnType().equals(ArgType.VOID)) {
        InsnNode get = insnList.get(0);
        InsnNode put = insnList.get(1);
        InsnArg retArg = returnBlock.getInstructions().get(0).getArg(0);
        if (get.getType() == InsnType.IGET && put.getType() == InsnType.IPUT && retArg.isRegister() && get.getResult().equalRegisterAndType((RegisterArg) retArg)) {
            RegisterArg retReg = (RegisterArg) retArg;
            retReg.getSVar().removeUse(retReg);
            CodeShrinker.shrinkMethod(mth);
            insnList = firstBlock.getInstructions();
            if (insnList.size() == 1) {
                addInlineAttr(mth, insnList.get(0));
            }
        }
    }
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) InsnArg(jadx.core.dex.instructions.args.InsnArg)

Aggregations

RegisterArg (jadx.core.dex.instructions.args.RegisterArg)67 InsnNode (jadx.core.dex.nodes.InsnNode)39 InsnArg (jadx.core.dex.instructions.args.InsnArg)24 SSAVar (jadx.core.dex.instructions.args.SSAVar)22 BlockNode (jadx.core.dex.nodes.BlockNode)17 PhiInsn (jadx.core.dex.instructions.PhiInsn)11 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)10 ArgType (jadx.core.dex.instructions.args.ArgType)8 ArrayList (java.util.ArrayList)8 PhiListAttr (jadx.core.dex.attributes.nodes.PhiListAttr)6 JadxRuntimeException (jadx.core.utils.exceptions.JadxRuntimeException)6 MethodNode (jadx.core.dex.nodes.MethodNode)4 MethodInfo (jadx.core.dex.info.MethodInfo)3 ConstClassNode (jadx.core.dex.instructions.ConstClassNode)3 LiteralArg (jadx.core.dex.instructions.args.LiteralArg)3 ConstructorInsn (jadx.core.dex.instructions.mods.ConstructorInsn)3 ClassNode (jadx.core.dex.nodes.ClassNode)3 FieldNode (jadx.core.dex.nodes.FieldNode)3 IContainer (jadx.core.dex.nodes.IContainer)3 ExceptionHandler (jadx.core.dex.trycatch.ExceptionHandler)3