Search in sources :

Example 1 with IMethodProto

use of jadx.api.plugins.input.data.IMethodProto in project jadx by skylot.

the class InvokeDecoder method decode.

@Override
public void decode(CodeDecodeState state) {
    DataReader reader = state.reader();
    int mthIdx = reader.readS2();
    if (payloadSize == 4) {
        reader.skip(2);
    }
    JavaInsnData insn = state.insn();
    insn.setIndex(mthIdx);
    boolean instanceCall;
    IMethodProto mthProto;
    if (apiOpcode == Opcode.INVOKE_CUSTOM) {
        ICallSite callSite = insn.getIndexAsCallSite();
        insn.setPayload(callSite);
        mthProto = (IMethodProto) callSite.getValues().get(2).getValue();
        // 'this' arg already included in proto args
        instanceCall = false;
    } else {
        IMethodRef mthRef = insn.getIndexAsMethod();
        mthRef.load();
        insn.setPayload(mthRef);
        mthProto = mthRef;
        instanceCall = apiOpcode != Opcode.INVOKE_STATIC;
    }
    int argsCount = mthProto.getArgTypes().size();
    if (instanceCall) {
        argsCount++;
    }
    // allocate twice of the size for worst case
    insn.setRegsCount(argsCount * 2);
    int[] regs = insn.getRegsArray();
    // calculate actual count of registers
    // set '1' in regs to be filled with stack values later, '0' for skip
    int regsCount = 0;
    if (instanceCall) {
        regs[regsCount++] = 1;
    }
    for (String type : mthProto.getArgTypes()) {
        int size = getRegsCountForType(type);
        regs[regsCount++] = 1;
        if (size == 2) {
            regs[regsCount++] = 0;
        }
    }
    insn.setRegsCount(regsCount);
    for (int i = regsCount - 1; i >= 0; i--) {
        if (regs[i] == 1) {
            state.pop(i);
        }
    }
    String returnType = mthProto.getReturnType();
    if (!returnType.equals("V")) {
        insn.setResultReg(state.push(returnType));
    } else {
        insn.setResultReg(-1);
    }
}
Also used : DataReader(jadx.plugins.input.java.data.DataReader) IMethodProto(jadx.api.plugins.input.data.IMethodProto) JavaInsnData(jadx.plugins.input.java.data.code.JavaInsnData) IMethodRef(jadx.api.plugins.input.data.IMethodRef) ICallSite(jadx.api.plugins.input.data.ICallSite)

Example 2 with IMethodProto

use of jadx.api.plugins.input.data.IMethodProto in project jadx by skylot.

the class CustomLambdaCall method buildMethodCall.

@NotNull
private static InvokeCustomNode buildMethodCall(MethodNode mth, InsnData insn, boolean isRange, List<EncodedValue> values, IMethodHandle callMthHandle) {
    RootNode root = mth.root();
    IMethodProto lambdaProto = (IMethodProto) values.get(2).getValue();
    MethodInfo lambdaInfo = MethodInfo.fromMethodProto(root, mth.getParentClass().getClassInfo(), "", lambdaProto);
    MethodHandleType methodHandleType = callMthHandle.getType();
    InvokeCustomNode invokeCustomNode = new InvokeCustomNode(lambdaInfo, insn, false, isRange);
    invokeCustomNode.setHandleType(methodHandleType);
    ClassInfo implCls = ClassInfo.fromType(root, lambdaInfo.getReturnType());
    String implName = (String) values.get(1).getValue();
    IMethodProto implProto = (IMethodProto) values.get(3).getValue();
    MethodInfo implMthInfo = MethodInfo.fromMethodProto(root, implCls, implName, implProto);
    invokeCustomNode.setImplMthInfo(implMthInfo);
    MethodInfo callMthInfo = MethodInfo.fromRef(root, callMthHandle.getMethodRef());
    InvokeNode invokeNode = buildInvokeNode(methodHandleType, invokeCustomNode, callMthInfo);
    if (methodHandleType == MethodHandleType.INVOKE_CONSTRUCTOR) {
        ConstructorInsn ctrInsn = new ConstructorInsn(mth, invokeNode);
        invokeCustomNode.setCallInsn(ctrInsn);
    } else {
        invokeCustomNode.setCallInsn(invokeNode);
    }
    MethodNode callMth = root.resolveMethod(callMthInfo);
    if (callMth != null) {
        invokeCustomNode.getCallInsn().addAttr(callMth);
        if (callMth.getAccessFlags().isSynthetic() && callMth.getParentClass().equals(mth.getParentClass())) {
            // inline only synthetic methods from same class
            callMth.add(AFlag.DONT_GENERATE);
            invokeCustomNode.setInlineInsn(true);
        }
    }
    if (!invokeCustomNode.isInlineInsn()) {
        IMethodProto effectiveMthProto = (IMethodProto) values.get(5).getValue();
        List<ArgType> args = Utils.collectionMap(effectiveMthProto.getArgTypes(), ArgType::parse);
        boolean sameArgs = args.equals(callMthInfo.getArgumentsTypes());
        invokeCustomNode.setUseRef(sameArgs);
    }
    // prevent args inlining into not generated invoke custom node
    for (InsnArg arg : invokeCustomNode.getArguments()) {
        arg.add(AFlag.DONT_INLINE);
    }
    return invokeCustomNode;
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) RootNode(jadx.core.dex.nodes.RootNode) IMethodProto(jadx.api.plugins.input.data.IMethodProto) InvokeCustomNode(jadx.core.dex.instructions.InvokeCustomNode) MethodHandleType(jadx.api.plugins.input.data.MethodHandleType) MethodNode(jadx.core.dex.nodes.MethodNode) InsnArg(jadx.core.dex.instructions.args.InsnArg) InvokeNode(jadx.core.dex.instructions.InvokeNode) MethodInfo(jadx.core.dex.info.MethodInfo) ConstructorInsn(jadx.core.dex.instructions.mods.ConstructorInsn) ClassInfo(jadx.core.dex.info.ClassInfo) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

IMethodProto (jadx.api.plugins.input.data.IMethodProto)2 ICallSite (jadx.api.plugins.input.data.ICallSite)1 IMethodRef (jadx.api.plugins.input.data.IMethodRef)1 MethodHandleType (jadx.api.plugins.input.data.MethodHandleType)1 ClassInfo (jadx.core.dex.info.ClassInfo)1 MethodInfo (jadx.core.dex.info.MethodInfo)1 InvokeCustomNode (jadx.core.dex.instructions.InvokeCustomNode)1 InvokeNode (jadx.core.dex.instructions.InvokeNode)1 ArgType (jadx.core.dex.instructions.args.ArgType)1 InsnArg (jadx.core.dex.instructions.args.InsnArg)1 ConstructorInsn (jadx.core.dex.instructions.mods.ConstructorInsn)1 MethodNode (jadx.core.dex.nodes.MethodNode)1 RootNode (jadx.core.dex.nodes.RootNode)1 DataReader (jadx.plugins.input.java.data.DataReader)1 JavaInsnData (jadx.plugins.input.java.data.code.JavaInsnData)1 NotNull (org.jetbrains.annotations.NotNull)1