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.joinpoint.management;
9   
10  import org.codehaus.aspectwerkz.AspectSystem;
11  import org.codehaus.aspectwerkz.ConstructorTuple;
12  import org.codehaus.aspectwerkz.CrossCuttingInfo;
13  import org.codehaus.aspectwerkz.DeploymentModel;
14  import org.codehaus.aspectwerkz.AdviceInfo;
15  import org.codehaus.aspectwerkz.MethodTuple;
16  import org.codehaus.aspectwerkz.aspect.AspectContainer;
17  import org.codehaus.aspectwerkz.aspect.management.AspectManager;
18  import org.codehaus.aspectwerkz.aspect.management.AspectRegistry;
19  import org.codehaus.aspectwerkz.aspect.management.Pointcut;
20  import org.codehaus.aspectwerkz.expression.ExpressionContext;
21  import org.codehaus.aspectwerkz.expression.PointcutType;
22  import org.codehaus.aspectwerkz.joinpoint.JoinPoint;
23  import org.codehaus.aspectwerkz.joinpoint.Rtti;
24  import org.codehaus.aspectwerkz.joinpoint.Signature;
25  import org.codehaus.aspectwerkz.joinpoint.impl.CatchClauseRttiImpl;
26  import org.codehaus.aspectwerkz.joinpoint.impl.CatchClauseSignatureImpl;
27  import org.codehaus.aspectwerkz.joinpoint.impl.ConstructorRttiImpl;
28  import org.codehaus.aspectwerkz.joinpoint.impl.ConstructorSignatureImpl;
29  import org.codehaus.aspectwerkz.joinpoint.impl.FieldRttiImpl;
30  import org.codehaus.aspectwerkz.joinpoint.impl.FieldSignatureImpl;
31  import org.codehaus.aspectwerkz.joinpoint.impl.MethodRttiImpl;
32  import org.codehaus.aspectwerkz.joinpoint.impl.MethodSignatureImpl;
33  import org.codehaus.aspectwerkz.reflect.ClassInfo;
34  import org.codehaus.aspectwerkz.reflect.ConstructorInfo;
35  import org.codehaus.aspectwerkz.reflect.FieldInfo;
36  import org.codehaus.aspectwerkz.reflect.MethodInfo;
37  import org.codehaus.aspectwerkz.reflect.impl.java.JavaClassInfo;
38  import org.codehaus.aspectwerkz.reflect.impl.java.JavaConstructorInfo;
39  import org.codehaus.aspectwerkz.reflect.impl.java.JavaFieldInfo;
40  import org.codehaus.aspectwerkz.reflect.impl.java.JavaMethodInfo;
41  import org.codehaus.aspectwerkz.transform.AsmHelper;
42  import org.codehaus.aspectwerkz.transform.AsmHelper;
43  import org.objectweb.asm.ClassWriter;
44  import org.objectweb.asm.CodeVisitor;
45  import org.objectweb.asm.Constants;
46  import org.objectweb.asm.Label;
47  import org.objectweb.asm.Type;
48  
49  import java.lang.reflect.Constructor;
50  import java.lang.reflect.Field;
51  import java.lang.reflect.InvocationTargetException;
52  import java.lang.reflect.Method;
53  import java.lang.reflect.Modifier;
54  import java.util.ArrayList;
55  import java.util.Iterator;
56  import java.util.List;
57  
58  /***
59   * Runtime (Just-In-Time/JIT) compiler. <p/>Compiles a custom JoinPoint class that invokes all advices in a specific
60   * advice chain (at a specific join point) and the target join point statically.
61   * 
62   * @author <a href="mailto:jboner@codehaus.org">Jonas Bonér </a>
63   * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur </a>
64   */
65  public class JitCompiler {
66      private static final List EMTPTY_ARRAY_LIST = new ArrayList();
67  
68      private static final String JIT_CLASS_PREFIX = "org/codehaus/aspectwerkz/joinpoint/management/___AW_JP_";
69  
70      private static final String STACKFRAME_FIELD_NAME = "m_stackFrame";
71  
72      private static final String SIGNATURE_FIELD_NAME = "m_signature";
73  
74      private static final String RTTI_FIELD_NAME = "m_rtti";
75  
76      private static final String SYSTEM_FIELD_NAME = "m_system";
77  
78      private static final String TARGET_INSTANCE_FIELD_NAME = "m_targetInstanceRef";
79  
80      private static final String TARGET_CLASS_FIELD_NAME = "m_targetClass";
81  
82      private static final String AROUND_ADVICE_FIELD_PREFIX = "m_around";
83  
84      private static final String BEFORE_ADVICE_FIELD_PREFIX = "m_before";
85  
86      private static final String AFTER_ADVICE_FIELD_PREFIX = "m_after";
87  
88      private static final String SHORT_CLASS_NAME = "java/lang/Short";
89  
90      private static final String INTEGER_CLASS_NAME = "java/lang/Integer";
91  
92      private static final String LONG_CLASS_NAME = "java/lang/Long";
93  
94      private static final String FLOAT_CLASS_NAME = "java/lang/Float";
95  
96      private static final String DOUBLE_CLASS_NAME = "java/lang/Double";
97  
98      private static final String BYTE_CLASS_NAME = "java/lang/Byte";
99  
100     private static final String BOOLEAN_CLASS_NAME = "java/lang/Boolean";
101 
102     private static final String CHARACTER_CLASS_NAME = "java/lang/Character";
103 
104     private static final String OBJECT_CLASS_SIGNATURE = "Ljava/lang/Object;";
105 
106     private static final String CLASS_CLASS_SIGNATURE = "Ljava/lang/Class;";
107 
108     private static final String JOIN_POINT_BASE_CLASS_NAME = "org/codehaus/aspectwerkz/joinpoint/management/JoinPointBase";
109 
110     private static final String SYSTEM_CLASS_SIGNATURE = "Lorg/codehaus/aspectwerkz/AspectSystem;";
111 
112     private static final String SYSTEM_CLASS_NAME = "org/codehaus/aspectwerkz/AspectSystem";
113 
114     private static final String ASPECT_MANAGER_CLASS_NAME = "org/codehaus/aspectwerkz/aspect/management/AspectManager";
115 
116     private static final String ASPECT_CONTAINER_CLASS_NAME = "org/codehaus/aspectwerkz/aspect/AspectContainer";
117 
118     private static final String THROWABLE_CLASS_NAME = "java/lang/Throwable";
119 
120     private static final String AROUND_ADVICE_METHOD_SIGNATURE = "(Lorg/codehaus/aspectwerkz/joinpoint/JoinPoint;)Ljava/lang/Object;";
121 
122     private static final String BEFORE_ADVICE_METHOD_SIGNATURE = "(Lorg/codehaus/aspectwerkz/joinpoint/JoinPoint;)V";
123 
124     private static final String AFTER_ADVICE_METHOD_SIGNATURE = "(Lorg/codehaus/aspectwerkz/joinpoint/JoinPoint;)V";
125 
126     private static final String JOIN_POINT_BASE_INIT_METHOD_SIGNATURE = "(Ljava/lang/String;ILjava/lang/Class;Ljava/util/List;Lorg/codehaus/aspectwerkz/expression/ExpressionContext;Lorg/codehaus/aspectwerkz/joinpoint/management/AroundAdviceExecutor;Lorg/codehaus/aspectwerkz/joinpoint/management/BeforeAdviceExecutor;Lorg/codehaus/aspectwerkz/joinpoint/management/AfterAdviceExecutor;)V";
127 
128     private static final String JIT_JOIN_POINT_INIT_METHOD_SIGNATURE = "(Ljava/lang/String;ILjava/lang/Class;Lorg/codehaus/aspectwerkz/joinpoint/Signature;Lorg/codehaus/aspectwerkz/joinpoint/Rtti;Ljava/util/List;Lorg/codehaus/aspectwerkz/expression/ExpressionContext;)V";
129 
130     private static final String SYSTEM_LOADER_CLASS_NAME = "org/codehaus/aspectwerkz/SystemLoader";
131 
132     private static final String INIT_METHOD_NAME = "<init>";
133 
134     private static final String GET_SYSTEM_METHOD_NAME = "getSystem";
135 
136     private static final String GET_SYSTEM_METHOD_NAME_SIGNATURE = "(Ljava/lang/Class;)Lorg/codehaus/aspectwerkz/AspectSystem;";
137 
138     private static final String GET_ASPECT_MANAGER_METHOD_NAME = "getAspectManager";
139 
140     private static final String GET_ASPECT_MANAGER_METHOD_NAME_SIGNATURE = "(Ljava/lang/String;)Lorg/codehaus/aspectwerkz/aspect/management/AspectManager;";
141 
142     private static final String GET_ASPECT_CONTAINER_METHOD_NAME = "getAspectContainer";
143 
144     private static final String GET_ASPECT_METHOD_SIGNATURE = "(I)Lorg/codehaus/aspectwerkz/aspect/AspectContainer;";
145 
146     private static final String SHORT_VALUE_METHOD_NAME = "shortValue";
147 
148     private static final String INT_VALUE_METHOD_NAME = "intValue";
149 
150     private static final String LONG_VALUE_METHOD_NAME = "longValue";
151 
152     private static final String FLOAT_VALUE_METHOD_NAME = "floatValue";
153 
154     private static final String DOUBLE_VALUE_METHOD_NAME = "doubleValue";
155 
156     private static final String BYTE_VALUE_METHOD_NAME = "byteValue";
157 
158     private static final String BOOLEAN_VALUE_METHOD_NAME = "booleanValue";
159 
160     private static final String CHAR_VALUE_METHOD_NAME = "charValue";
161 
162     private static final String CHAR_VALUE_METHOD_SIGNATURE = "()C";
163 
164     private static final String BOOLEAN_VALUE_METHOD_SIGNATURE = "()Z";
165 
166     private static final String BYTE_VALUE_METHOD_SIGNATURE = "()B";
167 
168     private static final String DOUBLE_VALUE_METHOD_SIGNATURE = "()D";
169 
170     private static final String FLOAT_VALUE_METHOD_SIGNATURE = "()F";
171 
172     private static final String LONG_VALUE_METHOD_SIGNATURE = "()J";
173 
174     private static final String INT_VALUE_METHOD_SIGNATURE = "()I";
175 
176     private static final String SHORT_VALUE_METHOD_SIGNATURE = "()S";
177 
178     private static final String SHORT_CLASS_INIT_METHOD_SIGNATURE = "(S)V";
179 
180     private static final String INTEGER_CLASS_INIT_METHOD_SIGNATURE = "(I)V";
181 
182     private static final String LONG_CLASS_INIT_METHOD_SIGNATURE = "(J)V";
183 
184     private static final String FLOAT_CLASS_INIT_METHOD_SIGNATURE = "(F)V";
185 
186     private static final String DOUBLE_CLASS_INIT_METHOD_SIGNATURE = "(D)V";
187 
188     private static final String BYTE_CLASS_INIT_METHOD_SIGNATURE = "(B)V";
189 
190     private static final String BOOLEAN_CLASS_INIT_METHOD_SIGNATURE = "(Z)V";
191 
192     private static final String CHARACTER_CLASS_INIT_METHOD_SIGNATURE = "(C)V";
193 
194     private static final String GET_PER_JVM_ASPECT_METHOD_NAME = "createPerJvmAspect";
195 
196     private static final String GET_PER_JVM_ASPECT_METHOD_SIGNATURE = "()Ljava/lang/Object;";
197 
198     private static final String GET_PER_CLASS_ASPECT_METHOD_NAME = "createPerClassAspect";
199 
200     private static final String GET_PER_CLASS_ASPECT_METHOD_SIGNATURE = "(Ljava/lang/Class;)Ljava/lang/Object;";
201 
202     private static final String GET_SIGNATURE_METHOD_NAME = "getSignature";
203 
204     private static final String GET_SIGNATURE_METHOD_SIGNATURE = "()Lorg/codehaus/aspectwerkz/joinpoint/Signature;";
205 
206     private static final String GET_RTTI_METHOD_NAME = "getRtti";
207 
208     private static final String GET_RTTI_METHOD_SIGNATURE = "()Lorg/codehaus/aspectwerkz/joinpoint/Rtti;";
209 
210     private static final String PROCEED_METHOD_NAME = "proceed";
211 
212     private static final String PROCEED_METHOD_SIGNATURE = "()Ljava/lang/Object;";
213 
214     private static final String GET_PARAMETER_VALUES_METHOD_NAME = "getParameterValues";
215 
216     private static final String GET_PARAMETER_VALUES_METHOD_SIGNATURE = "()[Ljava/lang/Object;";
217 
218     private static final String INVOKE_TARGET_METHOD_EXECUTION_METHOD_NAME = "invokeTargetMethodExecution";
219 
220     private static final String INVOKE_TARGET_METHOD_CALL_METHOD_NAME = "invokeTargetMethodCall";
221 
222     private static final String INVOKE_TARGET_METHOD_EXECUTION_METHOD_SIGNATURE = "(Lorg/codehaus/aspectwerkz/joinpoint/JoinPoint;)Ljava/lang/Object;";
223 
224     private static final String INVOKE_TARGET_METHOD_CALL_METHOD_SIGNATURE = "(Lorg/codehaus/aspectwerkz/joinpoint/JoinPoint;)Ljava/lang/Object;";
225 
226     private static final String INVOKE_TARGET_CONSTRUCTOR_EXECUTION_METHOD_NAME = "invokeTargetConstructorExecution";
227 
228     private static final String INVOKE_TARGET_CONSTRUCTOR_EXECUTION_METHOD_SIGNATURE = "(Lorg/codehaus/aspectwerkz/joinpoint/JoinPoint;)Ljava/lang/Object;";
229 
230     private static final String INVOKE_TARGET_CONSTRUCTOR_CALL_METHOD_NAME = "invokeTargetConstructorCall";
231 
232     private static final String INVOKE_TARGET_CONSTRUCTOR_CALL_METHOD_SIGNATURE = "(Lorg/codehaus/aspectwerkz/joinpoint/JoinPoint;)Ljava/lang/Object;";
233 
234     private static final String GET_TARGET_FIELD_METHOD_NAME = "getTargetField";
235 
236     private static final String GET_TARGET_FIELD_METHOD_SIGNATURE = "(Lorg/codehaus/aspectwerkz/joinpoint/JoinPoint;)Ljava/lang/Object;";
237 
238     private static final String SET_TARGET_FIELD_METHOD_NAME = "setTargetField";
239 
240     private static final String SET_TARGET_FIELD_METHOD_SIGNATURE = "(Lorg/codehaus/aspectwerkz/joinpoint/JoinPoint;)V";
241 
242     private static final String METHOD_SIGNATURE_IMPL_CLASS_NAME = "org/codehaus/aspectwerkz/joinpoint/impl/MethodSignatureImpl";
243 
244     private static final String CONSTRUCTOR_SIGNATURE_IMPL_CLASS_NAME = "org/codehaus/aspectwerkz/joinpoint/impl/ConstructorSignatureImpl";
245 
246     private static final String FIELD_SIGNATURE_IMPL_CLASS_NAME = "org/codehaus/aspectwerkz/joinpoint/impl/FieldSignatureImpl";
247 
248     private static final String METHOD_SIGNATURE_IMPL_CLASS_SIGNATURE = "Lorg/codehaus/aspectwerkz/joinpoint/impl/MethodSignatureImpl;";
249 
250     private static final String CONSTRUCTOR_SIGNATURE_IMPL_CLASS_SIGNATURE = "Lorg/codehaus/aspectwerkz/joinpoint/impl/ConstructorSignatureImpl;";
251 
252     private static final String FIELD_SIGNATURE_IMPL_CLASS_SIGNATURE = "Lorg/codehaus/aspectwerkz/joinpoint/impl/FieldSignatureImpl;";
253 
254     private static final String METHOD_RTTI_IMPL_CLASS_NAME = "org/codehaus/aspectwerkz/joinpoint/impl/MethodRttiImpl";
255 
256     private static final String CONSTRUCTOR_RTTI_IMPL_CLASS_NAME = "org/codehaus/aspectwerkz/joinpoint/impl/ConstructorRttiImpl";
257 
258     private static final String FIELD_RTTI_IMPL_CLASS_NAME = "org/codehaus/aspectwerkz/joinpoint/impl/FieldRttiImpl";
259 
260     private static final String METHOD_RTTI_IMPL_CLASS_SIGNATURE = "Lorg/codehaus/aspectwerkz/joinpoint/impl/MethodRttiImpl;";
261 
262     private static final String CONSTRUCTOR_RTTI_IMPL_CLASS_SIGNATURE = "Lorg/codehaus/aspectwerkz/joinpoint/impl/ConstructorRttiImpl;";
263 
264     private static final String FIELD_RTTI_IMPL_CLASS_SIGNATURE = "Lorg/codehaus/aspectwerkz/joinpoint/impl/FieldRttiImpl;";
265 
266     private static final String SET_RETURN_VALUE_METHOD_NAME = "setReturnValue";
267 
268     private static final String SET_RETURN_VALUE_METHOD_SIGNATURE = "(Ljava/lang/Object;)V";
269 
270     private static final String SET_NEW_INSTANCE_METHOD_NAME = "setNewInstance";
271 
272     private static final String SET_NEW_INSTANCE_METHOD_SIGNATURE = "(Ljava/lang/Object;)V";
273 
274     private static final String SET_FIELD_VALUE_METHOD_NAME = "setFieldValue";
275 
276     private static final String SET_FIELD_VALUE_METHOD_SIGNATURE = "(Ljava/lang/Object;)V";
277 
278     private static final String GET_FIELD_VALUE_METHOD_NAME = "getFieldValue";
279 
280     private static final String GET_FIELD_VALUE_METHOD_SIGNATURE = "()Ljava/lang/Object;";
281 
282     private static final String IS_IN_CFLOW_METOD_NAME = "isInCflow";
283 
284     private static final String IS_IN_CFLOW_METOD_SIGNATURE = "()Z";
285 
286     private static final String L = "L";
287 
288     private static final String I = "I";
289 
290     private static final String SEMICOLON = ";";
291 
292     private static final String WEAK_REFERENCE_CLASS_SIGNATURE = "Ljava/lang/ref/WeakReference;";
293 
294     private static final String WEAK_REFERENCE_CLASS_NAME = "java/lang/ref/WeakReference";
295 
296     private static final String WEAK_REFERENCE_GET_METHOD_NAME = "get";
297 
298     private static final String WEAK_REFERENCE_GET_METHOD_SIGNATURE = "()Ljava/lang/Object;";
299 
300     /***
301      * Private constructor to prevent instantiation.
302      */
303     private JitCompiler() {
304     }
305 
306     /***
307      * Compiles a join point class on the fly that invokes the advice chain and the target join point statically.
308      * 
309      * @param joinPointHash the join point hash
310      * @param joinPointType the join point joinPointType
311      * @param pointcutType the pointcut type
312      * @param advice a list with the advice
313      * @param declaringClass the declaring class
314      * @param targetClass the currently executing class
315      * @param system the system
316      * @param thisInstance
317      * @param targetInstance
318      * @param hotswapCount
319      * @return the JIT compiled join point
320      */
321     public static JoinPoint compileJoinPoint(
322         final int joinPointHash,
323         final int joinPointType,
324         final PointcutType pointcutType,
325         final AdviceIndexInfo[] advice,
326         final Class declaringClass,
327         final Class targetClass,
328         final AspectSystem system,
329         final Object thisInstance,
330         final Object targetInstance,
331         final int hotswapCount) {
332         try {
333             if (pointcutType.equals(PointcutType.HANDLER)) { // TODO: fix handler pointcuts
334                 return null;
335             }
336             AdviceInfo[] aroundAdvice = JoinPointManager.extractAroundAdvices(advice);
337             AdviceInfo[] beforeAdvice = JoinPointManager.extractBeforeAdvices(advice);
338             AdviceInfo[] afterAdvice = JoinPointManager.extractAfterFinallyAdvices(advice);
339             if ((aroundAdvice.length == 0) && (beforeAdvice.length == 0) && (afterAdvice.length == 0)) {
340                 return null; // no advice => bail out
341             }
342             RttiInfo rttiInfo = setRttiInfo(
343                 joinPointType,
344                 joinPointHash,
345                 declaringClass,
346                 system,
347                 targetInstance,
348                 targetInstance,
349                 targetClass);
350             StringBuffer buf = new StringBuffer();
351             buf.append(JIT_CLASS_PREFIX);
352             buf.append(pointcutType.toString());
353             buf.append('_');
354             buf.append(targetClass.getName());
355             buf.append('_');
356             buf.append(declaringClass.getName());
357             buf.append('_');
358             buf.append(new Integer(joinPointHash).toString());
359             buf.append('_');
360             buf.append(system.getDefiningClassLoader().hashCode());
361             buf.append('_');
362             buf.append(hotswapCount);
363             final String className = buf.toString().replace('.', '_').replace('-', '_');
364 
365             // use the loader that loaded the target class
366             ClassLoader loader = targetClass.getClassLoader();
367 
368             // try to load the class without generating it
369             // AW-160, AW-163
370             Class joinPointClass = AsmHelper.loadClass(loader, className);
371 
372             if (joinPointClass == null) {
373                 final ClassWriter cw = AsmHelper.newClassWriter(true);
374 
375                 cw.visit(
376                         AsmHelper.JAVA_VERSION,
377                         Constants.ACC_PUBLIC + Constants.ACC_SUPER,
378                         className,
379                         JOIN_POINT_BASE_CLASS_NAME,
380                         null, null
381                 );
382 
383                 createMemberFields(joinPointType, cw, className);
384                 if (createInitMethod(joinPointType, cw, className, aroundAdvice, beforeAdvice, afterAdvice)) {
385                     return null; // bail out, one of the advice has deployment model that is not
386                     // supported, use regular
387                     // join point instance
388                 }
389                 createGetSignatureMethod(joinPointType, cw, className);
390                 createGetRttiMethod(joinPointType, cw, className);
391                 createSetRttiMethod(joinPointType, cw, className);
392                 createProceedMethod(
393                     joinPointType,
394                     cw,
395                     className,
396                     declaringClass,
397                     joinPointHash,
398                     rttiInfo,
399                     aroundAdvice,
400                     beforeAdvice,
401                     afterAdvice);
402                 cw.visitEnd();
403 
404                 // FIXME: should be a VM option
405                  //AsmHelper.dumpClass("_dump", className, cw);
406 
407                 // load the generated class
408                 joinPointClass = AsmHelper.loadClass(loader, cw.toByteArray(), className);
409             }
410 
411             // create the generated class
412             Constructor constructor = joinPointClass.getDeclaredConstructor(new Class[] {
413                 String.class, int.class, Class.class, Signature.class, Rtti.class, List.class, ExpressionContext.class
414             });
415             return (JoinPoint) constructor.newInstance(new Object[] {
416                 "___AW_JIT_COMPILED",
417                 new Integer(joinPointType),
418                 declaringClass,
419                 rttiInfo.signature,
420                 rttiInfo.rtti,
421                 rttiInfo.cflowExpressions,
422                 rttiInfo.expressionContext
423             });
424         } catch (Throwable e) {
425             e.printStackTrace();
426             StringBuffer buf = new StringBuffer();
427             buf
428                     .append("WARNING: could not dynamically create, compile and load a JoinPoint class for join point with hash [");
429             buf.append(joinPointHash);
430             buf.append("] with target class [");
431             buf.append(targetClass);
432             buf.append("]: ");
433             if (e instanceof InvocationTargetException) {
434                 buf.append(((InvocationTargetException) e).getTargetException().toString());
435             } else {
436                 buf.append(e.toString());
437             }
438             java.lang.System.err.println(buf.toString());
439             return null; // bail out, no JIT compilation, use regular join point instance
440         }
441     }
442 
443     /***
444      * Creates some member fields needed.
445      * 
446      * @param joinPointType
447      * @param cw
448      * @param className
449      */
450     private static void createMemberFields(final int joinPointType, final ClassWriter cw, final String className) {
451         cw.visitField(Constants.ACC_PRIVATE, STACKFRAME_FIELD_NAME, I, null, null);
452         cw.visitField(Constants.ACC_PRIVATE, SYSTEM_FIELD_NAME, SYSTEM_CLASS_SIGNATURE, null, null);
453         switch (joinPointType) {
454             case JoinPointType.METHOD_EXECUTION:
455             case JoinPointType.METHOD_CALL:
456                 cw.visitField(
457                     Constants.ACC_PRIVATE,
458                     SIGNATURE_FIELD_NAME,
459                     METHOD_SIGNATURE_IMPL_CLASS_SIGNATURE,
460                     null,
461                     null);
462                 cw.visitField(Constants.ACC_PRIVATE, RTTI_FIELD_NAME, METHOD_RTTI_IMPL_CLASS_SIGNATURE, null, null);
463                 break;
464             case JoinPointType.CONSTRUCTOR_CALL:
465             case JoinPointType.CONSTRUCTOR_EXECUTION:
466                 cw.visitField(
467                     Constants.ACC_PRIVATE,
468                     SIGNATURE_FIELD_NAME,
469                     CONSTRUCTOR_SIGNATURE_IMPL_CLASS_SIGNATURE,
470                     null,
471                     null);
472                 cw
473                         .visitField(
474                             Constants.ACC_PRIVATE,
475                             RTTI_FIELD_NAME,
476                             CONSTRUCTOR_RTTI_IMPL_CLASS_SIGNATURE,
477                             null,
478                             null);
479                 break;
480             case JoinPointType.FIELD_SET:
481             case JoinPointType.FIELD_GET:
482                 cw.visitField(
483                     Constants.ACC_PRIVATE,
484                     SIGNATURE_FIELD_NAME,
485                     FIELD_SIGNATURE_IMPL_CLASS_SIGNATURE,
486                     null,
487                     null);
488                 cw.visitField(Constants.ACC_PRIVATE, RTTI_FIELD_NAME, FIELD_RTTI_IMPL_CLASS_SIGNATURE, null, null);
489                 break;
490             case JoinPointType.HANDLER:
491                 throw new UnsupportedOperationException("handler is not support yet");
492             case JoinPointType.STATIC_INITALIZATION:
493                 throw new UnsupportedOperationException("static initialization is not support yet");
494         }
495     }
496 
497     /***
498      * Creates an init method for the JIT join point.
499      * 
500      * @param joinPointType
501      * @param cw
502      * @param className
503      * @param aroundAdvices
504      * @param beforeAdvices
505      * @param afterAdvices
506      * @return true if the JIT compilation should be skipped
507      */
508     private static boolean createInitMethod(
509         final int joinPointType,
510         final ClassWriter cw,
511         final String className,
512         final AdviceInfo[] aroundAdvices,
513         final AdviceInfo[] beforeAdvices,
514         final AdviceInfo[] afterAdvices) {
515         CodeVisitor cv = cw.visitMethod(
516             Constants.ACC_PUBLIC,
517             INIT_METHOD_NAME,
518             JIT_JOIN_POINT_INIT_METHOD_SIGNATURE,
519             null,
520             null);
521         cv.visitVarInsn(Constants.ALOAD, 0);
522         cv.visitVarInsn(Constants.ALOAD, 1);
523         cv.visitVarInsn(Constants.ILOAD, 2);
524         cv.visitVarInsn(Constants.ALOAD, 3);
525         cv.visitVarInsn(Constants.ALOAD, 6);
526         cv.visitVarInsn(Constants.ALOAD, 7);
527         cv.visitInsn(Constants.ACONST_NULL);
528         cv.visitInsn(Constants.ACONST_NULL);
529         cv.visitInsn(Constants.ACONST_NULL);
530         cv.visitMethodInsn(
531             Constants.INVOKESPECIAL,
532             JOIN_POINT_BASE_CLASS_NAME,
533             INIT_METHOD_NAME,
534             JOIN_POINT_BASE_INIT_METHOD_SIGNATURE);
535 
536         // init the stack frame field
537         cv.visitVarInsn(Constants.ALOAD, 0);
538         cv.visitInsn(Constants.ICONST_M1);
539         cv.visitFieldInsn(Constants.PUTFIELD, className, STACKFRAME_FIELD_NAME, I);
540 
541         // init the signature field
542         cv.visitVarInsn(Constants.ALOAD, 0);
543         cv.visitVarInsn(Constants.ALOAD, 4);
544         switch (joinPointType) {
545             case JoinPointType.METHOD_EXECUTION:
546             case JoinPointType.METHOD_CALL:
547                 cv.visitTypeInsn(Constants.CHECKCAST, METHOD_SIGNATURE_IMPL_CLASS_NAME);
548                 cv.visitFieldInsn(
549                     Constants.PUTFIELD,
550                     className,
551                     SIGNATURE_FIELD_NAME,
552                     METHOD_SIGNATURE_IMPL_CLASS_SIGNATURE);
553                 break;
554             case JoinPointType.CONSTRUCTOR_CALL:
555             case JoinPointType.CONSTRUCTOR_EXECUTION:
556                 cv.visitTypeInsn(Constants.CHECKCAST, CONSTRUCTOR_SIGNATURE_IMPL_CLASS_NAME);
557                 cv.visitFieldInsn(
558                     Constants.PUTFIELD,
559                     className,
560                     SIGNATURE_FIELD_NAME,
561                     CONSTRUCTOR_SIGNATURE_IMPL_CLASS_SIGNATURE);
562                 break;
563             case JoinPointType.FIELD_SET:
564             case JoinPointType.FIELD_GET:
565                 cv.visitTypeInsn(Constants.CHECKCAST, FIELD_SIGNATURE_IMPL_CLASS_NAME);
566                 cv.visitFieldInsn(
567                     Constants.PUTFIELD,
568                     className,
569                     SIGNATURE_FIELD_NAME,
570                     FIELD_SIGNATURE_IMPL_CLASS_SIGNATURE);
571                 break;
572             case JoinPointType.HANDLER:
573                 throw new UnsupportedOperationException("handler is not support yet");
574             case JoinPointType.STATIC_INITALIZATION:
575                 throw new UnsupportedOperationException("static initialization is not support yet");
576         }
577 
578         // init the rtti field
579         cv.visitVarInsn(Constants.ALOAD, 0);
580         cv.visitVarInsn(Constants.ALOAD, 5);
581         switch (joinPointType) {
582             case JoinPointType.METHOD_EXECUTION:
583             case JoinPointType.METHOD_CALL:
584                 cv.visitTypeInsn(Constants.CHECKCAST, METHOD_RTTI_IMPL_CLASS_NAME);
585                 cv.visitFieldInsn(Constants.PUTFIELD, className, RTTI_FIELD_NAME, METHOD_RTTI_IMPL_CLASS_SIGNATURE);
586                 break;
587             case JoinPointType.CONSTRUCTOR_CALL:
588             case JoinPointType.CONSTRUCTOR_EXECUTION:
589                 cv.visitTypeInsn(Constants.CHECKCAST, CONSTRUCTOR_RTTI_IMPL_CLASS_NAME);
590                 cv
591                         .visitFieldInsn(
592                             Constants.PUTFIELD,
593                             className,
594                             RTTI_FIELD_NAME,
595                             CONSTRUCTOR_RTTI_IMPL_CLASS_SIGNATURE);
596                 break;
597             case JoinPointType.FIELD_SET:
598             case JoinPointType.FIELD_GET:
599                 cv.visitTypeInsn(Constants.CHECKCAST, FIELD_RTTI_IMPL_CLASS_NAME);
600                 cv.visitFieldInsn(Constants.PUTFIELD, className, RTTI_FIELD_NAME, FIELD_RTTI_IMPL_CLASS_SIGNATURE);
601                 break;
602             case JoinPointType.HANDLER:
603                 throw new UnsupportedOperationException("handler is not support yet");
604             case JoinPointType.STATIC_INITALIZATION:
605                 throw new UnsupportedOperationException("static initialization is not support yet");
606         }
607 
608         // init the system field
609         cv.visitVarInsn(Constants.ALOAD, 0);
610         cv.visitVarInsn(Constants.ALOAD, 3);
611         cv.visitMethodInsn(
612             Constants.INVOKESTATIC,
613             SYSTEM_LOADER_CLASS_NAME,
614             GET_SYSTEM_METHOD_NAME,
615             GET_SYSTEM_METHOD_NAME_SIGNATURE);
616         cv.visitFieldInsn(Constants.PUTFIELD, className, SYSTEM_FIELD_NAME, SYSTEM_CLASS_SIGNATURE);
617 
618         // init the aspect fields
619         for (int i = 0; i < aroundAdvices.length; i++) {
620             if (initAspectField(aroundAdvices[i], cw, AROUND_ADVICE_FIELD_PREFIX + i, cv, className)) {
621                 return true;
622             }
623         }
624         for (int i = 0; i < beforeAdvices.length; i++) {
625             if (initAspectField(beforeAdvices[i], cw, BEFORE_ADVICE_FIELD_PREFIX + i, cv, className)) {
626                 return true;
627             }
628         }
629         for (int i = 0; i < afterAdvices.length; i++) {
630             if (initAspectField(afterAdvices[i], cw, AFTER_ADVICE_FIELD_PREFIX + i, cv, className)) {
631                 return true;
632             }
633         }
634         cv.visitInsn(Constants.RETURN);
635         cv.visitMaxs(0, 0);
636         return false;
637     }
638 
639     /***
640      * Create and initialize the aspect field for a specific advice.
641      * 
642      * @param adviceTuple
643      * @param cw
644      * @param aspectFieldName
645      * @param cv
646      * @param className
647      */
648     private static boolean initAspectField(
649         final AdviceInfo adviceTuple,
650         final ClassWriter cw,
651         final String aspectFieldName,
652         final CodeVisitor cv,
653         final String className) {
654         final CrossCuttingInfo info = adviceTuple.getAspectManager().getAspectContainer(adviceTuple.getAspectIndex())
655                 .getCrossCuttingInfo();
656         final String aspectClassName = info.getAspectClass().getName().replace('.', '/');
657         final String aspectClassSignature = L + aspectClassName + SEMICOLON;
658 
659         // add the aspect field
660         cw.visitField(Constants.ACC_PRIVATE, aspectFieldName, aspectClassSignature, null, null);
661 
662         // handle the init in the constructor
663         cv.visitVarInsn(Constants.ALOAD, 0);
664         cv.visitVarInsn(Constants.ALOAD, 0);
665         cv.visitFieldInsn(Constants.GETFIELD, className, SYSTEM_FIELD_NAME, SYSTEM_CLASS_SIGNATURE);
666         cv.visitLdcInsn(adviceTuple.getAspectManager().getUuid());
667         cv.visitMethodInsn(
668             Constants.INVOKEVIRTUAL,
669             SYSTEM_CLASS_NAME,
670             GET_ASPECT_MANAGER_METHOD_NAME,
671             GET_ASPECT_MANAGER_METHOD_NAME_SIGNATURE);
672         cv.visitIntInsn(Constants.BIPUSH, adviceTuple.getAspectIndex());
673         cv.visitMethodInsn(
674             Constants.INVOKEVIRTUAL,
675             ASPECT_MANAGER_CLASS_NAME,
676             GET_ASPECT_CONTAINER_METHOD_NAME,
677             GET_ASPECT_METHOD_SIGNATURE);
678         switch (info.getDeploymentModel()) {
679             case DeploymentModel.PER_JVM:
680                 cv.visitMethodInsn(
681                     Constants.INVOKEINTERFACE,
682                     ASPECT_CONTAINER_CLASS_NAME,
683                     GET_PER_JVM_ASPECT_METHOD_NAME,
684                     GET_PER_JVM_ASPECT_METHOD_SIGNATURE);
685                 break;
686             case DeploymentModel.PER_CLASS:
687                 cv.visitVarInsn(Constants.ALOAD, 0);
688                 cv.visitFieldInsn(Constants.GETFIELD, className, TARGET_CLASS_FIELD_NAME, CLASS_CLASS_SIGNATURE);
689                 cv.visitMethodInsn(
690                     Constants.INVOKEINTERFACE,
691                     ASPECT_CONTAINER_CLASS_NAME,
692                     GET_PER_CLASS_ASPECT_METHOD_NAME,
693                     GET_PER_CLASS_ASPECT_METHOD_SIGNATURE);
694                 break;
695             default:
696                 return true;
697         }
698         cv.visitTypeInsn(Constants.CHECKCAST, aspectClassName);
699         cv.visitFieldInsn(Constants.PUTFIELD, className, aspectFieldName, aspectClassSignature);
700         return false;
701     }
702 
703     /***
704      * Creates a new getSignature method.
705      * 
706      * @param joinPointType
707      * @param cw
708      * @param className
709      */
710     private static void createGetSignatureMethod(final int joinPointType, final ClassWriter cw, final String className) {
711         CodeVisitor cv = cw.visitMethod(
712             Constants.ACC_PUBLIC,
713             GET_SIGNATURE_METHOD_NAME,
714             GET_SIGNATURE_METHOD_SIGNATURE,
715             null,
716             null);
717         cv.visitVarInsn(Constants.ALOAD, 0);
718         switch (joinPointType) {
719             case JoinPointType.METHOD_EXECUTION:
720             case JoinPointType.METHOD_CALL:
721                 cv.visitFieldInsn(
722                     Constants.GETFIELD,
723                     className,
724                     SIGNATURE_FIELD_NAME,
725                     METHOD_SIGNATURE_IMPL_CLASS_SIGNATURE);
726                 break;
727             case JoinPointType.CONSTRUCTOR_CALL:
728             case JoinPointType.CONSTRUCTOR_EXECUTION:
729                 cv.visitFieldInsn(
730                     Constants.GETFIELD,
731                     className,
732                     SIGNATURE_FIELD_NAME,
733                     CONSTRUCTOR_SIGNATURE_IMPL_CLASS_SIGNATURE);
734                 break;
735             case JoinPointType.FIELD_SET:
736             case JoinPointType.FIELD_GET:
737                 cv.visitFieldInsn(
738                     Constants.GETFIELD,
739                     className,
740                     SIGNATURE_FIELD_NAME,
741                     FIELD_SIGNATURE_IMPL_CLASS_SIGNATURE);
742                 break;
743             case JoinPointType.HANDLER:
744                 throw new UnsupportedOperationException("handler is not support yet");
745             case JoinPointType.STATIC_INITALIZATION:
746                 throw new UnsupportedOperationException("static initialization is not support yet");
747         }
748         cv.visitInsn(Constants.ARETURN);
749         cv.visitMaxs(0, 0);
750     }
751 
752     /***
753      * Creates a new getRtti method.
754      * 
755      * @param joinPointType
756      * @param cw
757      * @param className
758      */
759     private static void createGetRttiMethod(final int joinPointType, final ClassWriter cw, final String className) {
760         CodeVisitor cv = cw.visitMethod(
761             Constants.ACC_PUBLIC,
762             GET_RTTI_METHOD_NAME,
763             GET_RTTI_METHOD_SIGNATURE,
764             null,
765             null);
766         cv.visitVarInsn(Constants.ALOAD, 0);
767         switch (joinPointType) {
768             case JoinPointType.METHOD_EXECUTION:
769             case JoinPointType.METHOD_CALL:
770                 cv.visitFieldInsn(Constants.GETFIELD, className, RTTI_FIELD_NAME, METHOD_RTTI_IMPL_CLASS_SIGNATURE);
771                 break;
772             case JoinPointType.CONSTRUCTOR_CALL:
773             case JoinPointType.CONSTRUCTOR_EXECUTION:
774                 cv
775                         .visitFieldInsn(
776                             Constants.GETFIELD,
777                             className,
778                             RTTI_FIELD_NAME,
779                             CONSTRUCTOR_RTTI_IMPL_CLASS_SIGNATURE);
780                 break;
781             case JoinPointType.FIELD_SET:
782             case JoinPointType.FIELD_GET:
783                 cv.visitFieldInsn(Constants.GETFIELD, className, RTTI_FIELD_NAME, FIELD_RTTI_IMPL_CLASS_SIGNATURE);
784                 break;
785             case JoinPointType.HANDLER:
786                 throw new UnsupportedOperationException("handler is not support yet");
787             case JoinPointType.STATIC_INITALIZATION:
788                 throw new UnsupportedOperationException("static initialization is not support yet");
789         }
790         cv.visitInsn(Constants.ARETURN);
791         cv.visitMaxs(0, 0);
792     }
793 
794     /***
795      * Creates a new setRtti method for rtti management
796      *
797      * @param joinPointType
798      * @param cw
799      * @param className
800      */
801     private static void createSetRttiMethod(final int joinPointType, final ClassWriter cw, final String className) {
802         CodeVisitor cv = cw.visitMethod(
803             Constants.ACC_PROTECTED,
804             "setRtti",
805             "(Lorg/codehaus/aspectwerkz/joinpoint/Rtti;)V",
806             null,
807             null);
808         cv.visitVarInsn(Constants.ALOAD, 0);//this
809         cv.visitVarInsn(Constants.ALOAD, 1);//rtti arg
810         switch (joinPointType) {
811             case JoinPointType.METHOD_EXECUTION:
812             case JoinPointType.METHOD_CALL:
813                 cv.visitTypeInsn(Constants.CHECKCAST, METHOD_RTTI_IMPL_CLASS_NAME);
814                 cv.visitFieldInsn(Constants.PUTFIELD, className, RTTI_FIELD_NAME, METHOD_RTTI_IMPL_CLASS_SIGNATURE);
815                 break;
816             case JoinPointType.CONSTRUCTOR_CALL:
817             case JoinPointType.CONSTRUCTOR_EXECUTION:
818                 cv.visitTypeInsn(Constants.CHECKCAST, CONSTRUCTOR_RTTI_IMPL_CLASS_NAME);
819                 cv
820                         .visitFieldInsn(
821                             Constants.PUTFIELD,
822                             className,
823                             RTTI_FIELD_NAME,
824                             CONSTRUCTOR_RTTI_IMPL_CLASS_SIGNATURE);
825                 break;
826             case JoinPointType.FIELD_SET:
827             case JoinPointType.FIELD_GET:
828                 cv.visitTypeInsn(Constants.CHECKCAST, FIELD_RTTI_IMPL_CLASS_NAME);
829                 cv.visitFieldInsn(Constants.PUTFIELD, className, RTTI_FIELD_NAME, FIELD_RTTI_IMPL_CLASS_SIGNATURE);
830                 break;
831             case JoinPointType.HANDLER:
832                 throw new UnsupportedOperationException("handler is not support yet");
833             case JoinPointType.STATIC_INITALIZATION:
834                 throw new UnsupportedOperationException("static initialization is not support yet");
835         }
836         cv.visitInsn(Constants.RETURN);
837         cv.visitMaxs(0, 0);
838     }
839 
840     /***
841      * Create the proceed() method.
842      * 
843      * @param joinPointType
844      * @param cw
845      * @param className
846      * @param declaringClass
847      * @param joinPointHash
848      * @param signatureCflowExprStruct
849      * @param aroundAdvice
850      * @param beforeAdvice
851      * @param afterAdvice
852      */
853     private static void createProceedMethod(
854         final int joinPointType,
855         final ClassWriter cw,
856         final String className,
857         final Class declaringClass,
858         final int joinPointHash,
859         final RttiInfo signatureCflowExprStruct,
860         final AdviceInfo[] aroundAdvice,
861         final AdviceInfo[] beforeAdvice,
862         final AdviceInfo[] afterAdvice) {
863         CodeVisitor cv = cw.visitMethod(
864             Constants.ACC_PUBLIC | Constants.ACC_FINAL,
865             PROCEED_METHOD_NAME,
866             PROCEED_METHOD_SIGNATURE,
867             new String[] {
868                 THROWABLE_CLASS_NAME
869             },
870             null);
871         incrementStackFrameCounter(cv, className);
872         Labels labels = invokeAdvice(cv, className, aroundAdvice, beforeAdvice, afterAdvice, signatureCflowExprStruct, joinPointType);
873         resetStackFrameCounter(cv, className);
874         invokeJoinPoint(joinPointType, declaringClass, joinPointHash, cv, className);
875         cv.visitInsn(Constants.ARETURN);
876         cv.visitLabel(labels.handlerLabel);
877         cv.visitVarInsn(Constants.ASTORE, 2);
878         cv.visitLabel(labels.endLabel);
879         cv.visitVarInsn(Constants.ALOAD, 0);
880         cv.visitInsn(Constants.ICONST_M1);
881         cv.visitFieldInsn(Constants.PUTFIELD, className, STACKFRAME_FIELD_NAME, I);
882         cv.visitVarInsn(Constants.ALOAD, 2);
883         cv.visitInsn(Constants.ATHROW);
884 
885         // handle the final try-finally clause
886         cv.visitTryCatchBlock(labels.startLabel, labels.returnLabels[0], labels.handlerLabel, null);
887         for (int i = 1; i < labels.switchCaseLabels.length; i++) {
888             Label switchCaseLabel = labels.switchCaseLabels[i];
889             Label returnLabel = labels.returnLabels[i];
890             cv.visitTryCatchBlock(switchCaseLabel, returnLabel, labels.handlerLabel, null);
891         }
892         cv.visitTryCatchBlock(labels.handlerLabel, labels.endLabel, labels.handlerLabel, null);
893         cv.visitMaxs(0, 0);
894     }
895 
896     /***
897      * Invokes the specific join point.
898      * 
899      * @param joinPointType
900      * @param declaringClass
901      * @param joinPointHash
902      * @param cv
903      * @param className
904      */
905     private static void invokeJoinPoint(
906         final int joinPointType,
907         final Class declaringClass,
908         final int joinPointHash,
909         final CodeVisitor cv,
910         final String className) {
911         switch (joinPointType) {
912             case JoinPointType.METHOD_EXECUTION:
913                 invokeMethodExecutionJoinPoint(declaringClass, joinPointHash, cv, joinPointType, className);
914                 break;
915             case JoinPointType.METHOD_CALL:
916                 invokeMethodCallJoinPoint(declaringClass, joinPointHash, cv, joinPointType, className);
917                 break;
918             case JoinPointType.CONSTRUCTOR_CALL:
919 
920                 // TODO: BUG - should invoke the wrapper ctor to make sure the it works with
921                 // execution pc, but it does
922                 // not work
923                 //               invokeConstructorCallJoinPoint(
924                 //                        system, declaringClass, joinPointHash, joinPointType, cv, className
925                 //                );
926                 ConstructorTuple constructorTuple = AspectRegistry.getConstructorTuple(declaringClass, joinPointHash);
927                 if (constructorTuple.getOriginalConstructor().equals(constructorTuple.getWrapperConstructor())) {
928                     invokeConstructorCallJoinPoint(declaringClass, joinPointHash, joinPointType, cv, className);
929                 } else {
930                     java.lang.System.err
931                             .println("WARNING: When a constructor has both a CALL and EXECUTION join point, only the CALL will be executed. This limitation is due to a bug that has currently not been fixed yet.");
932                     invokeConstrutorExecutionJoinPoint(declaringClass, joinPointHash, joinPointType, cv, className);
933                 }
934                 break;
935             case JoinPointType.CONSTRUCTOR_EXECUTION:
936                 invokeConstrutorExecutionJoinPoint(declaringClass, joinPointHash, joinPointType, cv, className);
937                 break;
938             case JoinPointType.FIELD_SET:
939                 invokeSetFieldJoinPoint(cv, className);
940                 break;
941             case JoinPointType.FIELD_GET:
942                 invokeGetFieldJoinPoint(cv, className);
943                 break;
944             case JoinPointType.HANDLER:
945                 throw new UnsupportedOperationException("handler is not support yet");
946             case JoinPointType.STATIC_INITALIZATION:
947                 throw new UnsupportedOperationException("static initialization is not support yet");
948         }
949     }
950 
951     /***
952      * Invokes a method join point - execution context.
953      * 
954      * @param declaringClass
955      * @param joinPointHash
956      * @param cv
957      * @param joinPointType
958      * @param className
959      */
960     private static void invokeMethodExecutionJoinPoint(
961         final Class declaringClass,
962         final int joinPointHash,
963         final CodeVisitor cv,
964         final int joinPointType,
965         final String className) {
966         MethodTuple methodTuple = AspectRegistry.getMethodTuple(declaringClass, joinPointHash);
967         Method targetMethod = methodTuple.getOriginalMethod();
968         String declaringClassName = targetMethod.getDeclaringClass().getName().replace('.', '/');
969         String methodName = targetMethod.getName();
970         String methodDescriptor = Type.getMethodDescriptor(targetMethod);
971         Type[] argTypes = Type.getArgumentTypes(targetMethod);
972         if (Modifier.isPublic(targetMethod.getModifiers()) && Modifier.isPublic(declaringClass.getModifiers())) {
973             invokeMethod(
974                 targetMethod,
975                 cv,
976                 joinPointType,
977                 argTypes,
978                 className,
979                 declaringClassName,
980                 methodName,
981                 methodDescriptor);
982         } else {
983             invokeMethodExecutionReflectively(cv);
984         }
985         setReturnValue(targetMethod, cv, className);
986     }
987 
988     /***
989      * Invokes a method join point - call context.
990      * 
991      * @param declaringClass
992      * @param joinPointHash
993      * @param cv
994      * @param joinPointType
995      * @param className
996      */
997     private static void invokeMethodCallJoinPoint(
998         final Class declaringClass,
999         final int joinPointHash,
1000         final CodeVisitor cv,
1001         final int joinPointType,
1002         final String className) {
1003         MethodTuple methodTuple = AspectRegistry.getMethodTuple(declaringClass, joinPointHash);
1004         Method targetMethod = methodTuple.getWrapperMethod();
1005         String declaringClassName = targetMethod.getDeclaringClass().getName().replace('.', '/');
1006         String methodName = targetMethod.getName();
1007         String methodDescriptor = Type.getMethodDescriptor(targetMethod);
1008         Type[] argTypes = Type.getArgumentTypes(targetMethod);
1009         if (Modifier.isPublic(targetMethod.getModifiers()) && Modifier.isPublic(declaringClass.getModifiers())) {
1010             invokeMethod(
1011                 targetMethod,
1012                 cv,
1013                 joinPointType,
1014                 argTypes,
1015                 className,
1016                 declaringClassName,
1017                 methodName,
1018                 methodDescriptor);
1019         } else {
1020             invokeMethodCallReflectively(cv);
1021         }
1022         setReturnValue(targetMethod, cv, className);
1023     }
1024 
1025     /***
1026      * Invokes a constructor join point.
1027      * 
1028      * @param declaringClass
1029      * @param joinPointHash
1030      * @param joinPointType
1031      * @param cv
1032      * @param className
1033      */
1034     private static void invokeConstructorCallJoinPoint(
1035         final Class declaringClass,
1036         final int joinPointHash,
1037         final int joinPointType,
1038         final CodeVisitor cv,
1039         final String className) {
1040         ConstructorTuple constructorTuple = AspectRegistry.getConstructorTuple(declaringClass, joinPointHash);
1041         Constructor targetConstructor = constructorTuple.getWrapperConstructor();
1042         String declaringClassName = targetConstructor.getDeclaringClass().getName().replace('.', '/');
1043         String constructorDescriptor = AsmHelper.getConstructorDescriptor(targetConstructor);
1044         Signature signature = new ConstructorSignatureImpl(constructorTuple.getDeclaringClass(), constructorTuple);
1045         Type[] argTypes = AsmHelper.getArgumentTypes(targetConstructor);
1046         if (Modifier.isPublic(targetConstructor.getModifiers()) && Modifier.isPublic(declaringClass.getModifiers())) {
1047             invokeConstructorCall(joinPointType, argTypes, cv, className, declaringClassName, constructorDescriptor);
1048         } else {
1049             invokeConstructorCallReflectively(cv);
1050         }
1051         setNewInstance(cv, className);
1052     }
1053 
1054     /***
1055      * Invokes a constructor join point.
1056      * 
1057      * @param declaringClass
1058      * @param joinPointHash
1059      * @param joinPointType
1060      * @param cv
1061      * @param className
1062      */
1063     private static void invokeConstrutorExecutionJoinPoint(
1064         final Class declaringClass,
1065         final int joinPointHash,
1066         final int joinPointType,
1067         final CodeVisitor cv,
1068         final String className) {
1069         ConstructorTuple constructorTuple = AspectRegistry.getConstructorTuple(declaringClass, joinPointHash);
1070         Constructor targetConstructor = constructorTuple.getOriginalConstructor();
1071         String declaringClassName = targetConstructor.getDeclaringClass().getName().replace('.', '/');
1072         String constructorDescriptor = AsmHelper.getConstructorDescriptor(targetConstructor);
1073         Type[] argTypes = AsmHelper.getArgumentTypes(targetConstructor);
1074 
1075         // remove the last argument (the dummy JoinPointManager type)
1076         Type[] newArgTypes = new Type[argTypes.length - 1];
1077         for (int i = 0; i < newArgTypes.length; i++) {
1078             newArgTypes[i] = argTypes[i];
1079         }
1080         if (Modifier.isPublic(targetConstructor.getModifiers()) && Modifier.isPublic(declaringClass.getModifiers())) {
1081             invokeConstructorExecution(
1082                 joinPointType,
1083                 newArgTypes,
1084                 cv,
1085                 className,
1086                 declaringClassName,
1087                 constructorDescriptor);
1088         } else {
1089             invokeConstructorExecutionReflectively(cv);
1090         }
1091         setNewInstance(cv, className);
1092     }
1093 
1094     /***
1095      * Invokes set field.
1096      * 
1097      * @param cv
1098      * @param className
1099      */
1100     private static void invokeSetFieldJoinPoint(final CodeVisitor cv, final String className) {
1101         invokeTargetFieldSet(cv, className);
1102         setFieldValue(cv, className);
1103     }
1104 
1105     /***
1106      * Invokes get field.
1107      * 
1108      * @param cv
1109      * @param className
1110      */
1111     private static void invokeGetFieldJoinPoint(final CodeVisitor cv, final String className) {
1112         invokeTargetFieldGet(cv);
1113         setFieldValue(cv, className);
1114     }
1115 
1116     /***
1117      * Sets the return value.
1118      * 
1119      * @param targetMethod
1120      * @param cv
1121      * @param className
1122      */
1123     private static void setReturnValue(final Method targetMethod, final CodeVisitor cv, final String className) {
1124         if (Type.getReturnType(targetMethod).getSort() != Type.VOID) {
1125             cv.visitVarInsn(Constants.ASTORE, 1);
1126             cv.visitVarInsn(Constants.ALOAD, 0);
1127             cv.visitFieldInsn(Constants.GETFIELD, className, RTTI_FIELD_NAME, METHOD_RTTI_IMPL_CLASS_SIGNATURE);
1128             cv.visitVarInsn(Constants.ALOAD, 1);
1129             cv.visitMethodInsn(
1130                 Constants.INVOKEVIRTUAL,
1131                 METHOD_RTTI_IMPL_CLASS_NAME,
1132                 SET_RETURN_VALUE_METHOD_NAME,
1133                 SET_RETURN_VALUE_METHOD_SIGNATURE);
1134             cv.visitVarInsn(Constants.ALOAD, 1);
1135         }
1136     }
1137 
1138     /***
1139      * Sets the new instance value.
1140      * 
1141      * @param cv
1142      * @param className
1143      */
1144     private static void setNewInstance(final CodeVisitor cv, final String className) {
1145         cv.visitVarInsn(Constants.ASTORE, 1);
1146         cv.visitVarInsn(Constants.ALOAD, 0);
1147         cv.visitFieldInsn(Constants.GETFIELD, className, RTTI_FIELD_NAME, CONSTRUCTOR_RTTI_IMPL_CLASS_SIGNATURE);
1148         cv.visitVarInsn(Constants.ALOAD, 1);
1149         cv.visitMethodInsn(
1150             Constants.INVOKEVIRTUAL,
1151             CONSTRUCTOR_RTTI_IMPL_CLASS_NAME,
1152             SET_NEW_INSTANCE_METHOD_NAME,
1153             SET_NEW_INSTANCE_METHOD_SIGNATURE);
1154         cv.visitVarInsn(Constants.ALOAD, 1);
1155     }
1156 
1157     /***
1158      * Sets the field value.
1159      * 
1160      * @param cv
1161      * @param className
1162      */
1163     private static void setFieldValue(final CodeVisitor cv, final String className) {
1164         cv.visitVarInsn(Constants.ASTORE, 1);
1165         cv.visitVarInsn(Constants.ALOAD, 0);
1166         cv.visitFieldInsn(Constants.GETFIELD, className, RTTI_FIELD_NAME, FIELD_RTTI_IMPL_CLASS_SIGNATURE);
1167         cv.visitVarInsn(Constants.ALOAD, 1);
1168         cv.visitMethodInsn(
1169             Constants.INVOKEVIRTUAL,
1170             FIELD_RTTI_IMPL_CLASS_NAME,
1171             SET_FIELD_VALUE_METHOD_NAME,
1172             SET_FIELD_VALUE_METHOD_SIGNATURE);
1173         cv.visitVarInsn(Constants.ALOAD, 1);
1174     }
1175 
1176     /***
1177      * Handles invocation of a method.
1178      * 
1179      * @param targetMethod
1180      * @param cv
1181      * @param joinPointType
1182      * @param argTypes
1183      * @param className
1184      * @param declaringClassName
1185      * @param methodName
1186      * @param methodDescriptor
1187      */
1188     private static void invokeMethod(
1189         final Method targetMethod,
1190         final CodeVisitor cv,
1191         final int joinPointType,
1192         final Type[] argTypes,
1193         final String className,
1194         final String declaringClassName,
1195         final String methodName,
1196         final String methodDescriptor) {
1197         // public method => invoke statically
1198         prepareReturnValueWrapping(targetMethod, cv);
1199         prepareParameterUnwrapping(joinPointType, argTypes, cv, className);
1200         if (!Modifier.isStatic(targetMethod.getModifiers())) {
1201             cv.visitVarInsn(Constants.ALOAD, 0);
1202             cv.visitMethodInsn(Constants.INVOKESPECIAL, className, "getTarget", "()Ljava/lang/Object;");
1203             //AW-265
1204 //            cv
1205 //                    .visitFieldInsn(
1206 //                        Constants.GETFIELD,
1207 //                        className,
1208 //                        TARGET_INSTANCE_FIELD_NAME,
1209 //                        WEAK_REFERENCE_CLASS_SIGNATURE);
1210 //            cv.visitMethodInsn(
1211 //                Constants.INVOKEVIRTUAL,
1212 //                WEAK_REFERENCE_CLASS_NAME,
1213 //                WEAK_REFERENCE_GET_METHOD_NAME,
1214 //                WEAK_REFERENCE_GET_METHOD_SIGNATURE);
1215             cv.visitTypeInsn(Constants.CHECKCAST, declaringClassName);
1216         }
1217         unwrapParameters(argTypes, cv);
1218 
1219         // invoke the target method (static or member) statically
1220         if (Modifier.isStatic(targetMethod.getModifiers())) {
1221             cv.visitMethodInsn(Constants.INVOKESTATIC, declaringClassName, methodName, methodDescriptor);
1222         } else if (targetMethod.getDeclaringClass().isInterface()) {
1223             //AW-253
1224             cv.visitMethodInsn(Constants.INVOKEINTERFACE, declaringClassName, methodName, methodDescriptor);
1225         } else {
1226             cv.visitMethodInsn(Constants.INVOKEVIRTUAL, declaringClassName, methodName, methodDescriptor);
1227         }
1228         wrapReturnValue(targetMethod, cv);
1229     }
1230 
1231     /***
1232      * Handles invocation of a method reflectively - execution context.
1233      * 
1234      * @param cv
1235      */
1236     private static void invokeMethodExecutionReflectively(final CodeVisitor cv) {
1237         cv.visitVarInsn(Constants.ALOAD, 0);
1238         cv.visitMethodInsn(
1239             Constants.INVOKESTATIC,
1240             JOIN_POINT_BASE_CLASS_NAME,
1241             INVOKE_TARGET_METHOD_EXECUTION_METHOD_NAME,
1242             INVOKE_TARGET_METHOD_EXECUTION_METHOD_SIGNATURE);
1243     }
1244 
1245     /***
1246      * Handles invocation of a method reflectively - call context.
1247      * 
1248      * @param cv
1249      */
1250     private static void invokeMethodCallReflectively(final CodeVisitor cv) {
1251         cv.visitVarInsn(Constants.ALOAD, 0);
1252         cv.visitMethodInsn(
1253             Constants.INVOKESTATIC,
1254             JOIN_POINT_BASE_CLASS_NAME,
1255             INVOKE_TARGET_METHOD_CALL_METHOD_NAME,
1256             INVOKE_TARGET_METHOD_CALL_METHOD_SIGNATURE);
1257     }
1258 
1259     /***
1260      * Handles invocation of a constructor - call context.
1261      * 
1262      * @param joinPointType
1263      * @param argTypes
1264      * @param cv
1265      * @param className
1266      * @param declaringClassName
1267      * @param constructorDescriptor
1268      */
1269     private static void invokeConstructorCall(
1270         final int joinPointType,
1271         final Type[] argTypes,
1272         final CodeVisitor cv,
1273         final String className,
1274         final String declaringClassName,
1275         final String constructorDescriptor) {
1276         // public constructor => invoke statically
1277         prepareParameterUnwrapping(joinPointType, argTypes, cv, className);
1278         cv.visitTypeInsn(Constants.NEW, declaringClassName);
1279         cv.visitInsn(Constants.DUP);
1280         unwrapParameters(argTypes, cv);
1281         cv.visitMethodInsn(Constants.INVOKESPECIAL, declaringClassName, INIT_METHOD_NAME, constructorDescriptor);
1282     }
1283 
1284     /***
1285      * Handles invocation of a constructor reflectively.
1286      * 
1287      * @param cv
1288      */
1289     private static void invokeConstructorCallReflectively(final CodeVisitor cv) {
1290         // constructor is non-public -> invoke using reflection
1291         cv.visitVarInsn(Constants.ALOAD, 0);
1292         cv.visitMethodInsn(
1293             Constants.INVOKESTATIC,
1294             JOIN_POINT_BASE_CLASS_NAME,
1295             INVOKE_TARGET_CONSTRUCTOR_CALL_METHOD_NAME,
1296             INVOKE_TARGET_CONSTRUCTOR_CALL_METHOD_SIGNATURE);
1297     }
1298 
1299     /***
1300      * Handles invocation of a constructor - execution context.
1301      * 
1302      * @param joinPointType
1303      * @param newArgTypes
1304      * @param cv
1305      * @param className
1306      * @param declaringClassName
1307      * @param constructorDescriptor
1308      */
1309     private static void invokeConstructorExecution(
1310         final int joinPointType,
1311         final Type[] newArgTypes,
1312         final CodeVisitor cv,
1313         final String className,
1314         final String declaringClassName,
1315         final String constructorDescriptor) {
1316         // public constructor => invoke statically
1317         prepareParameterUnwrapping(joinPointType, newArgTypes, cv, className);
1318         cv.visitTypeInsn(Constants.NEW, declaringClassName);
1319         cv.visitInsn(Constants.DUP);
1320         unwrapParameters(newArgTypes, cv);
1321         cv.visitInsn(Constants.ACONST_NULL);
1322         cv.visitMethodInsn(Constants.INVOKESPECIAL, declaringClassName, INIT_METHOD_NAME, constructorDescriptor);
1323     }
1324 
1325     /***
1326      * Handles invocation of a constructor reflectively - execution context.
1327      * 
1328      * @param cv
1329      */
1330     private static void invokeConstructorExecutionReflectively(final CodeVisitor cv) {
1331         // constructor is non-public -> invoke using reflection
1332         cv.visitVarInsn(Constants.ALOAD, 0);
1333         cv.visitMethodInsn(
1334             Constants.INVOKESTATIC,
1335             JOIN_POINT_BASE_CLASS_NAME,
1336             INVOKE_TARGET_CONSTRUCTOR_EXECUTION_METHOD_NAME,
1337             INVOKE_TARGET_CONSTRUCTOR_EXECUTION_METHOD_SIGNATURE);
1338     }
1339 
1340     /***
1341      * Handles invocation of a field - get context.
1342      * 
1343      * @param cv
1344      */
1345     private static void invokeTargetFieldGet(final CodeVisitor cv) {
1346         cv.visitVarInsn(Constants.ALOAD, 0);
1347         cv.visitMethodInsn(
1348             Constants.INVOKESTATIC,
1349             JOIN_POINT_BASE_CLASS_NAME,
1350             GET_TARGET_FIELD_METHOD_NAME,
1351             GET_TARGET_FIELD_METHOD_SIGNATURE);
1352     }
1353 
1354     /***
1355      * Handles invocation of a field - set context.
1356      * 
1357      * @param cv
1358      */
1359     private static void invokeTargetFieldSet(final CodeVisitor cv, String className) {
1360         cv.visitVarInsn(Constants.ALOAD, 0);
1361         cv.visitMethodInsn(
1362             Constants.INVOKESTATIC,
1363             JOIN_POINT_BASE_CLASS_NAME,
1364             SET_TARGET_FIELD_METHOD_NAME,
1365             SET_TARGET_FIELD_METHOD_SIGNATURE);
1366         //cv.visitInsn(Constants.ACONST_NULL);
1367         // use rtti getPVals[0]
1368         cv.visitVarInsn(Constants.ALOAD, 0);
1369         cv.visitFieldInsn(Constants.GETFIELD, className, RTTI_FIELD_NAME, FIELD_RTTI_IMPL_CLASS_SIGNATURE);
1370         //cv.visitVarInsn(Constants.ALOAD, 1);
1371         cv.visitMethodInsn(
1372             Constants.INVOKEVIRTUAL,
1373             FIELD_RTTI_IMPL_CLASS_NAME,
1374             GET_PARAMETER_VALUES_METHOD_NAME,
1375             GET_PARAMETER_VALUES_METHOD_SIGNATURE);
1376         AsmHelper.loadIntegerConstant(cv, 0);
1377         cv.visitInsn(Constants.AALOAD);
1378 
1379     }
1380 
1381     /***
1382      * Resets the stack frame counter.
1383      * 
1384      * @param cv
1385      * @param className
1386      */
1387     private static void resetStackFrameCounter(final CodeVisitor cv, final String className) {
1388         cv.visitVarInsn(Constants.ALOAD, 0);
1389         cv.visitInsn(Constants.ICONST_M1);
1390         cv.visitFieldInsn(Constants.PUTFIELD, className, STACKFRAME_FIELD_NAME, I);
1391     }
1392 
1393     /***
1394      * Handles the incrementation of the stack frame.
1395      * 
1396      * @param cv
1397      * @param className
1398      */
1399     private static void incrementStackFrameCounter(final CodeVisitor cv, final String className) {
1400         cv.visitVarInsn(Constants.ALOAD, 0);
1401         cv.visitInsn(Constants.DUP);
1402         cv.visitFieldInsn(Constants.GETFIELD, className, STACKFRAME_FIELD_NAME, I);
1403         cv.visitInsn(Constants.ICONST_1);
1404         cv.visitInsn(Constants.IADD);
1405         cv.visitFieldInsn(Constants.PUTFIELD, className, STACKFRAME_FIELD_NAME, I);
1406     }
1407 
1408     /***
1409      * Handles the advice invocations. <p/>Creates a switch clause in which the advice chain is called recursively.
1410      * <p/>Wraps the switch clause in a try-finally statement in which the finally block resets the stack frame counter.
1411      * 
1412      * @param cv
1413      * @param className
1414      * @param aroundAdvices
1415      * @param beforeAdvices
1416      * @param afterAdvices
1417      * @param signatureCflowExprStruct
1418      * @param joinPointType
1419      * @return the labels needed to implement the last part of the try-finally clause
1420      */
1421     private static Labels invokeAdvice(
1422         final CodeVisitor cv,
1423         final String className,
1424         final AdviceInfo[] aroundAdvices,
1425         final AdviceInfo[] beforeAdvices,
1426         final AdviceInfo[] afterAdvices,
1427         final RttiInfo signatureCflowExprStruct,
1428         final int joinPointType) {
1429         // creates the labels needed for the switch and try-finally blocks
1430         int nrOfCases = aroundAdvices.length;
1431         boolean hasBeforeAfterAdvice = (beforeAdvices.length + afterAdvices.length) > 0;
1432         if (hasBeforeAfterAdvice) {
1433             nrOfCases += 1; // one more case
1434         }
1435         Label[] switchCaseLabels = new Label[nrOfCases];
1436         Label[] returnLabels = new Label[nrOfCases];
1437         int[] caseNumbers = new int[nrOfCases];
1438         for (int i = 0; i < switchCaseLabels.length; i++) {
1439             switchCaseLabels[i] = new Label();
1440             caseNumbers[i] = i;
1441         }
1442         for (int i = 0; i < returnLabels.length; i++) {
1443             returnLabels[i] = new Label();
1444         }
1445         Label tryStartLabel = new Label();
1446         Label defaultCaseLabel = new Label();
1447         Label gotoLabel = new Label();
1448         Label handlerLabel = new Label();
1449         Label endLabel = new Label();
1450         cv.visitLabel(tryStartLabel);
1451         if (signatureCflowExprStruct.cflowExpressions.size() > 0) {
1452             // add cflow check only if we have cflow expressions
1453             cv.visitVarInsn(Constants.ALOAD, 0);
1454             cv.visitMethodInsn(Constants.INVOKEVIRTUAL, className, IS_IN_CFLOW_METOD_NAME, IS_IN_CFLOW_METOD_SIGNATURE);
1455             cv.visitJumpInsn(Constants.IFEQ, defaultCaseLabel);
1456         }
1457         cv.visitVarInsn(Constants.ALOAD, 0);
1458         cv.visitFieldInsn(Constants.GETFIELD, className, STACKFRAME_FIELD_NAME, I);
1459 
1460         // create the switch table
1461         cv.visitLookupSwitchInsn(defaultCaseLabel, caseNumbers, switchCaseLabels);
1462         invokeBeforeAfterAdvice(
1463             hasBeforeAfterAdvice,
1464             beforeAdvices,
1465             afterAdvices,
1466             className,
1467             cv,
1468             switchCaseLabels,
1469             returnLabels,
1470             joinPointType);
1471         invokeAroundAdvice(hasBeforeAfterAdvice, aroundAdvices, className, cv, switchCaseLabels, returnLabels, joinPointType);
1472         cv.visitLabel(defaultCaseLabel);
1473 
1474         // put the labels in a data structure and return them
1475         Labels labelData = new Labels();
1476         labelData.switchCaseLabels = switchCaseLabels;
1477         labelData.returnLabels = returnLabels;
1478         labelData.startLabel = tryStartLabel;
1479         labelData.gotoLabel = gotoLabel;
1480         labelData.handlerLabel = handlerLabel;
1481         labelData.endLabel = endLabel;
1482         return labelData;
1483     }
1484 
1485     /***
1486      * Invokes before and after advice.
1487      * 
1488      * @param hasBeforeAfterAdvice
1489      * @param beforeAdvices
1490      * @param afterAdvices
1491      * @param className
1492      * @param cv
1493      * @param switchCaseLabels
1494      * @param returnLabels
1495      * @param joinPointType
1496      */
1497     private static void invokeBeforeAfterAdvice(
1498         boolean hasBeforeAfterAdvice,
1499         final AdviceInfo[] beforeAdvices,
1500         final AdviceInfo[] afterAdvices,
1501         final String className,
1502         final CodeVisitor cv,
1503         final Label[] switchCaseLabels,
1504         final Label[] returnLabels,
1505         final int joinPointType) {
1506         if (hasBeforeAfterAdvice) {
1507             cv.visitLabel(switchCaseLabels[0]);
1508 
1509             // add invocations to the before advices
1510             for (int i = 0; i < beforeAdvices.length; i++) {
1511                 AdviceInfo beforeAdvice = beforeAdvices[i];
1512                 AspectContainer container = beforeAdvice.getAspectManager().getAspectContainer(
1513                     beforeAdvice.getAspectIndex());
1514                 Method adviceMethod = container.getAdvice(beforeAdvice.getMethodIndex());
1515                 String aspectClassName = container.getCrossCuttingInfo().getAspectClass().getName().replace('.', '/');
1516                 String aspectFieldName = BEFORE_ADVICE_FIELD_PREFIX + i;
1517                 String aspectClassSignature = L + aspectClassName + SEMICOLON;
1518                 // handles advice with signature for args() support
1519                 //      JoinPoint as sole arg or:
1520                 //      this.getRtti().getParametersValues()[<index>], unwrap if primitive type
1521                 int[] argIndexes = beforeAdvice.getMethodToArgIndexes();
1522                 // if no arg or only JoinPoint, we consider for now that we have to push JoinPoint for old advice with JoinPoint as sole arg
1523                 if (isAdviceArgsJoinPointOnly(argIndexes)) {
1524                     cv.visitVarInsn(Constants.ALOAD, 0);
1525                     cv.visitFieldInsn(Constants.GETFIELD, className, aspectFieldName, aspectClassSignature);
1526                     cv.visitVarInsn(Constants.ALOAD, 0);
1527                 } else {
1528                     Type[] adviceArgTypes = Type.getArgumentTypes(adviceMethod);
1529                     // this.getRtti().getParameterValues() (array, store in register 2)
1530                     prepareParameterUnwrapping(joinPointType, adviceArgTypes, cv, className);
1531                     cv.visitVarInsn(Constants.ALOAD, 0);
1532                     cv.visitFieldInsn(Constants.GETFIELD, className, aspectFieldName, aspectClassSignature);
1533                     for (int j = 0; j < argIndexes.length; j++) {
1534                         int argIndex = argIndexes[j];
1535                         if (argIndex != -1) {
1536                             Type argumentType = adviceArgTypes[j];
1537                             cv.visitVarInsn(Constants.ALOAD, 2);//the param array
1538                             AsmHelper.loadIntegerConstant(cv, argIndex);//index
1539                             cv.visitInsn(Constants.AALOAD);
1540                             unwrapParameter(argumentType, cv);//unwrap
1541                         } else {
1542                             // assume JoinPoint - TODO support for static part optimization
1543                             cv.visitVarInsn(Constants.ALOAD, 0);
1544                         }
1545                     }
1546                 }
1547                 cv.visitMethodInsn(
1548                     Constants.INVOKEVIRTUAL,
1549                     aspectClassName,
1550                     adviceMethod.getName(),
1551                     Type.getMethodDescriptor(adviceMethod));
1552             }
1553 
1554             // add invocation to this.proceed
1555             cv.visitVarInsn(Constants.ALOAD, 0);
1556             cv.visitMethodInsn(Constants.INVOKEVIRTUAL, className, PROCEED_METHOD_NAME, PROCEED_METHOD_SIGNATURE);
1557             cv.visitVarInsn(Constants.ASTORE, 1);
1558 
1559             // add invocations to the after advices
1560             for (int i = afterAdvices.length - 1; i >= 0; i--) {
1561                 AdviceInfo afterAdvice = afterAdvices[i];
1562                 AspectContainer container = afterAdvice.getAspectManager().getAspectContainer(
1563                     afterAdvice.getAspectIndex());
1564                 Method adviceMethod = container.getAdvice(afterAdvice.getMethodIndex());
1565                 String aspectClassName = container.getCrossCuttingInfo().getAspectClass().getName().replace('.', '/');
1566                 String aspectFieldName = AFTER_ADVICE_FIELD_PREFIX + i;
1567                 String aspectClassSignature = L + aspectClassName + SEMICOLON;
1568                 // handles advice with signature for args() support
1569                 //      JoinPoint as sole arg or:
1570                 //      this.getRtti().getParametersValues()[<index>], unwrap if primitive type
1571                 int[] argIndexes = afterAdvice.getMethodToArgIndexes();
1572                 // if no arg or only JoinPoint, we consider for now that we have to push JoinPoint for old advice with JoinPoint as sole arg
1573                 if (isAdviceArgsJoinPointOnly(argIndexes)) {
1574                     cv.visitVarInsn(Constants.ALOAD, 0);
1575                     cv.visitFieldInsn(Constants.GETFIELD, className, aspectFieldName, aspectClassSignature);
1576                     cv.visitVarInsn(Constants.ALOAD, 0);
1577                 } else {
1578                     Type[] adviceArgTypes = Type.getArgumentTypes(adviceMethod);
1579                     // this.getRtti().getParameterValues() (array, store in register 2)
1580                     prepareParameterUnwrapping(joinPointType, adviceArgTypes, cv, className);
1581                     cv.visitVarInsn(Constants.ALOAD, 0);
1582                     cv.visitFieldInsn(Constants.GETFIELD, className, aspectFieldName, aspectClassSignature);
1583                     for (int j = 0; j < argIndexes.length; j++) {
1584                         int argIndex = argIndexes[j];
1585                         if (argIndex != -1) {
1586                             Type argumentType = adviceArgTypes[j];
1587                             cv.visitVarInsn(Constants.ALOAD, 2);//the param array
1588                             AsmHelper.loadIntegerConstant(cv, argIndex);//index
1589                             cv.visitInsn(Constants.AALOAD);
1590                             unwrapParameter(argumentType, cv);//unwrap
1591                         } else {
1592                             // assume JoinPoint - TODO support for static part optimization
1593                             cv.visitVarInsn(Constants.ALOAD, 0);
1594                         }
1595                     }
1596                 }
1597                 cv.visitMethodInsn(
1598                     Constants.INVOKEVIRTUAL,
1599                     aspectClassName,
1600                     adviceMethod.getName(),
1601                     Type.getMethodDescriptor(adviceMethod));
1602             }
1603             cv.visitLabel(returnLabels[0]);
1604             cv.visitVarInsn(Constants.ALOAD, 0);
1605             cv.visitInsn(Constants.ICONST_M1);
1606             cv.visitFieldInsn(Constants.PUTFIELD, className, STACKFRAME_FIELD_NAME, I);
1607             cv.visitVarInsn(Constants.ALOAD, 1);
1608             cv.visitInsn(Constants.ARETURN);
1609         }
1610     }
1611 
1612     /***
1613      * Invokes around advice.
1614      * 
1615      * @param hasBeforeAfterAdvice
1616      * @param aroundAdvices
1617      * @param className
1618      * @param cv
1619      * @param switchCaseLabels
1620      * @param returnLabels
1621      * @param joinPointType
1622      */
1623     private static void invokeAroundAdvice(
1624         boolean hasBeforeAfterAdvice,
1625         final AdviceInfo[] aroundAdvices,
1626         final String className,
1627         final CodeVisitor cv,
1628         final Label[] switchCaseLabels,
1629         final Label[] returnLabels,
1630         final int joinPointType) {
1631         int i = 0;
1632         int j = 0;
1633         if (hasBeforeAfterAdvice) {
1634             j = 1;
1635         }
1636         for (; i < aroundAdvices.length; i++, j++) {
1637             AdviceInfo aroundAdvice = aroundAdvices[i];
1638             AspectContainer container = aroundAdvice.getAspectManager().getAspectContainer(
1639                 aroundAdvice.getAspectIndex());
1640             Method adviceMethod = container.getAdvice(aroundAdvice.getMethodIndex());
1641             String aspectClassName = container.getCrossCuttingInfo().getAspectClass().getName().replace('.', '/');
1642             String aspectFieldName = AROUND_ADVICE_FIELD_PREFIX + i;
1643             String aspectClassSignature = L + aspectClassName + SEMICOLON;
1644             cv.visitLabel(switchCaseLabels[j]);
1645             // handles advice with signature for args() support
1646             //      JoinPoint as sole arg or:
1647             //      this.getRtti().getParametersValues()[<index>], unwrap if primitive type
1648             int[] argIndexes = aroundAdvice.getMethodToArgIndexes();
1649             // if no arg or only JoinPoint, we consider for now that we have to push JoinPoint for old advice with JoinPoint as sole arg
1650             if (isAdviceArgsJoinPointOnly(argIndexes)) {
1651                 cv.visitVarInsn(Constants.ALOAD, 0);
1652                 cv.visitFieldInsn(Constants.GETFIELD, className, aspectFieldName, aspectClassSignature);
1653                 cv.visitVarInsn(Constants.ALOAD, 0);
1654             } else {
1655                 Type[] adviceArgTypes = Type.getArgumentTypes(adviceMethod);
1656                 // this.getRtti().getParameterValues() (array, store in register 2)
1657                 prepareParameterUnwrapping(joinPointType, adviceArgTypes, cv, className);
1658                 cv.visitVarInsn(Constants.ALOAD, 0);
1659                 cv.visitFieldInsn(Constants.GETFIELD, className, aspectFieldName, aspectClassSignature);
1660                 for (int a = 0; a < argIndexes.length; a++) {
1661                     int argIndex = argIndexes[a];
1662                     if (argIndex != -1) {
1663                         Type argumentType = adviceArgTypes[a];
1664                         cv.visitVarInsn(Constants.ALOAD, 2);//the param array
1665                         AsmHelper.loadIntegerConstant(cv, argIndex);//index
1666                         cv.visitInsn(Constants.AALOAD);
1667                         unwrapParameter(argumentType, cv);//unwrap
1668                     } else {
1669                         // assume JoinPoint - TODO support for static part optimization
1670                         cv.visitVarInsn(Constants.ALOAD, 0);
1671                     }
1672                 }
1673             }
1674             cv.visitMethodInsn(
1675                 Constants.INVOKEVIRTUAL,
1676                 aspectClassName,
1677                 adviceMethod.getName(),
1678                 Type.getMethodDescriptor(adviceMethod));
1679 
1680             // try-finally management
1681             cv.visitVarInsn(Constants.ASTORE, 2);
1682             cv.visitLabel(returnLabels[j]);
1683             cv.visitVarInsn(Constants.ALOAD, 0);
1684             cv.visitInsn(Constants.ICONST_M1);
1685             cv.visitFieldInsn(Constants.PUTFIELD, className, STACKFRAME_FIELD_NAME, I);
1686             cv.visitVarInsn(Constants.ALOAD, 2);
1687             cv.visitInsn(Constants.ARETURN);
1688         }
1689     }
1690 
1691     /***
1692      * Prepares the unwrapping of the parameters.
1693      * 
1694      * @param joinPointType
1695      * @param argTypes
1696      * @param cv
1697      * @param className
1698      */
1699     private static void prepareParameterUnwrapping(
1700         final int joinPointType,
1701         final Type[] argTypes,
1702         final CodeVisitor cv,
1703         final String className) {
1704         if (argTypes.length != 0) {
1705             // handle paramerers
1706             cv.visitVarInsn(Constants.ALOAD, 0);
1707             switch (joinPointType) {
1708                 case JoinPointType.METHOD_EXECUTION:
1709                 case JoinPointType.METHOD_CALL:
1710                     cv.visitFieldInsn(Constants.GETFIELD, className, RTTI_FIELD_NAME, METHOD_RTTI_IMPL_CLASS_SIGNATURE);
1711                     cv.visitMethodInsn(
1712                         Constants.INVOKEVIRTUAL,
1713                         METHOD_RTTI_IMPL_CLASS_NAME,
1714                         GET_PARAMETER_VALUES_METHOD_NAME,
1715                         GET_PARAMETER_VALUES_METHOD_SIGNATURE);
1716                     break;
1717                 case JoinPointType.CONSTRUCTOR_EXECUTION:
1718                 case JoinPointType.CONSTRUCTOR_CALL:
1719                     cv.visitFieldInsn(
1720                         Constants.GETFIELD,
1721                         className,
1722                         RTTI_FIELD_NAME,
1723                         CONSTRUCTOR_RTTI_IMPL_CLASS_SIGNATURE);
1724                     cv.visitMethodInsn(
1725                         Constants.INVOKEVIRTUAL,
1726                         CONSTRUCTOR_RTTI_IMPL_CLASS_NAME,
1727                         GET_PARAMETER_VALUES_METHOD_NAME,
1728                         GET_PARAMETER_VALUES_METHOD_SIGNATURE);
1729                     break;
1730                 case JoinPointType.FIELD_GET:
1731                 case JoinPointType.FIELD_SET:
1732                     cv.visitFieldInsn(Constants.GETFIELD, className, RTTI_FIELD_NAME, FIELD_RTTI_IMPL_CLASS_SIGNATURE);
1733                     cv.visitMethodInsn(
1734                         Constants.INVOKEVIRTUAL,
1735                         FIELD_RTTI_IMPL_CLASS_NAME,
1736                         GET_PARAMETER_VALUES_METHOD_NAME,
1737                         GET_PARAMETER_VALUES_METHOD_SIGNATURE);
1738                     break;
1739                 case JoinPointType.HANDLER:
1740                     throw new UnsupportedOperationException("handler is not support yet");
1741                 case JoinPointType.STATIC_INITALIZATION:
1742                     throw new UnsupportedOperationException("static initialization is not support yet");
1743             }
1744             cv.visitVarInsn(Constants.ASTORE, 2);
1745         }
1746     }
1747 
1748     /***
1749      * Handle the unwrapping of the parameters.
1750      * 
1751      * @param argTypes
1752      * @param cv
1753      */
1754     private static void unwrapParameters(final Type[] argTypes, final CodeVisitor cv) {
1755         // unwrap the parameters
1756         for (int f = 0; f < argTypes.length; f++) {
1757             cv.visitVarInsn(Constants.ALOAD, 2);
1758             AsmHelper.loadIntegerConstant(cv, f);
1759             cv.visitInsn(Constants.AALOAD);
1760             Type argType = argTypes[f];
1761             unwrapParameter(argType, cv);
1762         }
1763     }
1764 
1765     /***
1766      * Unwrapp a single parameter which is already on the stack.
1767      * We skip the "null" test (to avoid NPE on longValue() etc) since
1768      * this method is used only in the RTTI parameters value extraction.
1769      * TODO: This may lead to issue if advice is setting rtti param to null.
1770      *
1771      * @param argType
1772      * @param cv
1773      */
1774     private static void unwrapParameter(final Type argType, final CodeVisitor cv) {
1775         // unwrap the parameter
1776         switch (argType.getSort()) {
1777             case Type.SHORT:
1778                 cv.visitTypeInsn(Constants.CHECKCAST, SHORT_CLASS_NAME);
1779                 cv.visitMethodInsn(
1780                     Constants.INVOKEVIRTUAL,
1781                     SHORT_CLASS_NAME,
1782                     SHORT_VALUE_METHOD_NAME,
1783                     SHORT_VALUE_METHOD_SIGNATURE);
1784                 break;
1785             case Type.INT:
1786                 cv.visitTypeInsn(Constants.CHECKCAST, INTEGER_CLASS_NAME);
1787                 cv.visitMethodInsn(
1788                     Constants.INVOKEVIRTUAL,
1789                     INTEGER_CLASS_NAME,
1790                     INT_VALUE_METHOD_NAME,
1791                     INT_VALUE_METHOD_SIGNATURE);
1792                 break;
1793             case Type.LONG:
1794                 cv.visitTypeInsn(Constants.CHECKCAST, LONG_CLASS_NAME);
1795                 cv.visitMethodInsn(
1796                     Constants.INVOKEVIRTUAL,
1797                     LONG_CLASS_NAME,
1798                     LONG_VALUE_METHOD_NAME,
1799                     LONG_VALUE_METHOD_SIGNATURE);
1800                 break;
1801             case Type.FLOAT:
1802                 cv.visitTypeInsn(Constants.CHECKCAST, FLOAT_CLASS_NAME);
1803                 cv.visitMethodInsn(
1804                     Constants.INVOKEVIRTUAL,
1805                     FLOAT_CLASS_NAME,
1806                     FLOAT_VALUE_METHOD_NAME,
1807                     FLOAT_VALUE_METHOD_SIGNATURE);
1808                 break;
1809             case Type.DOUBLE:
1810                 cv.visitTypeInsn(Constants.CHECKCAST, DOUBLE_CLASS_NAME);
1811                 cv.visitMethodInsn(
1812                     Constants.INVOKEVIRTUAL,
1813                     DOUBLE_CLASS_NAME,
1814                     DOUBLE_VALUE_METHOD_NAME,
1815                     DOUBLE_VALUE_METHOD_SIGNATURE);
1816                 break;
1817             case Type.BYTE:
1818                 cv.visitTypeInsn(Constants.CHECKCAST, BYTE_CLASS_NAME);
1819                 cv.visitMethodInsn(
1820                     Constants.INVOKEVIRTUAL,
1821                     BYTE_CLASS_NAME,
1822                     BYTE_VALUE_METHOD_NAME,
1823                     BYTE_VALUE_METHOD_SIGNATURE);
1824                 break;
1825             case Type.BOOLEAN:
1826                 cv.visitTypeInsn(Constants.CHECKCAST, BOOLEAN_CLASS_NAME);
1827                 cv.visitMethodInsn(
1828                     Constants.INVOKEVIRTUAL,
1829                     BOOLEAN_CLASS_NAME,
1830                     BOOLEAN_VALUE_METHOD_NAME,
1831                     BOOLEAN_VALUE_METHOD_SIGNATURE);
1832                 break;
1833             case Type.CHAR:
1834                 cv.visitTypeInsn(Constants.CHECKCAST, CHARACTER_CLASS_NAME);
1835                 cv.visitMethodInsn(
1836                     Constants.INVOKEVIRTUAL,
1837                     CHARACTER_CLASS_NAME,
1838                     CHAR_VALUE_METHOD_NAME,
1839                     CHAR_VALUE_METHOD_SIGNATURE);
1840                 break;
1841             case Type.OBJECT:
1842                 String objectTypeName = argType.getClassName().replace('.', '/');
1843                 cv.visitTypeInsn(Constants.CHECKCAST, objectTypeName);
1844                 break;
1845             case Type.ARRAY:
1846                 cv.visitTypeInsn(Constants.CHECKCAST, argType.getDescriptor());
1847                 break;
1848         }
1849     }
1850 
1851     /***
1852      * Prepare the return value wrapping.
1853      * 
1854      * @param targetMethod
1855      * @param cv
1856      */
1857     private static void prepareReturnValueWrapping(final Method targetMethod, final CodeVisitor cv) {
1858         switch (Type.getReturnType(targetMethod).getSort()) {
1859             case Type.SHORT:
1860                 cv.visitTypeInsn(Constants.NEW, SHORT_CLASS_NAME);
1861                 cv.visitInsn(Constants.DUP);
1862                 break;
1863             case Type.INT:
1864                 cv.visitTypeInsn(Constants.NEW, INTEGER_CLASS_NAME);
1865                 cv.visitInsn(Constants.DUP);
1866                 break;
1867             case Type.LONG:
1868                 cv.visitTypeInsn(Constants.NEW, LONG_CLASS_NAME);
1869                 cv.visitInsn(Constants.DUP);
1870                 break;
1871             case Type.FLOAT:
1872                 cv.visitTypeInsn(Constants.NEW, FLOAT_CLASS_NAME);
1873                 cv.visitInsn(Constants.DUP);
1874                 break;
1875             case Type.DOUBLE:
1876                 cv.visitTypeInsn(Constants.NEW, DOUBLE_CLASS_NAME);
1877                 cv.visitInsn(Constants.DUP);
1878                 break;
1879             case Type.BYTE:
1880                 cv.visitTypeInsn(Constants.NEW, BYTE_CLASS_NAME);
1881                 cv.visitInsn(Constants.DUP);
1882                 break;
1883             case Type.BOOLEAN:
1884                 cv.visitTypeInsn(Constants.NEW, BOOLEAN_CLASS_NAME);
1885                 cv.visitInsn(Constants.DUP);
1886                 break;
1887             case Type.CHAR:
1888                 cv.visitTypeInsn(Constants.NEW, CHARACTER_CLASS_NAME);
1889                 cv.visitInsn(Constants.DUP);
1890                 break;
1891         }
1892     }
1893 
1894     /***
1895      * Handle the return value wrapping.
1896      * 
1897      * @param targetMethod
1898      * @param cv
1899      */
1900     private static void wrapReturnValue(final Method targetMethod, final CodeVisitor cv) {
1901         switch (Type.getReturnType(targetMethod).getSort()) {
1902             case Type.VOID:
1903                 cv.visitInsn(Constants.ACONST_NULL);
1904                 break;
1905             case Type.SHORT:
1906                 cv.visitMethodInsn(
1907                     Constants.INVOKESPECIAL,
1908                     SHORT_CLASS_NAME,
1909                     INIT_METHOD_NAME,
1910                     SHORT_CLASS_INIT_METHOD_SIGNATURE);
1911                 break;
1912             case Type.INT:
1913                 cv.visitMethodInsn(
1914                     Constants.INVOKESPECIAL,
1915                     INTEGER_CLASS_NAME,
1916                     INIT_METHOD_NAME,
1917                     INTEGER_CLASS_INIT_METHOD_SIGNATURE);
1918                 break;
1919             case Type.LONG:
1920                 cv.visitMethodInsn(
1921                     Constants.INVOKESPECIAL,
1922                     LONG_CLASS_NAME,
1923                     INIT_METHOD_NAME,
1924                     LONG_CLASS_INIT_METHOD_SIGNATURE);
1925                 break;
1926             case Type.FLOAT:
1927                 cv.visitMethodInsn(
1928                     Constants.INVOKESPECIAL,
1929                     FLOAT_CLASS_NAME,
1930                     INIT_METHOD_NAME,
1931                     FLOAT_CLASS_INIT_METHOD_SIGNATURE);
1932                 break;
1933             case Type.DOUBLE:
1934                 cv.visitMethodInsn(
1935                     Constants.INVOKESPECIAL,
1936                     DOUBLE_CLASS_NAME,
1937                     INIT_METHOD_NAME,
1938                     DOUBLE_CLASS_INIT_METHOD_SIGNATURE);
1939                 break;
1940             case Type.BYTE:
1941                 cv.visitMethodInsn(
1942                     Constants.INVOKESPECIAL,
1943                     BYTE_CLASS_NAME,
1944                     INIT_METHOD_NAME,
1945                     BYTE_CLASS_INIT_METHOD_SIGNATURE);
1946                 break;
1947             case Type.BOOLEAN:
1948                 cv.visitMethodInsn(
1949                     Constants.INVOKESPECIAL,
1950                     BOOLEAN_CLASS_NAME,
1951                     INIT_METHOD_NAME,
1952                     BOOLEAN_CLASS_INIT_METHOD_SIGNATURE);
1953                 break;
1954             case Type.CHAR:
1955                 cv.visitMethodInsn(
1956                     Constants.INVOKESPECIAL,
1957                     CHARACTER_CLASS_NAME,
1958                     INIT_METHOD_NAME,
1959                     CHARACTER_CLASS_INIT_METHOD_SIGNATURE);
1960                 break;
1961         }
1962     }
1963 
1964     /***
1965      * Creates and sets the signature and a list with all the cflow expressions for the join point.
1966      * 
1967      * @param joinPointType
1968      * @param joinPointHash
1969      * @param declaringClass
1970      * @param system
1971      * @param thisInstance
1972      * @param targetInstance
1973      * @param targetClass
1974      * @return static info
1975      * @TODO HANDLER cflow management needs to be tested for all pointcuts (only verified to work for EXECUTION)
1976      */
1977     private static RttiInfo setRttiInfo(
1978         final int joinPointType,
1979         final int joinPointHash,
1980         final Class declaringClass,
1981         final AspectSystem system,
1982         final Object thisInstance,
1983         final Object targetInstance,
1984         final Class targetClass) {
1985         RttiInfo tuple = new RttiInfo();
1986         List cflowExpressionList = new ArrayList();
1987         AspectManager[] aspectManagers = system.getAspectManagers();
1988         switch (joinPointType) {
1989             case JoinPointType.METHOD_EXECUTION:
1990                 MethodTuple methodTuple = AspectRegistry.getMethodTuple(declaringClass, joinPointHash);
1991                 MethodSignatureImpl methodSignature = new MethodSignatureImpl(
1992                     methodTuple.getDeclaringClass(),
1993                     methodTuple);
1994                 tuple.signature = methodSignature;
1995                 tuple.rtti = new MethodRttiImpl(methodSignature, thisInstance, targetInstance);
1996                 MethodInfo methodInfo = JavaMethodInfo.getMethodInfo(methodTuple.getWrapperMethod());
1997                 ClassInfo withinInfo = JavaClassInfo.getClassInfo(targetClass);
1998                 ExpressionContext ctx = new ExpressionContext(PointcutType.EXECUTION, methodInfo, methodInfo);//AVAJ
1999                 for (int i = 0; i < aspectManagers.length; i++) {
2000                     for (Iterator it = aspectManagers[i].getPointcuts(ctx).iterator(); it.hasNext();) {
2001                         Pointcut pointcut = (Pointcut) it.next();
2002                         if (pointcut.getExpressionInfo().hasCflowPointcut()) {
2003                             cflowExpressionList.add(pointcut.getExpressionInfo().getCflowExpressionRuntime());
2004                         }
2005                     }
2006                 }
2007                 tuple.cflowExpressions = cflowExpressionList;
2008                 tuple.expressionContext = ctx;
2009                 break;
2010             case JoinPointType.METHOD_CALL:
2011                 methodTuple = AspectRegistry.getMethodTuple(declaringClass, joinPointHash);
2012                 methodSignature = new MethodSignatureImpl(methodTuple.getDeclaringClass(), methodTuple);
2013                 tuple.signature = methodSignature;
2014                 tuple.rtti = new MethodRttiImpl(methodSignature, thisInstance, targetInstance);
2015                 methodInfo = JavaMethodInfo.getMethodInfo(methodTuple.getWrapperMethod());
2016                 withinInfo = JavaClassInfo.getClassInfo(targetClass);
2017                 ctx = new ExpressionContext(PointcutType.CALL, methodInfo, withinInfo);
2018                 for (int i = 0; i < aspectManagers.length; i++) {
2019                     for (Iterator it = aspectManagers[i].getPointcuts(ctx).iterator(); it.hasNext();) {
2020                         Pointcut pointcut = (Pointcut) it.next();
2021                         if (pointcut.getExpressionInfo().hasCflowPointcut()) {
2022                             cflowExpressionList.add(pointcut.getExpressionInfo().getCflowExpressionRuntime());
2023                         }
2024                     }
2025                 }
2026                 tuple.cflowExpressions = cflowExpressionList;
2027                 tuple.expressionContext = ctx;
2028                 break;
2029             case JoinPointType.CONSTRUCTOR_EXECUTION:
2030                 ConstructorTuple constructorTuple = AspectRegistry.getConstructorTuple(declaringClass, joinPointHash);
2031                 ConstructorSignatureImpl constructorSignature = new ConstructorSignatureImpl(constructorTuple
2032                         .getDeclaringClass(), constructorTuple);
2033                 tuple.signature = constructorSignature;
2034                 tuple.rtti = new ConstructorRttiImpl(constructorSignature, thisInstance, targetInstance);
2035                 ConstructorInfo constructorInfo = JavaConstructorInfo.getConstructorInfo(constructorTuple
2036                         .getWrapperConstructor());
2037                 withinInfo = JavaClassInfo.getClassInfo(targetClass);
2038                 ctx = new ExpressionContext(PointcutType.EXECUTION, constructorInfo, constructorInfo);//AVAJ
2039                 for (int i = 0; i < aspectManagers.length; i++) {
2040                     for (Iterator it = aspectManagers[i].getPointcuts(ctx).iterator(); it.hasNext();) {
2041                         Pointcut pointcut = (Pointcut) it.next();
2042                         if (pointcut.getExpressionInfo().hasCflowPointcut()) {
2043                             cflowExpressionList.add(pointcut.getExpressionInfo().getCflowExpressionRuntime());
2044                         }
2045                     }
2046                 }
2047                 tuple.cflowExpressions = cflowExpressionList;
2048                 tuple.expressionContext = ctx;
2049                 break;
2050             case JoinPointType.CONSTRUCTOR_CALL:
2051                 constructorTuple = AspectRegistry.getConstructorTuple(declaringClass, joinPointHash);
2052                 constructorSignature = new ConstructorSignatureImpl(
2053                     constructorTuple.getDeclaringClass(),
2054                     constructorTuple);
2055                 tuple.signature = constructorSignature;
2056                 tuple.rtti = new ConstructorRttiImpl(constructorSignature, thisInstance, targetInstance);
2057                 constructorInfo = JavaConstructorInfo.getConstructorInfo(constructorTuple.getWrapperConstructor());
2058                 withinInfo = JavaClassInfo.getClassInfo(targetClass);
2059                 ctx = new ExpressionContext(PointcutType.CALL, constructorInfo, withinInfo);
2060                 for (int i = 0; i < aspectManagers.length; i++) {
2061                     for (Iterator it = aspectManagers[i].getPointcuts(ctx).iterator(); it.hasNext();) {
2062                         Pointcut pointcut = (Pointcut) it.next();
2063                         if (pointcut.getExpressionInfo().hasCflowPointcut()) {
2064                             cflowExpressionList.add(pointcut.getExpressionInfo().getCflowExpressionRuntime());
2065                         }
2066                     }
2067                 }
2068                 tuple.cflowExpressions = cflowExpressionList;
2069                 tuple.expressionContext = ctx;
2070                 break;
2071             case JoinPointType.FIELD_SET:
2072                 Field field = AspectRegistry.getField(declaringClass, joinPointHash);
2073                 FieldSignatureImpl fieldSignature = new FieldSignatureImpl(field.getDeclaringClass(), field);
2074                 tuple.signature = fieldSignature;
2075                 tuple.rtti = new FieldRttiImpl(fieldSignature, thisInstance, targetInstance);
2076                 FieldInfo fieldInfo = JavaFieldInfo.getFieldInfo(field);
2077                 withinInfo = JavaClassInfo.getClassInfo(targetClass);
2078                 ctx = new ExpressionContext(PointcutType.SET, fieldInfo, withinInfo);//AVAJ
2079                 for (int i = 0; i < aspectManagers.length; i++) {
2080                     for (Iterator it = aspectManagers[i].getPointcuts(ctx).iterator(); it.hasNext();) {
2081                         Pointcut pointcut = (Pointcut) it.next();
2082                         if (pointcut.getExpressionInfo().hasCflowPointcut()) {
2083                             cflowExpressionList.add(pointcut.getExpressionInfo().getCflowExpressionRuntime());
2084                         }
2085                     }
2086                 }
2087                 tuple.cflowExpressions = cflowExpressionList;
2088                 tuple.expressionContext = ctx;
2089                 break;
2090             case JoinPointType.FIELD_GET:
2091                 field = AspectRegistry.getField(declaringClass, joinPointHash);
2092                 fieldSignature = new FieldSignatureImpl(field.getDeclaringClass(), field);
2093                 tuple.signature = fieldSignature;
2094                 tuple.rtti = new FieldRttiImpl(fieldSignature, thisInstance, targetInstance);
2095                 fieldInfo = JavaFieldInfo.getFieldInfo(field);
2096                 withinInfo = JavaClassInfo.getClassInfo(targetClass);
2097                 ctx = new ExpressionContext(PointcutType.GET, fieldInfo, withinInfo);//AVAJ
2098                 for (int i = 0; i < aspectManagers.length; i++) {
2099                     for (Iterator it = aspectManagers[i].getPointcuts(ctx).iterator(); it.hasNext();) {
2100                         Pointcut pointcut = (Pointcut) it.next();
2101                         if (pointcut.getExpressionInfo().hasCflowPointcut()) {
2102                             cflowExpressionList.add(pointcut.getExpressionInfo().getCflowExpressionRuntime());
2103                         }
2104                     }
2105                 }
2106                 tuple.cflowExpressions = cflowExpressionList;
2107                 tuple.expressionContext = ctx;
2108                 break;
2109             case JoinPointType.HANDLER:
2110                 CatchClauseSignatureImpl catchClauseSignature = new CatchClauseSignatureImpl(
2111                     declaringClass,
2112                     declaringClass,
2113                     "");
2114                 tuple.signature = catchClauseSignature;
2115                 tuple.rtti = new CatchClauseRttiImpl(catchClauseSignature, thisInstance, targetInstance);
2116                 ClassInfo exceptionClassInfo = JavaClassInfo.getClassInfo(declaringClass);
2117                 withinInfo = JavaClassInfo.getClassInfo(targetClass);//AVAJ within/withincode support ?
2118                 ctx = new ExpressionContext(PointcutType.HANDLER, exceptionClassInfo, withinInfo);
2119                 for (int i = 0; i < aspectManagers.length; i++) {
2120                     for (Iterator it = aspectManagers[i].getPointcuts(ctx).iterator(); it.hasNext();) {
2121                         Pointcut pointcut = (Pointcut) it.next();
2122                         if (pointcut.getExpressionInfo().hasCflowPointcut()) {
2123                             cflowExpressionList.add(pointcut.getExpressionInfo().getCflowExpressionRuntime());
2124                         }
2125                     }
2126                 }
2127                 tuple.cflowExpressions = cflowExpressionList;
2128                 tuple.expressionContext = ctx;
2129                 break;
2130             case JoinPointType.STATIC_INITALIZATION:
2131                 throw new UnsupportedOperationException("static initialization is not support yet");
2132         }
2133         if (tuple.cflowExpressions == null) {
2134             tuple.cflowExpressions = EMTPTY_ARRAY_LIST;
2135         }
2136         return tuple;
2137     }
2138 
2139     /***
2140      * Test if the advice has JoinPoint as sole arg or is using args() support.
2141      *
2142      * @param methodToArgIndexes
2143      * @return true if simple advice without args() binding
2144      */
2145     private static boolean isAdviceArgsJoinPointOnly(int[] methodToArgIndexes) {
2146         for (int i = 0; i < methodToArgIndexes.length; i++) {
2147             int argIndex = methodToArgIndexes[i];
2148             if (argIndex >= 0) {
2149                 return false;
2150             }
2151         }
2152         return true;
2153     }
2154 
2155 
2156 
2157     /***
2158      * Struct for the labels needed in the switch and try-finally blocks in the proceed method.
2159      */
2160     static class Labels {
2161         public Label[] switchCaseLabels = null;
2162 
2163         public Label[] returnLabels = null;
2164 
2165         public Label startLabel = null;
2166 
2167         public Label gotoLabel = null;
2168 
2169         public Label handlerLabel = null;
2170 
2171         public Label endLabel = null;
2172     }
2173 
2174     /***
2175      * Struct for static info.
2176      */
2177     public static class RttiInfo {
2178         public Signature signature = null;
2179 
2180         public Rtti rtti = null;
2181 
2182         public List cflowExpressions = null;
2183 
2184         public ExpressionContext expressionContext = null;
2185     }
2186 }