KickJava   Java API By Example, From Geeks To Geeks.

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


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
10 import com.tc.aspectwerkz.transform.TransformationUtil;
11 import com.tc.aspectwerkz.transform.inlining.AsmHelper;
12
13 import java.lang.reflect.Modifier JavaDoc;
14
15 /**
16  * A compiler that compiles/generates a class that represents a specific join point, a class which invokes the advices
17  * and the target join point statically.
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 MethodCallJoinPointCompiler extends AbstractJoinPointCompiler {
23
24   /**
25    * Creates a new join point compiler instance.
26    *
27    * @param model
28    */

29   MethodCallJoinPointCompiler(final CompilationInfo.Model model) {
30     super(model);
31   }
32
33   /**
34    * Creates join point specific fields.
35    */

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

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

90   protected void createInlinedJoinPointInvocation(final MethodVisitor cv, final CompilerInput input) {
91
92     // load the target instance (arg0 else not available for static target)
93
if (!Modifier.isStatic(m_calleeMemberModifiers)) {
94       cv.visitVarInsn(ALOAD, 0);
95     }
96
97     String JavaDoc joinPointName = null; // can be prefixed
98

99     loadArgumentMemberFields(cv, input.argStartIndex);
100
101     // call the package protected wrapper method if target method is not public
102
if (!Modifier.isPublic(m_calleeMemberModifiers)) {
103       joinPointName = TransformationUtil.getWrapperMethodName(
104               m_calleeMemberName,
105               m_calleeMemberDesc,
106               m_calleeClassName,
107               INVOKE_WRAPPER_METHOD_PREFIX
108       );
109     } else {
110       joinPointName = m_calleeMemberName;
111     }
112     // FIXME - pbly broken if we are using a wrapper method - refactor this if / else
113
if (Modifier.isStatic(m_calleeMemberModifiers)) {
114       cv.visitMethodInsn(INVOKESTATIC, m_calleeClassName, joinPointName, m_calleeMemberDesc);
115     } else if (isInvokeInterface(m_calleeMemberModifiers)) {
116       // AW-253
117
cv.visitMethodInsn(INVOKEINTERFACE, m_calleeClassName, joinPointName, m_calleeMemberDesc);
118     } else {
119       cv.visitMethodInsn(INVOKEVIRTUAL, m_calleeClassName, joinPointName, m_calleeMemberDesc);
120     }
121   }
122
123   /**
124    * Creates a call to the target join point, the parameter(s) to the join point are retrieved from the invocation
125    * local join point instance.
126    *
127    * @param cv
128    */

129   protected void createJoinPointInvocation(final MethodVisitor cv) {
130
131     // load the target instance member field unless calleeMember is static
132
if (!Modifier.isStatic(m_calleeMemberModifiers)) {
133       cv.visitVarInsn(ALOAD, 0);
134       cv.visitFieldInsn(GETFIELD, m_joinPointClassName, CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature);
135     }
136
137     String JavaDoc joinPointName;
138     loadArguments(cv);
139     if (!Modifier.isPublic(m_calleeMemberModifiers)) {
140       joinPointName = TransformationUtil.getWrapperMethodName(
141               m_calleeMemberName,
142               m_calleeMemberDesc,
143               m_calleeClassName,
144               INVOKE_WRAPPER_METHOD_PREFIX
145       );
146     } else {
147       joinPointName = m_calleeMemberName;
148     }
149     // FIXME - pbly broken if we are using a wrapper method - refactor this if / else
150
if (Modifier.isStatic(m_calleeMemberModifiers)) {
151       cv.visitMethodInsn(INVOKESTATIC, m_calleeClassName, joinPointName, m_calleeMemberDesc);
152     } else if (isInvokeInterface(m_calleeMemberModifiers)) {
153       // AW-253
154
cv.visitMethodInsn(INVOKEINTERFACE, m_calleeClassName, joinPointName, m_calleeMemberDesc);
155     } else {
156       cv.visitMethodInsn(INVOKEVIRTUAL, m_calleeClassName, joinPointName, m_calleeMemberDesc);
157     }
158   }
159
160   /**
161    * Returns the join points return type.
162    *
163    * @return
164    */

165   protected Type getJoinPointReturnType() {
166     return Type.getReturnType(m_calleeMemberDesc);
167   }
168
169   /**
170    * Returns the join points argument type(s).
171    *
172    * @return
173    */

