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 * <p/>
17 * In this case, CALLEE is the catched exception instance itself.
18 *
19 * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
20 * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur </a>
21 */
22 public class HandlerJoinPointCompiler extends AbstractJoinPointCompiler {
23
24 /***
25 * Creates a new join point compiler instance.
26 *
27 * @param model
28 */
29 HandlerJoinPointCompiler(final CompilationInfo.Model model) {
30 super(model);
31 }
32
33 /***
34 * Creates join point specific fields.
35 */
36 protected void createJoinPointSpecificFields() {
37
38 String[] fieldNames = null;
39 Type fieldType = Type.getType(m_calleeClassSignature);
40 fieldNames = new String[1];
41 String fieldName = ARGUMENT_FIELD + 0;
42 fieldNames[0] = fieldName;
43 m_cw.visitField(ACC_PRIVATE, fieldName, fieldType.getDescriptor(), null, null);
44 m_fieldNames = fieldNames;
45 m_cw.visitField(
46 ACC_PRIVATE + ACC_STATIC,
47 SIGNATURE_FIELD_NAME,
48 HANDLER_SIGNATURE_IMPL_CLASS_SIGNATURE,
49 null,
50 null
51 );
52 }
53
54 /***
55 * Creates the signature for the join point.
56 *
57 * @param cv
58 */
59 protected void createSignature(final CodeVisitor cv) {
60 cv.visitFieldInsn(GETSTATIC, m_joinPointClassName, TARGET_CLASS_FIELD_NAME, CLASS_CLASS_SIGNATURE);
61
62 cv.visitMethodInsn(
63 INVOKESTATIC,
64 SIGNATURE_FACTORY_CLASS,
65 NEW_CATCH_CLAUSE_SIGNATURE_METHOD_NAME,
66 NEW_HANDLER_SIGNATURE_METHOD_SIGNATURE
67 );
68 cv.visitFieldInsn(
69 PUTSTATIC, m_joinPointClassName, SIGNATURE_FIELD_NAME, HANDLER_SIGNATURE_IMPL_CLASS_SIGNATURE
70 );
71
72 }
73
74 /***
75 * Optimized implementation that does not retrieve the parameters from the join point instance but is passed
76 * directly to the method from the input parameters in the 'invoke' method. Can only be used if no around advice
77 * exists.
78 *
79 * @param cv
80 * @param argStartIndex index on stack of first target method arg (0 or 1, depends of static target or not)
81 */
82 protected void createInlinedJoinPointInvocation(final CodeVisitor cv,
83 final boolean isOptimizedJoinPoint,
84 final int argStartIndex,
85 final int joinPointIndex) {
86
87 cv.visitVarInsn(ALOAD, 0);
88 }
89
90 /***
91 * Creates a call to the target join point, the parameter(s) to the join point are retrieved from the invocation
92 * local join point instance.
93 *
94 * @param cv
95 */
96 protected void createJoinPointInvocation(final CodeVisitor cv) {
97 cv.visitInsn(ACONST_NULL);
98 }
99
100 /***
101 * Returns the join points return type.
102 *
103 * @return
104 */
105 protected Type getJoinPointReturnType() {
106 return Type.getType(m_calleeClassSignature);
107 }
108
109 /***
110 * Returns the join points argument type(s).
111 *
112 * @return
113 */
114 protected Type[] getJoinPointArgumentTypes() {
115 return new Type[]{Type.getType(m_calleeClassSignature)};
116 }
117
118 /***
119 * Creates the getRtti method
120 */
121 protected void createGetRttiMethod() {
122 CodeVisitor cv = m_cw.visitMethod(ACC_PUBLIC, GET_RTTI_METHOD_NAME, GET_RTTI_METHOD_SIGNATURE, null, null);
123
124
125 cv.visitTypeInsn(NEW, HANDLER_RTTI_IMPL_CLASS_NAME);
126 cv.visitInsn(DUP);
127 cv.visitFieldInsn(
128 GETSTATIC, m_joinPointClassName, SIGNATURE_FIELD_NAME, HANDLER_SIGNATURE_IMPL_CLASS_SIGNATURE
129 );
130 cv.visitVarInsn(ALOAD, 0);
131 cv.visitFieldInsn(GETFIELD, m_joinPointClassName, CALLER_INSTANCE_FIELD_NAME, m_callerClassSignature);
132 cv.visitVarInsn(ALOAD, 0);
133 cv.visitFieldInsn(GETFIELD, m_joinPointClassName, CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature);
134 cv.visitMethodInsn(
135 INVOKESPECIAL, HANDLER_RTTI_IMPL_CLASS_NAME, INIT_METHOD_NAME, HANDLER_RTTI_IMPL_INIT_SIGNATURE
136 );
137
138 cv.visitInsn(ARETURN);
139 cv.visitMaxs(0, 0);
140 }
141
142 /***
143 * Creates the getSignature method.
144 */
145 protected void createGetSignatureMethod() {
146 CodeVisitor cv = m_cw.visitMethod(
147 ACC_PUBLIC,
148 GET_SIGNATURE_METHOD_NAME,
149 GET_SIGNATURE_METHOD_SIGNATURE,
150 null,
151 null
152 );
153 cv.visitFieldInsn(
154 GETSTATIC, m_joinPointClassName,
155 SIGNATURE_FIELD_NAME, HANDLER_SIGNATURE_IMPL_CLASS_SIGNATURE
156 );
157 cv.visitInsn(ARETURN);
158 cv.visitMaxs(0, 0);
159 }
160 }