1 16 package net.sf.cglib.proxy; 17 18 import java.lang.reflect.Method ; 19 import java.util.*; 20 import net.sf.cglib.core.*; 21 import org.objectweb.asm.ClassVisitor; 22 import org.objectweb.asm.Type; 23 24 28 class MixinEmitter extends ClassEmitter { 29 private static final String FIELD_NAME = "CGLIB$DELEGATES"; 30 private static final Signature CSTRUCT_OBJECT_ARRAY = 31 TypeUtils.parseConstructor("Object[]"); 32 private static final Type MIXIN = 33 TypeUtils.parseType("net.sf.cglib.proxy.Mixin"); 34 private static final Signature NEW_INSTANCE = 35 new Signature("newInstance", MIXIN, new Type[]{ Constants.TYPE_OBJECT_ARRAY }); 36 37 public MixinEmitter(ClassVisitor v, String className, Class [] classes, int[] route) { 38 super(v); 39 40 begin_class(Constants.V1_2, 41 Constants.ACC_PUBLIC, 42 className, 43 MIXIN, 44 TypeUtils.getTypes(getInterfaces(classes)), 45 Constants.SOURCE_FILE); 46 EmitUtils.null_constructor(this); 47 EmitUtils.factory_method(this, NEW_INSTANCE); 48 49 declare_field(Constants.ACC_PRIVATE, FIELD_NAME, Constants.TYPE_OBJECT_ARRAY, null); 50 51 CodeEmitter e = begin_method(Constants.ACC_PUBLIC, CSTRUCT_OBJECT_ARRAY, null); 52 e.load_this(); 53 e.super_invoke_constructor(); 54 e.load_this(); 55 e.load_arg(0); 56 e.putfield(FIELD_NAME); 57 e.return_value(); 58 e.end_method(); 59 60 Set unique = new HashSet(); 61 for (int i = 0; i < classes.length; i++) { 62 Method [] methods = getMethods(classes[i]); 63 for (int j = 0; j < methods.length; j++) { 64 if (unique.add(MethodWrapper.create(methods[j]))) { 65 MethodInfo method = ReflectUtils.getMethodInfo(methods[j]); 66 e = EmitUtils.begin_method(this, method, Constants.ACC_PUBLIC); 67 e.load_this(); 68 e.getfield(FIELD_NAME); 69 e.aaload((route != null) ? route[i] : i); 70 e.checkcast(method.getClassInfo().getType()); 71 e.load_args(); 72 e.invoke(method); 73 e.return_value(); 74 e.end_method(); 75 } 76 } 77 } 78 79 end_class(); 80 } 81 82 protected Class [] getInterfaces(Class [] classes) { 83 return classes; 84 } 85 86 protected Method [] getMethods(Class type) { 87 return type.getMethods(); 88 } 89 } 90 | Popular Tags |