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)) {
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;
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
366 ClassLoader loader = targetClass.getClassLoader();
367
368
369
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;
386
387
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
405
406
407
408 joinPointClass = AsmHelper.loadClass(loader, cw.toByteArray(), className);
409 }
410
411
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;
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
537 cv.visitVarInsn(Constants.ALOAD, 0);
538 cv.visitInsn(Constants.ICONST_M1);
539 cv.visitFieldInsn(Constants.PUTFIELD, className, STACKFRAME_FIELD_NAME, I);
540
541
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
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
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
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
660 cw.visitField(Constants.ACC_PRIVATE, aspectFieldName, aspectClassSignature, null, null);
661
662
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);
809 cv.visitVarInsn(Constants.ALOAD, 1);
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
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
921
922
923
924
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
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
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
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215 cv.visitTypeInsn(Constants.CHECKCAST, declaringClassName);
1216 }
1217 unwrapParameters(argTypes, cv);
1218
1219
1220 if (Modifier.isStatic(targetMethod.getModifiers())) {
1221 cv.visitMethodInsn(Constants.INVOKESTATIC, declaringClassName, methodName, methodDescriptor);
1222 } else if (targetMethod.getDeclaringClass().isInterface()) {
1223
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
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
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
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
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
1367
1368 cv.visitVarInsn(Constants.ALOAD, 0);
1369 cv.visitFieldInsn(Constants.GETFIELD, className, RTTI_FIELD_NAME, FIELD_RTTI_IMPL_CLASS_SIGNATURE);
1370
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
1430 int nrOfCases = aroundAdvices.length;
1431 boolean hasBeforeAfterAdvice = (beforeAdvices.length + afterAdvices.length) > 0;
1432 if (hasBeforeAfterAdvice) {
1433 nrOfCases += 1;
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
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
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
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
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
1519
1520
1521 int[] argIndexes = beforeAdvice.getMethodToArgIndexes();
1522
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
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);
1538 AsmHelper.loadIntegerConstant(cv, argIndex);
1539 cv.visitInsn(Constants.AALOAD);
1540 unwrapParameter(argumentType, cv);
1541 } else {
1542
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
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
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
1569
1570
1571 int[] argIndexes = afterAdvice.getMethodToArgIndexes();
1572
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
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);
1588 AsmHelper.loadIntegerConstant(cv, argIndex);
1589 cv.visitInsn(Constants.AALOAD);
1590 unwrapParameter(argumentType, cv);
1591 } else {
1592
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
1646
1647
1648 int[] argIndexes = aroundAdvice.getMethodToArgIndexes();
1649
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
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);
1665 AsmHelper.loadIntegerConstant(cv, argIndex);
1666 cv.visitInsn(Constants.AALOAD);
1667 unwrapParameter(argumentType, cv);
1668 } else {
1669
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
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
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
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
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);
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);
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);
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);
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);
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 }