1 4 package com.tc.aspectwerkz.transform.inlining.compiler; 5 6 import com.tc.asm.ClassWriter; 7 import com.tc.asm.MethodVisitor; 8 import com.tc.asm.Label; 9 import com.tc.asm.Type; 10 11 import com.tc.aspectwerkz.DeploymentModel; 12 import com.tc.aspectwerkz.reflect.ClassInfo; 13 import com.tc.aspectwerkz.aspect.AdviceInfo; 14 import com.tc.aspectwerkz.aspect.container.AspectFactoryManager; 15 import com.tc.aspectwerkz.definition.AspectDefinition; 16 import com.tc.aspectwerkz.joinpoint.management.AdviceInfoContainer; 17 import com.tc.aspectwerkz.joinpoint.management.JoinPointType; 18 import com.tc.aspectwerkz.transform.JoinPointCompiler; 19 import com.tc.aspectwerkz.transform.Properties; 20 import com.tc.aspectwerkz.transform.TransformationConstants; 21 import com.tc.aspectwerkz.transform.inlining.AdviceMethodInfo; 22 import com.tc.aspectwerkz.transform.inlining.AsmHelper; 23 import com.tc.aspectwerkz.transform.inlining.AspectInfo; 24 import com.tc.aspectwerkz.transform.inlining.AspectModelManager; 25 import com.tc.aspectwerkz.transform.inlining.EmittedJoinPoint; 26 import com.tc.aspectwerkz.transform.inlining.spi.AspectModel; 27 28 29 import java.lang.reflect.InvocationTargetException ; 30 import java.lang.reflect.Modifier ; 31 import java.util.ArrayList ; 32 import java.util.HashMap ; 33 import java.util.HashSet ; 34 import java.util.Iterator ; 35 import java.util.List ; 36 import java.util.Map ; 37 import java.util.Set ; 38 39 51 public abstract class AbstractJoinPointCompiler implements JoinPointCompiler, TransformationConstants { 52 53 public static final boolean DUMP_JP_CLASSES = Properties.DUMP_JIT_CLOSURES; 54 55 57 protected final String m_callerClassName; 58 protected final String m_calleeClassName; 59 public final String m_callerClassSignature; 60 public final String m_calleeClassSignature; 61 public final String m_joinPointClassName; 62 63 protected final int m_joinPointType; 64 protected final int m_joinPointHash; 65 protected final String m_callerMethodName; 66 protected final String m_callerMethodDesc; 67 protected final int m_callerMethodModifiers; 68 protected final String m_calleeMemberName; 69 protected final String m_calleeMemberDesc; 70 protected final int m_calleeMemberModifiers; 71 72 private final CompilationInfo.Model m_model; 73 74 protected ClassWriter m_cw; 75 protected AspectInfo[] m_aspectInfos; 76 protected AspectModel[] m_aspectModels; 77 protected AdviceMethodInfo[] m_aroundAdviceMethodInfos; 78 protected AdviceMethodInfo[] m_beforeAdviceMethodInfos; 79 protected AdviceMethodInfo[] m_afterFinallyAdviceMethodInfos; 80 protected AdviceMethodInfo[] m_afterReturningAdviceMethodInfos; 81 protected AdviceMethodInfo[] m_afterThrowingAdviceMethodInfos; 82 83 protected boolean m_hasAroundAdvices = false; 84 protected boolean m_requiresThisOrTarget = false; 85 protected boolean m_requiresJoinPoint = false; 86 protected boolean m_requiresProceedMethod = false; 87 88 public String [] m_fieldNames; 89 public Type[] m_argumentTypes; 90 protected Type m_returnType; 91 protected boolean m_isThisAdvisable = false; 92 93 private CompilerInput m_input; 94 95 100 public AbstractJoinPointCompiler(final CompilationInfo.Model model) { 101 m_model = model; 102 m_joinPointClassName = model.getJoinPointClassName(); 103 104 final EmittedJoinPoint emittedJoinPoint = model.getEmittedJoinPoint(); 105 106 m_joinPointHash = emittedJoinPoint.getJoinPointHash(); 107 m_joinPointType = emittedJoinPoint.getJoinPointType(); 108 109 m_callerMethodName = emittedJoinPoint.getCallerMethodName(); 110 m_callerMethodDesc = emittedJoinPoint.getCallerMethodDesc(); 111 m_callerMethodModifiers = emittedJoinPoint.getCallerMethodModifiers(); 112 113 m_calleeMemberName = emittedJoinPoint.getCalleeMemberName(); 114 m_calleeMemberDesc = emittedJoinPoint.getCalleeMemberDesc(); 115 m_calleeMemberModifiers = emittedJoinPoint.getCalleeMemberModifiers(); 116 117 m_callerClassName = emittedJoinPoint.getCallerClassName().replace('.', '/'); 119 m_calleeClassName = emittedJoinPoint.getCalleeClassName().replace('.', '/'); 120 m_callerClassSignature = L + emittedJoinPoint.getCallerClassName().replace('.', '/') + SEMICOLON; 121 m_calleeClassSignature = L + emittedJoinPoint.getCalleeClassName().replace('.', '/') + SEMICOLON; 122 123 m_argumentTypes = getJoinPointArgumentTypes(); 124 m_returnType = getJoinPointReturnType(); 125 126 initialize(model); 128 129 initializeCompilerInput(); 131 } 132 133 public String getCallerClassName() { 135 return m_callerClassName; 136 } 137 138 public String getCalleeClassName() { 139 return m_calleeClassName; 140 } 141 142 public String getCallerClassSignature() { 143 return m_callerClassSignature; 144 } 145 146 public String getCalleeClassSignature() { 147 return m_calleeClassSignature; 148 } 149 150 public String getJoinPointClassName() { 151 return m_joinPointClassName; 152 } 153 154 159 private void initialize(final CompilationInfo.Model model) { 160 final AdviceInfoContainer advices = model.getAdviceInfoContainer(); 162 collectAdviceInfo(advices); 163 164 setupReferencedAspectModels(); 166 167 m_hasAroundAdvices = m_aroundAdviceMethodInfos.length > 0; 169 m_isThisAdvisable = isCallerAdvisable(model); 171 m_requiresThisOrTarget = requiresThisOrTarget(); 172 m_requiresJoinPoint = requiresJoinPoint(); 173 m_requiresProceedMethod = requiresProceedMethod(); 174 175 m_cw = AsmHelper.newClassWriter(true); 176 } 177 178 181 private void initializeCompilerInput() { 182 m_input = new CompilerInput(); 183 184 m_input.calleeClassSignature = m_calleeClassSignature; 186 m_input.callerClassSignature = m_callerClassSignature; 187 m_input.joinPointClassName = m_joinPointClassName; 188 189 m_input.calleeIndex = INDEX_NOTAVAILABLE; 191 m_input.argStartIndex = 0; 192 if (!Modifier.isStatic(m_calleeMemberModifiers) && 193 m_joinPointType != JoinPointType.CONSTRUCTOR_CALL_INT && 194 m_joinPointType != JoinPointType.HANDLER_INT) { 195 m_input.calleeIndex = 0; 196 m_input.argStartIndex++; 197 } else { 198 m_input.calleeIndex = INDEX_NOTAVAILABLE; 200 } 201 m_input.callerIndex = m_input.argStartIndex + AsmHelper.getRegisterDepth(m_argumentTypes); 203 204 if (m_joinPointType == JoinPointType.HANDLER_INT) { 206 m_input.calleeIndex = 0; 207 m_input.callerIndex = 2; 208 m_input.argStartIndex = 1; 209 } 210 211 m_input.isOptimizedJoinPoint = !m_requiresJoinPoint && !m_requiresProceedMethod; 216 if (m_input.isOptimizedJoinPoint) { 217 m_input.joinPointInstanceIndex = INDEX_NOTAVAILABLE; 219 } else { 220 m_input.joinPointInstanceIndex = m_input.callerIndex + 1; 222 } 223 } 224 225 230 private void collectAdviceInfo(final AdviceInfoContainer advices) { 231 final Map aspectInfoByQualifiedName = new HashMap (); 233 m_beforeAdviceMethodInfos = getAdviceMethodInfos( 234 aspectInfoByQualifiedName, advices.getBeforeAdviceInfos() 235 ); 236 m_aroundAdviceMethodInfos = getAdviceMethodInfos( 237 aspectInfoByQualifiedName, advices.getAroundAdviceInfos() 238 ); 239 m_afterReturningAdviceMethodInfos = getAdviceMethodInfos( 240 aspectInfoByQualifiedName, advices.getAfterReturningAdviceInfos() 241 ); 242 m_afterFinallyAdviceMethodInfos = getAdviceMethodInfos( 243 aspectInfoByQualifiedName, advices.getAfterFinallyAdviceInfos() 244 ); 245 m_afterThrowingAdviceMethodInfos = getAdviceMethodInfos( 246 aspectInfoByQualifiedName, advices.getAfterThrowingAdviceInfos() 247 ); 248 249 m_aspectInfos = (AspectInfo[]) aspectInfoByQualifiedName.values().toArray(new AspectInfo[aspectInfoByQualifiedName.size()]); 250 251 253 } 254 255 260 private boolean isCallerAdvisable(final CompilationInfo.Model model) { 261 if (!Modifier.isStatic(m_callerMethodModifiers)) { 262 ClassInfo[] interfaces = model.getThisClassInfo().getInterfaces(); 263 for (int i = 0; i < interfaces.length; i++) { 264 if (interfaces[i].getName().equals(ADVISABLE_CLASS_JAVA_NAME)) { 265 return true; 266 } 267 } 268 } 269 return false; 270 } 271 272 275 private void setupReferencedAspectModels() { 276 Map aspectModelInstanceByType = new HashMap (); 277 for (int i = 0; i < m_aspectInfos.length; i++) { 278 AspectDefinition aspectDef = m_aspectInfos[i].getAspectDefinition(); 279 if (!aspectModelInstanceByType.containsKey(aspectDef.getAspectModel())) { 280 AspectModel aspectModel = AspectModelManager.getModelFor(aspectDef.getAspectModel()).getInstance( 281 m_model 282 ); 283 aspectModelInstanceByType.put(aspectDef.getAspectModel(), aspectModel); 284 } 285 AspectModel aspectModel = (AspectModel) aspectModelInstanceByType.get(aspectDef.getAspectModel()); 287 if (aspectModel == null) { 288 throw new Error ("Could not find AspectModel " + aspectDef.getAspectModel() + " for " + m_aspectInfos[i].getAspectQualifiedName()); 289 } 290 m_aspectInfos[i].setAspectModel(aspectModel); 291 } 292 293 m_aspectModels = (AspectModel[]) aspectModelInstanceByType.values().toArray(new AspectModel[]{}); 295 } 296 297 302 private String getJoinPointInterface() { 303 String joinPointInterface; 304 if (m_requiresProceedMethod || m_requiresJoinPoint) { 305 joinPointInterface = JOIN_POINT_CLASS_NAME; 306 } else { 307 joinPointInterface = STATIC_JOIN_POINT_CLASS_NAME; 308 } 309 return joinPointInterface; 310 } 311 312 319 private AdviceMethodInfo[] getAdviceMethodInfos(final Map aspectInfoByQualifiedName, 320 final AdviceInfo[] adviceInfos) { 321 List adviceMethodInfosSet = new ArrayList (); 322 for (int i = 0; i < adviceInfos.length; i++) { 323 AdviceInfo adviceInfo = adviceInfos[i]; 324 325 DeploymentModel deploymentModel = adviceInfo.getAspectDeploymentModel(); 327 328 if (requiresCallerInstance(deploymentModel) && Modifier.isStatic(m_callerMethodModifiers)) { 329 continue; 330 } 331 if (requiresCalleeInstance(deploymentModel) && Modifier.isStatic(m_calleeMemberModifiers)) { 332 continue; 333 } 334 335 final String aspectClassName = adviceInfo.getAspectClassName().replace('.', '/'); 336 337 final AspectInfo aspectInfo; 338 if (!aspectInfoByQualifiedName.containsKey(adviceInfo.getAspectQualifiedName())) { 339 aspectInfo = new AspectInfo( 340 adviceInfo.getAdviceDefinition().getAspectDefinition(), 341 ASPECT_FIELD_PREFIX + (aspectInfoByQualifiedName.size()), 342 aspectClassName, 343 L + aspectClassName + SEMICOLON 344 ); 345 aspectInfoByQualifiedName.put(adviceInfo.getAspectQualifiedName(), aspectInfo); 346 } else { 347 aspectInfo = (AspectInfo) aspectInfoByQualifiedName.get(adviceInfo.getAspectQualifiedName()); 348 } 349 350 AdviceMethodInfo adviceMethodInfo = new AdviceMethodInfo( 351 aspectInfo, 352 adviceInfo, 353 m_callerClassSignature, 354 m_calleeClassSignature, 355 m_joinPointClassName, 356 m_calleeMemberDesc 357 ); 358 adviceMethodInfosSet.add(adviceMethodInfo); 359 } 360 return (AdviceMethodInfo[]) adviceMethodInfosSet.toArray(new AdviceMethodInfo[adviceMethodInfosSet.size()]); 361 } 362 363 366 protected abstract void createJoinPointSpecificFields(); 367 368 373 protected abstract void createSignature(final MethodVisitor cv); 374 375 383 protected abstract void createInlinedJoinPointInvocation(final MethodVisitor cv, 384 final CompilerInput input); 385 386 392 protected abstract void createJoinPointInvocation(final MethodVisitor cv); 393 394 399 protected abstract Type getJoinPointReturnType(); 400 401 406 protected abstract Type[] getJoinPointArgumentTypes(); 407 408 411 protected abstract void createGetRttiMethod(); 412 413 416 protected abstract void createGetSignatureMethod(); 417 418 424 public final byte[] compile() { 425 try { 426 createClassHeader(); 427 createFieldsCommonToAllJoinPoints(); 428 createJoinPointSpecificFields(); 429 createMandatoryMethodInAspectModels(); 430 createStaticInitializer(); 431 createClinit(); 432 createInit(); 433 createUtilityMethods(); 434 createGetSignatureMethod(); 435 createInvokeMethod(); 436 if (m_requiresProceedMethod) { 437 createProceedMethod(m_input.getCopyForProceed()); 439 } 440 if (m_requiresJoinPoint) { 441 createGetRttiMethod(); 442 } 443 m_cw.visitEnd(); 444 445 if (DUMP_JP_CLASSES) { 446 AsmHelper.dumpClass(Properties.DUMP_DIR_CLOSURES, m_joinPointClassName, m_cw); 447 } 448 return m_cw.toByteArray(); 449 450 } catch (Exception e) { 451 e.printStackTrace(); 452 StringBuffer buf = new StringBuffer (); 453 buf.append("could not compile join point instance for join point with hash ["); 454 buf.append(m_joinPointHash); 455 buf.append("] and declaring class ["); 456 buf.append(m_callerClassName); 457 buf.append("] due to: "); 458 if (e instanceof InvocationTargetException ) { 459 buf.append(((InvocationTargetException ) e).getTargetException().toString()); 460 } else { 461 buf.append(e.toString()); 462 } 463 throw new RuntimeException (buf.toString()); 464 } 465 } 466 467 470 private void createFieldsCommonToAllJoinPoints() { 471 if (m_returnType.getSort() != Type.VOID) { 472 m_cw.visitField(ACC_PRIVATE, RETURN_VALUE_FIELD_NAME, m_returnType.getDescriptor(), null, null); 473 } 474 m_cw.visitField( 475 ACC_PRIVATE + ACC_STATIC, 476 TARGET_CLASS_FIELD_NAME_IN_JP, 477 CLASS_CLASS_SIGNATURE, 478 null, 479 null 480 ); 481 482 m_cw.visitField( 483 ACC_PRIVATE + ACC_STATIC + ACC_FINAL, 484 THIS_CLASS_FIELD_NAME_IN_JP, 485 CLASS_CLASS_SIGNATURE, 486 null, 487 null 488 ); 489 490 m_cw.visitField( 491 ACC_PRIVATE + ACC_STATIC + ACC_FINAL, 492 ENCLOSING_SJP_FIELD_NAME, 493 ENCLOSING_SJP_FIELD_CLASS_SIGNATURE, 494 null, 495 null 496 ); 497 498 m_cw.visitField(ACC_PRIVATE + ACC_STATIC, META_DATA_FIELD_NAME, MAP_CLASS_SIGNATURE, null, null); 499 m_cw.visitField( 500 ACC_PRIVATE + ACC_STATIC, 501 OPTIMIZED_JOIN_POINT_INSTANCE_FIELD_NAME, 502 L + m_joinPointClassName + SEMICOLON, 503 null, null 504 ); 505 m_cw.visitField(ACC_PRIVATE, CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature, null, null); 506 m_cw.visitField(ACC_PRIVATE, CALLER_INSTANCE_FIELD_NAME, m_callerClassSignature, null, null); 507 m_cw.visitField(ACC_PRIVATE, STACK_FRAME_COUNTER_FIELD_NAME, I, null, null); 508 509 if (m_isThisAdvisable) { 510 m_cw.visitField(ACC_PRIVATE, INTERCEPTOR_INDEX_FIELD_NAME, I, null, null); 511 512 m_cw.visitField( 513 ACC_PRIVATE, AROUND_INTERCEPTORS_FIELD_NAME, 514 AROUND_ADVICE_ARRAY_CLASS_SIGNATURE, null, null 515 ); 516 m_cw.visitField(ACC_PRIVATE, NR_OF_AROUND_INTERCEPTORS_FIELD_NAME, I, null, null); 517 518 m_cw.visitField( 519 ACC_PRIVATE, BEFORE_INTERCEPTORS_FIELD_NAME, 520 BEFORE_ADVICE_ARRAY_CLASS_SIGNATURE, null, null 521 ); 522 m_cw.visitField(ACC_PRIVATE, NR_OF_BEFORE_INTERCEPTORS_FIELD_NAME, I, null, null); 523 524 m_cw.visitField( 525 ACC_PRIVATE, AFTER_INTERCEPTORS_FIELD_NAME, 526 AFTER_ADVICE_ARRAY_CLASS_SIGNATURE, null, null 527 ); 528 m_cw.visitField(ACC_PRIVATE, NR_OF_AFTER_INTERCEPTORS_FIELD_NAME, I, null, null); 529 530 m_cw.visitField( 531 ACC_PRIVATE, AFTER_RETURNING_INTERCEPTORS_FIELD_NAME, 532 AFTER_RETURNING_ADVICE_ARRAY_CLASS_SIGNATURE, null, null 533 ); 534 m_cw.visitField(ACC_PRIVATE, NR_OF_AFTER_RETURNING_INTERCEPTORS_FIELD_NAME, I, null, null); 535 536 m_cw.visitField( 537 ACC_PRIVATE, AFTER_THROWING_INTERCEPTORS_FIELD_NAME, 538 AFTER_THROWING_ADVICE_ARRAY_CLASS_SIGNATURE, null, null 539 ); 540 m_cw.visitField(ACC_PRIVATE, NR_OF_AFTER_THROWING_INTERCEPTORS_FIELD_NAME, I, null, null); 541 } 542 } 543 544 547 private void createClinit() { 548 MethodVisitor cv = m_cw.visitMethod(ACC_STATIC, CLINIT_METHOD_NAME, NO_PARAM_RETURN_VOID_SIGNATURE, null, null); 549 cv.visitMethodInsn( 550 INVOKESTATIC, m_joinPointClassName, 551 STATIC_INITIALIZATION_METHOD_NAME, NO_PARAM_RETURN_VOID_SIGNATURE 552 ); 553 cv.visitInsn(RETURN); 554 cv.visitMaxs(0, 0); 555 } 556 557 560 private void createInit() { 561 MethodVisitor cv = m_cw.visitMethod(ACC_PRIVATE, INIT_METHOD_NAME, NO_PARAM_RETURN_VOID_SIGNATURE, null, null); 562 cv.visitVarInsn(ALOAD, 0); 563 564 boolean hasAroundClosureBaseClass = false; 565 AspectModel aspectModel = null; 566 567 for (int i = 0; i < m_aspectModels.length; i++) { 568 aspectModel = m_aspectModels[i]; 569 if (aspectModel.getAroundClosureClassInfo().getSuperClassName() != null 570 && !OBJECT_CLASS_NAME.equals(aspectModel.getAroundClosureClassInfo().getSuperClassName())) { 571 hasAroundClosureBaseClass = true; 572 break; 573 } 574 } 575 576 if (hasAroundClosureBaseClass) { 577 aspectModel.createInvocationOfAroundClosureSuperClass(cv); 579 } else { 580 cv.visitMethodInsn(INVOKESPECIAL, OBJECT_CLASS_NAME, INIT_METHOD_NAME, NO_PARAM_RETURN_VOID_SIGNATURE); 582 } 583 584 resetStackFrameCounter(cv); 585 586 cv.visitInsn(RETURN); 587 cv.visitMaxs(0, 0); 588 } 589 590 593 private void createClassHeader() { 594 595 Set interfaces = new HashSet (); 596 String baseClass = OBJECT_CLASS_NAME; 597 598 for (int i = 0; i < m_aspectModels.length; i++) { 600 AspectModel aspectModel = m_aspectModels[i]; 601 AspectModel.AroundClosureClassInfo closureClassInfo = aspectModel.getAroundClosureClassInfo(); 602 final String superClassName = closureClassInfo.getSuperClassName(); 603 final String [] interfaceNames = closureClassInfo.getInterfaceNames(); 604 if (superClassName != null) { 605 if (!baseClass.equals(OBJECT_CLASS_NAME)) { 606 throw new RuntimeException ( 607 "compiled join point can only subclass one around closure base class but more than registered aspect model requires a closure base class" 608 ); 609 } 610 baseClass = superClassName; 611 } 612 if (interfaceNames.length != 0) { 613 for (int j = 0; j < interfaceNames.length; j++) { 614 interfaces.add(interfaceNames[j]); 615 } 616 } 617 } 618 619 int i = 1; 620 String [] interfaceArr = new String [interfaces.size() + 1]; 621 interfaceArr[0] = getJoinPointInterface(); 622 for (Iterator it = interfaces.iterator(); it.hasNext(); i++) { 623 interfaceArr[i] = (String ) it.next(); 624 } 625 626 m_cw.visit( 627 AsmHelper.JAVA_VERSION, 628 ACC_PUBLIC + ACC_SUPER, 629 m_joinPointClassName, 630 null, 631 baseClass, 632 interfaceArr 633 ); 634 } 635 636 639 private void createMandatoryMethodInAspectModels() { 640 for (int i = 0; i < m_aspectModels.length; i++) { 641 m_aspectModels[i].createMandatoryMethods(m_cw, this); 642 } 643 } 644 645 648 private void createStaticInitializer() { 649 MethodVisitor cv = m_cw.visitMethod( 650 ACC_STATIC | ACC_PUBLIC, 651 STATIC_INITIALIZATION_METHOD_NAME, 652 NO_PARAM_RETURN_VOID_SIGNATURE, 653 null, null 654 ); 655 656 Label tryLabel = new Label(); 657 cv.visitLabel(tryLabel); 658 cv.visitLdcInsn(m_calleeClassName.replace('/', '.')); 659 cv.visitMethodInsn(INVOKESTATIC, CLASS_CLASS, FOR_NAME_METHOD_NAME, FOR_NAME_METHOD_SIGNATURE); 660 cv.visitFieldInsn(PUTSTATIC, m_joinPointClassName, TARGET_CLASS_FIELD_NAME_IN_JP, CLASS_CLASS_SIGNATURE); 661 662 cv.visitLdcInsn(m_callerClassName.replace('/', '.')); 663 cv.visitMethodInsn(INVOKESTATIC, CLASS_CLASS, FOR_NAME_METHOD_NAME, FOR_NAME_METHOD_SIGNATURE); 664 cv.visitFieldInsn(PUTSTATIC, m_joinPointClassName, THIS_CLASS_FIELD_NAME_IN_JP, CLASS_CLASS_SIGNATURE); 665 666 Label finallyLabel = new Label(); 667 cv.visitLabel(finallyLabel); 668 669 Label gotoFinallyLabel = new Label(); 670 cv.visitJumpInsn(GOTO, gotoFinallyLabel); 671 672 Label catchLabel = new Label(); 673 cv.visitLabel(catchLabel); 674 cv.visitVarInsn(ASTORE, 0); 675 676 cv.visitVarInsn(ALOAD, 0); 677 cv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Throwable", "printStackTrace", "()V"); 678 679 cv.visitTypeInsn(NEW, RUNTIME_EXCEPTION_CLASS_NAME); 680 cv.visitInsn(DUP); 681 cv.visitLdcInsn( 682 "could not load target class using Class.forName() in generated join point base class " 683 + m_joinPointClassName 684 ); 685 686 cv.visitMethodInsn( 687 INVOKESPECIAL, 688 RUNTIME_EXCEPTION_CLASS_NAME, 689 INIT_METHOD_NAME, 690 RUNTIME_EXCEPTION_INIT_METHOD_SIGNATURE 691 ); 692 693 cv.visitInsn(ATHROW); 694 cv.visitLabel(gotoFinallyLabel); 695 696 createEnclosingStaticJoinPoint(cv); 698 699 cv.visitTypeInsn(NEW, HASH_MAP_CLASS_NAME); 701 cv.visitInsn(DUP); 702 cv.visitMethodInsn(INVOKESPECIAL, HASH_MAP_CLASS_NAME, INIT_METHOD_NAME, NO_PARAM_RETURN_VOID_SIGNATURE); 703 cv.visitFieldInsn(PUTSTATIC, m_joinPointClassName, META_DATA_FIELD_NAME, MAP_CLASS_SIGNATURE); 704 705 createSignature(cv); 707 708 cv.visitTypeInsn(NEW, m_joinPointClassName); 710 cv.visitInsn(DUP); 711 cv.visitMethodInsn(INVOKESPECIAL, m_joinPointClassName, INIT_METHOD_NAME, NO_PARAM_RETURN_VOID_SIGNATURE); 712 cv.visitFieldInsn( 713 PUTSTATIC, 714 m_joinPointClassName, 715 OPTIMIZED_JOIN_POINT_INSTANCE_FIELD_NAME, 716 L + m_joinPointClassName + SEMICOLON 717 ); 718 719 for (int i = 0; i < m_aspectInfos.length; i++) { 721 AspectInfo m_aspectInfo = m_aspectInfos[i]; 722 723 cv.visitLdcInsn(m_aspectInfo.getAspectFactoryClassName()); 724 cv.visitLdcInsn(m_aspectInfo.getAspectDefinition().getSystemDefinition().getUuid()); 725 cv.visitLdcInsn(m_aspectInfo.getAspectClassName()); 726 cv.visitLdcInsn(m_aspectInfo.getAspectQualifiedName()); 727 AsmHelper.loadStringConstant(cv, m_aspectInfo.getAspectDefinition().getContainerClassName()); 728 StringBuffer sb = new StringBuffer (); 730 boolean hasOne = false; 731 boolean isFirst = true; 732 for (Iterator iterator = m_aspectInfo.getAspectDefinition().getParameters().entrySet().iterator(); iterator.hasNext();) 733 { 734 Map.Entry entry = (Map.Entry ) iterator.next(); 735 if (!isFirst) { 736 sb.append(DELIMITER); 737 } 738 isFirst = false; 739 hasOne = true; 740 sb.append(entry.getKey()).append(DELIMITER).append(entry.getValue()); 741 } 742 if (hasOne) { 743 cv.visitLdcInsn(sb.toString()); 744 } else { 745 cv.visitInsn(ACONST_NULL); 746 } 747 cv.visitFieldInsn(GETSTATIC, m_joinPointClassName, THIS_CLASS_FIELD_NAME_IN_JP, CLASS_CLASS_SIGNATURE); 748 cv.visitMethodInsn(INVOKEVIRTUAL, CLASS_CLASS, GETCLASSLOADER_METHOD_NAME, CLASS_CLASS_GETCLASSLOADER_METHOD_SIGNATURE); 749 cv.visitLdcInsn(m_aspectInfo.getDeploymentModel().toString()); 750 cv.visitMethodInsn( 751 INVOKESTATIC, 752 Type.getInternalName(AspectFactoryManager.class), 753 "loadAspectFactory", 754 "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/lang/String;)V" 755 ); 756 } 757 758 for (int i = 0; i < m_aspectInfos.length; i++) { 760 m_aspectInfos[i].getAspectModel().createAndStoreStaticAspectInstantiation( 761 m_cw, 762 cv, 763 m_aspectInfos[i], 764 m_joinPointClassName 765 ); 766 } 767 768 cv.visitInsn(RETURN); 769 cv.visitTryCatchBlock(tryLabel, finallyLabel, catchLabel, CLASS_NOT_FOUND_EXCEPTION_CLASS_NAME); 770 cv.visitMaxs(0, 0); 771 } 772 773 778 private void createEnclosingStaticJoinPoint(MethodVisitor cv) { 779 cv.visitFieldInsn( 780 GETSTATIC, 781 m_joinPointClassName, 782 THIS_CLASS_FIELD_NAME_IN_JP, 783 CLASS_CLASS_SIGNATURE 784 ); 785 cv.visitLdcInsn(m_callerMethodName); 786 cv.visitLdcInsn(m_callerMethodDesc); 787 788 cv.visitMethodInsn( 789 INVOKESTATIC, 790 SIGNATURE_FACTORY_CLASS, 791 NEW_ENCLOSING_SJP_METHOD_NAME, 792 NEW_ENCLOSING_SJP_METHOD_SIGNATURE 793 ); 794 cv.visitFieldInsn( 795 PUTSTATIC, 796 m_joinPointClassName, 797 ENCLOSING_SJP_FIELD_NAME, 798 ENCLOSING_SJP_FIELD_CLASS_SIGNATURE 799 ); 800 } 801 802 808 protected void createInvokeMethod() { 809 810 final String invokeDesc = buildInvokeMethodSignature(); 811 812 MethodVisitor cv = m_cw.visitMethod( 814 ACC_PUBLIC + ACC_FINAL + ACC_STATIC, 815 INVOKE_METHOD_NAME, 816 invokeDesc, 817 null, 818 new String []{ 819 THROWABLE_CLASS_NAME 820 } 821 ); 822 823 if (!m_input.isOptimizedJoinPoint) { 824 createInvocationLocalJoinPointInstance(cv, m_input); 826 } 827 828 836 initializeInstanceLevelAspects(cv, m_input); 838 839 createBeforeAdviceInvocations(cv, m_input); 841 842 if (m_afterFinallyAdviceMethodInfos.length == 0 && 844 m_afterThrowingAdviceMethodInfos.length == 0 && 845 !m_isThisAdvisable) { 846 createPartOfInvokeMethodWithoutAfterFinallyAndAfterThrowingAdviceTypes(cv, m_input); 847 } else if (m_afterThrowingAdviceMethodInfos.length == 0 && 848 !m_isThisAdvisable) { 849 createPartOfInvokeMethodWithoutAfterThrowingAdviceTypes(cv, m_input); 850 } else { 851 createPartOfInvokeMethodWithAllAdviceTypes(cv, m_input); 852 } 853 854 cv.visitMaxs(0, 0); 855 } 856 857 866 private void initializeInstanceLevelAspects(final MethodVisitor cv, final CompilerInput input) { 867 for (int i = 0; i < m_aspectInfos.length; i++) { 868 m_aspectInfos[i].getAspectModel().createAndStoreRuntimeAspectInstantiation(cv, input, m_aspectInfos[i]); 869 } 870 } 871 872 873 877 private void createPartOfInvokeMethodWithAllAdviceTypes(final MethodVisitor cv, 878 final CompilerInput input) { 879 final int returnValueIndex = (input.joinPointInstanceIndex != INDEX_NOTAVAILABLE) ? 880 (input.joinPointInstanceIndex + 1) : input.callerIndex + 1; 881 final int exceptionIndex1 = returnValueIndex + 1; 882 final int exceptionIndex2 = returnValueIndex + 2; 883 884 cv.visitInsn(ACONST_NULL); 885 cv.visitVarInsn(ASTORE, returnValueIndex); 886 887 Label tryLabel = new Label(); 888 cv.visitLabel(tryLabel); 889 if (!m_requiresProceedMethod) { 890 createInlinedJoinPointInvocation(cv, input); 892 int stackIndex = returnValueIndex; AsmHelper.storeType(cv, stackIndex, m_returnType); 894 addReturnedValueToJoinPoint(cv, input, returnValueIndex, false); 895 } else { 896 createInvocationToProceedMethod(cv, input.joinPointInstanceIndex, returnValueIndex); 897 } 898 899 createAfterReturningAdviceInvocations(cv, input); 900 901 Label finallyLabel1 = new Label(); 902 cv.visitLabel(finallyLabel1); 903 904 if (m_isThisAdvisable) { 905 final int registerDepth = input.callerIndex + 2; createAfterInterceptorInvocations(cv, input.joinPointInstanceIndex, registerDepth); 907 } 908 createAfterFinallyAdviceInvocations(cv, input); 909 910 Label gotoFinallyLabel = new Label(); 911 cv.visitJumpInsn(GOTO, gotoFinallyLabel); 912 913 Label catchLabel = new Label(); 914 cv.visitLabel(catchLabel); 915 916 cv.visitVarInsn(ASTORE, exceptionIndex1); 918 919 if (m_isThisAdvisable) { 920 createAfterThrowingInterceptorInvocations(cv, input.joinPointInstanceIndex, exceptionIndex1); 921 } 922 923 for (int i = m_afterThrowingAdviceMethodInfos.length - 1; i >= 0; i--) { 925 AdviceMethodInfo advice = m_afterThrowingAdviceMethodInfos[i]; 926 927 advice.setSpecialArgumentIndex(exceptionIndex1); 929 930 cv.visitVarInsn(ALOAD, exceptionIndex1); 932 933 final String specialArgTypeName = advice.getSpecialArgumentTypeName(); 934 if (specialArgTypeName != null) { 935 cv.visitTypeInsn(INSTANCEOF, specialArgTypeName); 937 938 Label ifInstanceOfLabel = new Label(); 939 cv.visitJumpInsn(IFEQ, ifInstanceOfLabel); 940 941 createAfterAdviceInvocation(cv, input, advice, exceptionIndex1); 943 944 cv.visitLabel(ifInstanceOfLabel); 945 } else { 946 createAfterAdviceInvocation(cv, input, advice, INDEX_NOTAVAILABLE); 948 } 949 } 950 951 cv.visitVarInsn(ALOAD, exceptionIndex1); 953 cv.visitInsn(ATHROW); 954 955 Label exceptionLabel = new Label(); 957 cv.visitLabel(exceptionLabel); 958 cv.visitVarInsn(ASTORE, exceptionIndex2); 959 960 Label finallyLabel2 = new Label(); 962 cv.visitLabel(finallyLabel2); 963 964 if (m_isThisAdvisable) { 965 final int registerDepth = input.callerIndex + 2; createAfterInterceptorInvocations(cv, input.joinPointInstanceIndex, registerDepth); 967 } 968 createAfterFinallyAdviceInvocations(cv, input); 969 970 cv.visitVarInsn(ALOAD, exceptionIndex2); 972 cv.visitInsn(ATHROW); 973 cv.visitLabel(gotoFinallyLabel); 974 975 if (m_returnType.getSort() != Type.VOID) { 977 if (m_requiresProceedMethod) { 978 cv.visitVarInsn(ALOAD, returnValueIndex); 979 AsmHelper.unwrapType(cv, m_returnType); 980 } else { 981 AsmHelper.loadType(cv, returnValueIndex, m_returnType); 982 } 983 } 984 985 AsmHelper.addReturnStatement(cv, m_returnType); 986 987 cv.visitTryCatchBlock(tryLabel, finallyLabel1, catchLabel, THROWABLE_CLASS_NAME); 989 cv.visitTryCatchBlock(tryLabel, finallyLabel1, exceptionLabel, null); 990 cv.visitTryCatchBlock(catchLabel, finallyLabel2, exceptionLabel, null); 991 } 992 993 997 private void createPartOfInvokeMethodWithoutAfterThrowingAdviceTypes(final MethodVisitor cv, 998 final CompilerInput input) { 999 final int returnValueIndex = (input.joinPointInstanceIndex != INDEX_NOTAVAILABLE) ? 1000 (input.joinPointInstanceIndex + 1) : input.callerIndex + 1; 1001 final int exceptionIndex = returnValueIndex + 1; 1002 1003 cv.visitInsn(ACONST_NULL); 1004 cv.visitVarInsn(ASTORE, returnValueIndex); 1005 1006 Label tryLabel = new Label(); 1007 cv.visitLabel(tryLabel); 1008 if (!m_requiresProceedMethod) { 1009 createInlinedJoinPointInvocation(cv, input); 1011 int stackIndex = returnValueIndex; AsmHelper.storeType(cv, stackIndex, m_returnType); 1013 addReturnedValueToJoinPoint(cv, input, returnValueIndex, false); 1014 } else { 1015 createInvocationToProceedMethod(cv, input.joinPointInstanceIndex, returnValueIndex); 1016 } 1017 1018 createAfterReturningAdviceInvocations(cv, input); 1019 1020 Label finallyLabel1 = new Label(); 1021 cv.visitLabel(finallyLabel1); 1022 1023 createAfterFinallyAdviceInvocations(cv, input); 1024 1025 Label gotoFinallyLabel = new Label(); 1026 cv.visitJumpInsn(GOTO, gotoFinallyLabel); 1027 1028 Label exceptionLabel = new Label(); 1029 cv.visitLabel(exceptionLabel); 1030 cv.visitVarInsn(ASTORE, exceptionIndex); 1031 1032 Label finallyLabel2 = new Label(); 1033 cv.visitLabel(finallyLabel2); 1034 1035 createAfterFinallyAdviceInvocations(cv, input); 1036 1037 cv.visitVarInsn(ALOAD, exceptionIndex); 1038 cv.visitInsn(ATHROW); 1039 1040 cv.visitLabel(gotoFinallyLabel); 1041 1042 if (m_returnType.getSort() != Type.VOID) { 1044 if (m_requiresProceedMethod) { 1045 cv.visitVarInsn(ALOAD, returnValueIndex); 1046 AsmHelper.unwrapType(cv, m_returnType); 1047 } else { 1048 AsmHelper.loadType(cv, returnValueIndex, m_returnType); 1049 } 1050 } 1051 1052 AsmHelper.addReturnStatement(cv, m_returnType); 1053 1054 cv.visitTryCatchBlock(tryLabel, finallyLabel1, exceptionLabel, null); 1055 cv.visitTryCatchBlock(exceptionLabel, finallyLabel2, exceptionLabel, null); 1056 } 1057 1058 1062 private void createPartOfInvokeMethodWithoutAfterFinallyAndAfterThrowingAdviceTypes(final MethodVisitor cv, 1063 final CompilerInput input) { 1064 1065 final int returnValueIndex = (input.joinPointInstanceIndex != INDEX_NOTAVAILABLE) ? 1066 (input.joinPointInstanceIndex + 1) : input.callerIndex + 1; 1067 if (!m_requiresProceedMethod) { 1068 createInlinedJoinPointInvocation(cv, input); 1070 int stackIndex = returnValueIndex; AsmHelper.storeType(cv, stackIndex, m_returnType); 1072 addReturnedValueToJoinPoint(cv, input, returnValueIndex, false); 1073 } else { 1074 createInvocationToProceedMethod(cv, input.joinPointInstanceIndex, returnValueIndex); 1075 } 1076 1077 createAfterReturningAdviceInvocations(cv, input); 1079 1080 if (m_returnType.getSort() != Type.VOID) { 1082 if (m_requiresProceedMethod) { 1083 cv.visitVarInsn(ALOAD, returnValueIndex); 1084 AsmHelper.unwrapType(cv, m_returnType); 1085 } else { 1086 AsmHelper.loadType(cv, returnValueIndex, m_returnType); 1087 } 1088 } 1089 1090 AsmHelper.addReturnStatement(cv, m_returnType); 1091 } 1092 1093 1100 private void createInvocationToProceedMethod(final MethodVisitor cv, 1101 final int joinPointInstanceIndex, 1102 final int returnValueIndex) { 1103 cv.visitVarInsn(ALOAD, joinPointInstanceIndex); 1104 cv.visitMethodInsn(INVOKEVIRTUAL, m_joinPointClassName, PROCEED_METHOD_NAME, PROCEED_METHOD_SIGNATURE); 1105 cv.visitVarInsn(ASTORE, returnValueIndex); 1106 } 1107 1108 1115 private void createInvocationLocalJoinPointInstance(final MethodVisitor cv, final CompilerInput input) { 1116 cv.visitTypeInsn(NEW, m_joinPointClassName); 1118 cv.visitInsn(DUP); 1119 cv.visitMethodInsn(INVOKESPECIAL, m_joinPointClassName, INIT_METHOD_NAME, NO_PARAM_RETURN_VOID_SIGNATURE); 1120 1121 cv.visitVarInsn(ASTORE, input.joinPointInstanceIndex); 1123 1124 int argStackIndex = input.argStartIndex; 1126 for (int i = 0; i < m_fieldNames.length; i++) { 1127 String fieldName = m_fieldNames[i]; 1128 cv.visitVarInsn(ALOAD, input.joinPointInstanceIndex); 1129 Type type = m_argumentTypes[i]; 1130 argStackIndex = AsmHelper.loadType(cv, argStackIndex, type); 1131 cv.visitFieldInsn(PUTFIELD, m_joinPointClassName, fieldName, type.getDescriptor()); 1132 } 1133 1134 cv.visitVarInsn(ALOAD, input.joinPointInstanceIndex); 1136 cv.visitVarInsn(ALOAD, input.callerIndex); 1137 cv.visitFieldInsn(PUTFIELD, m_joinPointClassName, CALLER_INSTANCE_FIELD_NAME, m_callerClassSignature); 1138 1139 cv.visitVarInsn(ALOAD, input.joinPointInstanceIndex); 1141 if (input.calleeIndex != INDEX_NOTAVAILABLE) { 1142 cv.visitVarInsn(ALOAD, 0); 1143 } else { 1144 cv.visitInsn(ACONST_NULL); 1145 } 1146 cv.visitFieldInsn(PUTFIELD, m_joinPointClassName, CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature); 1147 1148 if (m_isThisAdvisable) { 1149 createInitializationForAdvisableManagement(cv, input.joinPointInstanceIndex, input.callerIndex); 1150 } 1151 } 1152 1153 1159 private void createProceedMethod(CompilerInput input) { 1160 1161 MethodVisitor cv = m_cw.visitMethod( 1162 ACC_PUBLIC | ACC_FINAL, 1163 PROCEED_METHOD_NAME, 1164 PROCEED_METHOD_SIGNATURE, 1165 null, 1166 new String []{ 1167 THROWABLE_CLASS_NAME 1168 } 1169 ); 1170 1171 if (m_isThisAdvisable) { 1172 createAroundInterceptorInvocations(cv); 1173 } 1174 1175 incrementStackFrameCounter(cv); 1176 1177 Label tryLabel = new Label(); 1179 Label defaultCaseLabel = new Label(); 1180 Label gotoLabel = new Label(); 1181 Label handlerLabel = new Label(); 1182 Label endLabel = new Label(); 1183 1184 int nrOfCases = m_aroundAdviceMethodInfos.length; 1185 if (m_isThisAdvisable) { 1186 nrOfCases++; 1187 } 1188 1189 Label[] caseLabels = new Label[nrOfCases]; 1190 Label[] returnLabels = new Label[nrOfCases]; 1191 int[] caseNumbers = new int[nrOfCases]; 1192 for (int i = 0; i < caseLabels.length; i++) { 1193 caseLabels[i] = new Label(); 1194 caseNumbers[i] = i; 1195 } 1196 for (int i = 0; i < returnLabels.length; i++) { 1197 returnLabels[i] = new Label(); 1198 } 1199 1200 cv.visitLabel(tryLabel); 1202 1203 cv.visitVarInsn(ALOAD, 0); 1205 cv.visitFieldInsn(GETFIELD, m_joinPointClassName, STACK_FRAME_COUNTER_FIELD_NAME, I); 1206 cv.visitLookupSwitchInsn(defaultCaseLabel, caseNumbers, caseLabels); 1207 1208 for (int i = 0; i < m_aroundAdviceMethodInfos.length; i++) { 1210 cv.visitLabel(caseLabels[i]); 1211 1212 AdviceMethodInfo adviceInfo = m_aroundAdviceMethodInfos[i]; 1214 1215 Label endInstanceOflabel = beginRuntimeCheck(cv, input, adviceInfo.getAdviceInfo()); 1216 1217 adviceInfo.getAspectInfo().getAspectModel().loadAspect(cv, input, adviceInfo.getAspectInfo()); 1219 1220 adviceInfo.getAspectInfo().getAspectModel().createAroundAdviceArgumentHandling( 1222 cv, 1223 input, 1224 m_argumentTypes, 1225 adviceInfo 1226 ); 1227 1228 cv.visitMethodInsn( 1230 INVOKEVIRTUAL, 1231 adviceInfo.getAspectInfo().getAspectClassName(), 1232 adviceInfo.getAdviceInfo().getMethodName(), 1233 adviceInfo.getAdviceInfo().getMethodSignature() 1234 ); 1235 cv.visitVarInsn(ASTORE, 1); 1236 1237 if (endInstanceOflabel != null) { 1240 Label elseInstanceOfLabel = new Label(); 1241 cv.visitJumpInsn(GOTO, elseInstanceOfLabel); 1242 endRuntimeCheck(cv, adviceInfo.getAdviceInfo(), endInstanceOflabel); 1243 cv.visitVarInsn(ALOAD, 0); 1244 cv.visitMethodInsn(INVOKESPECIAL, m_joinPointClassName, PROCEED_METHOD_NAME, PROCEED_METHOD_SIGNATURE); 1245 cv.visitVarInsn(ASTORE, 1); 1246 cv.visitLabel(elseInstanceOfLabel); 1247 } 1248 1249 cv.visitLabel(returnLabels[i]); 1250 1251 cv.visitVarInsn(ALOAD, 1); 1252 cv.visitInsn(ARETURN); 1253 } 1254 1255 if (m_isThisAdvisable) { 1256 int delegationCaseIndex = caseLabels.length - 1; 1257 cv.visitLabel(caseLabels[delegationCaseIndex]); 1258 cv.visitVarInsn(ALOAD, 0); 1259 cv.visitInsn(ICONST_0); 1260 cv.visitFieldInsn(PUTFIELD, m_joinPointClassName, INTERCEPTOR_INDEX_FIELD_NAME, I); 1261 cv.visitVarInsn(ALOAD, 0); 1262 cv.visitMethodInsn(INVOKEVIRTUAL, m_joinPointClassName, PROCEED_METHOD_NAME, PROCEED_METHOD_SIGNATURE); 1263 1264 cv.visitLabel(returnLabels[delegationCaseIndex]); 1265 1266 cv.visitInsn(ARETURN); 1267 } 1268 1269 cv.visitLabel(defaultCaseLabel); 1271 1272 AsmHelper.prepareWrappingOfPrimitiveType(cv, Type.getReturnType(m_calleeMemberDesc)); 1273 1274 createJoinPointInvocation(cv); 1275 1276 Type m_returnType = null; 1277 if (m_joinPointType != JoinPointType.CONSTRUCTOR_CALL_INT) { 1278 m_returnType = Type.getReturnType(m_calleeMemberDesc); 1279 } else { 1280 m_returnType = Type.getType(m_calleeClassSignature); 1281 } 1282 AsmHelper.wrapPrimitiveType(cv, m_returnType); 1283 cv.visitVarInsn(ASTORE, 1); 1284 1285 addReturnedValueToJoinPoint(cv, input, 1, true); 1287 1288 if (m_joinPointType == JoinPointType.CONSTRUCTOR_CALL_INT) { 1290 cv.visitVarInsn(ALOAD, 0); 1291 cv.visitVarInsn(ALOAD, 1); 1292 cv.visitFieldInsn(PUTFIELD, m_joinPointClassName, CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature); 1293 } 1294 1295 cv.visitLabel(gotoLabel); 1296 1297 cv.visitVarInsn(ALOAD, 1); 1298 cv.visitInsn(ARETURN); 1299 1300 cv.visitLabel(handlerLabel); 1302 cv.visitVarInsn(ASTORE, 2); 1303 cv.visitLabel(endLabel); 1304 1305 cv.visitVarInsn(ALOAD, 2); 1306 cv.visitInsn(ATHROW); 1307 1308 cv.visitTryCatchBlock(tryLabel, returnLabels[0], handlerLabel, null); 1310 for (int i = 1; i < caseLabels.length; i++) { 1311 Label caseLabel = caseLabels[i]; 1312 Label returnLabel = returnLabels[i]; 1313 cv.visitTryCatchBlock(caseLabel, returnLabel, handlerLabel, null); 1314 } 1315 cv.visitTryCatchBlock(defaultCaseLabel, gotoLabel, handlerLabel, null); 1316 cv.visitTryCatchBlock(handlerLabel, endLabel, handlerLabel, null); 1317 cv.visitMaxs(0, 0); 1318 } 1319 1320 1325 private void createBeforeAdviceInvocations(final MethodVisitor cv, CompilerInput input) { 1326 for (int i = 0; i < m_beforeAdviceMethodInfos.length; i++) { 1327 AdviceMethodInfo adviceMethodInfo = m_beforeAdviceMethodInfos[i]; 1328 AspectInfo aspectInfo = adviceMethodInfo.getAspectInfo(); 1329 1330 if (requiresCallerInstance(aspectInfo.getDeploymentModel()) 1331 && input.callerIndex < 0) { 1332 continue; 1333 } 1334 if (requiresCalleeInstance(aspectInfo.getDeploymentModel()) 1335 && input.calleeIndex < 0) { 1336 continue; 1337 } 1338 1339 Label endInstanceOflabel = beginRuntimeCheck(cv, input, adviceMethodInfo.getAdviceInfo()); 1341 1342 final AspectModel aspectModel = adviceMethodInfo.getAspectInfo().getAspectModel(); 1344 aspectModel.loadAspect(cv, input, adviceMethodInfo.getAspectInfo()); 1345 1346 aspectModel.createBeforeOrAfterAdviceArgumentHandling( 1348 cv, input, m_argumentTypes, adviceMethodInfo, INDEX_NOTAVAILABLE 1349 ); 1350 1351 cv.visitMethodInsn( 1353 INVOKEVIRTUAL, 1354 adviceMethodInfo.getAspectInfo().getAspectClassName(), 1355 adviceMethodInfo.getAdviceInfo().getMethodName(), 1356 adviceMethodInfo.getAdviceInfo().getMethodSignature() 1357 ); 1358 1359 endRuntimeCheck(cv, adviceMethodInfo.getAdviceInfo(), endInstanceOflabel); 1361 } 1362 1363 if (m_isThisAdvisable) { 1364 createBeforeInterceptorInvocations( 1365 cv, 1366 input.joinPointInstanceIndex, 1367 input.callerIndex + 1 1368 ); 1369 } 1370 } 1371 1372 1378 private void createAfterFinallyAdviceInvocations(final MethodVisitor cv, 1379 final CompilerInput input) { 1380 for (int i = m_afterFinallyAdviceMethodInfos.length - 1; i >= 0; i--) { 1382 AdviceMethodInfo advice = m_afterFinallyAdviceMethodInfos[i]; 1383 createAfterAdviceInvocation(cv, input, advice, INDEX_NOTAVAILABLE); 1384 } 1385 } 1386 1387 1393 private void createAfterReturningAdviceInvocations(final MethodVisitor cv, 1394 final CompilerInput input) { 1395 final int returnValueIndex = (input.joinPointInstanceIndex != INDEX_NOTAVAILABLE) ? 1396 (input.joinPointInstanceIndex + 1) : input.callerIndex + 1; 1397 1398 if (m_isThisAdvisable) { 1399 createAfterReturningInterceptorInvocations(cv, input.joinPointInstanceIndex, returnValueIndex); 1400 } 1401 1402 boolean hasPoppedReturnValueFromStack = false; 1403 for (int i = m_afterReturningAdviceMethodInfos.length - 1; i >= 0; i--) { 1404 AdviceMethodInfo advice = m_afterReturningAdviceMethodInfos[i]; 1405 1406 advice.setSpecialArgumentIndex(returnValueIndex); 1408 1409 String specialArgDesc = advice.getSpecialArgumentTypeDesc(); 1410 if (specialArgDesc == null) { 1411 createAfterAdviceInvocation(cv, input, advice, INDEX_NOTAVAILABLE); 1413 } else { 1414 if (AsmHelper.isPrimitive(m_returnType)) { 1416 if (m_returnType.getDescriptor().equals(specialArgDesc)) { 1417 createAfterAdviceInvocation(cv, input, advice, returnValueIndex); 1418 } 1419 } else { 1420 cv.visitVarInsn(ALOAD, returnValueIndex); 1421 1422 cv.visitTypeInsn(INSTANCEOF, advice.getSpecialArgumentTypeName()); 1423 1424 Label label = new Label(); 1425 cv.visitJumpInsn(IFEQ, label); 1426 1427 createAfterAdviceInvocation(cv, input, advice, returnValueIndex); 1428 1429 cv.visitLabel(label); 1430 } 1431 } 1432 } 1433 1434 if (!m_requiresProceedMethod && hasPoppedReturnValueFromStack) { 1436 cv.visitVarInsn(ALOAD, returnValueIndex); 1437 } 1438 } 1439 1440 1448 private void createAfterAdviceInvocation(final MethodVisitor cv, 1449 final CompilerInput input, 1450 final AdviceMethodInfo adviceMethodInfo, 1451 final int specialArgIndex) { 1452 AspectInfo aspectInfo = adviceMethodInfo.getAspectInfo(); 1453 1454 if (requiresCallerInstance(aspectInfo.getDeploymentModel()) 1455 && input.callerIndex < 0) { 1456 return; } 1458 if (requiresCalleeInstance(aspectInfo.getDeploymentModel()) 1459 && input.calleeIndex < 0) { 1460 return; 1461 } 1462 Label endInstanceOflabel = beginRuntimeCheck(cv, input, adviceMethodInfo.getAdviceInfo()); 1464 1465 final AspectModel aspectModel = adviceMethodInfo.getAspectInfo().getAspectModel(); 1467 aspectModel.loadAspect(cv, input, aspectInfo); 1468 1469 aspectModel.createBeforeOrAfterAdviceArgumentHandling( 1470 cv, input, m_argumentTypes, adviceMethodInfo, specialArgIndex 1471 ); 1472 1473 cv.visitMethodInsn( 1474 INVOKEVIRTUAL, 1475 adviceMethodInfo.getAspectInfo().getAspectClassName(), 1476 adviceMethodInfo.getAdviceInfo().getMethodName(), 1477 adviceMethodInfo.getAdviceInfo().getMethodSignature() 1478 ); 1479 1480 endRuntimeCheck(cv, adviceMethodInfo.getAdviceInfo(), endInstanceOflabel); 1482 } 1483 1484 1492 private void addReturnedValueToJoinPoint(final MethodVisitor cv, 1493 final CompilerInput input, 1494 final int returnValueIndex, 1495 final boolean unwrap) { 1496 if (m_requiresJoinPoint && m_returnType.getSort() != Type.VOID) { 1497 if (m_joinPointType == JoinPointType.METHOD_EXECUTION_INT 1498 || m_joinPointType == JoinPointType.METHOD_CALL_INT 1499 || m_joinPointType == JoinPointType.CONSTRUCTOR_CALL_INT) { 1500 loadJoinPointInstance(cv, input); 1502 if (unwrap && AsmHelper.isPrimitive(m_returnType)) { 1503 cv.visitVarInsn(ALOAD, returnValueIndex); 1504 AsmHelper.unwrapType(cv, m_returnType); 1505 } else { 1506 AsmHelper.loadType(cv, returnValueIndex, m_returnType); 1507 } 1508 cv.visitFieldInsn( 1509 PUTFIELD, m_joinPointClassName, 1510 RETURN_VALUE_FIELD_NAME, m_returnType.getDescriptor() 1511 ); 1512 } 1513 } 1514 } 1515 1516 1522 public static void loadJoinPointInstance(final MethodVisitor cv, 1523 final CompilerInput input) { 1524 if (input.isOptimizedJoinPoint) { 1525 cv.visitFieldInsn( 1526 GETSTATIC, input.joinPointClassName, 1527 OPTIMIZED_JOIN_POINT_INSTANCE_FIELD_NAME, 1528 L + input.joinPointClassName + SEMICOLON 1529 ); 1530 } else { 1531 cv.visitVarInsn(ALOAD, input.joinPointInstanceIndex); 1532 } 1533 } 1534 1535 1541 protected final void loadArgumentMemberFields(final MethodVisitor cv, final int argStartIndex) { 1542 int argStackIndex = argStartIndex; 1543 for (int index = 0; index < m_argumentTypes.length; index++) { 1544 Type argumentType = m_argumentTypes[index]; 1545 argStackIndex = AsmHelper.loadType(cv, argStackIndex, argumentType); 1546 } 1547 } 1548 1549 1554 protected final void loadArguments(final MethodVisitor cv) { 1555 for (int i = 0; i < m_fieldNames.length; i++) { 1556 String fieldName = m_fieldNames[i]; 1557 Type argumentType = m_argumentTypes[i]; 1558 cv.visitVarInsn(ALOAD, 0); 1559 cv.visitFieldInsn(GETFIELD, m_joinPointClassName, fieldName, argumentType.getDescriptor()); 1560 } 1561 } 1562 1563 1568 private void resetStackFrameCounter(final MethodVisitor cv) { 1569 cv.visitVarInsn(ALOAD, 0); 1570 cv.visitInsn(ICONST_M1); 1571 cv.visitFieldInsn(PUTFIELD, m_joinPointClassName, STACK_FRAME_COUNTER_FIELD_NAME, I); 1572 } 1573 1574 1579 private void incrementStackFrameCounter(final MethodVisitor cv) { 1580 cv.visitVarInsn(ALOAD, 0); 1581 cv.visitInsn(DUP); 1582 cv.visitFieldInsn(GETFIELD, m_joinPointClassName, STACK_FRAME_COUNTER_FIELD_NAME, I); 1583 cv.visitInsn(ICONST_1); 1584 cv.visitInsn(IADD); 1585 cv.visitFieldInsn(PUTFIELD, m_joinPointClassName, STACK_FRAME_COUNTER_FIELD_NAME, I); 1586 } 1587 1588 1597 public final void createArgumentArrayAt(final MethodVisitor cv, final int stackFreeIndex) { 1598 AsmHelper.loadIntegerConstant(cv, m_fieldNames.length); 1599 cv.visitTypeInsn(ANEWARRAY, OBJECT_CLASS_NAME); 1600 cv.visitVarInsn(ASTORE, stackFreeIndex); 1601 1602 for (int i = 0; i < m_argumentTypes.length; i++) { 1603 cv.visitVarInsn(ALOAD, stackFreeIndex); 1604 AsmHelper.loadIntegerConstant(cv, i); 1605 AsmHelper.prepareWrappingOfPrimitiveType(cv, m_argumentTypes[i]); 1606 cv.visitVarInsn(ALOAD, 0); 1607 cv.visitFieldInsn(GETFIELD, m_joinPointClassName, ARGUMENT_FIELD + i, m_argumentTypes[i].getDescriptor()); 1608 AsmHelper.wrapPrimitiveType(cv, m_argumentTypes[i]); 1609 cv.visitInsn(AASTORE); 1610 } 1611 } 1612 1613 1616 private void createUtilityMethods() { 1617 MethodVisitor cv; 1618 1619 { 1621 cv = m_cw.visitMethod(ACC_PUBLIC, ADD_META_DATA_METHOD_NAME, ADD_META_DATA_METHOD_SIGNATURE, null, null); 1622 cv.visitFieldInsn(GETSTATIC, m_joinPointClassName, META_DATA_FIELD_NAME, MAP_CLASS_SIGNATURE); 1623 cv.visitVarInsn(ALOAD, 1); 1624 cv.visitVarInsn(ALOAD, 2); 1625 cv.visitMethodInsn( 1626 INVOKEINTERFACE, 1627 MAP_CLASS_NAME, 1628 PUT_METHOD_NAME, 1629 PUT_METHOD_SIGNATURE 1630 ); 1631 cv.visitInsn(POP); 1632 cv.visitInsn(RETURN); 1633 cv.visitMaxs(0, 0); 1634 } 1635 1636 { 1638 cv = m_cw.visitMethod(ACC_PUBLIC, GET_META_DATA_METHOD_NAME, GET_META_DATA_METHOD_SIGNATURE, null, null); 1639 cv.visitFieldInsn(GETSTATIC, m_joinPointClassName, META_DATA_FIELD_NAME, MAP_CLASS_SIGNATURE); 1640 cv.visitVarInsn(ALOAD, 1); 1641 cv.visitMethodInsn(INVOKEINTERFACE, MAP_CLASS_NAME, GET_METHOD_NAME, GET_METHOD_SIGNATURE); 1642 cv.visitInsn(ARETURN); 1643 cv.visitMaxs(0, 0); 1644 } 1645 1646 { 1648 cv = m_cw.visitMethod( 1649 ACC_PUBLIC, 1650 GET_CALLEE_METHOD_NAME, 1651 NO_PARAMS_SIGNATURE + OBJECT_CLASS_SIGNATURE, 1652 null, null 1653 ); 1654 cv.visitVarInsn(ALOAD, 0); 1655 cv.visitFieldInsn(GETFIELD, m_joinPointClassName, CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature); 1656 cv.visitInsn(ARETURN); 1657 cv.visitMaxs(0, 0); 1658 } 1659 1660 { 1662 cv = m_cw.visitMethod( 1663 ACC_PUBLIC, 1664 GET_CALLER_METHOD_NAME, 1665 NO_PARAMS_SIGNATURE + OBJECT_CLASS_SIGNATURE, 1666 null, null 1667 ); 1668 cv.visitVarInsn(ALOAD, 0); 1669 cv.visitFieldInsn(GETFIELD, m_joinPointClassName, CALLER_INSTANCE_FIELD_NAME, m_callerClassSignature); 1670 cv.visitInsn(ARETURN); 1671 cv.visitMaxs(0, 0); 1672 } 1673 1674 { 1676 cv = m_cw.visitMethod( 1677 ACC_PUBLIC, 1678 GET_TARGET_METHOD_NAME, 1679 NO_PARAMS_SIGNATURE + OBJECT_CLASS_SIGNATURE, 1680 null, null 1681 ); 1682 cv.visitVarInsn(ALOAD, 0); 1683 cv.visitFieldInsn(GETFIELD, m_joinPointClassName, CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature); 1684 cv.visitInsn(ARETURN); 1685 cv.visitMaxs(0, 0); 1686 } 1687 1688 { 1690 cv = m_cw.visitMethod( 1691 ACC_PUBLIC, 1692 GET_THIS_METHOD_NAME, 1693 NO_PARAMS_SIGNATURE + OBJECT_CLASS_SIGNATURE, 1694 null, null 1695 ); 1696 cv.visitVarInsn(ALOAD, 0); 1697 cv.visitFieldInsn(GETFIELD, m_joinPointClassName, CALLER_INSTANCE_FIELD_NAME, m_callerClassSignature); 1698 cv.visitInsn(ARETURN); 1699 cv.visitMaxs(0, 0); 1700 } 1701 1702 { 1704 cv = 1705 m_cw.visitMethod( 1706 ACC_PUBLIC, 1707 GET_CALLER_CLASS_METHOD_NAME, 1708 GET_CALLER_CLASS_METHOD_SIGNATURE, 1709 null, 1710 null 1711 ); 1712 cv.visitFieldInsn(GETSTATIC, m_joinPointClassName, THIS_CLASS_FIELD_NAME_IN_JP, CLASS_CLASS_SIGNATURE); 1713 cv.visitInsn(ARETURN); 1714 cv.visitMaxs(0, 0); 1715 } 1716 1717 { 1719 cv = 1720 m_cw.visitMethod( 1721 ACC_PUBLIC, 1722 GET_CALLEE_CLASS_METHOD_NAME, 1723 GET_CALLEE_CLASS_METHOD_SIGNATURE, 1724 null, 1725 null 1726 ); 1727 cv.visitFieldInsn(GETSTATIC, m_joinPointClassName, TARGET_CLASS_FIELD_NAME_IN_JP, CLASS_CLASS_SIGNATURE); 1728 cv.visitInsn(ARETURN); 1729 cv.visitMaxs(0, 0); 1730 } 1731 1732 { 1734 cv = 1735 m_cw.visitMethod( 1736 ACC_PUBLIC, 1737 GET_TARGET_CLASS_METHOD_NAME, 1738 GET_TARGET_CLASS_METHOD_SIGNATURE, 1739 null, 1740 null 1741 ); 1742 cv.visitFieldInsn(GETSTATIC, m_joinPointClassName, TARGET_CLASS_FIELD_NAME_IN_JP, CLASS_CLASS_SIGNATURE); 1743 cv.visitInsn(ARETURN); 1744 cv.visitMaxs(0, 0); 1745 } 1746 1747 { 1749 cv = m_cw.visitMethod(ACC_PUBLIC, GET_TYPE_METHOD_NAME, GET_TYPE_METHOD_SIGNATURE, null, null); 1750 AsmHelper.loadIntegerConstant(cv, m_joinPointType); 1751 cv.visitMethodInsn( 1752 INVOKESTATIC, Type.getType(JoinPointType.class).getInternalName(), "fromInt", 1753 "(I)" + Type.getType(JoinPointType.class).getDescriptor() 1754 ); 1755 cv.visitInsn(ARETURN); 1756 cv.visitMaxs(0, 0); 1757 } 1758 1759 { 1761 cv = m_cw.visitMethod( 1762 ACC_PUBLIC, 1763 GET_ENCLOSING_SJP_METHOD_NAME, 1764 GET_ENCLOSING_SJP_METHOD_SIGNATURE, 1765 null, 1766 null 1767 ); 1768 cv.visitVarInsn(ALOAD, 0); 1769 cv.visitFieldInsn( 1770 GETSTATIC, 1771 m_joinPointClassName, 1772 ENCLOSING_SJP_FIELD_NAME, 1773 ENCLOSING_SJP_FIELD_CLASS_SIGNATURE 1774 ); 1775 cv.visitInsn(ARETURN); 1776 cv.visitMaxs(0, 0); 1777 } 1778 1779 } 1780 1781 1918 1923 protected String buildInvokeMethodSignature() { 1924 StringBuffer invokeDescBuf = new StringBuffer (); 1925 invokeDescBuf.append('('); 1926 if (m_joinPointType != JoinPointType.CONSTRUCTOR_CALL_INT) { 1927 if (!Modifier.isStatic(m_calleeMemberModifiers)) { 1928 invokeDescBuf.append(m_calleeClassSignature); 1930 } 1931 } 1932 for (int i = 0; i < m_argumentTypes.length; i++) { 1934 Type type = m_argumentTypes[i]; 1935 invokeDescBuf.append(type.getDescriptor()); 1936 } 1937 invokeDescBuf.append(m_callerClassSignature); 1939 invokeDescBuf.append(')'); 1940 invokeDescBuf.append(m_returnType.getDescriptor()); 1941 return invokeDescBuf.toString(); 1942 } 1943 1944 1949 private boolean requiresThisOrTarget() { 1950 return m_isThisAdvisable || 1951 requiresThisOrTarget(m_aroundAdviceMethodInfos) || 1952 requiresThisOrTarget(m_beforeAdviceMethodInfos) || 1953 requiresThisOrTarget(m_afterFinallyAdviceMethodInfos) || 1954 requiresThisOrTarget(m_afterReturningAdviceMethodInfos) || 1955 requiresThisOrTarget(m_afterThrowingAdviceMethodInfos); 1956 } 1957 1958 1963 private boolean requiresJoinPoint() { 1964 if (m_isThisAdvisable || 1965 requiresJoinPoint(m_aroundAdviceMethodInfos) || 1966 requiresJoinPoint(m_beforeAdviceMethodInfos) || 1967 requiresJoinPoint(m_afterFinallyAdviceMethodInfos) || 1968 requiresJoinPoint(m_afterReturningAdviceMethodInfos) || 1969 requiresJoinPoint(m_afterThrowingAdviceMethodInfos)) { 1970 return true; 1971 } 1972 1973 for (int i = 0; i < m_aspectModels.length; i++) { 1975 if (m_aspectModels[i].requiresReflectiveInfo()) { 1976 return true; 1978 } 1979 } 1980 1981 return false; 1982 } 1983 1984 1990 private boolean requiresThisOrTarget(final AdviceMethodInfo[] adviceMethodInfos) { 1991 for (int i = 0; i < adviceMethodInfos.length; i++) { 1992 if (adviceMethodInfos[i].requiresThisOrTarget()) { 1993 return true; 1994 } 1995 } 1996 return false; 1997 } 1998 1999 2005 private boolean requiresJoinPoint(final AdviceMethodInfo[] adviceMethodInfos) { 2006 for (int i = 0; i < adviceMethodInfos.length; i++) { 2007 if (adviceMethodInfos[i].requiresJoinPoint()) { 2008 return true; 2009 } 2010 } 2011 return false; 2012 } 2013 2014 2021 private Label beginRuntimeCheck(final MethodVisitor cv, 2022 final CompilerInput input, 2023 final AdviceInfo adviceInfo) { 2024 Label endRuntimeCheckLabel = null; 2025 DeploymentModel deploymentModel = adviceInfo.getAspectDeploymentModel(); 2026 if (adviceInfo.hasTargetWithRuntimeCheck() 2027 || adviceInfo.getAdviceDefinition().hasCflowOrCflowBelow() 2028 || DeploymentModel.PER_THIS.equals(deploymentModel) 2029 || DeploymentModel.PER_TARGET.equals(deploymentModel)) { 2030 2031 int perObjectCheckType = RuntimeCheckVisitor.NULL_PER_OBJECT_TYPE; 2032 2033 if (DeploymentModel.PER_THIS.equals(deploymentModel)) { 2034 perObjectCheckType = RuntimeCheckVisitor.PER_THIS_TYPE; 2035 } else if (DeploymentModel.PER_TARGET.equals(deploymentModel)) { 2036 perObjectCheckType = RuntimeCheckVisitor.PER_TARGET_TYPE; 2037 } 2038 2039 endRuntimeCheckLabel = new Label(); 2040 RuntimeCheckVisitor runtimeCheckVisitor = new RuntimeCheckVisitor( 2042 cv, 2043 adviceInfo.getExpressionInfo(), 2044 input, 2045 perObjectCheckType, 2046 adviceInfo.getAspectQualifiedName() 2047 ); 2048 runtimeCheckVisitor.pushCheckOnStack(adviceInfo); 2049 cv.visitJumpInsn(IFEQ, endRuntimeCheckLabel); 2050 } 2051 return endRuntimeCheckLabel; 2052 } 2053 2054 2061 private void endRuntimeCheck(final MethodVisitor cv, final AdviceInfo adviceInfo, final Label label) { 2062 DeploymentModel deployModel = adviceInfo.getAspectDeploymentModel(); 2063 2064 if (adviceInfo.hasTargetWithRuntimeCheck() 2065 || adviceInfo.getAdviceDefinition().hasCflowOrCflowBelow() 2066 || DeploymentModel.PER_THIS.equals(deployModel) 2067 || DeploymentModel.PER_TARGET.equals(deployModel)) { 2068 2069 cv.visitLabel(label); 2070 } 2071 } 2072 2073 2079 public static void loadCallee(final MethodVisitor cv, 2080 final CompilerInput input) { 2081 if (input.isOptimizedJoinPoint) { 2082 cv.visitVarInsn(ALOAD, input.calleeIndex); 2084 } else { 2085 loadJoinPointInstance(cv, input); 2086 cv.visitFieldInsn( 2087 GETFIELD, input.joinPointClassName, CALLEE_INSTANCE_FIELD_NAME, input.calleeClassSignature 2088 ); 2089 } 2090 } 2091 2092 2098 public static void loadCaller(final MethodVisitor cv, 2099 final CompilerInput input) { 2100 if (input.isOptimizedJoinPoint) { 2101 cv.visitVarInsn(ALOAD, input.callerIndex); 2103 } else { 2104 loadJoinPointInstance(cv, input); 2105 cv.visitFieldInsn( 2106 GETFIELD, input.joinPointClassName, CALLER_INSTANCE_FIELD_NAME, input.callerClassSignature 2107 ); 2108 } 2109 } 2110 2111 2162 2169 private void createInitializationForAdvisableManagement(final MethodVisitor cv, 2170 final int joinPointInstanceIndex, 2171 final int advisableIndex) { 2172 cv.visitVarInsn(ALOAD, joinPointInstanceIndex); 2174 cv.visitInsn(ICONST_M1); 2175 cv.visitFieldInsn(PUTFIELD, m_joinPointClassName, INTERCEPTOR_INDEX_FIELD_NAME, I); 2176 2177 initializeAroundInterceptors(cv, joinPointInstanceIndex, advisableIndex); 2178 initializeBeforeInterceptors(cv, joinPointInstanceIndex, advisableIndex); 2179 initializeAfterInterceptors(cv, joinPointInstanceIndex, advisableIndex); 2180 initializeAfterReturningInterceptors(cv, joinPointInstanceIndex, advisableIndex); 2181 initializeAfterThrowingInterceptors(cv, joinPointInstanceIndex, advisableIndex); 2182 } 2183 2184 2191 private void initializeAroundInterceptors(final MethodVisitor cv, 2192 final int joinPointInstanceIndex, 2193 final int advisableIndex) { 2194 cv.visitVarInsn(ALOAD, joinPointInstanceIndex); 2195 cv.visitVarInsn(ALOAD, advisableIndex); 2196 cv.visitTypeInsn(CHECKCAST, ADVISABLE_CLASS_NAME); 2197 cv.visitLdcInsn(new Integer (m_joinPointClassName.hashCode())); 2198 cv.visitMethodInsn( 2199 INVOKEINTERFACE, 2200 ADVISABLE_CLASS_NAME, 2201 GET_AROUND_ADVICE_METHOD_NAME, 2202 GET_AROUND_ADVICE_METHOD_SIGNATURE 2203 ); 2204 cv.visitFieldInsn( 2205 PUTFIELD, 2206 m_joinPointClassName, 2207 AROUND_INTERCEPTORS_FIELD_NAME, 2208 AROUND_ADVICE_ARRAY_CLASS_SIGNATURE 2209 ); 2210 2211 cv.visitVarInsn(ALOAD, joinPointInstanceIndex); 2212 cv.visitVarInsn(ALOAD, joinPointInstanceIndex); 2213 cv.visitFieldInsn( 2214 GETFIELD, 2215 m_joinPointClassName, 2216 AROUND_INTERCEPTORS_FIELD_NAME, 2217 AROUND_ADVICE_ARRAY_CLASS_SIGNATURE 2218 ); 2219 cv.visitInsn(ARRAYLENGTH); 2220 cv.visitFieldInsn(PUTFIELD, m_joinPointClassName, NR_OF_AROUND_INTERCEPTORS_FIELD_NAME, I); 2221 } 2222 2223 2230 private void initializeBeforeInterceptors(final MethodVisitor cv, 2231 final int joinPointInstanceIndex, 2232 final int advisableIndex) { 2233 cv.visitVarInsn(ALOAD, joinPointInstanceIndex); 2234 cv.visitVarInsn(ALOAD, advisableIndex); 2235 cv.visitTypeInsn(CHECKCAST, ADVISABLE_CLASS_NAME); 2236 cv.visitLdcInsn(new Integer (m_joinPointClassName.hashCode())); 2237 cv.visitMethodInsn( 2238 INVOKEINTERFACE, 2239 ADVISABLE_CLASS_NAME, 2240 GET_BEFORE_ADVICE_METHOD_NAME, 2241 GET_BEFORE_ADVICE_METHOD_SIGNATURE 2242 ); 2243 cv.visitFieldInsn( 2244 PUTFIELD, 2245 m_joinPointClassName, 2246 BEFORE_INTERCEPTORS_FIELD_NAME, 2247 BEFORE_ADVICE_ARRAY_CLASS_SIGNATURE 2248 ); 2249 2250 cv.visitVarInsn(ALOAD, joinPointInstanceIndex); 2251 cv.visitVarInsn(ALOAD, joinPointInstanceIndex); 2252 cv.visitFieldInsn( 2253 GETFIELD, 2254 m_joinPointClassName, 2255 BEFORE_INTERCEPTORS_FIELD_NAME, 2256 BEFORE_ADVICE_ARRAY_CLASS_SIGNATURE 2257 ); 2258 cv.visitInsn(ARRAYLENGTH); 2259 cv.visitFieldInsn(PUTFIELD, m_joinPointClassName, NR_OF_BEFORE_INTERCEPTORS_FIELD_NAME, I); 2260 } 2261 2262 2269 private void initializeAfterInterceptors(final MethodVisitor cv, 2270 final int joinPointInstanceIndex, 2271 final int advisableIndex) { 2272 cv.visitVarInsn(ALOAD, joinPointInstanceIndex); 2273 cv.visitVarInsn(ALOAD, advisableIndex); 2274 cv.visitTypeInsn(CHECKCAST, ADVISABLE_CLASS_NAME); 2275 cv.visitLdcInsn(new Integer (m_joinPointClassName.hashCode())); 2276 cv.visitMethodInsn( 2277 INVOKEINTERFACE, 2278 ADVISABLE_CLASS_NAME, 2279 GET_AFTER_ADVICE_METHOD_NAME, 2280 GET_AFTER_ADVICE_METHOD_SIGNATURE 2281 ); 2282 cv.visitFieldInsn( 2283 PUTFIELD, 2284 m_joinPointClassName, 2285 AFTER_INTERCEPTORS_FIELD_NAME, 2286 AFTER_ADVICE_ARRAY_CLASS_SIGNATURE 2287 ); 2288 2289 cv.visitVarInsn(ALOAD, joinPointInstanceIndex); 2290 cv.visitVarInsn(ALOAD, joinPointInstanceIndex); 2291 cv.visitFieldInsn( 2292 GETFIELD, 2293 m_joinPointClassName, 2294 AFTER_INTERCEPTORS_FIELD_NAME, 2295 AFTER_ADVICE_ARRAY_CLASS_SIGNATURE 2296 ); 2297 cv.visitInsn(ARRAYLENGTH); 2298 cv.visitFieldInsn(PUTFIELD, m_joinPointClassName, NR_OF_AFTER_INTERCEPTORS_FIELD_NAME, I); 2299 } 2300 2301 2308 private void initializeAfterReturningInterceptors(final MethodVisitor cv, 2309 final int joinPointInstanceIndex, 2310 final int advisableIndex) { 2311 cv.visitVarInsn(ALOAD, joinPointInstanceIndex); 2312 cv.visitVarInsn(ALOAD, advisableIndex); 2313 cv.visitTypeInsn(CHECKCAST, ADVISABLE_CLASS_NAME); 2314 cv.visitLdcInsn(new Integer (m_joinPointClassName.hashCode())); 2315 cv.visitMethodInsn( 2316 INVOKEINTERFACE, 2317 ADVISABLE_CLASS_NAME, 2318 GET_AFTER_RETURNING_ADVICE_METHOD_NAME, 2319 GET_AFTER_RETURNING_ADVICE_METHOD_SIGNATURE 2320 ); 2321 cv.visitFieldInsn( 2322 PUTFIELD, 2323 m_joinPointClassName, 2324 AFTER_RETURNING_INTERCEPTORS_FIELD_NAME, 2325 AFTER_RETURNING_ADVICE_ARRAY_CLASS_SIGNATURE 2326 ); 2327 2328 cv.visitVarInsn(ALOAD, joinPointInstanceIndex); 2329 cv.visitVarInsn(ALOAD, joinPointInstanceIndex); 2330 cv.visitFieldInsn( 2331 GETFIELD, 2332 m_joinPointClassName, 2333 AFTER_RETURNING_INTERCEPTORS_FIELD_NAME, 2334 AFTER_RETURNING_ADVICE_ARRAY_CLASS_SIGNATURE 2335 ); 2336 cv.visitInsn(ARRAYLENGTH); 2337 cv.visitFieldInsn(PUTFIELD, m_joinPointClassName, NR_OF_AFTER_RETURNING_INTERCEPTORS_FIELD_NAME, I); 2338 } 2339 2340 2347 private void initializeAfterThrowingInterceptors(final MethodVisitor cv, 2348 final int joinPointInstanceIndex, 2349 final int advisableIndex) { 2350 cv.visitVarInsn(ALOAD, joinPointInstanceIndex); 2351 cv.visitVarInsn(ALOAD, advisableIndex); 2352 cv.visitTypeInsn(CHECKCAST, ADVISABLE_CLASS_NAME); 2353 cv.visitLdcInsn(new Integer (m_joinPointClassName.hashCode())); 2354 cv.visitMethodInsn( 2355 INVOKEINTERFACE, 2356 ADVISABLE_CLASS_NAME, 2357 GET_AFTER_THROWING_ADVICE_METHOD_NAME, 2358 GET_AFTER_THROWING_ADVICE_METHOD_SIGNATURE 2359 ); 2360 cv.visitFieldInsn( 2361 PUTFIELD, 2362 m_joinPointClassName, 2363 AFTER_THROWING_INTERCEPTORS_FIELD_NAME, 2364 AFTER_THROWING_ADVICE_ARRAY_CLASS_SIGNATURE 2365 ); 2366 2367 cv.visitVarInsn(ALOAD, joinPointInstanceIndex); 2368 cv.visitVarInsn(ALOAD, joinPointInstanceIndex); 2369 cv.visitFieldInsn( 2370 GETFIELD, 2371 m_joinPointClassName, 2372 AFTER_THROWING_INTERCEPTORS_FIELD_NAME, 2373 AFTER_THROWING_ADVICE_ARRAY_CLASS_SIGNATURE 2374 ); 2375 cv.visitInsn(ARRAYLENGTH); 2376 cv.visitFieldInsn(PUTFIELD, m_joinPointClassName, NR_OF_AFTER_THROWING_INTERCEPTORS_FIELD_NAME, I); 2377 } 2378 2379 2384 private void createAroundInterceptorInvocations(final MethodVisitor cv) { 2385 cv.visitVarInsn(ALOAD, 0); 2386 cv.visitFieldInsn(GETFIELD, m_joinPointClassName, INTERCEPTOR_INDEX_FIELD_NAME, I); 2387 cv.visitInsn(ICONST_M1); 2388 Label ifStatementLabel = new Label(); 2389 cv.visitJumpInsn(IF_ICMPEQ, ifStatementLabel); 2390 cv.visitVarInsn(ALOAD, 0); 2391 cv.visitFieldInsn(GETFIELD, m_joinPointClassName, INTERCEPTOR_INDEX_FIELD_NAME, I); 2392 cv.visitVarInsn(ALOAD, 0); 2393 cv.visitFieldInsn(GETFIELD, m_joinPointClassName, NR_OF_AROUND_INTERCEPTORS_FIELD_NAME, I); 2394 cv.visitJumpInsn(IF_ICMPGE, ifStatementLabel); 2395 cv.visitVarInsn(ALOAD, 0); 2396 cv.visitFieldInsn( 2397 GETFIELD, 2398 m_joinPointClassName, 2399 AROUND_INTERCEPTORS_FIELD_NAME, 2400 AROUND_ADVICE_ARRAY_CLASS_SIGNATURE 2401 ); 2402 cv.visitVarInsn(ALOAD, 0); 2403 cv.visitInsn(DUP); 2404 cv.visitFieldInsn(GETFIELD, m_joinPointClassName, INTERCEPTOR_INDEX_FIELD_NAME, I); 2405 cv.visitInsn(DUP_X1); 2406 cv.visitInsn(ICONST_1); 2407 cv.visitInsn(IADD); 2408 cv.visitFieldInsn(PUTFIELD, m_joinPointClassName, INTERCEPTOR_INDEX_FIELD_NAME, I); 2409 cv.visitInsn(AALOAD); 2410 cv.visitVarInsn(ALOAD, 0); 2411 cv.visitMethodInsn( 2412 INVOKEINTERFACE, 2413 AROUND_ADVICE_CLASS_NAME, 2414 INTERCEPT_INVOKE_METHOD_NAME, 2415 AROUND_ADVICE_INVOKE_METHOD_SIGNATURE 2416 ); 2417 cv.visitInsn(ARETURN); 2418 cv.visitLabel(ifStatementLabel); 2419 } 2420 2421 2428 private void createBeforeInterceptorInvocations(final MethodVisitor cv, 2429 final int joinPointInstanceIndex, 2430 final int registerDepth) { 2431 final int loopIndex = registerDepth + 1; 2432 cv.visitInsn(ICONST_0); 2433 cv.visitVarInsn(ISTORE, loopIndex); 2434 Label loopStartLabel = new Label(); 2435 cv.visitLabel(loopStartLabel); 2436 cv.visitVarInsn(ILOAD, loopIndex); 2437 cv.visitVarInsn(ALOAD, joinPointInstanceIndex); 2438 cv.visitFieldInsn( 2439 GETFIELD, 2440 m_joinPointClassName, 2441 NR_OF_BEFORE_INTERCEPTORS_FIELD_NAME, 2442 I 2443 ); 2444 Label loopCheckCondLabel = new Label(); 2445 cv.visitJumpInsn(IF_ICMPGE, loopCheckCondLabel); 2446 cv.visitVarInsn(ALOAD, joinPointInstanceIndex); 2447 cv.visitFieldInsn( 2448 GETFIELD, 2449 m_joinPointClassName, 2450 BEFORE_INTERCEPTORS_FIELD_NAME, 2451 BEFORE_ADVICE_ARRAY_CLASS_SIGNATURE 2452 ); 2453 cv.visitVarInsn(ILOAD, loopIndex); 2454 cv.visitInsn(AALOAD); 2455 cv.visitVarInsn(ALOAD, joinPointInstanceIndex); 2456 cv.visitMethodInsn( 2457 INVOKEINTERFACE, 2458 BEFORE_ADVICE_CLASS_NAME, 2459 INTERCEPT_INVOKE_METHOD_NAME, 2460 BEFORE_ADVICE_INVOKE_METHOD_SIGNATURE 2461 ); 2462 cv.visitIincInsn(loopIndex, 1); 2463 cv.visitJumpInsn(GOTO, loopStartLabel); 2464 cv.visitLabel(loopCheckCondLabel); 2465 } 2466 2467 2474 private void createAfterInterceptorInvocations(final MethodVisitor cv, 2475 final int joinPointInstanceIndex, 2476 final int registerDepth) { 2477 final int loopIndex = registerDepth + 1; 2478 cv.visitVarInsn(ALOAD, joinPointInstanceIndex); 2479 cv.visitFieldInsn( 2480 GETFIELD, 2481 m_joinPointClassName, 2482 NR_OF_AFTER_INTERCEPTORS_FIELD_NAME, 2483 I 2484 ); 2485 cv.visitInsn(ICONST_1); 2486 cv.visitInsn(ISUB); 2487 cv.visitVarInsn(ISTORE, loopIndex); 2488 Label loopLabel1 = new Label(); 2489 cv.visitLabel(loopLabel1); 2490 cv.visitVarInsn(ILOAD, loopIndex); 2491 Label loopLabel2 = new Label(); 2492 cv.visitJumpInsn(IFLT, loopLabel2); 2493 cv.visitVarInsn(ALOAD, joinPointInstanceIndex); 2494 cv.visitFieldInsn( 2495 GETFIELD, 2496 m_joinPointClassName, 2497 AFTER_INTERCEPTORS_FIELD_NAME, 2498 AFTER_ADVICE_ARRAY_CLASS_SIGNATURE 2499 ); 2500 cv.visitVarInsn(ILOAD, loopIndex); 2501 cv.visitInsn(AALOAD); 2502 cv.visitVarInsn(ALOAD, joinPointInstanceIndex); 2503 cv.visitMethodInsn( 2504 INVOKEINTERFACE, 2505 AFTER_ADVICE_CLASS_NAME, 2506 INTERCEPT_INVOKE_METHOD_NAME, 2507 AFTER_ADVICE_INVOKE_METHOD_SIGNATURE 2508 ); 2509 cv.visitIincInsn(loopIndex, -1); 2510 cv.visitJumpInsn(GOTO, loopLabel1); 2511 cv.visitLabel(loopLabel2); 2512 } 2513 2514 2521 private void createAfterReturningInterceptorInvocations(final MethodVisitor cv, 2522 final int joinPointInstanceIndex, 2523 final int returnValueInstanceIndex) { 2524 final int loopIndex = returnValueInstanceIndex + 1; 2525 cv.visitVarInsn(ALOAD, joinPointInstanceIndex); 2526 cv.visitFieldInsn( 2527 GETFIELD, 2528 m_joinPointClassName, 2529 NR_OF_AFTER_RETURNING_INTERCEPTORS_FIELD_NAME, 2530 I 2531 ); 2532 cv.visitInsn(ICONST_1); 2533 cv.visitInsn(ISUB); 2534 cv.visitVarInsn(ISTORE, loopIndex); 2535 Label loopLabel1 = new Label(); 2536 cv.visitLabel(loopLabel1); 2537 cv.visitVarInsn(ILOAD, loopIndex); 2538 Label loopLabel2 = new Label(); 2539 cv.visitJumpInsn(IFLT, loopLabel2); 2540 cv.visitVarInsn(ALOAD, joinPointInstanceIndex); 2541 cv.visitFieldInsn( 2542 GETFIELD, 2543 m_joinPointClassName, 2544 AFTER_RETURNING_INTERCEPTORS_FIELD_NAME, 2545 AFTER_RETURNING_ADVICE_ARRAY_CLASS_SIGNATURE 2546 ); 2547 cv.visitVarInsn(ILOAD, loopIndex); 2548 cv.visitInsn(AALOAD); 2549 cv.visitVarInsn(ALOAD, joinPointInstanceIndex); 2550 cv.visitVarInsn(ALOAD, returnValueInstanceIndex); 2551 cv.visitMethodInsn( 2552 INVOKEINTERFACE, 2553 AFTER_RETURNING_ADVICE_CLASS_NAME, 2554 INTERCEPT_INVOKE_METHOD_NAME, 2555 AFTER_RETURNING_ADVICE_INVOKE_METHOD_SIGNATURE 2556 ); 2557 cv.visitIincInsn(loopIndex, -1); 2558 cv.visitJumpInsn(GOTO, loopLabel1); 2559 cv.visitLabel(loopLabel2); 2560 } 2561 2562 2569 private void createAfterThrowingInterceptorInvocations(final MethodVisitor cv, 2570 final int joinPointInstanceIndex, 2571 final int exceptionInstanceIndex) { 2572 final int loopIndex = exceptionInstanceIndex + 1; 2573 cv.visitVarInsn(ALOAD, joinPointInstanceIndex); 2574 cv.visitFieldInsn( 2575 GETFIELD, 2576 m_joinPointClassName, 2577 NR_OF_AFTER_THROWING_INTERCEPTORS_FIELD_NAME, 2578 I 2579 ); 2580 cv.visitInsn(ICONST_1); 2581 cv.visitInsn(ISUB); 2582 cv.visitVarInsn(ISTORE, loopIndex); 2583 Label loopLabel1 = new Label(); 2584 cv.visitLabel(loopLabel1); 2585 cv.visitVarInsn(ILOAD, loopIndex); 2586 Label loopLabel2 = new Label(); 2587 cv.visitJumpInsn(IFLT, loopLabel2); 2588 cv.visitVarInsn(ALOAD, joinPointInstanceIndex); 2589 cv.visitFieldInsn( 2590 GETFIELD, 2591 m_joinPointClassName, 2592 AFTER_THROWING_INTERCEPTORS_FIELD_NAME, 2593 AFTER_THROWING_ADVICE_ARRAY_CLASS_SIGNATURE 2594 ); 2595 cv.visitVarInsn(ILOAD, loopIndex); 2596 cv.visitInsn(AALOAD); 2597 cv.visitVarInsn(ALOAD, joinPointInstanceIndex); 2598 cv.visitVarInsn(ALOAD, exceptionInstanceIndex); 2599 cv.visitMethodInsn( 2600 INVOKEINTERFACE, 2601 AFTER_THROWING_ADVICE_CLASS_NAME, 2602 INTERCEPT_INVOKE_METHOD_NAME, 2603 AFTER_THROWING_ADVICE_INVOKE_METHOD_SIGNATURE 2604 ); 2605 cv.visitIincInsn(loopIndex, -1); 2606 cv.visitJumpInsn(GOTO, loopLabel1); 2607 cv.visitLabel(loopLabel2); 2608 } 2609 2610 2615 private boolean requiresProceedMethod() { 2616 return m_hasAroundAdvices || m_isThisAdvisable; 2617 } 2618 2619 public static boolean requiresCallerInstance(DeploymentModel deployModel) { 2620 return DeploymentModel.PER_INSTANCE.equals(deployModel) 2621 || DeploymentModel.PER_THIS.equals(deployModel); 2622 } 2623 2624 public static boolean requiresCalleeInstance(DeploymentModel deployModel) { 2625 return DeploymentModel.PER_TARGET.equals(deployModel); 2626 } 2627 2628 public static boolean requiresCallerOrCallee(DeploymentModel deploymentModel) { 2629 return requiresCallerInstance(deploymentModel) 2630 || requiresCalleeInstance(deploymentModel); 2631 } 2632 2633 public final AspectModel[] getAspectModels() { 2634 return m_aspectModels; 2635 } 2636 2637} 2638 | Popular Tags |