public static MethodNode replaceInvokeOrigin()

in bytekit-core/src/main/java/com/alibaba/bytekit/asm/inst/impl/InstrumentImpl.java [26:124]


    public static MethodNode replaceInvokeOrigin(String originOwner, MethodNode originMethodNode,
                    MethodNode apmMethodNode) {

        // 查找到所有的 InstrumentApi.invokeOrigin() 指令
        List<MethodInsnNode> methodInsnNodes = AsmUtils.findMethodInsnNode(apmMethodNode, InstrumentApi.class.getName().replace('.', '/')
                        , "invokeOrigin", "()Ljava/lang/Object;");

        Type originReturnType = Type.getMethodType(originMethodNode.desc).getReturnType();

        for (MethodInsnNode methodInsnNode : methodInsnNodes) {
            InsnList instructions = new InsnList();

            AbstractInsnNode secondInsnNode = methodInsnNode.getNext();

            // 如果是 非 static ,则要 load this
            boolean isStatic = AsmUtils.isStatic(originMethodNode);
            int opcode = isStatic ? Opcodes.INVOKESTATIC : Opcodes.INVOKEVIRTUAL;
            if (!isStatic) {
                AsmOpUtils.loadThis(instructions);
            }
            AsmOpUtils.loadArgs(instructions, originMethodNode);

            MethodInsnNode originMethodInsnNode = new MethodInsnNode(opcode, originOwner, originMethodNode.name,
                            originMethodNode.desc, false);
            // 调用原来的函数
            instructions.add(originMethodInsnNode);

            int sort = originReturnType.getSort();
            if (sort == Type.VOID) {
                if (secondInsnNode != null) {
                    if (secondInsnNode.getOpcode() == Opcodes.POP) {
                        // TODO 原来的函数没有返回值,这里要把 POP去掉。有没有可能是 POP2 ?
                        apmMethodNode.instructions.remove(secondInsnNode);
                    } else {
                        // TODO 原来函数没有返回值,这里有没有可能要赋值??是否要 push null?
                        AsmOpUtils.pushNUll(instructions);
                    }
                }
            } else if (sort >= Type.BOOLEAN && sort <= Type.DOUBLE) {
                if (secondInsnNode.getOpcode() == Opcodes.POP) {
                    // 原来是 pop掉一个栈,如果函数返回的是 long,则要pop2
                    if (originReturnType.getSize() == 2) {
                        apmMethodNode.instructions.insert(secondInsnNode, new InsnNode(Opcodes.POP2));
                        apmMethodNode.instructions.remove(secondInsnNode);
                    }
                } else {
                    /**
                     * 需要把下面两条cast和unbox的指令删掉
                     *
                     * <pre>
                     * CHECKCAST java/lang/Integer
                     * INVOKEVIRTUAL java/lang/Integer.intValue ()I
                     * </pre>
                     */
                    boolean removeCheckCast = false;
                    if (secondInsnNode.getOpcode() == Opcodes.CHECKCAST) {
                        TypeInsnNode typeInsnNode = (TypeInsnNode) secondInsnNode;
                        // 从原始函数的返回值,获取到它对应的自动box的类
                        Type boxedType = AsmOpUtils.getBoxedType(originReturnType);
                        if (Type.getObjectType(typeInsnNode.desc).equals(boxedType)) {
                            AbstractInsnNode thridInsnNode = secondInsnNode.getNext();
                            if (thridInsnNode != null && thridInsnNode.getOpcode() == Opcodes.INVOKEVIRTUAL) {
                                MethodInsnNode valueInsnNode = (MethodInsnNode) thridInsnNode;
                                Method unBoxMethod = AsmOpUtils.getUnBoxMethod(originReturnType);
                                if (unBoxMethod.getDescriptor().equals(valueInsnNode.desc)
                                                && valueInsnNode.owner.equals(boxedType.getInternalName())) {
                                    apmMethodNode.instructions.remove(thridInsnNode);
                                    apmMethodNode.instructions.remove(secondInsnNode);
                                    removeCheckCast = true;
                                }
                            }
                        }
                    }
                    if (!removeCheckCast) {
                        // 没有被转换为原始类型,也没有pop,则说明赋值给了一个对象,用类似Long.valudOf转换为Object
                        AsmOpUtils.box(instructions, originReturnType);

                    }

                }
            } else {// ARRAY/OBJECT
                // 移掉可能有的 check cast
                if (secondInsnNode.getOpcode() == Opcodes.CHECKCAST) {
                    TypeInsnNode typeInsnNode = (TypeInsnNode) secondInsnNode;
                    if (Type.getObjectType(typeInsnNode.desc).equals(originReturnType)) {
                        apmMethodNode.instructions.remove(secondInsnNode);
                    }
                }
            }
            apmMethodNode.instructions.insertBefore(methodInsnNode, instructions);
            apmMethodNode.instructions.remove(methodInsnNode);
        }

        MethodProcessor methodProcessor = new MethodProcessor(originOwner, apmMethodNode);
        // 要保留origin method的line number
        methodProcessor.inline(originOwner, originMethodNode, false);

        return apmMethodNode;
    }