package org.deuce.transform.asm.method; import java.util.List; import org.deuce.objectweb.asm.MethodAdapter; import org.deuce.objectweb.asm.MethodVisitor; import org.deuce.objectweb.asm.Opcodes; import org.deuce.objectweb.asm.Type; import org.deuce.transform.UseStrongIso; import org.deuce.transform.asm.Field; public class StaticMethodTransformer extends MethodAdapter { final static public String CLASS_BASE = "__CLASS_BASE__"; private final List<Field> fields; private final String className; private final MethodVisitor staticMethod; private final String fieldsHolderName; private final String staticField; public StaticMethodTransformer(MethodVisitor mv, MethodVisitor staticMethod, List<Field> fields, String staticField, String className, String fieldsHolderName) { super(mv); this.staticMethod = staticMethod; this.fields = fields; this.staticField = staticField; this.className = className; this.fieldsHolderName = fieldsHolderName; } @Override public void visitCode() { if(fields.size() > 0){ for( Field field : fields) addField( field); if(staticField != null) addClassBase(staticField); } } private void addField( Field field) { staticMethod.visitLdcInsn(Type.getObjectType(className)); if(field.objName != null) staticMethod.visitLdcInsn(field.objName); else staticMethod.visitLdcInsn(field.getFieldName()); staticMethod.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Class", "getDeclaredField", "(Ljava/lang/String;)Ljava/lang/reflect/Field;"); staticMethod.visitMethodInsn(Opcodes.INVOKESTATIC, "org/deuce/reflection/AddressUtil", "getAddress", "(Ljava/lang/reflect/Field;)J"); staticMethod.visitFieldInsn(Opcodes.PUTSTATIC, fieldsHolderName, field.getFieldNameAddress(), "J"); } private void addClassBase(String staticFieldBase) { staticMethod.visitLdcInsn(Type.getObjectType(className)); staticMethod.visitLdcInsn(staticFieldBase); staticMethod.visitMethodInsn(Opcodes.INVOKESTATIC, "org/deuce/reflection/AddressUtil", "staticFieldBase", "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Object;"); staticMethod.visitFieldInsn(Opcodes.PUTSTATIC, fieldsHolderName, CLASS_BASE, "Ljava/lang/Object;"); if(UseStrongIso.USE_STRONG_ISO) { staticMethod.visitLdcInsn(Type.getObjectType(className)); staticMethod.visitLdcInsn(staticFieldBase); staticMethod.visitMethodInsn(Opcodes.INVOKESTATIC, "org/deuce/reflection/AddressUtil", "staticFieldBase", "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Object;"); staticMethod.visitFieldInsn(Opcodes.PUTSTATIC, fieldsHolderName, CLASS_BASE, "Ljava/lang/Object;"); } } @Override public void visitEnd(){ super.visitEnd(); // TODO can we do it cleaner? if( super.mv != staticMethod) staticMethod.visitEnd(); } }