View Javadoc

    1   /***************************************************************************************
    2    * Copyright (c) Jonas BonŽr, Alexandre Vasseur. All rights reserved.                 *
    3    * http://aspectwerkz.codehaus.org                                                    *
    4    * ---------------------------------------------------------------------------------- *
    5    * The software in this package is published under the terms of the LGPL license      *
    6    * a copy of which has been included with this distribution in the license.txt file.  *
    7    **************************************************************************************/
    8   package org.codehaus.aspectwerkz.transform.inlining.compiler;
    9
    10  import org.objectweb.asm.CodeVisitor;
    11  import org.objectweb.asm.Type;
    12
    13  /***
    14   * A compiler that compiles/generates a class that represents a specific join point, a class which invokes the advices
    15   * and the target join point statically.
    16   * <p/>
    17   * In this case, CALLEE is the catched exception instance itself.
    18   *
    19   * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
    20   * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur </a>
    21   */
    22  public class HandlerJoinPointCompiler extends AbstractJoinPointCompiler {
    23
    24      /***
    25       * Creates a new join point compiler instance.
    26       *
    27       * @param model
    28       */
    29      HandlerJoinPointCompiler(final CompilationInfo.Model model) {
    30          super(model);
    31      }
    32
    33      /***
    34       * Creates join point specific fields.
    35       */
    36      protected void createJoinPointSpecificFields() {
    37          // create the field argument field
    38          String[] fieldNames = null;
    39          Type fieldType = Type.getType(m_calleeClassSignature);
    40          fieldNames = new String[1];
    41          String fieldName = ARGUMENT_FIELD + 0;
    42          fieldNames[0] = fieldName;
    43          m_cw.visitField(ACC_PRIVATE, fieldName, fieldType.getDescriptor(), null, null);
    44          m_fieldNames = fieldNames;
    45          m_cw.visitField(
    46                  ACC_PRIVATE + ACC_STATIC,
    47                  SIGNATURE_FIELD_NAME,
    48                  HANDLER_SIGNATURE_IMPL_CLASS_SIGNATURE,
    49                  null,
    50                  null
    51          );
    52      }
    53
    54      /***
    55       * Creates the signature for the join point.
    56       *
    57       * @param cv
    58       */
    59      protected void createSignature(final CodeVisitor cv) {
    60          cv.visitFieldInsn(GETSTATIC, m_joinPointClassName, TARGET_CLASS_FIELD_NAME, CLASS_CLASS_SIGNATURE);
    61
    62          cv.visitMethodInsn(
    63                  INVOKESTATIC,
    64                  SIGNATURE_FACTORY_CLASS,
    65                  NEW_CATCH_CLAUSE_SIGNATURE_METHOD_NAME,
    66                  NEW_HANDLER_SIGNATURE_METHOD_SIGNATURE
    67          );
    68          cv.visitFieldInsn(
    69                  PUTSTATIC, m_joinPointClassName, SIGNATURE_FIELD_NAME, HANDLER_SIGNATURE_IMPL_CLASS_SIGNATURE
    70          );
    71
    72      }
    73
    74      /***
    75       * Optimized implementation that does not retrieve the parameters from the join point instance but is passed
    76       * directly to the method from the input parameters in the 'invoke' method. Can only be used if no around advice
    77       * exists.
    78       *
    79       * @param cv
    80       * @param argStartIndex index on stack of first target method arg (0 or 1, depends of static target or not)
    81       */
    82      protected void createInlinedJoinPointInvocation(final CodeVisitor cv,
    83                                                      final boolean isOptimizedJoinPoint,
    84                                                      final int argStartIndex,
    85                                                      final int joinPointIndex) {
    86          // load the exception
    87          cv.visitVarInsn(ALOAD, 0);//TODO if changed perhaps load CALLEE instead that host the exception ?
    88      }
    89
    90      /***
    91       * Creates a call to the target join point, the parameter(s) to the join point are retrieved from the invocation
    92       * local join point instance.
    93       *
    94       * @param cv
    95       */
    96      protected void createJoinPointInvocation(final CodeVisitor cv) {
    97          cv.visitInsn(ACONST_NULL);
    98      }
    99
    100     /***
    101      * Returns the join points return type.
    102      *
    103      * @return
    104      */
    105     protected Type getJoinPointReturnType() {
    106         return Type.getType(m_calleeClassSignature);
    107     }
    108
    109     /***
    110      * Returns the join points argument type(s).
    111      *
    112      * @return
    113      */
    114     protected Type[] getJoinPointArgumentTypes() {
    115         return new Type[]{Type.getType(m_calleeClassSignature)};//TODO should callee be arg instead ? to bind it later ?
    116     }
    117
    118     /***
    119      * Creates the getRtti method
    120      */
    121     protected void createGetRttiMethod() {
    122         CodeVisitor cv = m_cw.visitMethod(ACC_PUBLIC, GET_RTTI_METHOD_NAME, GET_RTTI_METHOD_SIGNATURE, null, null);
    123
    124         // new CtorRttiImpl( .. )
    125         cv.visitTypeInsn(NEW, HANDLER_RTTI_IMPL_CLASS_NAME);
    126         cv.visitInsn(DUP);
    127         cv.visitFieldInsn(
    128                 GETSTATIC, m_joinPointClassName, SIGNATURE_FIELD_NAME, HANDLER_SIGNATURE_IMPL_CLASS_SIGNATURE
    129         );
    130         cv.visitVarInsn(ALOAD, 0);
    131         cv.visitFieldInsn(GETFIELD, m_joinPointClassName, CALLER_INSTANCE_FIELD_NAME, m_callerClassSignature);
    132         cv.visitVarInsn(ALOAD, 0);
    133         cv.visitFieldInsn(GETFIELD, m_joinPointClassName, CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature);
    134         cv.visitMethodInsn(
    135                 INVOKESPECIAL, HANDLER_RTTI_IMPL_CLASS_NAME, INIT_METHOD_NAME, HANDLER_RTTI_IMPL_INIT_SIGNATURE
    136         );
    137
    138         cv.visitInsn(ARETURN);
    139         cv.visitMaxs(0, 0);
    140     }
    141
    142     /***
    143      * Creates the getSignature method.
    144      */
    145     protected void createGetSignatureMethod() {
    146         CodeVisitor cv = m_cw.visitMethod(
    147                 ACC_PUBLIC,
    148                 GET_SIGNATURE_METHOD_NAME,
    149                 GET_SIGNATURE_METHOD_SIGNATURE,
    150                 null,
    151                 null
    152         );
    153         cv.visitFieldInsn(
    154                 GETSTATIC, m_joinPointClassName,
    155                 SIGNATURE_FIELD_NAME, HANDLER_SIGNATURE_IMPL_CLASS_SIGNATURE
    156         );
    157         cv.visitInsn(ARETURN);
    158         cv.visitMaxs(0, 0);
    159     }
    160 }