1 8 package org.codehaus.aspectwerkz.transform.inlining.weaver; 9 10 import org.objectweb.asm.ClassAdapter; 11 import org.objectweb.asm.ClassVisitor; 12 import org.objectweb.asm.CodeVisitor; 13 import org.objectweb.asm.Attribute; 14 import org.objectweb.asm.CodeAdapter; 15 import org.codehaus.aspectwerkz.transform.Context; 16 import org.codehaus.aspectwerkz.transform.TransformationConstants; 17 import org.codehaus.aspectwerkz.transform.inlining.ContextImpl; 18 import org.codehaus.aspectwerkz.transform.inlining.EmittedJoinPoint; 19 20 import java.util.Iterator ; 21 22 36 public class JoinPointInitVisitor extends ClassAdapter implements TransformationConstants { 37 38 private final ContextImpl m_ctx; 39 private boolean m_hasClinitMethod = false; 40 private boolean m_hasInitJoinPointsMethod = false; 41 private boolean m_hasClassField = false; 42 private boolean m_hasEmittedJoinPointsField = false; 43 44 50 public JoinPointInitVisitor(final ClassVisitor cv, final Context ctx) { 51 super(cv); 52 m_ctx = (ContextImpl) ctx; 53 } 54 55 63 public CodeVisitor visitMethod(final int access, 64 final String name, 65 final String desc, 66 final String [] exceptions, 67 final Attribute attrs) { 68 69 if (CLINIT_METHOD_NAME.equals(name)) { 70 m_hasClinitMethod = true; 71 CodeVisitor ca = new InsertBeforeClinitCodeAdapter(cv.visitMethod(access, name, desc, exceptions, attrs)); 75 ca.visitMaxs(0, 0); 76 return ca; 77 78 } else if (INIT_JOIN_POINTS_METHOD_NAME.equals(name)) { 79 m_hasInitJoinPointsMethod = true; 80 CodeVisitor ca = new InsertBeforeInitJoinPointsCodeAdapter( 82 cv.visitMethod(access, name, desc, exceptions, attrs) 83 ); 84 ca.visitMaxs(0, 0); 85 return ca; 86 } else { 87 return super.visitMethod(access, name, desc, exceptions, attrs); 88 } 89 } 90 91 100 public void visitField(int access, String name, String desc, Object value, Attribute attrs) { 101 if (TARGET_CLASS_FIELD_NAME.equals(name)) { 102 m_hasClassField = true; 103 } else if (EMITTED_JOINPOINTS_FIELD_NAME.equals(name)) { 104 m_hasEmittedJoinPointsField = true; 105 } 106 super.visitField(access, name, desc, value, attrs); 107 } 108 109 113 public void visitEnd() { 114 if (!m_ctx.isAdvised()) { 115 super.visitEnd(); 116 return; 117 } 118 119 if (!m_hasClassField) { 120 cv.visitField( 123 ACC_PRIVATE + ACC_FINAL + ACC_STATIC + ACC_SYNTHETIC, 124 TARGET_CLASS_FIELD_NAME, 125 CLASS_CLASS_SIGNATURE, 126 null, 127 null 128 ); 129 } 130 131 if (!m_hasEmittedJoinPointsField && m_ctx.isMadeAdvisable()) { 132 cv.visitField( 135 ACC_PRIVATE + ACC_FINAL + ACC_STATIC + ACC_SYNTHETIC, 136 EMITTED_JOINPOINTS_FIELD_NAME, 137 "Lgnu/trove/TIntObjectHashMap;", 138 null, 139 null 140 ); 141 } 142 143 if (!m_hasClinitMethod) { 144 CodeVisitor ca = new InsertBeforeClinitCodeAdapter( 145 cv.visitMethod( 146 ACC_STATIC, 147 CLINIT_METHOD_NAME, 148 NO_PARAMS_RETURN_VOID_METHOD_SIGNATURE, 149 null, 150 null 151 ) 152 ); 153 ca.visitInsn(RETURN); 154 ca.visitMaxs(0, 0); 155 } 156 157 if (!m_hasInitJoinPointsMethod) { 158 CodeVisitor mv = new InsertBeforeInitJoinPointsCodeAdapter( 159 cv.visitMethod( 160 ACC_PRIVATE + ACC_FINAL + ACC_STATIC + ACC_SYNTHETIC, 161 INIT_JOIN_POINTS_METHOD_NAME, 162 NO_PARAMS_RETURN_VOID_METHOD_SIGNATURE, 163 null, 164 null 165 ) 166 ); 167 mv.visitInsn(RETURN); 168 mv.visitMaxs(0, 0); 169 } 170 171 cv.visitEnd(); 172 } 173 174 179 public class InsertBeforeClinitCodeAdapter extends CodeAdapter { 180 181 public InsertBeforeClinitCodeAdapter(CodeVisitor ca) { 182 super(ca); 183 if (!m_hasClassField) { 184 cv.visitLdcInsn(m_ctx.getClassName().replace('/', '.')); 185 cv.visitMethodInsn(INVOKESTATIC, CLASS_CLASS, FOR_NAME_METHOD_NAME, FOR_NAME_METHOD_SIGNATURE); 186 cv.visitFieldInsn(PUTSTATIC, m_ctx.getClassName(), TARGET_CLASS_FIELD_NAME, CLASS_CLASS_SIGNATURE); 187 } 188 if (!m_hasEmittedJoinPointsField && m_ctx.isMadeAdvisable()) { 189 cv.visitTypeInsn(NEW, "gnu/trove/TIntObjectHashMap"); 191 cv.visitInsn(DUP); 192 cv.visitMethodInsn(INVOKESPECIAL, "gnu/trove/TIntObjectHashMap", "<init>", "()V"); 193 cv.visitFieldInsn(PUTSTATIC, m_ctx.getClassName(), EMITTED_JOINPOINTS_FIELD_NAME, "Lgnu/trove/TIntObjectHashMap;"); 194 } 195 if (!m_hasClassField) { 196 cv.visitMethodInsn( 197 INVOKESTATIC, 198 m_ctx.getClassName(), 199 INIT_JOIN_POINTS_METHOD_NAME, 200 NO_PARAMS_RETURN_VOID_METHOD_SIGNATURE 201 ); 202 } 203 } 204 } 205 206 212 public class InsertBeforeInitJoinPointsCodeAdapter extends CodeAdapter { 213 214 public InsertBeforeInitJoinPointsCodeAdapter(CodeVisitor ca) { 215 super(ca); 216 217 for (Iterator iterator = m_ctx.getEmittedJoinPoints().iterator(); iterator.hasNext();) { 220 221 EmittedJoinPoint jp = (EmittedJoinPoint) iterator.next(); 222 cv.visitLdcInsn(new Integer (jp.getJoinPointType())); 223 224 cv.visitFieldInsn(GETSTATIC, m_ctx.getClassName(), TARGET_CLASS_FIELD_NAME, CLASS_CLASS_SIGNATURE); 225 cv.visitLdcInsn(jp.getCallerMethodName()); 226 cv.visitLdcInsn(jp.getCallerMethodDesc()); 227 cv.visitLdcInsn(new Integer (jp.getCallerMethodModifiers())); 228 229 cv.visitLdcInsn(jp.getCalleeClassName()); 230 cv.visitLdcInsn(jp.getCalleeMemberName()); 231 cv.visitLdcInsn(jp.getCalleeMemberDesc()); 232 cv.visitLdcInsn(new Integer (jp.getCalleeMemberModifiers())); 233 234 cv.visitLdcInsn(new Integer (jp.getJoinPointHash())); 235 cv.visitLdcInsn(jp.getJoinPointClassName()); 236 cv.visitMethodInsn( 237 INVOKESTATIC, 238 JOIN_POINT_MANAGER_CLASS_NAME, 239 LOAD_JOIN_POINT_METHOD_NAME, 240 LOAD_JOIN_POINT_METHOD_SIGNATURE 241 ); 242 243 if (m_ctx.isMadeAdvisable()) { 244 cv.visitFieldInsn(GETSTATIC, m_ctx.getClassName(), EMITTED_JOINPOINTS_FIELD_NAME, "Lgnu/trove/TIntObjectHashMap;"); 246 cv.visitLdcInsn(new Integer (jp.getJoinPointClassName().hashCode())); 248 249 250 cv.visitTypeInsn(NEW, "org/codehaus/aspectwerkz/transform/inlining/EmittedJoinPoint"); 251 cv.visitInsn(DUP); 252 253 cv.visitLdcInsn(new Integer (jp.getJoinPointType())); 254 255 cv.visitLdcInsn(m_ctx.getClassName()); 256 cv.visitLdcInsn(jp.getCallerMethodName()); 257 cv.visitLdcInsn(jp.getCallerMethodDesc()); 258 cv.visitLdcInsn(new Integer (jp.getCallerMethodModifiers())); 259 260 cv.visitLdcInsn(jp.getCalleeClassName()); 261 cv.visitLdcInsn(jp.getCalleeMemberName()); 262 cv.visitLdcInsn(jp.getCalleeMemberDesc()); 263 cv.visitLdcInsn(new Integer (jp.getCalleeMemberModifiers())); 264 265 cv.visitLdcInsn(new Integer (jp.getJoinPointHash())); 266 cv.visitLdcInsn(jp.getJoinPointClassName()); 267 268 cv.visitMethodInsn(INVOKESPECIAL, "org/codehaus/aspectwerkz/transform/inlining/EmittedJoinPoint", "<init>", 269 "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;IILjava/lang/String;)V" 270 ); 271 cv.visitMethodInsn( 272 INVOKEVIRTUAL, 273 "gnu/trove/TIntObjectHashMap", 274 "put", 275 "(ILjava/lang/Object;)Ljava/lang/Object;" 276 ); 277 } 278 } 279 } 280 } 281 282 } | Popular Tags |