View Javadoc

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          // create the field argument field
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          // load the exception
87          cv.visitVarInsn(ALOAD, 0);//TODO if changed perhaps load CALLEE instead that host the exception ?
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)};//TODO should callee be arg instead ? to bind it later ?
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         // new CtorRttiImpl( .. )
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 }