1 4 package com.tc.object.bytecode; 5 6 import com.tc.asm.ClassAdapter; 7 import com.tc.asm.ClassVisitor; 8 import com.tc.asm.Label; 9 import com.tc.asm.MethodVisitor; 10 import com.tc.asm.Opcodes; 11 import com.tc.asm.Type; 12 import com.tc.util.FieldUtils; 13 14 import java.util.HashSet ; 15 import java.util.Set ; 16 17 public class JavaLangReflectFieldAdapter extends ClassAdapter implements Opcodes, ClassAdapterFactory { 18 19 private static final Set setters = new HashSet (); 20 private static final Set getters = new HashSet (); 21 22 static { 23 getters.add("get(Ljava/lang/Object;)Ljava/lang/Object;"); 24 25 setters.add("set(Ljava/lang/Object;Ljava/lang/Object;)V"); 26 setters.add("setByte(Ljava/lang/Object;B)V"); 27 setters.add("setBoolean(Ljava/lang/Object;Z)V"); 28 setters.add("setChar(Ljava/lang/Object;C)V"); 29 setters.add("setDouble(Ljava/lang/Object;D)V"); 30 setters.add("setFloat(Ljava/lang/Object;F)V"); 31 setters.add("setInt(Ljava/lang/Object;I)V"); 32 setters.add("setLong(Ljava/lang/Object;J)V"); 33 setters.add("setShort(Ljava/lang/Object;S)V"); 34 } 35 36 public JavaLangReflectFieldAdapter() { 37 super(null); 38 } 39 40 private JavaLangReflectFieldAdapter(ClassVisitor cv, ClassLoader caller) { 41 super(cv); 42 } 43 44 public ClassAdapter create(ClassVisitor visitor, ClassLoader loader) { 45 return new JavaLangReflectFieldAdapter(visitor, loader); 46 } 47 48 public MethodVisitor visitMethod(int access, String name, String desc, String signature, String [] exceptions) { 49 MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); 50 51 String method = name + desc; 52 53 if (setters.contains(method)) { 54 callFieldUtilSetter(mv, name, desc); 55 } else if (getters.contains(method)) { 56 rewriteGetter(mv, name, desc); 57 return null; 58 } 59 60 return mv; 61 } 62 63 private String getFieldUtilsSetterDesc(String desc) { 64 int index = desc.indexOf(")"); 65 StringBuffer sb = new StringBuffer (desc.substring(0, index)); 66 sb.append("Ljava/lang/reflect/Field;)Z"); 67 return sb.toString(); 68 } 69 70 private void callFieldUtilSetter(MethodVisitor mv, String name, String desc) { 71 Type type = Type.getArgumentTypes(desc)[1]; 72 Label notSet = new Label(); 73 mv.visitVarInsn(ALOAD, 1); 74 mv.visitVarInsn(type.getOpcode(ILOAD), 2); 75 mv.visitVarInsn(ALOAD, 0); 76 mv.visitMethodInsn(INVOKESTATIC, FieldUtils.CLASS, name, getFieldUtilsSetterDesc(desc)); 77 mv.visitJumpInsn(IFEQ, notSet); 78 mv.visitInsn(RETURN); 79 mv.visitLabel(notSet); 80 } 81 82 private void rewriteGetter(MethodVisitor mv, String name, String desc) { 83 Type returnType = Type.getReturnType(desc); 84 85 mv.visitCode(); 86 mv.visitVarInsn(ALOAD, 1); 87 mv.visitVarInsn(ALOAD, 0); 88 mv.visitVarInsn(ALOAD, 0); 89 mv.visitVarInsn(ALOAD, 1); 90 mv.visitMethodInsn(INVOKESPECIAL, "java/lang/reflect/Field", "getFieldAccessor", 91 "(Ljava/lang/Object;)Lsun/reflect/FieldAccessor;"); 92 mv.visitMethodInsn(INVOKESTATIC, FieldUtils.CLASS, name, FieldUtils.GET_DESC + returnType.getDescriptor()); 93 mv.visitInsn(returnType.getOpcode(IRETURN)); 94 mv.visitMaxs(0, 0); 95 mv.visitEnd(); 96 } 97 98 } | Popular Tags |