174   protected Type[] getJoinPointArgumentTypes() {
175     return Type.getArgumentTypes(m_calleeMemberDesc);
176   }
177
178   /**
179    * Creates the getRtti method
180    */

181   protected void createGetRttiMethod() {
182     MethodVisitor cv = m_cw.visitMethod(ACC_PUBLIC, GET_RTTI_METHOD_NAME, GET_RTTI_METHOD_SIGNATURE, null, null);
183
184     // new MethodRttiImpl( .. )
185
cv.visitTypeInsn(NEW, METHOD_RTTI_IMPL_CLASS_NAME);
186     cv.visitInsn(DUP);
187     cv.visitFieldInsn(
188             GETSTATIC, m_joinPointClassName, SIGNATURE_FIELD_NAME, METHOD_SIGNATURE_IMPL_CLASS_SIGNATURE
189     );
190     cv.visitVarInsn(ALOAD, 0);
191     cv.visitFieldInsn(GETFIELD, m_joinPointClassName, CALLER_INSTANCE_FIELD_NAME, m_callerClassSignature);
192     cv.visitVarInsn(ALOAD, 0);
193     cv.visitFieldInsn(GETFIELD, m_joinPointClassName, CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature);
194     cv.visitMethodInsn(
195             INVOKESPECIAL, METHOD_RTTI_IMPL_CLASS_NAME, INIT_METHOD_NAME, METHOD_RTTI_IMPL_INIT_SIGNATURE
196     );
197
198     // set the arguments
199
cv.visitInsn(DUP);
200     createArgumentArrayAt(cv, 1);
201     cv.visitVarInsn(ALOAD, 1);
202     cv.visitMethodInsn(
203             INVOKEVIRTUAL, METHOD_RTTI_IMPL_CLASS_NAME, SET_PARAMETER_VALUES_METHOD_NAME,
204             SET_PARAMETER_VALUES_METHOD_SIGNATURE
205     );
206
207     // set the Returned instance
208
if (m_returnType.getSort() != Type.VOID) {
209       cv.visitInsn(DUP);
210       if (AsmHelper.isPrimitive(m_returnType)) {
211         AsmHelper.prepareWrappingOfPrimitiveType(cv, m_returnType);
212         cv.visitVarInsn(ALOAD, 0);
213         cv.visitFieldInsn(
214                 GETFIELD, m_joinPointClassName, RETURN_VALUE_FIELD_NAME, m_returnType.getDescriptor()
215         );
216         AsmHelper.wrapPrimitiveType(cv, m_returnType);
217       } else {
218         cv.visitVarInsn(ALOAD, 0);
219         cv.visitFieldInsn(
220                 GETFIELD, m_joinPointClassName, RETURN_VALUE_FIELD_NAME, m_returnType.getDescriptor()
221         );
222       }
223       cv.visitMethodInsn(
224               INVOKEVIRTUAL, METHOD_RTTI_IMPL_CLASS_NAME, SET_RETURN_VALUE_METHOD_NAME,
225               SET_RETURN_VALUE_METHOD_SIGNATURE
226       );
227     }
228
229     cv.visitInsn(ARETURN);
230     cv.visitMaxs(0, 0);
231   }
232
233   /**
234    * Creates the getSignature method.
235    */

236   protected void createGetSignatureMethod() {
237     MethodVisitor cv = m_cw.visitMethod(
238             ACC_PUBLIC,
239             GET_SIGNATURE_METHOD_NAME,
240             GET_SIGNATURE_METHOD_SIGNATURE,
241             null,
242             null
243     );
244
245     cv.visitFieldInsn(
246             GETSTATIC, m_joinPointClassName,
247             SIGNATURE_FIELD_NAME, METHOD_SIGNATURE_IMPL_CLASS_SIGNATURE
248     );
249     cv.visitInsn(ARETURN);
250     cv.visitMaxs(0, 0);
251   }
252
253   /**
254    * See AW-253
255    * For INVOKE INTERFACE, we are using a custom modifier to track it down in order to avoid to do the
256    * hierarchy resolution ourself here
257    */

258   private boolean isInvokeInterface(int modifier) {
259     return (modifier & MODIFIER_INVOKEINTERFACE) != 0;
260   }
261 }
Popular Tags