KickJava   Java API By Example, From Geeks To Geeks.

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


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 /**
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 CodeVisitor cv) {
63         cv.visitFieldInsn(GETSTATIC, m_joinPointClassName, TARGET_CLASS_FIELD_NAME, 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 argStartIndex index on stack of first target method arg (0 or 1, depends of static target or not)
85      */

86     protected void createInlinedJoinPointInvocation(final CodeVisitor cv, final boolean isOptimizedJoinPoint,
87                                                     final int argStartIndex, final int joinPointIndex) {
88         cv.visitTypeInsn(NEW, m_calleeClassName);
89         cv.visitInsn(DUP);
90         loadArgumentMemberFields(cv, argStartIndex);
91         cv.visitMethodInsn(
92                 INVOKESPECIAL, m_calleeClassName, INIT_METHOD_NAME/*FIXME caller wrapper factory*/,
93                 m_calleeMemberDesc
94         );
95         // assign to CALLEE
96
//TODO - might not be needed / feasible for optimized jp - we should ensure that it is affected to target for
97
// after advice that comes after (but should we support target on ctor call)
98
cv.visitInsn(DUP);
99         loadJoinPointInstance(cv, isOptimizedJoinPoint, joinPointIndex);
100         cv.visitInsn(SWAP);
101         cv.visitFieldInsn(PUTFIELD, m_joinPointClassName, CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature);
102     }
103
104     /**
105      * Creates a call to the target join point, the parameter(s) to the join point are retrieved from the invocation
106      * local join point instance.
107      *
108      * @param cv
109      */

110     protected void createJoinPointInvocation(final CodeVisitor cv) {
111         cv.visitTypeInsn(NEW, m_calleeClassName);
112         cv.visitInsn(DUP);
113         loadArguments(cv);
114         cv.visitMethodInsn(
115                 INVOKESPECIAL, m_calleeClassName, INIT_METHOD_NAME/*FIXME caller wrapper factory*/,
116                 m_calleeMemberDesc
117         );
118
119         // put it in CALLEE field
120
cv.visitInsn(DUP);
121         cv.visitVarInsn(ALOAD, 0);
122         cv.visitInsn(SWAP);
123         cv.visitFieldInsn(PUTFIELD, m_joinPointClassName, CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature);
124     }
125
126     /**
127      * Returns the join points return type.
128      *
129      * @return
130      */

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

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

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

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