KickJava   Java API By Example, From Geeks To Geeks.

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


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 import com.tc.aspectwerkz.transform.TransformationUtil;
10
11 import java.lang.reflect.Modifier JavaDoc;
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 ConstructorExecutionJoinPointCompiler extends AbstractJoinPointCompiler {
21
22   /**
23    * Creates a new join point compiler instance.
24    *
25    * @param model
26    */

27   ConstructorExecutionJoinPointCompiler(final CompilationInfo.Model model) {
28     super(model);
29   }
30
31   /**
32    * Creates join point specific fields.
33    */

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

63   protected void createSignature(final MethodVisitor cv) {
64     cv.visitFieldInsn(GETSTATIC, m_joinPointClassName, TARGET_CLASS_FIELD_NAME_IN_JP, CLASS_CLASS_SIGNATURE);
65     cv.visitLdcInsn(new Integer JavaDoc(m_joinPointHash));
66
67     cv.visitMethodInsn(
68             INVOKESTATIC,
69             SIGNATURE_FACTORY_CLASS,
70             NEW_CONSTRUCTOR_SIGNATURE_METHOD_NAME,
71             NEW_CONSTRUCTOR_SIGNATURE_METHOD_SIGNATURE
72     );
73     cv.visitFieldInsn(
74             PUTSTATIC, m_joinPointClassName, SIGNATURE_FIELD_NAME,
75             CONSTRUCTOR_SIGNATURE_IMPL_CLASS_SIGNATURE
76     );
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 input
86    */

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

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

125   protected Type getJoinPointReturnType() {
126     return Type.getReturnType(m_calleeMemberDesc);
127   }
128
129   /**
130    * Returns the join points argument type(s).
131    *
132    * @return
133    */

134   protected Type[] getJoinPointArgumentTypes() {
135     return Type.getArgumentTypes(m_calleeMemberDesc);
136   }
137
138   /**
139    * Creates the getRtti method
140    */

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

175   protected void createGetSignatureMethod() {
176     MethodVisitor cv = m_cw.visitMethod(
177             ACC_PUBLIC,
178             GET_SIGNATURE_METHOD_NAME,
179             GET_SIGNATURE_METHOD_SIGNATURE,
180             null,
181             null
182     );
183     cv.visitFieldInsn(
184             GETSTATIC, m_joinPointClassName,
185             SIGNATURE_FIELD_NAME, CONSTRUCTOR_SIGNATURE_IMPL_CLASS_SIGNATURE
186     );
187     cv.visitInsn(ARETURN);
188     cv.visitMaxs(0, 0);
189   }
190 }
Popular Tags