KickJava   Java API By Example, From Geeks To Geeks.

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


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 MethodExecutionJoinPointCompiler extends AbstractJoinPointCompiler {
23
24   /**
25    * Creates a new join point compiler instance.
26    *
27    * @param model
28    */

29   MethodExecutionJoinPointCompiler(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
48     m_fieldNames = fieldNames;
49
50     m_cw.visitField(
51             ACC_PRIVATE + ACC_STATIC,
52             SIGNATURE_FIELD_NAME,
53             METHOD_SIGNATURE_IMPL_CLASS_SIGNATURE,
54             null,
55             null
56     );
57   }
58
59   /**
60    * Creates the signature for the join point.
61    * <p/>
62    * FIXME signature field should NOT be of type Signature but of the specific type (update all refs as well)
63    *
64    * @param cv
65    */

66   protected void createSignature(final MethodVisitor cv) {
67     cv.visitFieldInsn(GETSTATIC, m_joinPointClassName, TARGET_CLASS_FIELD_NAME_IN_JP, CLASS_CLASS_SIGNATURE);
68     cv.visitLdcInsn(new Integer JavaDoc(m_joinPointHash));
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     joinPointName = TransformationUtil.getPrefixedOriginalMethodName(
101             m_calleeMemberName,
102             m_calleeClassName
103     );
104     if (Modifier.isStatic(m_calleeMemberModifiers)) {
105       cv.visitMethodInsn(INVOKESTATIC, m_calleeClassName, joinPointName, m_calleeMemberDesc);
106     } else {
107       cv.visitMethodInsn(INVOKEVIRTUAL, m_calleeClassName, joinPointName, m_calleeMemberDesc);
108     }
109
110   }
111
112   /**
113    * Creates a call to the target join point, the parameter(s) to the join point are retrieved from the invocation
114    * local join point instance.
115    *
116    * @param cv
117    */

118   protected void createJoinPointInvocation(final MethodVisitor cv) {
119
120     // load the target instance member field unless calleeMember is static
121
if (!Modifier.isStatic(m_calleeMemberModifiers)) {
122       cv.visitVarInsn(ALOAD, 0);
123       cv.visitFieldInsn(GETFIELD, m_joinPointClassName, CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature);
124     }
125
126     String JavaDoc joinPointName;
127     loadArguments(cv);
128     joinPointName = TransformationUtil.getPrefixedOriginalMethodName(
129             m_calleeMemberName,
130             m_calleeClassName
131     );
132     if (Modifier.isStatic(m_calleeMemberModifiers)) {
133       cv.visitMethodInsn(INVOKESTATIC, m_calleeClassName, joinPointName, m_calleeMemberDesc);
134     } else {
135       cv.visitMethodInsn(INVOKEVIRTUAL, m_calleeClassName, joinPointName, m_calleeMemberDesc);
136     }
137   }
138
139   /**
140    * Returns the join points return type.
141    *
142    * @return
143    */

144   protected Type getJoinPointReturnType() {
145     return Type.getReturnType(m_calleeMemberDesc);
146   }
147
148   /**
149    * Returns the join points argument type(s).
150    *
151    * @return
152    */

153   protected Type[] getJoinPointArgumentTypes() {
154     return Type.getArgumentTypes(m_calleeMemberDesc);
155   }
156
157   /**
158    * Creates the getRtti method
159    */

160   protected void createGetRttiMethod() {
161     MethodVisitor cv = m_cw.visitMethod(ACC_PUBLIC, GET_RTTI_METHOD_NAME, GET_RTTI_METHOD_SIGNATURE, null, null);
162
163     // new MethodRttiImpl( .. )
164
cv.visitTypeInsn(NEW, METHOD_RTTI_IMPL_CLASS_NAME);
165     cv.visitInsn(DUP);
166     cv.visitFieldInsn(
167             GETSTATIC, m_joinPointClassName, SIGNATURE_FIELD_NAME, METHOD_SIGNATURE_IMPL_CLASS_SIGNATURE
168     );
169     cv.visitVarInsn(ALOAD, 0);
170     cv.visitFieldInsn(GETFIELD, m_joinPointClassName, CALLER_INSTANCE_FIELD_NAME, m_callerClassSignature);
171     cv.visitVarInsn(ALOAD, 0);
172     cv.visitFieldInsn(GETFIELD, m_joinPointClassName, CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature);
173     cv.visitMethodInsn(
174             INVOKESPECIAL, METHOD_RTTI_IMPL_CLASS_NAME, INIT_METHOD_NAME, METHOD_RTTI_IMPL_INIT_SIGNATURE
175     );
176
177     // set the arguments
178
cv.visitInsn(DUP);
179     createArgumentArrayAt(cv, 1);
180     cv.visitVarInsn(ALOAD, 1);
181     cv.visitMethodInsn(
182             INVOKEVIRTUAL, METHOD_RTTI_IMPL_CLASS_NAME, SET_PARAMETER_VALUES_METHOD_NAME,
183             SET_PARAMETER_VALUES_METHOD_SIGNATURE
184     );
185
186     // set the Returned instance
187
if (m_returnType.getSort() != Type.VOID) {
188       cv.visitInsn(DUP);
189       if (AsmHelper.isPrimitive(m_returnType)) {
190         AsmHelper.prepareWrappingOfPrimitiveType(cv, m_returnType);
191         cv.visitVarInsn(ALOAD, 0);
192         cv.visitFieldInsn(
193                 GETFIELD, m_joinPointClassName, RETURN_VALUE_FIELD_NAME, m_returnType.getDescriptor()
194         );
195         AsmHelper.wrapPrimitiveType(cv, m_returnType);
196       } else {
197         cv.visitVarInsn(ALOAD, 0);
198         cv.visitFieldInsn(
199                 GETFIELD, m_joinPointClassName, RETURN_VALUE_FIELD_NAME, m_returnType.getDescriptor()
200         );
201       }
202       cv.visitMethodInsn(
203               INVOKEVIRTUAL, METHOD_RTTI_IMPL_CLASS_NAME, SET_RETURN_VALUE_METHOD_NAME,
204               SET_RETURN_VALUE_METHOD_SIGNATURE
205       );
206     }
207
208     cv.visitInsn(ARETURN);
209     cv.visitMaxs(0, 0);
210   }
211
212   /**
213    * Creates the getSignature method.
214    */

215   protected void createGetSignatureMethod() {
216     MethodVisitor cv = m_cw.visitMethod(
217             ACC_PUBLIC,
218             GET_SIGNATURE_METHOD_NAME,
219             GET_SIGNATURE_METHOD_SIGNATURE,
220             null,
221             null
222     );
223
224     cv.visitFieldInsn(
225             GETSTATIC, m_joinPointClassName,
226             SIGNATURE_FIELD_NAME, METHOD_SIGNATURE_IMPL_CLASS_SIGNATURE
227     );
228     cv.visitInsn(ARETURN);
229     cv.visitMaxs(0, 0);
230   }
231 }
Popular Tags