KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > aspectwerkz > transform > inlining > compiler > ConstructorCallJoinPointCompiler


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tc.aspectwerkz.transform.inlining.compiler;
5
6 import com.tc.asm.MethodVisitor;
7 import com.tc.asm.Type;
8
9 import com.tc.aspectwerkz.transform.TransformationUtil;
10
11 import java.lang.reflect.Modifier JavaDoc;
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  *
17  * @author <a HREF="mailto:jboner@codehaus.org">Jonas BonŽr </a>
18  * @author <a HREF="mailto:alex AT gnilux DOT com">Alexandre Vasseur </a>
19  */

20 public class ConstructorCallJoinPointCompiler extends AbstractJoinPointCompiler {
21   /**
22    * Creates a new join point compiler instance.
23    *
24    * @param model
25    */

26   ConstructorCallJoinPointCompiler(final CompilationInfo.Model model) {
27     super(model);
28   }
29
30   /**
31    * Creates join point specific fields.
32    */

33   protected void createJoinPointSpecificFields() {
34     String JavaDoc[] fieldNames = null;
35     // create the method argument fields
36
Type[] argumentTypes = Type.getArgumentTypes(m_calleeMemberDesc);
37     fieldNames = new String JavaDoc[argumentTypes.length];
38     for (int i = 0; i < argumentTypes.length; i++) {
39       Type argumentType = argumentTypes[i];
40       String JavaDoc fieldName = ARGUMENT_FIELD + i;
41       fieldNames[i] = fieldName;
42       m_cw.visitField(ACC_PRIVATE, fieldName, argumentType.getDescriptor(), null, null);
43     }
44     m_fieldNames = fieldNames;
45
46     m_cw.visitField(
47             ACC_PRIVATE + ACC_STATIC,
48             SIGNATURE_FIELD_NAME,
49             CONSTRUCTOR_SIGNATURE_IMPL_CLASS_SIGNATURE,
50             null,
51             null
52     );
53   }
54
55   /**
56    * Creates the signature for the join point.
57    * <p/>
58    * FIXME signature field should NOT be of type Signature but of the specific type (update all refs as well)
59    *
60    * @param cv
61    */

62   protected void createSignature(final MethodVisitor cv) {
63     cv.visitFieldInsn(GETSTATIC, m_joinPointClassName, TARGET_CLASS_FIELD_NAME_IN_JP, CLASS_CLASS_SIGNATURE);
64     cv.visitLdcInsn(new Integer JavaDoc(m_joinPointHash));
65
66     cv.visitMethodInsn(
67             INVOKESTATIC,
68             SIGNATURE_FACTORY_CLASS,
69             NEW_CONSTRUCTOR_SIGNATURE_METHOD_NAME,
70             NEW_CONSTRUCTOR_SIGNATURE_METHOD_SIGNATURE
71     );
72     cv.visitFieldInsn(
73             PUTSTATIC, m_joinPointClassName, SIGNATURE_FIELD_NAME,
74             CONSTRUCTOR_SIGNATURE_IMPL_CLASS_SIGNATURE
75     );
76   }
77
78   /**
79    * Optimized implementation that does not retrieve the parameters from the join point instance but is passed
80    * directly to the method from the input parameters in the 'invoke' method. Can only be used if no around advice
81    * exists.
82    *
83    * @param cv
84    * @param input
85    */

86   protected void createInlinedJoinPointInvocation(final MethodVisitor cv, final CompilerInput input) {
87     if (!Modifier.isPublic(m_calleeMemberModifiers)) {
88       loadArgumentMemberFields(cv, input.argStartIndex);
89       cv.visitMethodInsn(
90               INVOKESTATIC,
91               m_calleeClassName,
92               TransformationUtil.getWrapperMethodName(
93                       m_calleeMemberName,
94                       m_calleeMemberDesc,
95                       m_calleeClassName,
96                       INVOKE_WRAPPER_METHOD_PREFIX
97               ),
98               Type.getMethodDescriptor(Type.getType(m_calleeClassSignature), m_argumentTypes)
99       );
100     } else {
101       cv.visitTypeInsn(NEW, m_calleeClassName);
102       cv.visitInsn(DUP);
103       loadArgumentMemberFields(cv, input.argStartIndex);
104       cv.visitMethodInsn(
105               INVOKESPECIAL, m_calleeClassName, INIT_METHOD_NAME,
106               m_calleeMemberDesc
107       );
108     }
109     // assign to CALLEE
110
//TODO - might not be needed / feasible for optimized jp - we should ensure that it is affected to target for
111
// after advice that comes after (but should we support target on ctor call)
112
cv.visitInsn(DUP);
113     loadJoinPointInstance(cv, input);
114     cv.visitInsn(SWAP);
115     cv.visitFieldInsn(PUTFIELD, m_joinPointClassName, CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature);
116   }
117
118   /**
119    * Creates a call to the target join point, the parameter(s) to the join point are retrieved from the invocation
120    * local join point instance.
121    *
122    * @param cv
123    */

124   protected void createJoinPointInvocation(final MethodVisitor cv) {
125     if (!Modifier.isPublic(m_calleeMemberModifiers)) {
126       loadArguments(cv);
127       cv.visitMethodInsn(
128               INVOKESTATIC,
129               m_calleeClassName,
130               TransformationUtil.getWrapperMethodName(
131                       m_calleeMemberName,
132                       m_calleeMemberDesc,
133                       m_calleeClassName,
134                       INVOKE_WRAPPER_METHOD_PREFIX
135               ),
136               Type.getMethodDescriptor(Type.getType(m_calleeClassSignature), m_argumentTypes)
137       );
138     } else {
139       cv.visitTypeInsn(NEW, m_calleeClassName);
140       cv.visitInsn(DUP);
141       loadArguments(cv);
142       cv.visitMethodInsn(
143               INVOKESPECIAL, m_calleeClassName, INIT_METHOD_NAME,
144               m_calleeMemberDesc
145       );
146     }
147
148     // put it in CALLEE field
149
cv.visitInsn(DUP);
150     cv.visitVarInsn(ALOAD, 0);
151     cv.visitInsn(SWAP);
152     cv.visitFieldInsn(PUTFIELD, m_joinPointClassName, CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature);
153   }
154
155   /**
156    * Returns the join points return type.
157    *
158    * @return
159    */

160   protected Type getJoinPointReturnType() {
161     return Type.getReturnType(m_calleeClassSignature);
162   }
163
164   /**
165    * Returns the join points argument type(s).
166    *
167    * @return
168    */

169   protected Type[] getJoinPointArgumentTypes() {
170     return Type.getArgumentTypes(m_calleeMemberDesc);
171   }
172
173   /**
174    * Creates the getRtti method
175    */

176   protected void createGetRttiMethod() {
177     MethodVisitor cv = m_cw.visitMethod(ACC_PUBLIC, GET_RTTI_METHOD_NAME, GET_RTTI_METHOD_SIGNATURE, null, null);
178
179     // new CtorRttiImpl( .. )
180
cv.visitTypeInsn(NEW, CONSTRUCTOR_RTTI_IMPL_CLASS_NAME);
181     cv.visitInsn(DUP);
182     cv.visitFieldInsn(
183             GETSTATIC, m_joinPointClassName, SIGNATURE_FIELD_NAME, CONSTRUCTOR_SIGNATURE_IMPL_CLASS_SIGNATURE
184     );
185     cv.visitVarInsn(ALOAD, 0);
186     cv.visitFieldInsn(GETFIELD, m_joinPointClassName, CALLER_INSTANCE_FIELD_NAME, m_callerClassSignature);
187     cv.visitVarInsn(ALOAD, 0);
188     // use RETURNED field instead
189
cv.visitFieldInsn(GETFIELD, m_joinPointClassName, RETURN_VALUE_FIELD_NAME, m_calleeClassSignature);
190     cv.visitMethodInsn(
191             INVOKESPECIAL, CONSTRUCTOR_RTTI_IMPL_CLASS_NAME, INIT_METHOD_NAME,
192             CONSTRUCTOR_RTTI_IMPL_INIT_SIGNATURE
193     );
194
195     // set the arguments
196
cv.visitInsn(DUP);
197     createArgumentArrayAt(cv, 1);
198     cv.visitVarInsn(ALOAD, 1);
199     cv.visitMethodInsn(
200             INVOKEVIRTUAL, CONSTRUCTOR_RTTI_IMPL_CLASS_NAME, SET_PARAMETER_VALUES_METHOD_NAME,
201             SET_PARAMETER_VALUES_METHOD_SIGNATURE
202     );
203
204     cv.visitInsn(ARETURN);
205     cv.visitMaxs(0, 0);
206   }
207
208   /**
209    * Creates the getSignature method.
210    */

211   protected void createGetSignatureMethod() {
212     MethodVisitor cv = m_cw.visitMethod(
213             ACC_PUBLIC,
214             GET_SIGNATURE_METHOD_NAME,
215             GET_SIGNATURE_METHOD_SIGNATURE,
216             null,
217             null
218     );
219     cv.visitFieldInsn(
220             GETSTATIC, m_joinPointClassName,
221             SIGNATURE_FIELD_NAME, CONSTRUCTOR_SIGNATURE_IMPL_CLASS_SIGNATURE
222     );
223     cv.visitInsn(ARETURN);
224     cv.visitMaxs(0, 0);
225   }
226 }
Popular Tags