com.alibaba.hotswap.processor.jdk.reflect.modifier.ConstructorNewInstanceModifier.java Source code

Java tutorial

Introduction

Here is the source code for com.alibaba.hotswap.processor.jdk.reflect.modifier.ConstructorNewInstanceModifier.java

Source

/*
 * Copyright 2012 Alibaba.com All right reserved. This software is the
 * confidential and proprietary information of Alibaba.com ("Confidential
 * Information"). You shall not disclose such Confidential Information and shall
 * use it only in accordance with the terms of the license agreement you entered
 * into with Alibaba.com.
 */
package com.alibaba.hotswap.processor.jdk.reflect.modifier;

import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;

import com.alibaba.hotswap.constant.HotswapConstants;
import com.alibaba.hotswap.meta.ClassMeta;
import com.alibaba.hotswap.processor.basic.BaseMethodAdapter;
import com.alibaba.hotswap.processor.jdk.helper.MethodReflectHelper;
import com.alibaba.hotswap.runtime.HotswapRuntime;
import com.alibaba.hotswap.util.HotswapMethodUtil;

/**
 * @author zhuyong 2012-7-6
 */
public class ConstructorNewInstanceModifier extends BaseMethodAdapter {

    public ConstructorNewInstanceModifier(MethodVisitor mv, int access, String name, String desc) {
        super(mv, access, name, desc);
    }

    @Override
    public void visitCode() {
        super.visitCode();
        Label old = new Label();

        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitFieldInsn(Opcodes.GETFIELD, "java/lang/reflect/Constructor", "parameterTypes",
                "[Ljava/lang/Class;");
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(MethodReflectHelper.class),
                "isUniformConstructorArgsType", "([Ljava/lang/Class;)Z");
        ifZCmp(NE, old);

        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitFieldInsn(Opcodes.GETFIELD, "java/lang/reflect/Constructor", "clazz", "Ljava/lang/Class;");
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Class", "getName", "()Ljava/lang/String;");
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(HotswapRuntime.class), "hasClassMeta",
                "(Ljava/lang/String;)Z");
        mv.visitJumpInsn(Opcodes.IFEQ, old);

        // check it as a primary constructor
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitFieldInsn(Opcodes.GETFIELD, "java/lang/reflect/Constructor", "clazz", "Ljava/lang/Class;");
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Class", "getName", "()Ljava/lang/String;");
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(HotswapRuntime.class), "getClassMeta",
                "(Ljava/lang/String;)Lcom/alibaba/hotswap/meta/ClassMeta;");
        mv.visitLdcInsn(HotswapConstants.INIT);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(Type.class), "getConstructorDescriptor",
                "(Ljava/lang/reflect/Constructor;)Ljava/lang/String;");
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(ClassMeta.class), "isPrimaryInitMethod",
                "(Ljava/lang/String;Ljava/lang/String;)Z");
        mv.visitJumpInsn(Opcodes.IFNE, old);

        // get uniform constructor
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitFieldInsn(Opcodes.GETFIELD, "java/lang/reflect/Constructor", "clazz", "Ljava/lang/Class;");
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(HotswapMethodUtil.class),
                "getConstructorParamTypes", "()[Ljava/lang/Class;");
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Class", "getConstructor",
                "([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;");

        // index and objs
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitFieldInsn(Opcodes.GETFIELD, "java/lang/reflect/Constructor", "clazz", "Ljava/lang/Class;");
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Class", "getName", "()Ljava/lang/String;");
        mv.visitLdcInsn(HotswapConstants.INIT);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(Type.class), "getConstructorDescriptor",
                "(Ljava/lang/reflect/Constructor;)Ljava/lang/String;");
        loadArgs();
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(HotswapMethodUtil.class), "getMethodParams",
                "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)[Ljava/lang/Object;");

        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Constructor", "newInstance",
                "([Ljava/lang/Object;)Ljava/lang/Object;");
        mv.visitInsn(Opcodes.ARETURN);

        mv.visitLabel(old);
    }
}