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
    11  import org.objectweb.asm.CodeVisitor;
    12  import org.objectweb.asm.Type;
    13
    14  import org.codehaus.aspectwerkz.transform.TransformationUtil;
    15  import org.codehaus.aspectwerkz.transform.inlining.AsmHelper;
    16
    17  import java.lang.reflect.Modifier;
    18
    19  /***
    20   * A compiler that compiles/generates a class that represents a specific join
    21   * point, a class which invokes the advices and the target join point
    22   * statically.
    23   *
    24   * @author <a href="mailto:the_mindstorm@evolva.ro">Alex Popescu </a>
    25   * @version $Revision: 1.1 $
    26   */
    27  public class StaticInitializationJoinPointCompiler extends AbstractJoinPointCompiler {
    28  	private static final Type[] ARG_TYPES = new Type[0];
    29
    30  	/***
    31  	 * Creates a new join point compiler instance.
    32  	 *
    33  	 * @param model
    34  	 */
    35  	StaticInitializationJoinPointCompiler(final CompilationInfo.Model model) {
    36  		super(model);
    37  	}
    38
    39  	/***
    40  	 * Creates join point specific fields.
    41  	 */
    42  	protected void createJoinPointSpecificFields() {
    43  	    m_fieldNames = new String[0];
    44
    45  		m_cw.visitField(ACC_PRIVATE + ACC_STATIC,
    46  						SIGNATURE_FIELD_NAME,
    47  						STATICINITIALIZATION_SIGNATURE_IMPL_CLASS_SIGNATURE,
    48  						null,
    49  						null);
    50  	}
    51
    52  	/***
    53  	 * Creates the signature for the join point.
    54  	 *
    55  	 * @param cv
    56  	 */
    57  	protected void createSignature(final CodeVisitor cv) {
    58  		cv.visitFieldInsn(GETSTATIC,
    59  		                  m_joinPointClassName,
    60  		                  TARGET_CLASS_FIELD_NAME,
    61  		                  CLASS_CLASS_SIGNATURE);
    62  		cv.visitMethodInsn(INVOKESTATIC,
    63  		                   SIGNATURE_FACTORY_CLASS,
    64  		                   NEW_STATICINITIALIZATION_SIGNATURE_METHOD_NAME,
    65  		                   NEW_STATICINITIALIZATION_SIGNATURE_METHOD_SIGNATURE);
    66  		cv.visitFieldInsn(PUTSTATIC,
    67  		                  m_joinPointClassName,
    68  		                  SIGNATURE_FIELD_NAME,
    69  		                  STATICINITIALIZATION_SIGNATURE_IMPL_CLASS_SIGNATURE);
    70  	}
    71
    72  	/***
    73  	 * Optimized implementation that does not retrieve the parameters from the
    74  	 * join point instance but is passed directly to the method from the input
    75  	 * parameters in the 'invoke' method. Can only be used if no around advice
    76  	 * exists.
    77  	 *
    78  	 * @param cv
    79  	 * @param argStartIndex
    80  	 *            index on stack of first target method arg (0 or 1, depends of
    81  	 *            static target or not)
    82  	 */
    83  	protected void createInlinedJoinPointInvocation(final CodeVisitor cv,
    84  													final boolean isOptimizedJoinPoint,
    85  													final int argStartIndex,
    86  													final int joinPointIndex) {
    87  		String joinPointName = TransformationUtil.getPrefixedOriginalClinitName(m_calleeClassName);
    88
    89  		cv.visitMethodInsn(INVOKESTATIC, m_calleeClassName, joinPointName, m_calleeMemberDesc);
    90  	}
    91
    92  	/***
    93  	 * Creates a call to the target join point, the parameter(s) to the join
    94  	 * point are retrieved from the invocation local join point instance.
    95  	 *
    96  	 * @param cv
    97  	 */
    98  	protected void createJoinPointInvocation(final CodeVisitor cv) {
    99
    100 		// load the target instance member field unless calleeMember is static
    101 		String joinPointName = TransformationUtil.getPrefixedOriginalClinitName(m_calleeClassName);
    102 		cv.visitMethodInsn(INVOKESTATIC, m_calleeClassName, joinPointName, m_calleeMemberDesc);
    103 	}
    104
    105 	/***
    106 	 * Returns the join points return type.
    107 	 *
    108 	 * @return
    109 	 */
    110 	protected Type getJoinPointReturnType() {
    111 		return Type.VOID_TYPE;
    112 	}
    113
    114 	/***
    115 	 * Returns the join points argument type(s).
    116 	 *
    117 	 * @return
    118 	 */
    119 	protected Type[] getJoinPointArgumentTypes() {
    120 		return ARG_TYPES;
    121 	}
    122
    123 	/***
    124 	 * Creates the getRtti method
    125 	 */
    126 	protected void createGetRttiMethod() {
    127 		CodeVisitor cv = m_cw.visitMethod(ACC_PUBLIC,
    128 		                                  GET_RTTI_METHOD_NAME,
    129 		                                  GET_RTTI_METHOD_SIGNATURE,
    130 		                                  null,
    131 		                                  null
    132 		);
    133
    134 		// new StaticInitializationRttiImpl
    135 		cv.visitTypeInsn(NEW, STATICINITIALIZATION_RTTI_IMPL_CLASS_NAME);
    136 		cv.visitInsn(DUP);
    137 		cv.visitFieldInsn(GETSTATIC,
    138 		                  m_joinPointClassName,
    139 		                  SIGNATURE_FIELD_NAME,
    140 		                  STATICINITIALIZATION_SIGNATURE_IMPL_CLASS_SIGNATURE);
    141         cv.visitMethodInsn(INVOKESPECIAL,
    142                            STATICINITIALIZATION_RTTI_IMPL_CLASS_NAME,
    143                            INIT_METHOD_NAME,
    144                            STATICINITIALIZATION_RTTI_IMPL_INIT_SIGNATURE
    145         );
    146
    147 		cv.visitInsn(ARETURN);
    148 		cv.visitMaxs(0, 0);
    149 	}
    150
    151 	/***
    152 	 * Creates the getSignature method.
    153 	 */
    154 	protected void createGetSignatureMethod() {
    155 		CodeVisitor cv = m_cw.visitMethod(ACC_PUBLIC,
    156 		                                  GET_SIGNATURE_METHOD_NAME,
    157 		                                  GET_SIGNATURE_METHOD_SIGNATURE,
    158 		                                  null,
    159 		                                  null);
    160
    161 		cv.visitFieldInsn(GETSTATIC,
    162 		                  m_joinPointClassName,
    163 		                  SIGNATURE_FIELD_NAME,
    164 		                  STATICINITIALIZATION_SIGNATURE_IMPL_CLASS_SIGNATURE);
    165 		cv.visitInsn(ARETURN);
    166 		cv.visitMaxs(0, 0);
    167 	}
    168 }