1 8 package org.codehaus.aspectwerkz.transform.inlining.weaver; 9 10 import org.objectweb.asm.Constants; 11 import org.objectweb.asm.ClassAdapter; 12 import org.objectweb.asm.ClassVisitor; 13 import org.objectweb.asm.CodeVisitor; 14 import org.objectweb.asm.Type; 15 import org.objectweb.asm.Attribute; 16 import org.codehaus.aspectwerkz.transform.Context; 17 import org.codehaus.aspectwerkz.transform.TransformationUtil; 18 import org.codehaus.aspectwerkz.transform.TransformationConstants; 19 import org.codehaus.aspectwerkz.transform.inlining.ContextImpl; 20 import org.codehaus.aspectwerkz.transform.inlining.EmittedJoinPoint; 21 import org.codehaus.aspectwerkz.transform.inlining.AsmHelper; 22 import org.codehaus.aspectwerkz.joinpoint.management.JoinPointType; 23 24 import java.util.List ; 25 import java.util.Iterator ; 26 import java.util.Set ; 27 import java.lang.reflect.Modifier ; 28 29 35 public class AddWrapperVisitor extends ClassAdapter implements Constants, TransformationConstants { 36 37 private ContextImpl m_context; 38 39 private Set m_addedMethods; 40 41 42 public AddWrapperVisitor(ClassVisitor classVisitor, Context context, Set alreadyAddedMethods) { 43 super(classVisitor); 44 m_context = (ContextImpl) context; 45 m_addedMethods = alreadyAddedMethods; 46 } 47 48 57 public void visit(final int version, final int access, 58 final String name, 59 final String superName, 60 final String [] interfaces, 61 final String sourceFile) { 62 List jps = m_context.getEmittedJoinPoints(); 65 for (Iterator iterator = jps.iterator(); iterator.hasNext();) { 66 EmittedJoinPoint emittedJoinPoint = (EmittedJoinPoint) iterator.next(); 67 int jpType = emittedJoinPoint.getJoinPointType(); 68 String calleeName = emittedJoinPoint.getCalleeMemberName(); 69 if (Modifier.isPublic(emittedJoinPoint.getCalleeMemberModifiers()) 70 || !name.equals(emittedJoinPoint.getCalleeClassName())) { continue; 72 } 73 switch (jpType) { 74 case (JoinPointType.FIELD_GET_INT) : 75 createGetFieldWrapperMethod( 76 Modifier.isStatic(emittedJoinPoint.getCalleeMemberModifiers()), 77 name, 78 emittedJoinPoint.getCalleeMemberName(), 79 emittedJoinPoint.getCalleeMemberDesc() 80 ); 81 break; 82 case (JoinPointType.FIELD_SET_INT) : 83 createPutFieldWrapperMethod( 84 Modifier.isStatic(emittedJoinPoint.getCalleeMemberModifiers()), 85 name, 86 emittedJoinPoint.getCalleeMemberName(), 87 emittedJoinPoint.getCalleeMemberDesc() 88 ); 89 break; 90 case (JoinPointType.METHOD_EXECUTION_INT) : 91 case (JoinPointType.METHOD_CALL_INT) : 92 createMethodWrapperMethod( 93 emittedJoinPoint.getCalleeMemberModifiers(), 94 name, 95 emittedJoinPoint.getCalleeMemberName(), 96 emittedJoinPoint.getCalleeMemberDesc(), 97 new String [0], null ); 100 break; 101 } 102 } 103 104 super.visit(version, access, name, superName, interfaces, sourceFile); 105 } 106 107 115 private void createGetFieldWrapperMethod(final boolean isStaticField, 116 final String declaringTypeName, 117 final String name, 118 final String desc) { 119 String wrapperName = TransformationUtil.getWrapperMethodName( 120 name, desc, declaringTypeName, GETFIELD_WRAPPER_METHOD_PREFIX 121 ); 122 123 StringBuffer signature = new StringBuffer (); 124 signature.append('('); 125 signature.append(')'); 126 signature.append(desc); 127 128 final String wrapperKey = AlreadyAddedMethodAdapter.getMethodKey(wrapperName, signature.toString()); 129 if (m_addedMethods.contains(wrapperKey)) { 130 return; 131 } 132 m_addedMethods.add(wrapperKey); 133 134 int modifiers = ACC_SYNTHETIC; 135 if (isStaticField) { 136 modifiers |= ACC_STATIC; 137 } 138 139 CodeVisitor mv = cv.visitMethod( 140 modifiers, 141 wrapperName, 142 signature.toString(), 143 new String []{}, 144 null 145 ); 146 147 if (isStaticField) { 148 mv.visitFieldInsn(GETSTATIC, declaringTypeName, name, desc); 149 } else { 150 mv.visitVarInsn(ALOAD, 0); 151 mv.visitFieldInsn(GETFIELD, declaringTypeName, name, desc); 152 } 153 154 AsmHelper.addReturnStatement(mv, Type.getType(desc)); 155 mv.visitMaxs(0, 0); 156 } 157 158 167 private void createPutFieldWrapperMethod(boolean isStaticField, 168 final String declaringTypeName, 169 final String name, 170 final String desc) { 171 String wrapperName = TransformationUtil.getWrapperMethodName( 172 name, desc, declaringTypeName, PUTFIELD_WRAPPER_METHOD_PREFIX 173 ); 174 175 StringBuffer signature = new StringBuffer (); 176 signature.append('('); 177 signature.append(desc); 178 signature.append(')'); 179 signature.append('V'); 180 181 final String wrapperKey = AlreadyAddedMethodAdapter.getMethodKey(wrapperName, signature.toString()); 182 if (m_addedMethods.contains(wrapperKey)) { 183 return; 184 } 185 m_addedMethods.add(wrapperKey); 186 187 int modifiers = ACC_SYNTHETIC; 188 if (isStaticField) { 189 modifiers |= ACC_STATIC; 190 } 191 192 CodeVisitor mv = cv.visitMethod( 193 modifiers, 194 wrapperName, 195 signature.toString(), 196 new String []{}, 197 null 198 ); 199 200 Type fieldType = Type.getType(desc); 201 if (isStaticField) { 202 AsmHelper.loadArgumentTypes(mv, new Type[]{fieldType}, true); 203 mv.visitFieldInsn(PUTSTATIC, declaringTypeName, name, desc); 204 } else { 205 mv.visitVarInsn(ALOAD, 0); 206 AsmHelper.loadArgumentTypes(mv, new Type[]{fieldType}, false); 207 mv.visitFieldInsn(PUTFIELD, declaringTypeName, name, desc); 208 } 209 210 AsmHelper.addReturnStatement(mv, Type.VOID_TYPE); 211 mv.visitMaxs(0, 0); 212 } 213 214 224 private void createMethodWrapperMethod(final int access, 225 final String declaringTypeName, 226 final String name, 227 final String desc, 228 final String [] exceptions, 229 final Attribute attrs) { 230 final String wrapperName = TransformationUtil.getWrapperMethodName( 231 name, desc, declaringTypeName, INVOKE_WRAPPER_METHOD_PREFIX 232 ); 233 234 final String wrapperKey = AlreadyAddedMethodAdapter.getMethodKey(wrapperName, desc); 235 if (m_addedMethods.contains(wrapperKey)) { 236 return; 237 } 238 m_addedMethods.add(wrapperKey); 239 240 int modifiers = ACC_SYNTHETIC; 241 if (Modifier.isStatic(access)) { 242 modifiers |= ACC_STATIC; 243 } 244 245 CodeVisitor mv = super.visitMethod( 246 modifiers, 247 wrapperName, 248 desc, 249 exceptions, 250 attrs 251 ); 252 253 if (Modifier.isStatic(access)) { 254 AsmHelper.loadArgumentTypes(mv, Type.getArgumentTypes(desc), Modifier.isStatic(access)); 255 mv.visitMethodInsn(INVOKESTATIC, declaringTypeName, name, desc); 256 } else { 257 mv.visitVarInsn(ALOAD, 0); 258 AsmHelper.loadArgumentTypes(mv, Type.getArgumentTypes(desc), Modifier.isStatic(access)); 259 mv.visitMethodInsn(INVOKEVIRTUAL, declaringTypeName, name, desc); 260 } 261 262 AsmHelper.addReturnStatement(mv, Type.getReturnType(desc)); 263 264 mv.visitMaxs(0, 0); 265 } 266 267 } 268 | Popular Tags |