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.MethodVisitor; 9 import com.tc.asm.Opcodes; 10 import com.tc.asm.Type; 11 import com.tc.exception.TCRuntimeException; 12 13 import java.util.HashSet ; 14 import java.util.Set ; 15 16 public class JavaLangReflectArrayAdapter extends ClassAdapter implements Opcodes, ClassAdapterFactory { 17 private final static Set nonNativeMethods = new HashSet (2); 18 private final static Set excludeMethods = new HashSet (2); 19 20 static { 21 nonNativeMethods.add("newInstance"); 22 nonNativeMethods.add("<init>"); 23 24 excludeMethods.add("getLength"); 25 excludeMethods.add("getByte"); 26 excludeMethods.add("getBoolean"); 27 excludeMethods.add("getChar"); 28 excludeMethods.add("getDouble"); 29 excludeMethods.add("getFloat"); 30 excludeMethods.add("getInt"); 31 excludeMethods.add("getLong"); 32 excludeMethods.add("getShort"); 33 } 34 35 public JavaLangReflectArrayAdapter() { 36 super(null); 37 } 38 39 private JavaLangReflectArrayAdapter(ClassVisitor cv, ClassLoader caller) { 40 super(cv); 41 } 42 43 public ClassAdapter create(ClassVisitor visitor, ClassLoader loader) { 44 return new JavaLangReflectArrayAdapter(visitor, loader); 45 } 46 47 private boolean isNative(int access) { 48 return (access & Opcodes.ACC_NATIVE) == Opcodes.ACC_NATIVE; 49 } 50 51 private boolean isPrivate(int access) { 52 return (access & Opcodes.ACC_PRIVATE) == Opcodes.ACC_PRIVATE; 53 } 54 55 public MethodVisitor visitMethod(int access, String name, String description, String signature, String [] exceptions) { 56 if (!isNative(access)) { 57 if (!nonNativeMethods.contains(name)) { 58 throw new TCRuntimeException("Unexpected non-native method: " + name + description); 59 } else { 60 return super.visitMethod(access, name, description, signature, exceptions); 61 } 62 } 63 64 if (isPrivate(access)) { 65 return super.visitMethod(access, name, description, signature, exceptions); 66 } else if (isNative(access) && !excludeMethods.contains(name)) { 67 MethodVisitor mv = super.visitMethod(access ^ Opcodes.ACC_NATIVE, name, description, signature, exceptions); 68 addArrayUtilMethodCode(mv, name, description); 69 return mv; 70 } else { 71 return super.visitMethod(access, name, description, signature, exceptions); 72 } 73 } 74 75 private void addArrayUtilMethodCode(MethodVisitor mv, String methodName, String description) { 76 mv.visitCode(); 77 78 Type[] params = Type.getArgumentTypes(description); 79 Type returnType = Type.getReturnType(description); 80 for (int i = 0; i < params.length; i++) { 81 mv.visitVarInsn(params[i].getOpcode(ILOAD), i); 82 } 83 mv.visitMethodInsn(INVOKESTATIC, ManagerUtil.CLASS, methodName, description); 84 mv.visitInsn(returnType.getOpcode(IRETURN)); 85 mv.visitMaxs(0, 0); 86 mv.visitEnd(); 87 } 88 89 } 90 | Popular Tags |