Package org.nutz.lang.reflect

Source Code of org.nutz.lang.reflect.FastClassAdpter

package org.nutz.lang.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;

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

public class FastClassAdpter implements Opcodes {

  protected final MethodVisitor mv;

  protected String enhancedSuperName;

  protected Type returnType;

  protected String[] descs;

  protected String[] methodNames;

  protected int[] modifies;

  protected int[] invokeOps;

  private FastClassAdpter(MethodVisitor mv, String enhancedSuperName) {
    this.mv = mv;
    this.enhancedSuperName = enhancedSuperName;
  }

  public void createInokeMethod() {
    mv.visitCode();

    for (int i = 0; i < methodNames.length; i++) {
      mv.visitVarInsn(ILOAD, 2);
      visitX(i);
      Label l0 = new Label();
      mv.visitJumpInsn(IF_ICMPNE, l0);
      if (!Modifier.isStatic(modifies[i])) {
        mv.visitVarInsn(ALOAD, 1);
        returnType = Type.getObjectType(enhancedSuperName);
        checkCast();
      }
      Type args[] = Type.getArgumentTypes(descs[i]);
      for (int j = 0; j < args.length; j++) {
        mv.visitVarInsn(ALOAD, 3);
        visitX(j);
        mv.visitInsn(AALOAD);
        returnType = args[j];
        checkCast();
      }
      mv.visitMethodInsninvokeOps[i],
                enhancedSuperName,
                methodNames[i],
                Type.getMethodDescriptorType.getReturnType(descs[i]),
                              Type.getArgumentTypes(descs[i])));
      returnType = Type.getReturnType(descs[i]);
      if (returnType.equals(Type.VOID_TYPE))
        mv.visitInsn(ACONST_NULL);
      else if (returnType.getOpcode(IRETURN) != ARETURN)
        packagePrivateData(returnType);
      mv.visitInsn(ARETURN);
      mv.visitLabel(l0);
    }

    mv.visitInsn(ACONST_NULL);
    mv.visitInsn(ARETURN);
    mv.visitMaxs(4, 3);
    mv.visitEnd();
  }

  public void createInokeConstructor(Constructor<?>[] constructors) {
    mv.visitCode();
    for (int i = 0; i < constructors.length; i++) {
      mv.visitVarInsn(ILOAD, 1);
      visitX(i);
      Label l0 = new Label();
      mv.visitJumpInsn(IF_ICMPNE, l0);
      mv.visitTypeInsn(NEW, enhancedSuperName);
      mv.visitInsn(DUP);

      Type args[] = Type.getArgumentTypes(Type.getConstructorDescriptor(constructors[i]));
      for (int j = 0; j < args.length; j++) {
        mv.visitVarInsn(ALOAD, 2);
        visitX(j);
        mv.visitInsn(AALOAD);
        returnType = args[j];
        checkCast();
      }
      mv.visitMethodInsnINVOKESPECIAL,
                enhancedSuperName,
                "<init>",
                Type.getConstructorDescriptor(constructors[i]));
      mv.visitInsn(ARETURN);
      mv.visitLabel(l0);
    }
    mv.visitInsn(ACONST_NULL);
    mv.visitInsn(ARETURN);
    mv.visitMaxs(4, 3);
    mv.visitEnd();
  }

  protected void loadInsn(final Type type, final int index) {
    mv.visitVarInsn(type.getOpcode(Opcodes.ILOAD), index);
  }

  protected void visitX(int i) {
    if (i < 6) {
      mv.visitInsn(i + ICONST_0);
    } else {
      mv.visitIntInsn(BIPUSH, i);
    }
  }

  protected boolean packagePrivateData(Type type) {
    if (type.equals(Type.BOOLEAN_TYPE)) {
      mv.visitMethodInsnINVOKESTATIC,
                "java/lang/Boolean",
                "valueOf",
                "(Z)Ljava/lang/Boolean;");
    } else if (type.equals(Type.BYTE_TYPE)) {
      mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;");
    } else if (type.equals(Type.CHAR_TYPE)) {
      mv.visitMethodInsnINVOKESTATIC,
                "java/lang/Character",
                "valueOf",
                "(C)Ljava/lang/Character;");
    } else if (type.equals(Type.SHORT_TYPE)) {
      mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;");
    } else if (type.equals(Type.INT_TYPE)) {
      mv.visitMethodInsnINVOKESTATIC,
                "java/lang/Integer",
                "valueOf",
                "(I)Ljava/lang/Integer;");
    } else if (type.equals(Type.LONG_TYPE)) {
      mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;");
    } else if (type.equals(Type.FLOAT_TYPE)) {
      mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;");
    } else if (type.equals(Type.DOUBLE_TYPE)) {
      mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;");
    } else {
      return false;
    }
    return true;
  }

  protected void unpackagePrivateData(Type type) {
    if (type.equals(Type.BOOLEAN_TYPE)) {
      mv.visitMethodInsnINVOKESTATIC,
                "org/nutz/aop/asm/Helper",
                "valueOf",
                "(Ljava/lang/Boolean;)Z");
    } else if (type.equals(Type.BYTE_TYPE)) {
      mv.visitMethodInsnINVOKESTATIC,
                "org/nutz/aop/asm/Helper",
                "valueOf",
                "(Ljava/lang/Byte;)B");
    } else if (type.equals(Type.CHAR_TYPE)) {
      mv.visitMethodInsnINVOKESTATIC,
                "org/nutz/aop/asm/Helper",
                "valueOf",
                "(Ljava/lang/Character;)C");
    } else if (type.equals(Type.SHORT_TYPE)) {
      mv.visitMethodInsnINVOKESTATIC,
                "org/nutz/aop/asm/Helper",
                "valueOf",
                "(Ljava/lang/Short;)S");
    } else if (type.equals(Type.INT_TYPE)) {
      mv.visitMethodInsnINVOKESTATIC,
                "org/nutz/aop/asm/Helper",
                "valueOf",
                "(Ljava/lang/Integer;)I");
    } else if (type.equals(Type.LONG_TYPE)) {
      mv.visitMethodInsnINVOKESTATIC,
                "org/nutz/aop/asm/Helper",
                "valueOf",
                "(Ljava/lang/Long;)J");
    } else if (type.equals(Type.FLOAT_TYPE)) {
      mv.visitMethodInsnINVOKESTATIC,
                "org/nutz/aop/asm/Helper",
                "valueOf",
                "(Ljava/lang/Float;)F");
    } else if (type.equals(Type.DOUBLE_TYPE)) {
      mv.visitMethodInsnINVOKESTATIC,
                "org/nutz/aop/asm/Helper",
                "valueOf",
                "(Ljava/lang/Double;)D");
    }
  }

  protected boolean isObject = true;

  protected void checkCast() {
    if (returnType.getSort() == Type.ARRAY) {
      mv.visitTypeInsn(CHECKCAST, returnType.getDescriptor());
      return;
    }
    if (returnType.equals(Type.getType(Object.class))) {
      ;
    } else {
      if (returnType.getOpcode(IRETURN) != ARETURN) {
        checkCast2();
        unpackagePrivateData(returnType);
        isObject = false;
      } else {
        mv.visitTypeInsn(CHECKCAST, returnType.getClassName().replace('.', '/'));
      }
    }
  }

  protected void checkCast2() {
    if (returnType.equals(Type.BOOLEAN_TYPE)) {
      mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean");
    } else if (returnType.equals(Type.BYTE_TYPE)) {
      mv.visitTypeInsn(CHECKCAST, "java/lang/Byte");
    } else if (returnType.equals(Type.CHAR_TYPE)) {
      mv.visitTypeInsn(CHECKCAST, "java/lang/Character");
    } else if (returnType.equals(Type.SHORT_TYPE)) {
      mv.visitTypeInsn(CHECKCAST, "java/lang/Short");
    } else if (returnType.equals(Type.INT_TYPE)) {
      mv.visitTypeInsn(CHECKCAST, "java/lang/Integer");
    } else if (returnType.equals(Type.LONG_TYPE)) {
      mv.visitTypeInsn(CHECKCAST, "java/lang/Long");
    } else if (returnType.equals(Type.FLOAT_TYPE)) {
      mv.visitTypeInsn(CHECKCAST, "java/lang/Float");
    } else if (returnType.equals(Type.DOUBLE_TYPE)) {
      mv.visitTypeInsn(CHECKCAST, "java/lang/Double");
    }
  }

  public final static void createInokeMethodMethodVisitor mv,
                        String[] methodNames,
                        String[] descs,
                        int[] modifies,
                        int[] invokeOps,
                        String enhancedSuperName) {
    FastClassAdpter adpter = new FastClassAdpter(mv, enhancedSuperName);
    adpter.descs = descs;
    adpter.methodNames = methodNames;
    adpter.modifies = modifies;
    adpter.invokeOps = invokeOps;
    adpter.createInokeMethod();
  }

  public final static void createInokeConstructor(MethodVisitor mv,
                          String enhancedSuperName,
                          Constructor<?>[] constructors) {
    FastClassAdpter adpter = new FastClassAdpter(mv, enhancedSuperName);
    adpter.createInokeConstructor(constructors);
  }
}
TOP

Related Classes of org.nutz.lang.reflect.FastClassAdpter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.