package jef.accelerator.asm; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Type; import jef.tools.reflect.BeanUtils; public class ASMUtils { public static boolean isAndroid(String vmName) { if (vmName == null) { // default is false return false; } String lowerVMName = vmName.toLowerCase(); return lowerVMName.contains("dalvik") // || lowerVMName.contains("lemur") // aliyun-vm name ; } public static boolean isAndroid() { return isAndroid(System.getProperty("java.vm.name")); } public static String getDesc(Method method) { StringBuffer buf = new StringBuffer(); buf.append("("); java.lang.Class<?>[] types = method.getParameterTypes(); for (int i = 0; i < types.length; ++i) { buf.append(getDesc(types[i])); } buf.append(")"); buf.append(getDesc(method.getReturnType())); return buf.toString(); } public static String getDesc(Class<?> returnType) { if (returnType.isPrimitive()) { return getPrimitiveLetter(returnType); } else if (returnType.isArray()) { return "[" + getDesc(returnType.getComponentType()); } else { return "L" + getType(returnType) + ";"; } } public static String getType(Class<?> parameterType) { if (parameterType.isArray()) { return "[" + getDesc(parameterType.getComponentType()); } else { if (!parameterType.isPrimitive()) { String clsName = parameterType.getName(); return clsName.replace('.', '/'); } else { return getPrimitiveLetter(parameterType); } } } public static String getPrimitiveLetter(Class<?> type) { if (Integer.TYPE.equals(type)) { return "I"; } else if (Void.TYPE.equals(type)) { return "V"; } else if (Boolean.TYPE.equals(type)) { return "Z"; } else if (Character.TYPE.equals(type)) { return "C"; } else if (Byte.TYPE.equals(type)) { return "B"; } else if (Short.TYPE.equals(type)) { return "S"; } else if (Float.TYPE.equals(type)) { return "F"; } else if (Long.TYPE.equals(type)) { return "J"; } else if (Double.TYPE.equals(type)) { return "D"; } throw new IllegalStateException("Type: " + type.getCanonicalName() + " is not a primitive type"); } public static Type getMethodType(Class<?> clazz, String methodName) { try { Method method = clazz.getMethod(methodName); return method.getGenericReturnType(); } catch (Exception ex) { return null; } } public static Type getFieldType(Class<?> clazz, String fieldName) { Class<?> clz = clazz; while (clz != Object.class) { try { Field field = clazz.getDeclaredField(fieldName); return field.getGenericType(); } catch (Exception ex) { } clz = clz.getSuperclass(); } return null; } public static boolean checkName(String name) { for (int i = 0; i < name.length(); ++i) { char c = name.charAt(i); if (c < '\001' || c > '\177') { return false; } } return true; } /** * get the class object of primitive type * * @param mw * @param rawType */ public static void getPrimitiveType(MethodVisitor mw, Class<?> rawType) { Class<?> wrapClz = BeanUtils.toWrapperClass(rawType); mw.visitFieldInsn(Opcodes.GETSTATIC, getType(wrapClz), "TYPE", "Ljava/lang/Class;"); } /** * 生成拆箱方法 * * @param mw * @param primitive * 原生类型 */ public static void doUnwrap(MethodVisitor mw, Class<?> primitive, Class<?> wrapped) { String name = primitive.getName() + "Value"; mw.visitMethodInsn(Opcodes.INVOKEVIRTUAL, getType(wrapped), name, getMethodDesc(primitive)); } /** * 生成装箱方法 * * @param mw * @param type * 原生类型 */ public static void doWrap(MethodVisitor mw, Class<?> type) { Class<?> wrapped = BeanUtils.toWrapperClass(type); mw.visitMethodInsn(Opcodes.INVOKESTATIC, getType(wrapped), "valueOf", getMethodDesc(wrapped, type)); } public static void doWrap(MethodVisitor mw, jef.accelerator.asm.Type paramType) { Class<?> w; switch (paramType.getSort()) { case jef.accelerator.asm.Type.BOOLEAN: w = Boolean.class; break; case jef.accelerator.asm.Type.BYTE: w = Byte.class; break; case jef.accelerator.asm.Type.CHAR: w = Character.class; break; case jef.accelerator.asm.Type.DOUBLE: w = Double.class; break; case jef.accelerator.asm.Type.FLOAT: w = Float.class; break; case jef.accelerator.asm.Type.INT: w = Integer.class; break; case jef.accelerator.asm.Type.LONG: w = Long.class; break; case jef.accelerator.asm.Type.SHORT: w = Short.class; break; default: throw new IllegalArgumentException(); } mw.visitMethodInsn(Opcodes.INVOKESTATIC, getType(w), "valueOf", getMethodDesc(w, BeanUtils.toPrimitiveClass(w))); } public static int getLoadIns(jef.accelerator.asm.Type paramType) { switch (paramType.getSort()) { case jef.accelerator.asm.Type.BOOLEAN: return Opcodes.ILOAD; case jef.accelerator.asm.Type.BYTE: return Opcodes.ILOAD; case jef.accelerator.asm.Type.CHAR: return Opcodes.ILOAD; case jef.accelerator.asm.Type.DOUBLE: return Opcodes.DLOAD; case jef.accelerator.asm.Type.FLOAT: return Opcodes.FLOAD; case jef.accelerator.asm.Type.INT: return Opcodes.ILOAD; case jef.accelerator.asm.Type.LONG: return Opcodes.LLOAD; case jef.accelerator.asm.Type.SHORT: return Opcodes.ILOAD; default: return Opcodes.ALOAD; } } public static void iconst(MethodVisitor mw, int s) { switch (s) { case 0: mw.visitInsn(Opcodes.ICONST_0); break; case 1: mw.visitInsn(Opcodes.ICONST_1); break; case 2: mw.visitInsn(Opcodes.ICONST_2); break; case 3: mw.visitInsn(Opcodes.ICONST_3); break; case 4: mw.visitInsn(Opcodes.ICONST_4); break; case 5: mw.visitInsn(Opcodes.ICONST_5); break; default: mw.visitIntInsn(Opcodes.BIPUSH, s); } } /** * 生成方法签名 * * @param returnType * @param params * @return */ public static String getMethodDesc(Class<?> returnType, Class<?>... params) { StringBuilder sb = new StringBuilder("("); for (Class<?> c : params) { sb.append(getDesc(c)); } sb.append(')'); sb.append(getDesc(returnType)); return sb.toString(); } }