1 4 package com.tc.aspectwerkz.transform.inlining.weaver; 5 6 import java.lang.reflect.Modifier ; 7 import java.util.Iterator ; 8 import java.util.Set ; 9 10 import com.tc.asm.*; 11 12 import com.tc.aspectwerkz.definition.SystemDefinition; 13 import com.tc.aspectwerkz.intercept.AdvisableImpl; 14 import com.tc.aspectwerkz.joinpoint.management.JoinPointType; 15 import com.tc.aspectwerkz.transform.InstrumentationContext; 16 import com.tc.aspectwerkz.transform.TransformationConstants; 17 import com.tc.aspectwerkz.transform.TransformationUtil; 18 import com.tc.aspectwerkz.transform.inlining.AsmCopyAdapter; 19 import com.tc.aspectwerkz.transform.inlining.AsmHelper; 20 import com.tc.aspectwerkz.transform.inlining.EmittedJoinPoint; 21 import com.tc.aspectwerkz.reflect.ClassInfo; 22 import com.tc.aspectwerkz.reflect.MethodInfo; 23 import com.tc.aspectwerkz.expression.PointcutType; 24 import com.tc.aspectwerkz.expression.ExpressionContext; 25 26 41 public class MethodExecutionVisitor extends ClassAdapter implements TransformationConstants { 42 43 private final ClassInfo m_classInfo; 44 private final InstrumentationContext m_ctx; 45 private String m_declaringTypeName; 46 private final Set m_addedMethods; 47 48 56 public MethodExecutionVisitor(final ClassVisitor cv, 57 final ClassInfo classInfo, 58 final InstrumentationContext ctx, 59 final Set addedMethods) { 60 super(cv); 61 m_classInfo = classInfo; 62 m_ctx = (InstrumentationContext) ctx; 63 m_addedMethods = addedMethods; 64 } 65 66 75 public void visit(final int version, 76 final int access, 77 final String name, 78 final String signature, 79 final String superName, 80 final String [] interfaces) { 81 m_declaringTypeName = name; 82 super.visit(version, access, name, signature, superName, interfaces); 83 } 84 85 95 public MethodVisitor visitMethod(final int access, 96 final String name, 97 final String desc, 98 final String signature, 99 final String [] exceptions) { 100 101 if (INIT_METHOD_NAME.equals(name) || 102 CLINIT_METHOD_NAME.equals(name) || 103 name.startsWith(ASPECTWERKZ_PREFIX) || 104 name.startsWith(SYNTHETIC_MEMBER_PREFIX) || 105 name.startsWith(WRAPPER_METHOD_PREFIX) || 106 (AdvisableImpl.ADD_ADVICE_METHOD_NAME.equals(name) && AdvisableImpl.ADD_ADVICE_METHOD_DESC.equals(desc)) || 107 (AdvisableImpl.REMOVE_ADVICE_METHOD_NAME.equals(name) && AdvisableImpl.REMOVE_ADVICE_METHOD_DESC.equals(desc))) 108 { 109 return cv.visitMethod(access, name, desc, signature, exceptions); 110 } 111 112 int hash = AsmHelper.calculateMethodHash(name, desc); 113 MethodInfo methodInfo = m_classInfo.getMethod(hash); 114 if (methodInfo == null) { 115 System.err.println( 116 "AW::WARNING " + 117 "metadata structure could not be build for method [" 118 + m_classInfo.getName().replace('/', '.') 119 + '.' + name + ':' + desc + ']' 120 ); 121 return cv.visitMethod(access, name, desc, signature, exceptions); 123 } 124 125 ExpressionContext ctx = new ExpressionContext(PointcutType.EXECUTION, methodInfo, methodInfo); 126 127 if (methodFilter(m_ctx.getDefinitions(), ctx, methodInfo)) { 128 return cv.visitMethod(access, name, desc, signature, exceptions); 129 } else { 130 String prefixedOriginalName = TransformationUtil.getPrefixedOriginalMethodName(name, m_declaringTypeName); 131 if (m_addedMethods.contains(AlreadyAddedMethodAdapter.getMethodKey(prefixedOriginalName, desc))) { 132 return cv.visitMethod(access, name, desc, signature, exceptions); 133 } 134 135 m_ctx.markAsAdvised(); 136 137 final MethodVisitor proxyMethod = createProxyMethod(access, name, desc, signature, exceptions, methodInfo); 139 140 int modifiers = ACC_SYNTHETIC; 141 if (Modifier.isStatic(access)) { 142 modifiers |= ACC_STATIC; 143 } 144 return new MethodAdapter(cv.visitMethod(modifiers, prefixedOriginalName, desc, signature, exceptions)) { 147 public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 148 return new AsmCopyAdapter.CopyAnnotationAdapter( 149 super.visitAnnotation(desc, visible), 150 proxyMethod.visitAnnotation(desc, visible) 151 ); 152 } 153 154 public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) { 155 return new AsmCopyAdapter.CopyAnnotationAdapter( 156 super.visitParameterAnnotation(parameter, desc, visible), 157 proxyMethod.visitParameterAnnotation(parameter, desc, visible) 158 ); 159 } 160 161 public void visitAttribute(Attribute attr) { 162 super.visitAttribute(attr); 163 proxyMethod.visitAttribute(attr); 164 } 165 }; 166 } 167 } 168 169 181 private MethodVisitor createProxyMethod(final int access, 182 final String name, 183 final String desc, 184 final String signature, 185 final String [] exceptions, 186 final MethodInfo methodInfo) { 187 MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions); 188 189 if (!Modifier.isStatic(access)) { 191 mv.visitVarInsn(ALOAD, 0); 192 } 193 AsmHelper.loadArgumentTypes(mv, Type.getArgumentTypes(desc), Modifier.isStatic(access)); 195 if (Modifier.isStatic(access)) { 197 mv.visitInsn(ACONST_NULL); 198 } else { 199 mv.visitVarInsn(ALOAD, 0); 200 } 201 202 int joinPointHash = AsmHelper.calculateMethodHash(name, desc); 203 String joinPointClassName = TransformationUtil.getJoinPointClassName( 204 m_declaringTypeName, 205 name, 206 desc, 207 m_declaringTypeName, 208 JoinPointType.METHOD_EXECUTION_INT, 209 joinPointHash 210 ); 211 212 215 mv.visitMethodInsn( 216 INVOKESTATIC, 217 joinPointClassName, 218 INVOKE_METHOD_NAME, 219 TransformationUtil.getInvokeSignatureForCodeJoinPoints( 220 access, desc, m_declaringTypeName, m_declaringTypeName 221 ) 222 ); 223 224 AsmHelper.addReturnStatement(mv, Type.getReturnType(desc)); 225 mv.visitMaxs(0, 0); 226 227 m_ctx.addEmittedJoinPoint( 229 new EmittedJoinPoint( 230 JoinPointType.METHOD_EXECUTION_INT, 231 m_declaringTypeName, 232 name, 233 desc, 234 access, 235 m_declaringTypeName, 236 name, 237 desc, 238 access, 239 joinPointHash, 240 joinPointClassName, 241 EmittedJoinPoint.NO_LINE_NUMBER 242 ) 243 ); 244 245 return mv; 246 } 247 248 256 public static boolean methodFilter(final Set definitions, 257 final ExpressionContext ctx, 258 final MethodInfo methodInfo) { 259 if (Modifier.isAbstract(methodInfo.getModifiers()) 260 || Modifier.isNative(methodInfo.getModifiers()) 261 || methodInfo.getName().equals(INIT_METHOD_NAME) 262 || methodInfo.getName().equals(CLINIT_METHOD_NAME) 263 || methodInfo.getName().startsWith(ORIGINAL_METHOD_PREFIX)) { 264 return true; 265 } 266 for (Iterator it = definitions.iterator(); it.hasNext();) { 267 if (((SystemDefinition) it.next()).hasPointcut(ctx)) { 268 return false; 269 } else { 270 continue; 271 } 272 } 273 return true; 274 } 275 } | Popular Tags |