1 4 package com.tc.aspectwerkz.transform.inlining.weaver; 5 6 import com.tc.asm.Opcodes; 7 import com.tc.asm.ClassAdapter; 8 import com.tc.asm.ClassVisitor; 9 import com.tc.asm.MethodVisitor; 10 import com.tc.asm.Type; 11 12 import com.tc.aspectwerkz.joinpoint.management.JoinPointType; 13 import com.tc.aspectwerkz.transform.InstrumentationContext; 14 import com.tc.aspectwerkz.transform.TransformationConstants; 15 import com.tc.aspectwerkz.transform.TransformationUtil; 16 import com.tc.aspectwerkz.transform.inlining.AsmHelper; 17 import com.tc.aspectwerkz.transform.inlining.EmittedJoinPoint; 18 19 import java.util.List ; 20 import java.util.Iterator ; 21 import java.util.Set ; 22 import java.lang.reflect.Modifier ; 23 24 30 public class AddWrapperVisitor extends ClassAdapter implements Opcodes, TransformationConstants { 31 32 private InstrumentationContext m_context; 33 34 private Set m_addedMethods; 35 36 37 public AddWrapperVisitor(ClassVisitor classVisitor, InstrumentationContext context, Set alreadyAddedMethods) { 38 super(classVisitor); 39 m_context = (InstrumentationContext) context; 40 m_addedMethods = alreadyAddedMethods; 41 } 42 43 52 public void visit(final int version, final int access, 53 final String name, 54 final String signature, 55 final String superName, 56 final String [] interfaces) { 57 List jps = m_context.getEmittedJoinPoints(); 60 for (Iterator iterator = jps.iterator(); iterator.hasNext();) { 61 EmittedJoinPoint emittedJoinPoint = (EmittedJoinPoint) iterator.next(); 62 int jpType = emittedJoinPoint.getJoinPointType(); 63 if (Modifier.isPublic(emittedJoinPoint.getCalleeMemberModifiers()) 64 || !name.equals(emittedJoinPoint.getCalleeClassName())) { continue; 66 } 67 switch (jpType) { 68 case (JoinPointType.FIELD_GET_INT) : 69 createGetFieldWrapperMethod( 70 Modifier.isStatic(emittedJoinPoint.getCalleeMemberModifiers()), 71 name, 72 emittedJoinPoint.getCalleeMemberName(), 73 emittedJoinPoint.getCalleeMemberDesc(), 74 null ); 76 break; 77 case (JoinPointType.FIELD_SET_INT) : 78 createPutFieldWrapperMethod( 79 Modifier.isStatic(emittedJoinPoint.getCalleeMemberModifiers()), 80 name, 81 emittedJoinPoint.getCalleeMemberName(), 82 emittedJoinPoint.getCalleeMemberDesc(), 83 null ); 85 break; 86 case (JoinPointType.METHOD_EXECUTION_INT) : 87 case (JoinPointType.METHOD_CALL_INT) : 88 createMethodWrapperMethod( 89 emittedJoinPoint.getCalleeMemberModifiers(), 90 name, 91 emittedJoinPoint.getCalleeMemberName(), 92 emittedJoinPoint.getCalleeMemberDesc(), 93 null, EMPTY_STRING_ARRAY ); 96 break; 97 case (JoinPointType.CONSTRUCTOR_CALL_INT) : 98 case (JoinPointType.CONSTRUCTOR_EXECUTION_INT) : 99 createConstructorWrapperMethod( 100 emittedJoinPoint.getCalleeMemberModifiers(), 101 name, 102 emittedJoinPoint.getCalleeMemberName(), 103 emittedJoinPoint.getCalleeMemberDesc(), 104 null, EMPTY_STRING_ARRAY ); 107 break; 108 } 109 } 110 111 super.visit(version, access, name, signature, superName, interfaces); 112 } 113 114 123 private void createGetFieldWrapperMethod(final boolean isStaticField, 124 final String declaringTypeName, 125 final String name, 126 final String desc, 127 final String signature) { 128 String wrapperName = TransformationUtil.getWrapperMethodName( 129 name, desc, declaringTypeName, GETFIELD_WRAPPER_METHOD_PREFIX 130 ); 131 132 StringBuffer wsignature = new StringBuffer (); 133 wsignature.append('('); 134 wsignature.append(')'); 135 wsignature.append(desc); 136 137 final String wrapperKey = AlreadyAddedMethodAdapter.getMethodKey(wrapperName, wsignature.toString()); 138 if (m_addedMethods.contains(wrapperKey)) { 139 return; 140 } 141 m_addedMethods.add(wrapperKey); 142 143 int modifiers = ACC_SYNTHETIC; 144 if (isStaticField) { 145 modifiers |= ACC_STATIC; 146 } 147 148 MethodVisitor mv = cv.visitMethod( 149 modifiers, 150 wrapperName, 151 wsignature.toString(), 152 signature, 153 EMPTY_STRING_ARRAY 154 ); 155 156 if (isStaticField) { 157 mv.visitFieldInsn(GETSTATIC, declaringTypeName, name, desc); 158 } else { 159 mv.visitVarInsn(ALOAD, 0); 160 mv.visitFieldInsn(GETFIELD, declaringTypeName, name, desc); 161 } 162 163 AsmHelper.addReturnStatement(mv, Type.getType(desc)); 164 mv.visitMaxs(0, 0); 165 } 166 167 177 private void createPutFieldWrapperMethod(boolean isStaticField, 178 final String declaringTypeName, 179 final String name, 180 final String desc, 181 final String signature) { 182 String wrapperName = TransformationUtil.getWrapperMethodName( 183 name, desc, declaringTypeName, PUTFIELD_WRAPPER_METHOD_PREFIX 184 ); 185 186 StringBuffer wsignature = new StringBuffer (); 187 wsignature.append('('); 188 wsignature.append(desc); 189 wsignature.append(')'); 190 wsignature.append('V'); 191 192 final String wrapperKey = AlreadyAddedMethodAdapter.getMethodKey(wrapperName, wsignature.toString()); 193 if (m_addedMethods.contains(wrapperKey)) { 194 return; 195 } 196 m_addedMethods.add(wrapperKey); 197 198 int modifiers = ACC_SYNTHETIC; 199 if (isStaticField) { 200 modifiers |= ACC_STATIC; 201 } 202 203 MethodVisitor mv = cv.visitMethod( 204 modifiers, 205 wrapperName, 206 wsignature.toString(), 207 signature, 208 EMPTY_STRING_ARRAY 209 ); 210 211 Type fieldType = Type.getType(desc); 212 if (isStaticField) { 213 AsmHelper.loadArgumentTypes(mv, new Type[]{fieldType}, true); 214 mv.visitFieldInsn(PUTSTATIC, declaringTypeName, name, desc); 215 } else { 216 mv.visitVarInsn(ALOAD, 0); 217 AsmHelper.loadArgumentTypes(mv, new Type[]{fieldType}, false); 218 mv.visitFieldInsn(PUTFIELD, declaringTypeName, name, desc); 219 } 220 221 AsmHelper.addReturnStatement(mv, Type.VOID_TYPE); 222 mv.visitMaxs(0, 0); 223 } 224 225 235 private void createMethodWrapperMethod(final int access, 236 final String declaringTypeName, 237 final String name, 238 final String desc, 239 final String signature, 240 final String [] exceptions) { 241 final String wrapperName = TransformationUtil.getWrapperMethodName( 242 name, desc, declaringTypeName, INVOKE_WRAPPER_METHOD_PREFIX 243 ); 244 245 final String wrapperKey = AlreadyAddedMethodAdapter.getMethodKey(wrapperName, desc); 246 if (m_addedMethods.contains(wrapperKey)) { 247 return; 248 } 249 m_addedMethods.add(wrapperKey); 250 251 int modifiers = ACC_SYNTHETIC; 252 if (Modifier.isStatic(access)) { 253 modifiers |= ACC_STATIC; 254 } 255 256 MethodVisitor mv = super.visitMethod( 257 modifiers, 258 wrapperName, 259 desc, 260 signature, 261 exceptions 262 ); 263 264 if (Modifier.isStatic(access)) { 265 AsmHelper.loadArgumentTypes(mv, Type.getArgumentTypes(desc), Modifier.isStatic(access)); 266 mv.visitMethodInsn(INVOKESTATIC, declaringTypeName, name, desc); 267 } else { 268 mv.visitVarInsn(ALOAD, 0); 269 AsmHelper.loadArgumentTypes(mv, Type.getArgumentTypes(desc), Modifier.isStatic(access)); 270 mv.visitMethodInsn(INVOKEVIRTUAL, declaringTypeName, name, desc); 271 } 272 273 AsmHelper.addReturnStatement(mv, Type.getReturnType(desc)); 274 275 mv.visitMaxs(0, 0); 276 } 277 278 288 private void createConstructorWrapperMethod(final int access, 289 final String declaringTypeName, 290 final String name, 291 final String desc, 292 final String signature, 293 final String [] exceptions) { 294 final String wrapperName = TransformationUtil.getWrapperMethodName( 295 name, desc, declaringTypeName, INVOKE_WRAPPER_METHOD_PREFIX 296 ); 297 298 final String wrapperKey = AlreadyAddedMethodAdapter.getMethodKey(wrapperName, desc); 299 if (m_addedMethods.contains(wrapperKey)) { 300 return; 301 } 302 m_addedMethods.add(wrapperKey); 303 304 int modifiers = ACC_SYNTHETIC; 305 modifiers |= ACC_STATIC; 306 307 Type declaringType = Type.getType('L' + declaringTypeName + ';'); 308 String ctorDesc = Type.getMethodDescriptor(declaringType, Type.getArgumentTypes(desc)); 309 310 MethodVisitor mv = super.visitMethod( 311 modifiers, 312 wrapperName, 313 ctorDesc, 314 signature, 315 exceptions 316 ); 317 318 mv.visitTypeInsn(NEW, declaringTypeName); 319 mv.visitInsn(DUP); 320 AsmHelper.loadArgumentTypes(mv, Type.getArgumentTypes(desc), true); 321 mv.visitMethodInsn(INVOKESPECIAL, declaringTypeName, name, desc); 322 AsmHelper.addReturnStatement(mv, declaringType); 323 324 mv.visitMaxs(0, 0); 325 } 326 327 } 328 | Popular Tags |