KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > codehaus > aspectwerkz > transform > inlining > compiler > FieldSetJoinPointCompiler


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 import org.objectweb.asm.CodeVisitor;
11 import org.objectweb.asm.Type;
12
13 import org.codehaus.aspectwerkz.transform.TransformationUtil;
14 import org.codehaus.aspectwerkz.transform.inlining.compiler.AbstractJoinPointCompiler;
15 import org.codehaus.aspectwerkz.transform.inlining.AsmHelper;
16
17 import java.lang.reflect.Modifier JavaDoc;
18
19 /**
20  * A compiler that compiles/generates a class that represents a specific join point, a class which invokes the advices
21  * and the target join point statically.
22  *
23  * @author <a HREF="mailto:jboner@codehaus.org">Jonas Bonér </a>
24  * @author <a HREF="mailto:alex AT gnilux DOT com">Alexandre Vasseur </a>
25  */

26 public class FieldSetJoinPointCompiler extends AbstractJoinPointCompiler {
27
28     /**
29      * Creates a new join point compiler instance.
30      *
31      * @param model
32      */

33     FieldSetJoinPointCompiler(final CompilationInfo.Model model) {
34         super(model);
35     }
36
37     /**
38      * Creates join point specific fields.
39      */

40     protected void createJoinPointSpecificFields() {
41         String JavaDoc[] fieldNames = null;
42         // create the field argument field
43
Type fieldType = Type.getType(m_calleeMemberDesc);
44         fieldNames = new String JavaDoc[1];
45         String JavaDoc fieldName = ARGUMENT_FIELD + 0;
46         fieldNames[0] = fieldName;
47         m_cw.visitField(ACC_PRIVATE, fieldName, fieldType.getDescriptor(), null, null);
48         m_fieldNames = fieldNames;
49
50         m_cw.visitField(
51                 ACC_PRIVATE + ACC_STATIC,
52                 SIGNATURE_FIELD_NAME,
53                 FIELD_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 CodeVisitor cv) {
67         cv.visitFieldInsn(GETSTATIC, m_joinPointClassName, TARGET_CLASS_FIELD_NAME, CLASS_CLASS_SIGNATURE);
68         cv.visitLdcInsn(new Integer JavaDoc(m_joinPointHash));
69
70         cv.visitMethodInsn(
71                 INVOKESTATIC,
72                 SIGNATURE_FACTORY_CLASS,
73                 NEW_FIELD_SIGNATURE_METHOD_NAME,
74                 NEW_FIELD_SIGNATURE_METHOD_SIGNATURE
75         );
76         cv.visitFieldInsn(PUTSTATIC, m_joinPointClassName, SIGNATURE_FIELD_NAME, FIELD_SIGNATURE_IMPL_CLASS_SIGNATURE);
77     }
78
79     /**
80      * Optimized implementation that does not retrieve the parameters from the join point instance but is passed
81      * directly to the method from the input parameters in the 'invoke' method. Can only be used if no around advice
82      * exists.
83      *
84      * @param cv
85      * @param argStartIndex index on stack of first target method arg (0 or 1, depends of static target or not)
86      */

87     protected void createInlinedJoinPointInvocation(final CodeVisitor cv, final boolean isOptimizedJoinPoint,
88                                                     final int argStartIndex, final int joinPointIndex) {
89
90         // load the target instance (arg0 else not available for static target)
91
if (!Modifier.isStatic(m_calleeMemberModifiers)) {
92             cv.visitVarInsn(ALOAD, 0);
93         }
94
95         loadArgumentMemberFields(cv, argStartIndex);
96
97         // do we have a public field ? If so don't use the wrappers
98
if (Modifier.isPublic(m_calleeMemberModifiers)) {
99             if (Modifier.isStatic(m_calleeMemberModifiers)) {
100                 cv.visitFieldInsn(PUTSTATIC, m_calleeClassName, m_calleeMemberName, m_calleeMemberDesc);
101             } else {
102                 cv.visitFieldInsn(PUTFIELD, m_calleeClassName, m_calleeMemberName, m_calleeMemberDesc);
103             }
104         } else {
105             String JavaDoc joinPointName = null; // can be prefixed
106
joinPointName = m_calleeMemberName;
107             joinPointName = TransformationUtil.getWrapperMethodName(
108                     joinPointName,
109                     m_calleeMemberDesc,
110                     m_calleeClassName,
111                     PUTFIELD_WRAPPER_METHOD_PREFIX
112             );
113             StringBuffer JavaDoc sig = new StringBuffer JavaDoc();
114             sig.append('(');
115             sig.append(m_calleeMemberDesc);
116             sig.append(')');
117             sig.append('V');
118             if (Modifier.isStatic(m_calleeMemberModifiers)) {
119                 cv.visitMethodInsn(INVOKESTATIC, m_calleeClassName, joinPointName, sig.toString());
120             } else {
121                 cv.visitMethodInsn(INVOKEVIRTUAL, m_calleeClassName, joinPointName, sig.toString());
122             }
123         }
124
125         AsmHelper.addDefaultValue(cv, m_argumentTypes[0]);
126     }
127
128     /**
129      * Creates a call to the target join point, the parameter(s) to the join point are retrieved from the invocation
130      * local join point instance.
131      *
132      * @param cv
133      */

134     protected void createJoinPointInvocation(final CodeVisitor cv) {
135
136         // load the target instance member field unless calleeMember is static
137
if (!Modifier.isStatic(m_calleeMemberModifiers)) {
138             cv.visitVarInsn(ALOAD, 0);
139             cv.visitFieldInsn(GETFIELD, m_joinPointClassName, CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature);
140         }
141
142         loadArguments(cv);
143
144         // do we have a public field ? If so don't use the wrappers
145
if (Modifier.isPublic(m_calleeMemberModifiers)) {
146             if (Modifier.isStatic(m_calleeMemberModifiers)) {
147                 cv.visitFieldInsn(PUTSTATIC, m_calleeClassName, m_calleeMemberName, m_calleeMemberDesc);
148             } else {
149                 cv.visitFieldInsn(PUTFIELD, m_calleeClassName, m_calleeMemberName, m_calleeMemberDesc);
150             }
151         } else {
152             String JavaDoc joinPointName = TransformationUtil.getWrapperMethodName(
153                     m_calleeMemberName,
154                     m_calleeMemberDesc,
155                     m_calleeClassName,
156                     PUTFIELD_WRAPPER_METHOD_PREFIX
157             );
158             StringBuffer JavaDoc putFieldWrapperDesc = new StringBuffer JavaDoc();
159             putFieldWrapperDesc.append('(');
160             putFieldWrapperDesc.append(m_calleeMemberDesc);
161             putFieldWrapperDesc.append(')');
162             putFieldWrapperDesc.append('V');
163             if (Modifier.isStatic(m_calleeMemberModifiers)) {
164                 cv.visitMethodInsn(INVOKESTATIC, m_calleeClassName, joinPointName, putFieldWrapperDesc.toString());
165             } else {
166                 cv.visitMethodInsn(INVOKEVIRTUAL, m_calleeClassName, joinPointName, putFieldWrapperDesc.toString());
167             }
168         }
169
170         AsmHelper.addDefaultValue(cv, m_argumentTypes[0]);
171     }
172
173     /**
174      * Returns the join points return type.
175      *
176      * @return
177      */

178     protected Type getJoinPointReturnType() {
179         return Type.getType(m_calleeMemberDesc);
180     }
181
182     /**
183      * Returns the join points argument type(s).
184      *
185      * @return
186      */

187     protected Type[] getJoinPointArgumentTypes() {
188         return new Type[]{Type.getType(m_calleeMemberDesc)};
189     }
190
191     /**
192      * Creates the getRtti method
193      */

194     protected void createGetRttiMethod() {
195         CodeVisitor cv = m_cw.visitMethod(ACC_PUBLIC, GET_RTTI_METHOD_NAME, GET_RTTI_METHOD_SIGNATURE, null, null);
196
197         // new FieldRttiImpl( .. )
198
cv.visitTypeInsn(NEW, FIELD_RTTI_IMPL_CLASS_NAME);
199         cv.visitInsn(DUP);
200         cv.visitFieldInsn(GETSTATIC, m_joinPointClassName, SIGNATURE_FIELD_NAME, FIELD_SIGNATURE_IMPL_CLASS_SIGNATURE);
201         cv.visitVarInsn(ALOAD, 0);
202         cv.visitFieldInsn(GETFIELD, m_joinPointClassName, CALLER_INSTANCE_FIELD_NAME, m_callerClassSignature);
203         cv.visitVarInsn(ALOAD, 0);
204         cv.visitFieldInsn(GETFIELD, m_joinPointClassName, CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature);
205         cv.visitMethodInsn(
206                 INVOKESPECIAL, FIELD_RTTI_IMPL_CLASS_NAME, INIT_METHOD_NAME, FIELD_RTTI_IMPL_INIT_SIGNATURE
207         );
208
209         // set the value
210
cv.visitInsn(DUP);
211         if (AsmHelper.isPrimitive(m_returnType)) {
212             AsmHelper.prepareWrappingOfPrimitiveType(cv, m_returnType);
213             cv.visitVarInsn(ALOAD, 0);
214             cv.visitFieldInsn(GETFIELD, m_joinPointClassName, RETURN_VALUE_FIELD_NAME, m_returnType.getDescriptor());
215             AsmHelper.wrapPrimitiveType(cv, m_returnType);
216         } else {
217             cv.visitVarInsn(ALOAD, 0);
218             cv.visitFieldInsn(GETFIELD, m_joinPointClassName, RETURN_VALUE_FIELD_NAME, m_returnType.getDescriptor());
219         }
220         cv.visitMethodInsn(
221                 INVOKEVIRTUAL,
222                 FIELD_RTTI_IMPL_CLASS_NAME,
223                 SET_FIELD_VALUE_METHOD_NAME,
224                 SET_FIELD_VALUE_METHOD_SIGNATURE
225         );
226
227         cv.visitInsn(ARETURN);
228         cv.visitMaxs(0, 0);
229     }
230
231     /**
232      * Creates the getSignature method.
233      */

234     protected void createGetSignatureMethod() {
235         CodeVisitor cv = m_cw.visitMethod(
236                 ACC_PUBLIC,
237                 GET_SIGNATURE_METHOD_NAME,
238                 GET_SIGNATURE_METHOD_SIGNATURE,
239                 null,
240                 null
241         );
242         cv.visitFieldInsn(
243                 GETSTATIC, m_joinPointClassName,
244                 SIGNATURE_FIELD_NAME, FIELD_SIGNATURE_IMPL_CLASS_SIGNATURE
245         );
246         cv.visitInsn(ARETURN);
247         cv.visitMaxs(0, 0);
248     }
249 }
Popular Tags