KickJava   Java API By Example, From Geeks To Geeks.

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


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
15 import java.lang.reflect.Modifier JavaDoc;
16
17 /**
18  * A compiler that compiles/generates a class that represents a specific join point, a class which invokes the advices
19  * and the target join point statically.
20  *
21  * @author <a HREF="mailto:jboner@codehaus.org">Jonas BonŽr </a>
22  * @author <a HREF="mailto:alex AT gnilux DOT com">Alexandre Vasseur </a>
23  */

24 public class ConstructorExecutionJoinPointCompiler extends AbstractJoinPointCompiler {
25
26     /**
27      * Creates a new join point compiler instance.
28      *
29      * @param model
30      */

31     ConstructorExecutionJoinPointCompiler(final CompilationInfo.Model model) {
32         super(model);
33     }
34
35     /**
36      * Creates join point specific fields.
37      */

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

67     protected void createSignature(final CodeVisitor cv) {
68         cv.visitFieldInsn(GETSTATIC, m_joinPointClassName, TARGET_CLASS_FIELD_NAME, CLASS_CLASS_SIGNATURE);
69         cv.visitLdcInsn(new Integer JavaDoc(m_joinPointHash));
70
71         cv.visitMethodInsn(
72                 INVOKESTATIC,
73                 SIGNATURE_FACTORY_CLASS,
74                 NEW_CONSTRUCTOR_SIGNATURE_METHOD_NAME,
75                 NEW_CONSTRUCTOR_SIGNATURE_METHOD_SIGNATURE
76         );
77         cv.visitFieldInsn(
78                 PUTSTATIC, m_joinPointClassName, SIGNATURE_FIELD_NAME,
79                 CONSTRUCTOR_SIGNATURE_IMPL_CLASS_SIGNATURE
80         );
81     }
82
83     /**
84      * Optimized implementation that does not retrieve the parameters from the join point instance but is passed
85      * directly to the method from the input parameters in the 'invoke' method. Can only be used if no around advice
86      * exists.
87      *
88      * @param cv
89      * @param argStartIndex index on stack of first target method arg (0 or 1, depends of static target or not)
90      */

91     protected void createInlinedJoinPointInvocation(final CodeVisitor cv, final boolean isOptimizedJoinPoint,
92                                                     final int argStartIndex, final int joinPointIndex) {
93
94         // load the target instance (arg0 else not available for static target)
95
if (!Modifier.isStatic(m_calleeMemberModifiers)) {
96             cv.visitVarInsn(ALOAD, 0);
97         }
98
99         loadArgumentMemberFields(cv, argStartIndex);
100         String JavaDoc bodyName = TransformationUtil.getConstructorBodyMethodName(m_calleeClassName);
101         String JavaDoc bodyDesc = TransformationUtil.getConstructorBodyMethodSignature(m_calleeMemberDesc, m_calleeClassName);
102         cv.visitMethodInsn(INVOKESTATIC, m_calleeClassName, bodyName, bodyDesc);
103     }
104
105     /**
106      * Creates a call to the target join point, the parameter(s) to the join point are retrieved from the invocation
107      * local join point instance.
108      *
109      * @param cv
110      */

111     protected void createJoinPointInvocation(final CodeVisitor cv) {
112
113         // load the target instance member field unless calleeMember is static
114
if (!Modifier.isStatic(m_calleeMemberModifiers)) {
115             cv.visitVarInsn(ALOAD, 0);
116             cv.visitFieldInsn(GETFIELD, m_joinPointClassName, CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature);
117         }
118
119         loadArguments(cv);
120         String JavaDoc bodyName = TransformationUtil.getConstructorBodyMethodName(m_calleeClassName);
121         String JavaDoc bodyDesc = TransformationUtil.getConstructorBodyMethodSignature(m_calleeMemberDesc, m_calleeClassName);
122         cv.visitMethodInsn(INVOKESTATIC, m_calleeClassName, bodyName, bodyDesc);
123     }
124
125     /**
126      * Returns the join points return type.
127      *
128      * @return
129      */

130     protected Type getJoinPointReturnType() {
131         return Type.getReturnType(m_calleeMemberDesc);
132     }
133
134     /**
135      * Returns the join points argument type(s).
136      *
137      * @return
138      */

139     protected Type[] getJoinPointArgumentTypes() {
140         return Type.getArgumentTypes(m_calleeMemberDesc);
141     }
142
143     /**
144      * Creates the getRtti method
145      */

146     protected void createGetRttiMethod() {
147         CodeVisitor cv = m_cw.visitMethod(ACC_PUBLIC, GET_RTTI_METHOD_NAME, GET_RTTI_METHOD_SIGNATURE, null, null);
148
149         // new CtorRttiImpl( .. )
150
cv.visitTypeInsn(NEW, CONSTRUCTOR_RTTI_IMPL_CLASS_NAME);
151         cv.visitInsn(DUP);
152         cv.visitFieldInsn(
153                 GETSTATIC, m_joinPointClassName, SIGNATURE_FIELD_NAME, CONSTRUCTOR_SIGNATURE_IMPL_CLASS_SIGNATURE
154         );
155         cv.visitVarInsn(ALOAD, 0);
156         cv.visitFieldInsn(GETFIELD, m_joinPointClassName, CALLER_INSTANCE_FIELD_NAME, m_callerClassSignature);
157         cv.visitVarInsn(ALOAD, 0);
158         cv.visitFieldInsn(GETFIELD, m_joinPointClassName, CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature);
159         cv.visitMethodInsn(
160                 INVOKESPECIAL, CONSTRUCTOR_RTTI_IMPL_CLASS_NAME, INIT_METHOD_NAME,
161                 CONSTRUCTOR_RTTI_IMPL_INIT_SIGNATURE
162         );
163
164         // set the arguments
165
cv.visitInsn(DUP);
166         createArgumentArrayAt(cv, 1);
167         cv.visitVarInsn(ALOAD, 1);
168         cv.visitMethodInsn(
169                 INVOKEVIRTUAL, CONSTRUCTOR_RTTI_IMPL_CLASS_NAME, SET_PARAMETER_VALUES_METHOD_NAME,
170                 SET_PARAMETER_VALUES_METHOD_SIGNATURE
171         );
172
173         cv.visitInsn(ARETURN);
174         cv.visitMaxs(0, 0);
175     }
176
177     /**
178      * Creates the getSignature method.
179      */

180     protected void createGetSignatureMethod() {
181         CodeVisitor cv = m_cw.visitMethod(
182                 ACC_PUBLIC,
183                 GET_SIGNATURE_METHOD_NAME,
184                 GET_SIGNATURE_METHOD_SIGNATURE,
185                 null,
186                 null
187         );
188         cv.visitFieldInsn(
189                 GETSTATIC, m_joinPointClassName,
190                 SIGNATURE_FIELD_NAME, CONSTRUCTOR_SIGNATURE_IMPL_CLASS_SIGNATURE
191         );
192         cv.visitInsn(ARETURN);
193         cv.visitMaxs(0, 0);
194     }
195 }
Popular Tags