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 }