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
11 import org.objectweb.asm.CodeVisitor;
12 import org.objectweb.asm.Type;
13
14 import org.codehaus.aspectwerkz.transform.TransformationUtil;
15 import org.codehaus.aspectwerkz.transform.inlining.AsmHelper;
16
17 import java.lang.reflect.Modifier;
18
19 /***
20 * A compiler that compiles/generates a class that represents a specific join
21 * point, a class which invokes the advices and the target join point
22 * statically.
23 *
24 * @author <a href="mailto:the_mindstorm@evolva.ro">Alex Popescu </a>
25 * @version $Revision: 1.1 $
26 */
27 public class StaticInitializationJoinPointCompiler extends AbstractJoinPointCompiler {
28 private static final Type[] ARG_TYPES = new Type[0];
29
30 /***
31 * Creates a new join point compiler instance.
32 *
33 * @param model
34 */
35 StaticInitializationJoinPointCompiler(final CompilationInfo.Model model) {
36 super(model);
37 }
38
39 /***
40 * Creates join point specific fields.
41 */
42 protected void createJoinPointSpecificFields() {
43 m_fieldNames = new String[0];
44
45 m_cw.visitField(ACC_PRIVATE + ACC_STATIC,
46 SIGNATURE_FIELD_NAME,
47 STATICINITIALIZATION_SIGNATURE_IMPL_CLASS_SIGNATURE,
48 null,
49 null);
50 }
51
52 /***
53 * Creates the signature for the join point.
54 *
55 * @param cv
56 */
57 protected void createSignature(final CodeVisitor cv) {
58 cv.visitFieldInsn(GETSTATIC,
59 m_joinPointClassName,
60 TARGET_CLASS_FIELD_NAME,
61 CLASS_CLASS_SIGNATURE);
62 cv.visitMethodInsn(INVOKESTATIC,
63 SIGNATURE_FACTORY_CLASS,
64 NEW_STATICINITIALIZATION_SIGNATURE_METHOD_NAME,
65 NEW_STATICINITIALIZATION_SIGNATURE_METHOD_SIGNATURE);
66 cv.visitFieldInsn(PUTSTATIC,
67 m_joinPointClassName,
68 SIGNATURE_FIELD_NAME,
69 STATICINITIALIZATION_SIGNATURE_IMPL_CLASS_SIGNATURE);
70 }
71
72 /***
73 * Optimized implementation that does not retrieve the parameters from the
74 * join point instance but is passed directly to the method from the input
75 * parameters in the 'invoke' method. Can only be used if no around advice
76 * exists.
77 *
78 * @param cv
79 * @param argStartIndex
80 * index on stack of first target method arg (0 or 1, depends of
81 * static target or not)
82 */
83 protected void createInlinedJoinPointInvocation(final CodeVisitor cv,
84 final boolean isOptimizedJoinPoint,
85 final int argStartIndex,
86 final int joinPointIndex) {
87 String joinPointName = TransformationUtil.getPrefixedOriginalClinitName(m_calleeClassName);
88
89 cv.visitMethodInsn(INVOKESTATIC, m_calleeClassName, joinPointName, m_calleeMemberDesc);
90 }
91
92 /***
93 * Creates a call to the target join point, the parameter(s) to the join
94 * point are retrieved from the invocation local join point instance.
95 *
96 * @param cv
97 */
98 protected void createJoinPointInvocation(final CodeVisitor cv) {
99
100
101 String joinPointName = TransformationUtil.getPrefixedOriginalClinitName(m_calleeClassName);
102 cv.visitMethodInsn(INVOKESTATIC, m_calleeClassName, joinPointName, m_calleeMemberDesc);
103 }
104
105 /***
106 * Returns the join points return type.
107 *
108 * @return
109 */
110 protected Type getJoinPointReturnType() {
111 return Type.VOID_TYPE;
112 }
113
114 /***
115 * Returns the join points argument type(s).
116 *
117 * @return
118 */
119 protected Type[] getJoinPointArgumentTypes() {
120 return ARG_TYPES;
121 }
122
123 /***
124 * Creates the getRtti method
125 */
126 protected void createGetRttiMethod() {
127 CodeVisitor cv = m_cw.visitMethod(ACC_PUBLIC,
128 GET_RTTI_METHOD_NAME,
129 GET_RTTI_METHOD_SIGNATURE,
130 null,
131 null
132 );
133
134
135 cv.visitTypeInsn(NEW, STATICINITIALIZATION_RTTI_IMPL_CLASS_NAME);
136 cv.visitInsn(DUP);
137 cv.visitFieldInsn(GETSTATIC,
138 m_joinPointClassName,
139 SIGNATURE_FIELD_NAME,
140 STATICINITIALIZATION_SIGNATURE_IMPL_CLASS_SIGNATURE);
141 cv.visitMethodInsn(INVOKESPECIAL,
142 STATICINITIALIZATION_RTTI_IMPL_CLASS_NAME,
143 INIT_METHOD_NAME,
144 STATICINITIALIZATION_RTTI_IMPL_INIT_SIGNATURE
145 );
146
147 cv.visitInsn(ARETURN);
148 cv.visitMaxs(0, 0);
149 }
150
151 /***
152 * Creates the getSignature method.
153 */
154 protected void createGetSignatureMethod() {
155 CodeVisitor cv = m_cw.visitMethod(ACC_PUBLIC,
156 GET_SIGNATURE_METHOD_NAME,
157 GET_SIGNATURE_METHOD_SIGNATURE,
158 null,
159 null);
160
161 cv.visitFieldInsn(GETSTATIC,
162 m_joinPointClassName,
163 SIGNATURE_FIELD_NAME,
164 STATICINITIALIZATION_SIGNATURE_IMPL_CLASS_SIGNATURE);
165 cv.visitInsn(ARETURN);
166 cv.visitMaxs(0, 0);
167 }
168 }