Source Code Cross Referenced for AbstractJoinPointCompiler.java in  » Aspect-oriented » aspectwerkz-2.0 » org » codehaus » aspectwerkz » transform » inlining » compiler » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Aspect oriented » aspectwerkz 2.0 » org.codehaus.aspectwerkz.transform.inlining.compiler 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /**************************************************************************************
0002:         * Copyright (c) Jonas BonŽr, Alexandre Vasseur. All rights reserved.                 *
0003:         * http://aspectwerkz.codehaus.org                                                    *
0004:         * ---------------------------------------------------------------------------------- *
0005:         * The software in this package is published under the terms of the LGPL license      *
0006:         * a copy of which has been included with this distribution in the license.txt file.  *
0007:         **************************************************************************************/package org.codehaus.aspectwerkz.transform.inlining.compiler;
0008:
0009:        import org.objectweb.asm.ClassWriter;
0010:        import org.objectweb.asm.CodeVisitor;
0011:        import org.objectweb.asm.Constants;
0012:        import org.objectweb.asm.Label;
0013:        import org.objectweb.asm.Type;
0014:
0015:        import org.codehaus.aspectwerkz.DeploymentModel;
0016:        import org.codehaus.aspectwerkz.cflow.CflowCompiler;
0017:        import org.codehaus.aspectwerkz.reflect.ClassInfo;
0018:        import org.codehaus.aspectwerkz.reflect.ClassInfoHelper;
0019:        import org.codehaus.aspectwerkz.reflect.MethodInfo;
0020:        import org.codehaus.aspectwerkz.reflect.ReflectionInfo;
0021:        import org.codehaus.aspectwerkz.reflect.impl.asm.AsmClassInfo;
0022:        import org.codehaus.aspectwerkz.aspect.AdviceInfo;
0023:        import org.codehaus.aspectwerkz.exception.DefinitionException;
0024:        import org.codehaus.aspectwerkz.aspect.AdviceType;
0025:        import org.codehaus.aspectwerkz.definition.AspectDefinition;
0026:        import org.codehaus.aspectwerkz.transform.Compiler;
0027:        import org.codehaus.aspectwerkz.transform.TransformationConstants;
0028:        import org.codehaus.aspectwerkz.transform.inlining.EmittedJoinPoint;
0029:        import org.codehaus.aspectwerkz.transform.inlining.AsmHelper;
0030:        import org.codehaus.aspectwerkz.transform.inlining.AdviceMethodInfo;
0031:        import org.codehaus.aspectwerkz.transform.inlining.AspectInfo;
0032:        import org.codehaus.aspectwerkz.transform.inlining.AspectModelManager;
0033:        import org.codehaus.aspectwerkz.transform.inlining.spi.AspectModel;
0034:        import org.codehaus.aspectwerkz.joinpoint.management.JoinPointType;
0035:        import org.codehaus.aspectwerkz.joinpoint.management.AdviceInfoContainer;
0036:
0037:        import java.lang.reflect.InvocationTargetException;
0038:        import java.lang.reflect.Modifier;
0039:        import java.util.Iterator;
0040:        import java.util.ArrayList;
0041:        import java.util.List;
0042:        import java.util.Set;
0043:        import java.util.HashSet;
0044:        import java.util.HashMap;
0045:        import java.util.Map;
0046:
0047:        /**
0048:         * Abstract base class for the different join point compiler implementations.
0049:         * <p/>
0050:         * Compiles/generates a class that represents a specific join point, a class which invokes the advices
0051:         * and the target join point statically.
0052:         * <p/>
0053:         * FIXME: depending on hotswap needs, remove the implements StaticJP or JP decision
0054:         * FIXME: remove isOptimizedJP and put it global
0055:         *
0056:         * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
0057:         * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur </a>
0058:         * @author <a href="mailto:the_mindstorm@evolva.ro">Alex Popescu</a>
0059:         */
0060:        public abstract class AbstractJoinPointCompiler implements  Compiler,
0061:                TransformationConstants {
0062:
0063:            protected static final String TARGET_CLASS_FIELD_NAME = "TARGET_CLASS";
0064:            protected static final String THIS_CLASS_FIELD_NAME = "THIS_CLASS";
0065:
0066:            // FIXME define these two using VM option - if dump dir specified then dump
0067:            public static final boolean DUMP_JIT_CLASSES = false;
0068:            protected static final String DUMP_DIR = "_dump";
0069:
0070:            protected final String m_callerClassName;
0071:            protected final String m_calleeClassName;
0072:            protected final String m_callerClassSignature;
0073:            protected final String m_calleeClassSignature;
0074:            protected final String m_joinPointClassName;
0075:            protected final int m_joinPointType;
0076:            protected final int m_joinPointHash;
0077:            protected final String m_callerMethodName;
0078:            protected final String m_callerMethodDesc;
0079:            protected final int m_callerMethodModifiers;
0080:            protected final String m_calleeMemberName;
0081:            protected final String m_calleeMemberDesc;
0082:            protected final int m_calleeMemberModifiers;
0083:
0084:            protected ClassWriter m_cw;
0085:            protected AspectInfo[] m_aspectInfos;
0086:            protected AspectModel[] m_aspectModels;
0087:            protected AdviceMethodInfo[] m_aroundAdviceMethodInfos;
0088:            protected AdviceMethodInfo[] m_beforeAdviceMethodInfos;
0089:            protected AdviceMethodInfo[] m_afterFinallyAdviceMethodInfos;
0090:            protected AdviceMethodInfo[] m_afterReturningAdviceMethodInfos;
0091:            protected AdviceMethodInfo[] m_afterThrowingAdviceMethodInfos;
0092:            protected final List m_customProceedMethodStructs = new ArrayList();
0093:
0094:            protected boolean m_hasAroundAdvices = false;
0095:            protected boolean m_requiresThisOrTarget = false;
0096:            protected boolean m_requiresJoinPoint = false;
0097:
0098:            protected String[] m_fieldNames;
0099:            protected Type[] m_argumentTypes;
0100:            protected Type m_returnType;
0101:            protected boolean m_isThisAdvisable = false;
0102:
0103:            /**
0104:             * Creates a new join point compiler instance.
0105:             *
0106:             * @param model the compilation model
0107:             */
0108:            public AbstractJoinPointCompiler(final CompilationInfo.Model model) {
0109:                m_joinPointClassName = model.getJoinPointClassName();
0110:
0111:                final EmittedJoinPoint emittedJoinPoint = model
0112:                        .getEmittedJoinPoint();
0113:
0114:                m_joinPointHash = emittedJoinPoint.getJoinPointHash();
0115:                m_joinPointType = emittedJoinPoint.getJoinPointType();
0116:
0117:                m_callerMethodName = emittedJoinPoint.getCallerMethodName();
0118:                m_callerMethodDesc = emittedJoinPoint.getCallerMethodDesc();
0119:                m_callerMethodModifiers = emittedJoinPoint
0120:                        .getCallerMethodModifiers();
0121:
0122:                m_calleeMemberName = emittedJoinPoint.getCalleeMemberName();
0123:                m_calleeMemberDesc = emittedJoinPoint.getCalleeMemberDesc();
0124:                m_calleeMemberModifiers = emittedJoinPoint
0125:                        .getCalleeMemberModifiers();
0126:
0127:                // NOTE: internal compiler class name format is ALWAYS using '/'
0128:                m_callerClassName = emittedJoinPoint.getCallerClassName()
0129:                        .replace('.', '/');
0130:                m_calleeClassName = emittedJoinPoint.getCalleeClassName()
0131:                        .replace('.', '/');
0132:                m_callerClassSignature = L
0133:                        + emittedJoinPoint.getCallerClassName().replace('.',
0134:                                '/') + SEMICOLON;
0135:                m_calleeClassSignature = L
0136:                        + emittedJoinPoint.getCalleeClassName().replace('.',
0137:                                '/') + SEMICOLON;
0138:
0139:                m_argumentTypes = getJoinPointArgumentTypes();
0140:                m_returnType = getJoinPointReturnType();
0141:
0142:                initialize(model);
0143:            }
0144:
0145:            /**
0146:             * Initializes the the join point compiler.
0147:             *
0148:             * @param model the compilation model
0149:             */
0150:            private synchronized void initialize(
0151:                    final CompilationInfo.Model model) {
0152:                // check if 'target' is Advisable, e.g. can handle runtime per instance deployment
0153:                checkIfThisIsAdvisable(model);
0154:
0155:                // create the aspect fields
0156:                final AdviceInfoContainer advices = model
0157:                        .getAdviceInfoContainer();
0158:
0159:                collectAdviceInfo(advices);
0160:                collectCustomProceedMethods(model, advices);
0161:
0162:                // compute the optimization we can use
0163:                m_hasAroundAdvices = m_aroundAdviceMethodInfos.length > 0;
0164:                m_requiresThisOrTarget = requiresThisOrTarget();
0165:                m_requiresJoinPoint = requiresJoinPoint();
0166:
0167:                // setup models at the end so that they can override m_requiresJoinPoint
0168:                setupReferencedAspectModels();
0169:
0170:                m_cw = AsmHelper.newClassWriter(true);
0171:            }
0172:
0173:            /**
0174:             * Collects the advice info.
0175:             *
0176:             * @param advices
0177:             */
0178:            private void collectAdviceInfo(final AdviceInfoContainer advices) {
0179:                final List aspectQualifiedNames = new ArrayList();// in fact a Set but we need indexOf
0180:                final Set aspectInfos = new HashSet();
0181:                m_beforeAdviceMethodInfos = getAdviceMethodInfos(
0182:                        aspectQualifiedNames, aspectInfos, advices
0183:                                .getBeforeAdviceInfos());
0184:                m_aroundAdviceMethodInfos = getAdviceMethodInfos(
0185:                        aspectQualifiedNames, aspectInfos, advices
0186:                                .getAroundAdviceInfos());
0187:                m_afterReturningAdviceMethodInfos = getAdviceMethodInfos(
0188:                        aspectQualifiedNames, aspectInfos, advices
0189:                                .getAfterReturningAdviceInfos());
0190:                m_afterFinallyAdviceMethodInfos = getAdviceMethodInfos(
0191:                        aspectQualifiedNames, aspectInfos, advices
0192:                                .getAfterFinallyAdviceInfos());
0193:                m_afterThrowingAdviceMethodInfos = getAdviceMethodInfos(
0194:                        aspectQualifiedNames, aspectInfos, advices
0195:                                .getAfterThrowingAdviceInfos());
0196:
0197:                m_aspectInfos = (AspectInfo[]) aspectInfos
0198:                        .toArray(new AspectInfo[aspectInfos.size()]);
0199:            }
0200:
0201:            /**
0202:             * Collects the custom proceed methods used in the advice specified.
0203:             *
0204:             * @param model
0205:             * @param advices
0206:             */
0207:            private void collectCustomProceedMethods(
0208:                    final CompilationInfo.Model model,
0209:                    final AdviceInfoContainer advices) {
0210:                ClassLoader loader = model.getThisClassInfo().getClassLoader();
0211:                final AdviceInfo[] beforeAdviceInfos = advices
0212:                        .getBeforeAdviceInfos();
0213:                for (int i = 0; i < beforeAdviceInfos.length; i++) {
0214:                    collectCustomProceedMethods(beforeAdviceInfos[i], loader);
0215:                }
0216:                final AdviceInfo[] aroundAdviceInfos = advices
0217:                        .getAroundAdviceInfos();
0218:                for (int i = 0; i < aroundAdviceInfos.length; i++) {
0219:                    collectCustomProceedMethods(aroundAdviceInfos[i], loader);
0220:                }
0221:                final AdviceInfo[] afterFinallyAdviceInfos = advices
0222:                        .getAfterFinallyAdviceInfos();
0223:                for (int i = 0; i < afterFinallyAdviceInfos.length; i++) {
0224:                    collectCustomProceedMethods(afterFinallyAdviceInfos[i],
0225:                            loader);
0226:                }
0227:                final AdviceInfo[] afterReturningAdviceInfos = advices
0228:                        .getAfterReturningAdviceInfos();
0229:                for (int i = 0; i < afterReturningAdviceInfos.length; i++) {
0230:                    collectCustomProceedMethods(afterReturningAdviceInfos[i],
0231:                            loader);
0232:                }
0233:                final AdviceInfo[] afterThrowingAdviceInfos = advices
0234:                        .getAfterThrowingAdviceInfos();
0235:                for (int i = 0; i < afterThrowingAdviceInfos.length; i++) {
0236:                    collectCustomProceedMethods(afterThrowingAdviceInfos[i],
0237:                            loader);
0238:                }
0239:            }
0240:
0241:            /**
0242:             * Collects the custom proceed methods used in the advice specified.
0243:             *
0244:             * @param adviceInfo
0245:             * @param loader
0246:             */
0247:            private void collectCustomProceedMethods(
0248:                    final AdviceInfo adviceInfo, final ClassLoader loader) {
0249:                final Type[] paramTypes = adviceInfo.getMethodParameterTypes();
0250:                if (paramTypes.length != 0) {
0251:                    Type firstParam = paramTypes[0];
0252:                    //TODO should we support JP at other positions or lock the other advice models then so that JP..
0253:                    // ..is not there or first only ?
0254:                    // check if first param is an object but not a JP or SJP
0255:                    if (firstParam.getSort() == Type.OBJECT
0256:                            && !firstParam.getClassName().equals(
0257:                                    JOIN_POINT_JAVA_CLASS_NAME)
0258:                            && !firstParam.getClassName().equals(
0259:                                    STATIC_JOIN_POINT_JAVA_CLASS_NAME)) {
0260:                        ClassInfo classInfo = AsmClassInfo.getClassInfo(
0261:                                firstParam.getClassName(), loader);
0262:                        if (ClassInfoHelper.implements Interface(classInfo,
0263:                                JOIN_POINT_JAVA_CLASS_NAME)
0264:                                || ClassInfoHelper.implements Interface(
0265:                                        classInfo,
0266:                                        STATIC_JOIN_POINT_JAVA_CLASS_NAME)) {
0267:                            // we have ourselves a custom joinpoint
0268:                            MethodInfo[] methods = classInfo.getMethods();
0269:                            for (int j = 0; j < methods.length; j++) {
0270:                                MethodInfo method = methods[j];
0271:                                if (method.getName()
0272:                                        .equals(PROCEED_METHOD_NAME)) {
0273:                                    // we inherit the binding from the advice that actually use us
0274:                                    // for now the first advice sets the rule
0275:                                    // it is up to the user to ensure consistency if the custom proceed
0276:                                    // is used more than once in different advices.
0277:                                    m_customProceedMethodStructs
0278:                                            .add(new CustomProceedMethodStruct(
0279:                                                    method,
0280:                                                    adviceInfo
0281:                                                            .getMethodToArgIndexes()));
0282:                                }
0283:                            }
0284:                        }
0285:                    }
0286:                }
0287:            }
0288:
0289:            /**
0290:             * Checks if the this class implements the Advisable interface.
0291:             *
0292:             * @param model
0293:             */
0294:            private void checkIfThisIsAdvisable(
0295:                    final CompilationInfo.Model model) {
0296:                if (!Modifier.isStatic(m_callerMethodModifiers)) {
0297:                    ClassInfo[] interfaces = model.getThisClassInfo()
0298:                            .getInterfaces();
0299:                    for (int i = 0; i < interfaces.length; i++) {
0300:                        if (interfaces[i].getName().equals(
0301:                                ADVISABLE_CLASS_JAVA_NAME)) {
0302:                            m_isThisAdvisable = true;
0303:                            break;
0304:                        }
0305:                    }
0306:                }
0307:            }
0308:
0309:            /**
0310:             * Retrives and sets the aspect models that are referenced in this compilation phase.
0311:             */
0312:            private void setupReferencedAspectModels() {
0313:                Map aspectModelMap = new HashMap();
0314:                for (int i = 0; i < m_aspectInfos.length; i++) {
0315:                    AspectDefinition aspectDef = m_aspectInfos[i]
0316:                            .getAspectDefinition();
0317:                    if (aspectDef.isAspectWerkzAspect()) {
0318:                        continue; // AW Aspect Model not managed by AspectModelManager
0319:                    }
0320:                    String type = aspectDef.getAspectModel();
0321:                    AspectModel aspectModel = AspectModelManager
0322:                            .getModelFor(type);
0323:                    aspectModelMap.put(type, aspectModel);
0324:                    if (aspectModel.requiresReflectiveInfo()) {
0325:                        m_requiresJoinPoint = true; // if at least one model requries RTTI then build it
0326:                    }
0327:                }
0328:                m_aspectModels = (AspectModel[]) aspectModelMap.values()
0329:                        .toArray(new AspectModel[aspectModelMap.size()]);
0330:            }
0331:
0332:            /**
0333:             * Returns the join point interface class name.
0334:             *
0335:             * @return
0336:             */
0337:            private String getJoinPointInterface() {
0338:                String joinPointInterface;
0339:                if (requiresProceedMethod() || m_requiresJoinPoint) {
0340:                    joinPointInterface = JOIN_POINT_CLASS_NAME;
0341:                } else {
0342:                    joinPointInterface = STATIC_JOIN_POINT_CLASS_NAME;
0343:                }
0344:                return joinPointInterface;
0345:            }
0346:
0347:            /**
0348:             * Retrieves the advice method infos.
0349:             *
0350:             * @param aspectQualifiedNames
0351:             * @param aspectInfos
0352:             * @param adviceInfos
0353:             * @return
0354:             */
0355:            protected AdviceMethodInfo[] getAdviceMethodInfos(
0356:                    final List aspectQualifiedNames, final Set aspectInfos,
0357:                    final AdviceInfo[] adviceInfos) {
0358:                List adviceMethodInfosSet = new ArrayList();
0359:                for (int i = 0; i < adviceInfos.length; i++) {
0360:                    AdviceInfo adviceInfo = adviceInfos[i];
0361:
0362:                    // if we have a perinstance deployed aspect and a static member CALLER -> skip and go on
0363:                    DeploymentModel deploymentModel = adviceInfo
0364:                            .getAdviceDefinition().getAspectDefinition()
0365:                            .getDeploymentModel();
0366:                    if (deploymentModel.equals(DeploymentModel.PER_INSTANCE)
0367:                            && Modifier.isStatic(m_callerMethodModifiers)) {
0368:                        continue;
0369:                    }
0370:
0371:                    final String aspectClassName = adviceInfo
0372:                            .getAspectClassName().replace('.', '/');
0373:
0374:                    if (!aspectQualifiedNames.contains(adviceInfo
0375:                            .getAspectQualifiedName())) {
0376:                        aspectQualifiedNames.add(adviceInfo
0377:                                .getAspectQualifiedName());
0378:                    }
0379:                    int aspectIndex = aspectQualifiedNames.indexOf(adviceInfo
0380:                            .getAspectQualifiedName());
0381:                    AdviceMethodInfo adviceMethodInfo = new AdviceMethodInfo(
0382:                            adviceInfo, ASPECT_FIELD_PREFIX + aspectIndex,
0383:                            aspectClassName, L + aspectClassName + SEMICOLON,
0384:                            m_callerClassSignature, m_calleeClassSignature,
0385:                            m_joinPointClassName, m_calleeMemberDesc);
0386:                    adviceMethodInfosSet.add(adviceMethodInfo);
0387:                    aspectInfos.add(adviceMethodInfo.getAspectInfo());
0388:                }
0389:                return (AdviceMethodInfo[]) adviceMethodInfosSet
0390:                        .toArray(new AdviceMethodInfo[adviceMethodInfosSet
0391:                                .size()]);
0392:            }
0393:
0394:            /**
0395:             * Creates join point specific fields.
0396:             */
0397:            protected abstract void createJoinPointSpecificFields();
0398:
0399:            /**
0400:             * Creates the signature for the join point.
0401:             *
0402:             * @param cv
0403:             */
0404:            protected abstract void createSignature(final CodeVisitor cv);
0405:
0406:            /**
0407:             * Optimized implementation that does not retrieve the parameters from the join point instance but is passed
0408:             * directly to the method from the input parameters in the 'invoke' method. Can only be used if no around advice
0409:             * exists.
0410:             *
0411:             * @param cv
0412:             * @param argStartIndex index on stack of first target method arg (0 or 1, depends of static target or not)
0413:             */
0414:            protected abstract void createInlinedJoinPointInvocation(
0415:                    final CodeVisitor cv, final boolean isOptimizedJoinPoint,
0416:                    final int argStartIndex, final int joinPointIndex);
0417:
0418:            /**
0419:             * Creates a call to the target join point, the parameter(s) to the join point are retrieved from the invocation
0420:             * local join point instance.
0421:             *
0422:             * @param cv
0423:             */
0424:            protected abstract void createJoinPointInvocation(
0425:                    final CodeVisitor cv);
0426:
0427:            /**
0428:             * Returns the join points return type.
0429:             *
0430:             * @return
0431:             */
0432:            protected abstract Type getJoinPointReturnType();
0433:
0434:            /**
0435:             * Returns the join points argument type(s).
0436:             *
0437:             * @return
0438:             */
0439:            protected abstract Type[] getJoinPointArgumentTypes();
0440:
0441:            /**
0442:             * Creates the getRtti method
0443:             */
0444:            protected abstract void createGetRttiMethod();
0445:
0446:            /**
0447:             * Creates the getSignature method
0448:             */
0449:            protected abstract void createGetSignatureMethod();
0450:
0451:            /**
0452:             * Compiles a join point class, one specific class for each distinct join point. The compiled join point class
0453:             * inherits the base join point class.
0454:             *
0455:             * @return the generated, compiled and loaded join point class
0456:             */
0457:            public byte[] compile() {
0458:                try {
0459:                    // TODO: INNER CLASS OR NOT?
0460:                    // flag it as a public static inner class
0461:                    // Note: if <init> changes, we will need to pass the containing instance as arg0 and add a syntetic field
0462:                    //            int innerIndex = m_joinPointClassName.lastIndexOf('$');
0463:                    //            m_cw.visitInnerClass(m_joinPointClassName,
0464:                    //                    m_joinPointClassName.substring(0, innerIndex),
0465:                    //                    m_joinPointClassName.substring(innerIndex + 1, m_joinPointClassName.length()),
0466:                    //                    ACC_PUBLIC + ACC_STATIC);
0467:
0468:                    createClassHeader();
0469:                    createMandatoryMethodInAspectModels();
0470:                    createFieldsCommonToAllJoinPoints();
0471:                    createJoinPointSpecificFields();
0472:                    createStaticInitializer();
0473:                    createClinit();
0474:                    createInit();
0475:                    createUtilityMethods();
0476:                    createCopyMethod();
0477:                    createGetSignatureMethod();
0478:                    createInvokeMethod();
0479:                    if (requiresProceedMethod()) {
0480:                        createProceedMethod();
0481:                    }
0482:                    if (m_requiresJoinPoint) {
0483:                        createGetRttiMethod();
0484:                    }
0485:                    createCustomProceedMethods();
0486:                    m_cw.visitEnd();
0487:
0488:                    if (DUMP_JIT_CLASSES) {
0489:                        AsmHelper.dumpClass(DUMP_DIR, m_joinPointClassName,
0490:                                m_cw);
0491:                    }
0492:                    return m_cw.toByteArray();
0493:
0494:                } catch (Exception e) {
0495:                    e.printStackTrace();
0496:                    StringBuffer buf = new StringBuffer();
0497:                    buf
0498:                            .append("could not compile join point instance for join point with hash [");
0499:                    buf.append(m_joinPointHash);
0500:                    buf.append("] and declaring class [");
0501:                    buf.append(m_callerClassName);
0502:                    buf.append("] due to: ");
0503:                    if (e instanceof  InvocationTargetException) {
0504:                        buf.append(((InvocationTargetException) e)
0505:                                .getTargetException().toString());
0506:                    } else {
0507:                        buf.append(e.toString());
0508:                    }
0509:                    throw new RuntimeException(buf.toString());
0510:                }
0511:            }
0512:
0513:            /**
0514:             * Creates join point specific fields.
0515:             */
0516:            protected void createFieldsCommonToAllJoinPoints() {
0517:                if (m_returnType.getSort() != Type.VOID) {
0518:                    m_cw.visitField(ACC_PRIVATE, RETURN_VALUE_FIELD_NAME,
0519:                            m_returnType.getDescriptor(), null, null);
0520:                }
0521:                m_cw.visitField(ACC_PRIVATE + ACC_STATIC,
0522:                        TARGET_CLASS_FIELD_NAME, CLASS_CLASS_SIGNATURE, null,
0523:                        null);
0524:
0525:                m_cw.visitField(ACC_PRIVATE + ACC_STATIC + ACC_FINAL,
0526:                        THIS_CLASS_FIELD_NAME, CLASS_CLASS_SIGNATURE, null,
0527:                        null);
0528:
0529:                m_cw.visitField(ACC_PRIVATE + ACC_STATIC + ACC_FINAL,
0530:                        ENCLOSING_SJP_FIELD_NAME,
0531:                        ENCLOSING_SJP_FIELD_CLASS_SIGNATURE, null, null);
0532:
0533:                m_cw.visitField(ACC_PRIVATE + ACC_STATIC, META_DATA_FIELD_NAME,
0534:                        MAP_CLASS_SIGNATURE, null, null);
0535:                m_cw.visitField(ACC_PRIVATE + ACC_STATIC,
0536:                        OPTIMIZED_JOIN_POINT_INSTANCE_FIELD_NAME, L
0537:                                + m_joinPointClassName + SEMICOLON, null, null);
0538:                m_cw.visitField(ACC_PRIVATE, CALLEE_INSTANCE_FIELD_NAME,
0539:                        m_calleeClassSignature, null, null);
0540:                m_cw.visitField(ACC_PRIVATE, CALLER_INSTANCE_FIELD_NAME,
0541:                        m_callerClassSignature, null, null);
0542:                m_cw.visitField(ACC_PRIVATE, STACK_FRAME_COUNTER_FIELD_NAME, I,
0543:                        null, null);
0544:
0545:                if (m_isThisAdvisable) {
0546:                    m_cw.visitField(ACC_PRIVATE, INTERCEPTOR_INDEX_FIELD_NAME,
0547:                            I, null, null);
0548:
0549:                    m_cw.visitField(ACC_PRIVATE,
0550:                            AROUND_INTERCEPTORS_FIELD_NAME,
0551:                            AROUND_ADVICE_ARRAY_CLASS_SIGNATURE, null, null);
0552:                    m_cw
0553:                            .visitField(ACC_PRIVATE,
0554:                                    NR_OF_AROUND_INTERCEPTORS_FIELD_NAME, I,
0555:                                    null, null);
0556:
0557:                    m_cw.visitField(ACC_PRIVATE,
0558:                            BEFORE_INTERCEPTORS_FIELD_NAME,
0559:                            BEFORE_ADVICE_ARRAY_CLASS_SIGNATURE, null, null);
0560:                    m_cw
0561:                            .visitField(ACC_PRIVATE,
0562:                                    NR_OF_BEFORE_INTERCEPTORS_FIELD_NAME, I,
0563:                                    null, null);
0564:
0565:                    m_cw.visitField(ACC_PRIVATE, AFTER_INTERCEPTORS_FIELD_NAME,
0566:                            AFTER_ADVICE_ARRAY_CLASS_SIGNATURE, null, null);
0567:                    m_cw.visitField(ACC_PRIVATE,
0568:                            NR_OF_AFTER_INTERCEPTORS_FIELD_NAME, I, null, null);
0569:
0570:                    m_cw.visitField(ACC_PRIVATE,
0571:                            AFTER_RETURNING_INTERCEPTORS_FIELD_NAME,
0572:                            AFTER_RETURNING_ADVICE_ARRAY_CLASS_SIGNATURE, null,
0573:                            null);
0574:                    m_cw.visitField(ACC_PRIVATE,
0575:                            NR_OF_AFTER_RETURNING_INTERCEPTORS_FIELD_NAME, I,
0576:                            null, null);
0577:
0578:                    m_cw.visitField(ACC_PRIVATE,
0579:                            AFTER_THROWING_INTERCEPTORS_FIELD_NAME,
0580:                            AFTER_THROWING_ADVICE_ARRAY_CLASS_SIGNATURE, null,
0581:                            null);
0582:                    m_cw.visitField(ACC_PRIVATE,
0583:                            NR_OF_AFTER_THROWING_INTERCEPTORS_FIELD_NAME, I,
0584:                            null, null);
0585:                }
0586:            }
0587:
0588:            /**
0589:             * Creates the clinit method for the join point.
0590:             */
0591:            protected void createClinit() {
0592:                CodeVisitor cv = m_cw.visitMethod(ACC_STATIC,
0593:                        CLINIT_METHOD_NAME, NO_PARAM_RETURN_VOID_SIGNATURE,
0594:                        null, null);
0595:                cv.visitMethodInsn(INVOKESTATIC, m_joinPointClassName,
0596:                        STATIC_INITIALIZATION_METHOD_NAME,
0597:                        NO_PARAM_RETURN_VOID_SIGNATURE);
0598:                cv.visitInsn(RETURN);
0599:                cv.visitMaxs(0, 0);
0600:            }
0601:
0602:            /**
0603:             * Creates the init method for the join point.
0604:             */
0605:            protected void createInit() {
0606:                CodeVisitor cv = m_cw.visitMethod(ACC_PRIVATE,
0607:                        INIT_METHOD_NAME, NO_PARAM_RETURN_VOID_SIGNATURE, null,
0608:                        null);
0609:                cv.visitVarInsn(ALOAD, 0);
0610:
0611:                boolean hasAroundClosureBaseClass = false;
0612:                AspectModel aspectModel = null;
0613:
0614:                for (int i = 0; i < m_aspectModels.length; i++) {
0615:                    aspectModel = m_aspectModels[i];
0616:                    if (aspectModel.getAroundClosureClassInfo()
0617:                            .getSuperClassName() != null) {
0618:                        hasAroundClosureBaseClass = true;
0619:                        break;
0620:                    }
0621:                }
0622:
0623:                if (hasAroundClosureBaseClass) {
0624:                    // invoke the super class constructor
0625:                    aspectModel.createInvocationOfAroundClosureSuperClass(cv);
0626:                } else {
0627:                    // invoke the constructor of java.lang.Object
0628:                    cv.visitMethodInsn(INVOKESPECIAL, OBJECT_CLASS_NAME,
0629:                            INIT_METHOD_NAME, NO_PARAM_RETURN_VOID_SIGNATURE);
0630:                }
0631:
0632:                resetStackFrameCounter(cv);
0633:
0634:                cv.visitInsn(RETURN);
0635:                cv.visitMaxs(0, 0);
0636:            }
0637:
0638:            /**
0639:             * Creates the class header for the join point.
0640:             */
0641:            private void createClassHeader() {
0642:
0643:                Set interfaces = new HashSet();
0644:                String baseClass = OBJECT_CLASS_NAME;
0645:
0646:                // get the different aspect models required interfaces
0647:                for (int i = 0; i < m_aspectModels.length; i++) {
0648:                    AspectModel aspectModel = m_aspectModels[i];
0649:                    AspectModel.AroundClosureClassInfo closureClassInfo = aspectModel
0650:                            .getAroundClosureClassInfo();
0651:                    final String super ClassName = closureClassInfo
0652:                            .getSuperClassName();
0653:                    final String[] interfaceNames = closureClassInfo
0654:                            .getInterfaceNames();
0655:                    if (super ClassName != null) {
0656:                        if (!baseClass.equals(OBJECT_CLASS_NAME)) {
0657:                            throw new RuntimeException(
0658:                                    "compiled join point can only subclass one around closure base class but more than registered aspect model requires a closure base class");
0659:                        }
0660:                        baseClass = super ClassName;
0661:                    }
0662:                    if (interfaceNames.length != 0) {
0663:                        for (int j = 0; j < interfaceNames.length; j++) {
0664:                            interfaces.add(interfaceNames[j]);
0665:                        }
0666:                    }
0667:                }
0668:
0669:                // get the custom join point interfaces
0670:                for (Iterator it = m_customProceedMethodStructs.iterator(); it
0671:                        .hasNext();) {
0672:                    MethodInfo methodInfo = ((CustomProceedMethodStruct) it
0673:                            .next()).customProceed;
0674:                    interfaces.add(methodInfo.getDeclaringType().getName()
0675:                            .replace('.', '/'));
0676:                }
0677:
0678:                int i = 1;
0679:                String[] interfaceArr = new String[interfaces.size() + 1];
0680:                interfaceArr[0] = getJoinPointInterface();
0681:                for (Iterator it = interfaces.iterator(); it.hasNext(); i++) {
0682:                    interfaceArr[i] = (String) it.next();
0683:                }
0684:
0685:                m_cw.visit(AsmHelper.JAVA_VERSION, ACC_PUBLIC + ACC_SUPER,
0686:                        m_joinPointClassName, baseClass, interfaceArr, null);
0687:            }
0688:
0689:            /**
0690:             * Creates the methods that are mandatory methods in the around closure in the different aspect models.
0691:             */
0692:            private void createMandatoryMethodInAspectModels() {
0693:                for (int i = 0; i < m_aspectModels.length; i++) {
0694:                    m_aspectModels[i].createMandatoryMethods(m_cw,
0695:                            m_joinPointClassName);
0696:                }
0697:            }
0698:
0699:            /**
0700:             * Creates the custom proceed methods.
0701:             */
0702:            private void createCustomProceedMethods() {
0703:                Set addedMethodSignatures = new HashSet();
0704:                for (Iterator it = m_customProceedMethodStructs.iterator(); it
0705:                        .hasNext();) {
0706:                    CustomProceedMethodStruct customProceedStruct = (CustomProceedMethodStruct) it
0707:                            .next();
0708:                    MethodInfo methodInfo = customProceedStruct.customProceed;
0709:                    final String desc = methodInfo.getSignature();
0710:
0711:                    if (addedMethodSignatures.contains(desc)) {
0712:                        continue;
0713:                    }
0714:                    addedMethodSignatures.add(desc);
0715:
0716:                    CodeVisitor cv = m_cw.visitMethod(ACC_PUBLIC | ACC_FINAL,
0717:                            PROCEED_METHOD_NAME, desc,
0718:                            new String[] { THROWABLE_CLASS_NAME }, null);
0719:
0720:                    // update the joinpoint instance with the given values
0721:                    // starts at 1 since first arg is the custom join point by convention
0722:                    //TODO see JoinPointManage for this custom jp is first convention
0723:                    int argStackIndex = 1;
0724:                    for (int i = 1; i < customProceedStruct.adviceToTargetArgs.length; i++) {
0725:                        int targetArg = customProceedStruct.adviceToTargetArgs[i];
0726:                        if (targetArg >= 0) {
0727:                            // regular arg
0728:                            String fieldName = m_fieldNames[targetArg];
0729:                            cv.visitVarInsn(ALOAD, 0);
0730:                            Type type = m_argumentTypes[targetArg];
0731:                            argStackIndex = AsmHelper.loadType(cv,
0732:                                    argStackIndex, type);
0733:                            cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
0734:                                    fieldName, type.getDescriptor());
0735:                        } else if (targetArg == AdviceInfo.TARGET_ARG) {
0736:                            cv.visitVarInsn(ALOAD, 0);
0737:                            argStackIndex = AsmHelper.loadType(cv,
0738:                                    argStackIndex, Type
0739:                                            .getType(m_calleeClassSignature));
0740:                            cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
0741:                                    CALLEE_INSTANCE_FIELD_NAME,
0742:                                    m_calleeClassSignature);
0743:                        } else if (targetArg == AdviceInfo.THIS_ARG) {
0744:                            cv.visitVarInsn(ALOAD, 0);
0745:                            argStackIndex = AsmHelper.loadType(cv,
0746:                                    argStackIndex, Type
0747:                                            .getType(m_callerClassSignature));
0748:                            cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
0749:                                    CALLER_INSTANCE_FIELD_NAME,
0750:                                    m_callerClassSignature);
0751:                        } else {
0752:                            ;//skip it
0753:                        }
0754:                    }
0755:
0756:                    // call proceed()
0757:                    // and handles unwrapping for returning primitive
0758:                    Type returnType = Type
0759:                            .getType(customProceedStruct.customProceed
0760:                                    .getReturnType().getSignature());
0761:                    if (AsmHelper.isPrimitive(returnType)) {
0762:                        cv.visitVarInsn(ALOAD, 0);
0763:                        cv.visitMethodInsn(INVOKESPECIAL, m_joinPointClassName,
0764:                                PROCEED_METHOD_NAME, PROCEED_METHOD_SIGNATURE);
0765:                        AsmHelper.unwrapType(cv, returnType);
0766:                    } else {
0767:                        cv.visitVarInsn(ALOAD, 0);
0768:                        cv.visitMethodInsn(INVOKESPECIAL, m_joinPointClassName,
0769:                                PROCEED_METHOD_NAME, PROCEED_METHOD_SIGNATURE);
0770:                        if (!returnType.getClassName().equals(
0771:                                OBJECT_CLASS_SIGNATURE)) {
0772:                            cv.visitTypeInsn(CHECKCAST, returnType
0773:                                    .getInternalName());
0774:                        }
0775:                    }
0776:                    AsmHelper.addReturnStatement(cv, returnType);
0777:                    cv.visitMaxs(0, 0);
0778:                }
0779:            }
0780:
0781:            /**
0782:             * Creates the static initialization method (not clinit) for the join point.
0783:             */
0784:            protected void createStaticInitializer() {
0785:                CodeVisitor cv = m_cw.visitMethod(ACC_STATIC | ACC_PUBLIC,
0786:                        STATIC_INITIALIZATION_METHOD_NAME,
0787:                        NO_PARAM_RETURN_VOID_SIGNATURE, null, null);
0788:
0789:                Label tryLabel = new Label();
0790:                cv.visitLabel(tryLabel);
0791:                cv.visitLdcInsn(m_calleeClassName.replace('/', '.'));
0792:                cv.visitMethodInsn(INVOKESTATIC, CLASS_CLASS,
0793:                        FOR_NAME_METHOD_NAME, FOR_NAME_METHOD_SIGNATURE);
0794:                cv.visitFieldInsn(PUTSTATIC, m_joinPointClassName,
0795:                        TARGET_CLASS_FIELD_NAME, CLASS_CLASS_SIGNATURE);
0796:
0797:                cv.visitLdcInsn(m_callerClassName.replace('/', '.'));
0798:                cv.visitMethodInsn(INVOKESTATIC, CLASS_CLASS,
0799:                        FOR_NAME_METHOD_NAME, FOR_NAME_METHOD_SIGNATURE);
0800:                cv.visitFieldInsn(PUTSTATIC, m_joinPointClassName,
0801:                        THIS_CLASS_FIELD_NAME, CLASS_CLASS_SIGNATURE);
0802:
0803:                Label finallyLabel = new Label();
0804:                cv.visitLabel(finallyLabel);
0805:
0806:                Label gotoFinallyLabel = new Label();
0807:                cv.visitJumpInsn(GOTO, gotoFinallyLabel);
0808:
0809:                Label catchLabel = new Label();
0810:                cv.visitLabel(catchLabel);
0811:                cv.visitVarInsn(ASTORE, 0);
0812:
0813:                cv.visitVarInsn(ALOAD, 0);
0814:                cv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Throwable",
0815:                        "printStackTrace", "()V");
0816:
0817:                cv.visitTypeInsn(NEW, RUNTIME_EXCEPTION_CLASS_NAME);
0818:                cv.visitInsn(DUP);
0819:                cv
0820:                        .visitLdcInsn("could not load target class using Class.forName() in generated join point base class "
0821:                                + m_joinPointClassName);
0822:
0823:                cv.visitMethodInsn(INVOKESPECIAL, RUNTIME_EXCEPTION_CLASS_NAME,
0824:                        INIT_METHOD_NAME,
0825:                        RUNTIME_EXCEPTION_INIT_METHOD_SIGNATURE);
0826:
0827:                cv.visitInsn(ATHROW);
0828:                cv.visitLabel(gotoFinallyLabel);
0829:
0830:                // create the enclosing static joinpoint
0831:                createEnclosingStaticJoinPoint(cv);
0832:
0833:                // create the metadata map
0834:                cv.visitTypeInsn(NEW, HASH_MAP_CLASS_NAME);
0835:                cv.visitInsn(DUP);
0836:                cv.visitMethodInsn(INVOKESPECIAL, HASH_MAP_CLASS_NAME,
0837:                        INIT_METHOD_NAME, NO_PARAM_RETURN_VOID_SIGNATURE);
0838:                cv.visitFieldInsn(PUTSTATIC, m_joinPointClassName,
0839:                        META_DATA_FIELD_NAME, MAP_CLASS_SIGNATURE);
0840:
0841:                // create the Signature instance
0842:                createSignature(cv);
0843:
0844:                // create the static JoinPoint instance
0845:                cv.visitTypeInsn(NEW, m_joinPointClassName);
0846:                cv.visitInsn(DUP);
0847:                cv.visitMethodInsn(INVOKESPECIAL, m_joinPointClassName,
0848:                        INIT_METHOD_NAME, NO_PARAM_RETURN_VOID_SIGNATURE);
0849:                cv.visitFieldInsn(PUTSTATIC, m_joinPointClassName,
0850:                        OPTIMIZED_JOIN_POINT_INSTANCE_FIELD_NAME, L
0851:                                + m_joinPointClassName + SEMICOLON);
0852:
0853:                // create and initialize the aspect fields
0854:                for (int i = 0; i < m_aspectInfos.length; i++) {
0855:                    createAndInitializeAspectField(m_aspectInfos[i], cv);
0856:                }
0857:
0858:                cv.visitInsn(RETURN);
0859:                cv.visitTryCatchBlock(tryLabel, finallyLabel, catchLabel,
0860:                        CLASS_NOT_FOUND_EXCEPTION_CLASS_NAME);
0861:                cv.visitMaxs(0, 0);
0862:            }
0863:
0864:            /**
0865:             * Add and initialize the static field for enclosing joint point static part
0866:             *
0867:             * @param cv
0868:             */
0869:            protected void createEnclosingStaticJoinPoint(CodeVisitor cv) {
0870:                cv.visitFieldInsn(GETSTATIC, m_joinPointClassName,
0871:                        THIS_CLASS_FIELD_NAME, CLASS_CLASS_SIGNATURE);
0872:                cv.visitLdcInsn(m_callerMethodName);
0873:                cv.visitLdcInsn(m_callerMethodDesc);
0874:
0875:                cv.visitMethodInsn(INVOKESTATIC, SIGNATURE_FACTORY_CLASS,
0876:                        NEW_ENCLOSING_SJP_METHOD_NAME,
0877:                        NEW_ENCLOSING_SJP_METHOD_SIGNATURE);
0878:                cv.visitFieldInsn(PUTSTATIC, m_joinPointClassName,
0879:                        ENCLOSING_SJP_FIELD_NAME,
0880:                        ENCLOSING_SJP_FIELD_CLASS_SIGNATURE);
0881:            }
0882:
0883:            /**
0884:             * Create and initialize the aspect field for a specific aspect (qualified since it depends
0885:             * on the param, deployment model, container etc).
0886:             *
0887:             * @param aspectInfo
0888:             * @param cv
0889:             */
0890:            protected boolean createAndInitializeAspectField(
0891:                    final AspectInfo aspectInfo, final CodeVisitor cv) {
0892:                if (aspectInfo.getAspectDefinition().isAspectWerkzAspect()) {
0893:                    // AW aspect
0894:                    // create the field to host the aspect and retrieve the aspect to set it to the field
0895:                    createAspectReferenceField(m_cw, aspectInfo);
0896:                    createAspectInstantiation(cv, aspectInfo,
0897:                            m_joinPointClassName);
0898:                } else {
0899:                    // non-AW aspect
0900:                    final String type = aspectInfo.getAspectDefinition()
0901:                            .getAspectModel();
0902:                    final AspectModel aspectModel = AspectModelManager
0903:                            .getModelFor(type);
0904:                    aspectModel.createAspectReferenceField(m_cw, aspectInfo,
0905:                            m_joinPointClassName);
0906:                    aspectModel.createAspectInstantiation(cv, aspectInfo,
0907:                            m_joinPointClassName);
0908:                }
0909:
0910:                return false;
0911:            }
0912:
0913:            /**
0914:             * Creates aspect reference field (static or non static field).
0915:             *
0916:             * @param cw
0917:             * @param aspectInfo
0918:             */
0919:            public static void createAspectReferenceField(final ClassWriter cw,
0920:                    final AspectInfo aspectInfo) {
0921:                String aspectClassSignature = aspectInfo
0922:                        .getAspectClassSignature();
0923:
0924:                // create a field depending on the aspect deployment model
0925:                DeploymentModel deploymentModel = aspectInfo
0926:                        .getDeploymentModel();
0927:                if (deploymentModel.equals(DeploymentModel.PER_JVM)
0928:                        || deploymentModel.equals(DeploymentModel.PER_CLASS)) {
0929:                    // add the aspect static field
0930:                    cw.visitField(ACC_PRIVATE + ACC_STATIC, aspectInfo
0931:                            .getAspectFieldName(), aspectClassSignature, null,
0932:                            null);
0933:                } else if (deploymentModel.equals(DeploymentModel.PER_INSTANCE)) {
0934:                    // add the aspect field as a non static field
0935:                    //TODO - may bee skip the aspect and all its advice is target is static, or ctor call
0936:                    //that is no instance available
0937:                    cw.visitField(ACC_PRIVATE, aspectInfo.getAspectFieldName(),
0938:                            aspectClassSignature, null, null);
0939:                } else {
0940:                    throw new UnsupportedOperationException(
0941:                            "unsupported deployment model - "
0942:                                    + aspectInfo.getAspectClassName() + " "
0943:                                    + deploymentModel);
0944:                }
0945:            }
0946:
0947:            /**
0948:             * Creates instantiation of aspects using the Aspects.aspectOf() methods which uses the AspectContainer impls.
0949:             * We are using the THIS_CLASS classloader since the aspect can be visible from that one only f.e. for get/set/call
0950:             *
0951:             * @param cv
0952:             * @param aspectInfo
0953:             * @param joinPointClassName
0954:             */
0955:            public static void createAspectInstantiation(final CodeVisitor cv,
0956:                    final AspectInfo aspectInfo, final String joinPointClassName) {
0957:                String aspectClassSignature = aspectInfo
0958:                        .getAspectClassSignature();
0959:                String aspectClassName = aspectInfo.getAspectClassName();
0960:                // retrieve the aspect set it to the field
0961:                DeploymentModel deploymentModel = aspectInfo
0962:                        .getDeploymentModel();
0963:                if (CflowCompiler.isCflowClass(aspectClassName)) {
0964:                    // handle Cflow native aspectOf
0965:                    cv.visitMethodInsn(INVOKESTATIC, aspectClassName,
0966:                            CflowCompiler.CFLOW_ASPECTOF_METHOD_NAME, "()"
0967:                                    + aspectClassSignature);
0968:                    cv.visitFieldInsn(PUTSTATIC, joinPointClassName, aspectInfo
0969:                            .getAspectFieldName(), aspectClassSignature);
0970:                } else if (deploymentModel.equals(DeploymentModel.PER_JVM)) {
0971:                    // AW-355, AW-415 we need a ClassLoader here
0972:                    cv.visitFieldInsn(GETSTATIC, joinPointClassName,
0973:                            THIS_CLASS_FIELD_NAME, CLASS_CLASS_SIGNATURE);
0974:                    cv.visitMethodInsn(INVOKEVIRTUAL, CLASS_CLASS,
0975:                            GETCLASSLOADER_METHOD_NAME,
0976:                            CLASS_CLASS_GETCLASSLOADER_METHOD_SIGNATURE);
0977:                    cv.visitLdcInsn(aspectInfo.getAspectQualifiedName());
0978:                    cv.visitLdcInsn(aspectInfo.getAspectDefinition()
0979:                            .getContainerClassName());
0980:                    cv.visitMethodInsn(INVOKESTATIC, ASPECTS_CLASS_NAME,
0981:                            ASPECT_OF_METHOD_NAME,
0982:                            ASPECT_OF_PER_JVM_METHOD_SIGNATURE);
0983:                    cv.visitTypeInsn(CHECKCAST, aspectClassName);
0984:                    cv.visitFieldInsn(PUTSTATIC, joinPointClassName, aspectInfo
0985:                            .getAspectFieldName(), aspectClassSignature);
0986:                } else if (deploymentModel.equals(DeploymentModel.PER_CLASS)) {
0987:                    cv.visitLdcInsn(aspectInfo.getAspectQualifiedName());
0988:                    cv.visitLdcInsn(aspectInfo.getAspectDefinition()
0989:                            .getContainerClassName());
0990:                    cv.visitFieldInsn(GETSTATIC, joinPointClassName,
0991:                            THIS_CLASS_FIELD_NAME, CLASS_CLASS_SIGNATURE);
0992:                    cv.visitMethodInsn(INVOKESTATIC, ASPECTS_CLASS_NAME,
0993:                            ASPECT_OF_METHOD_NAME,
0994:                            ASPECT_OF_PER_CLASS_METHOD_SIGNATURE);
0995:                    cv.visitTypeInsn(CHECKCAST, aspectClassName);
0996:                    cv.visitFieldInsn(PUTSTATIC, joinPointClassName, aspectInfo
0997:                            .getAspectFieldName(), aspectClassSignature);
0998:                } else if (deploymentModel.equals(DeploymentModel.PER_INSTANCE)) {
0999:                } else {
1000:                    throw new UnsupportedOperationException(
1001:                            "unsupported deployment model - "
1002:                                    + aspectInfo.getAspectClassName() + " "
1003:                                    + deploymentModel);
1004:                }
1005:            }
1006:
1007:            /**
1008:             * Creates the 'invoke' method. If possible delegates to the target join point directly, e.g. does not invoke the
1009:             * 'proceed' method (Used when a join point has zero around advice).
1010:             */
1011:            protected void createInvokeMethod() {
1012:
1013:                final String invokeDesc = buildInvokeMethodSignature();
1014:
1015:                // create the method
1016:                CodeVisitor cv = m_cw.visitMethod(ACC_PUBLIC + ACC_FINAL
1017:                        + ACC_STATIC, INVOKE_METHOD_NAME, invokeDesc,
1018:                        new String[] { THROWABLE_CLASS_NAME }, null);
1019:
1020:                // compute the callee and caller index from the invoke(..) signature
1021:                int calleeIndex = INDEX_NOTAVAILABLE;
1022:                int argStartIndex = 0;
1023:                if (!Modifier.isStatic(m_calleeMemberModifiers)
1024:                        && m_joinPointType != JoinPointType.CONSTRUCTOR_CALL_INT
1025:                        && m_joinPointType != JoinPointType.HANDLER_INT) {
1026:                    calleeIndex = 0;
1027:                    argStartIndex++;
1028:                } else {
1029:                    calleeIndex = INDEX_NOTAVAILABLE;// no callee in the invoke(..) parameters
1030:                }
1031:                int callerIndex = argStartIndex
1032:                        + AsmHelper.getRegisterDepth(m_argumentTypes);
1033:
1034:                // custom logic overrides for handler jp
1035:                if (m_joinPointType == JoinPointType.HANDLER_INT) {
1036:                    calleeIndex = 0;
1037:                    callerIndex = 2;
1038:                    argStartIndex = 1;
1039:                }
1040:
1041:                // do we need to keep track of CALLEE, ARGS etc, if not then completely skip it
1042:                // and make use of the optimized join point instance
1043:                // while not using its fields (does not support reentrancy and thread safety)
1044:                final boolean isOptimizedJoinPoint = !m_requiresJoinPoint
1045:                        && !requiresProceedMethod();
1046:                int joinPointIndex = INDEX_NOTAVAILABLE;
1047:
1048:                if (!isOptimizedJoinPoint) {
1049:                    // create a new JP and makes use of it
1050:                    joinPointIndex = callerIndex + 1;
1051:                    createInvocationLocalJoinPointInstance(cv, argStartIndex,
1052:                            joinPointIndex, callerIndex, calleeIndex);
1053:                }
1054:
1055:                // initialize the instance level aspects (perInstance)
1056:                initializeInstanceLevelAspects(cv, isOptimizedJoinPoint,
1057:                        joinPointIndex, callerIndex, calleeIndex);
1058:
1059:                // before advices
1060:                createBeforeAdviceInvocations(cv, isOptimizedJoinPoint,
1061:                        argStartIndex, joinPointIndex, callerIndex, calleeIndex);
1062:
1063:                // handle different combinations of after advice (finally/throwing/returning)
1064:                if (m_afterFinallyAdviceMethodInfos.length == 0
1065:                        && m_afterThrowingAdviceMethodInfos.length == 0
1066:                        && !m_isThisAdvisable) {
1067:                    createPartOfInvokeMethodWithoutAfterFinallyAndAfterThrowingAdviceTypes(
1068:                            cv, isOptimizedJoinPoint, joinPointIndex,
1069:                            argStartIndex, callerIndex, calleeIndex);
1070:                } else if (m_afterThrowingAdviceMethodInfos.length == 0
1071:                        && !m_isThisAdvisable) {
1072:                    createPartOfInvokeMethodWithoutAfterThrowingAdviceTypes(cv,
1073:                            isOptimizedJoinPoint, joinPointIndex,
1074:                            argStartIndex, callerIndex, calleeIndex);
1075:                } else {
1076:                    createPartOfInvokeMethodWithAllAdviceTypes(cv,
1077:                            OPTIMIZED_JOIN_POINT, joinPointIndex,
1078:                            argStartIndex, callerIndex, calleeIndex);
1079:                }
1080:
1081:                cv.visitMaxs(0, 0);
1082:            }
1083:
1084:            /**
1085:             * Initializes instance level aspects, retrieves them from the target instance through the
1086:             * <code>HasInstanceLevelAspect</code> interfaces.
1087:             * <p/>
1088:             * Use by 'perInstance', 'perThis' and 'perTarget' deployment models.
1089:             *
1090:             * @param cv
1091:             * @param isOptimizedJoinPoint
1092:             * @param joinPointIndex
1093:             * @param callerIndex
1094:             * @param calleeIndex
1095:             */
1096:            protected void initializeInstanceLevelAspects(final CodeVisitor cv,
1097:                    final boolean isOptimizedJoinPoint,
1098:                    final int joinPointIndex, final int callerIndex,
1099:                    final int calleeIndex) {
1100:                for (int i = 0; i < m_aspectInfos.length; i++) {
1101:                    AspectInfo aspectInfo = m_aspectInfos[i];
1102:                    if (aspectInfo.getDeploymentModel() == DeploymentModel.PER_INSTANCE) {
1103:                        // gen code: aspectField = (<TYPE>)((HasInstanceLocalAspect)CALLER).aw$getAspect(className, qualifiedName, containerClassName)
1104:                        loadJoinPointInstance(cv, isOptimizedJoinPoint,
1105:                                joinPointIndex);
1106:                        if (callerIndex >= 0) {
1107:                            cv.visitVarInsn(ALOAD, callerIndex);
1108:                        } else {
1109:                            // caller instance not available - skipping
1110:                            //TODO clean up should not occur
1111:                        }
1112:                        cv.visitLdcInsn(aspectInfo.getAspectClassName()
1113:                                .replace('/', '.'));
1114:                        cv.visitLdcInsn(aspectInfo.getAspectQualifiedName());
1115:                        cv.visitLdcInsn(aspectInfo.getAspectDefinition()
1116:                                .getContainerClassName());
1117:                        cv.visitMethodInsn(INVOKEINTERFACE,
1118:                                HAS_INSTANCE_LEVEL_ASPECT_INTERFACE_NAME,
1119:                                GET_INSTANCE_LEVEL_ASPECT_METHOD_NAME,
1120:                                GET_INSTANCE_LEVEL_ASPECT_METHOD_SIGNATURE);
1121:                        cv.visitTypeInsn(CHECKCAST, aspectInfo
1122:                                .getAspectClassName());
1123:                        cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
1124:                                aspectInfo.getAspectFieldName(), aspectInfo
1125:                                        .getAspectClassSignature());
1126:                    }
1127:                }
1128:            }
1129:
1130:            /**
1131:             * @param cv
1132:             * @param isOptimizedJoinPoint
1133:             * @param joinPointInstanceIndex
1134:             * @param argStartIndex
1135:             * @param callerIndex
1136:             * @param calleeIndex
1137:             */
1138:            protected void createPartOfInvokeMethodWithAllAdviceTypes(
1139:                    final CodeVisitor cv, final boolean isOptimizedJoinPoint,
1140:                    final int joinPointInstanceIndex, final int argStartIndex,
1141:                    final int callerIndex, final int calleeIndex) {
1142:                final int returnValueIndex = (joinPointInstanceIndex != INDEX_NOTAVAILABLE) ? (joinPointInstanceIndex + 1)
1143:                        : callerIndex + 1;
1144:                final int exceptionIndex1 = returnValueIndex + 1;
1145:                final int exceptionIndex2 = returnValueIndex + 2;
1146:
1147:                cv.visitInsn(ACONST_NULL);
1148:                cv.visitVarInsn(ASTORE, returnValueIndex);
1149:
1150:                Label tryLabel = new Label();
1151:                cv.visitLabel(tryLabel);
1152:                if (!requiresProceedMethod()) {
1153:                    // if no around advice then optimize by invoking the target JP directly and no call to proceed()
1154:                    createInlinedJoinPointInvocation(cv, isOptimizedJoinPoint,
1155:                            argStartIndex, joinPointInstanceIndex);
1156:                    int stackIndex = returnValueIndex;//use another int since storeType will update it
1157:                    AsmHelper.storeType(cv, stackIndex, m_returnType);
1158:                    addReturnedValueToJoinPoint(cv, returnValueIndex,
1159:                            joinPointInstanceIndex, false);
1160:                } else {
1161:                    createInvocationToProceedMethod(cv, joinPointInstanceIndex,
1162:                            returnValueIndex);
1163:                }
1164:
1165:                createAfterReturningAdviceInvocations(cv, isOptimizedJoinPoint,
1166:                        argStartIndex, joinPointInstanceIndex, callerIndex,
1167:                        calleeIndex);
1168:
1169:                Label finallyLabel1 = new Label();
1170:                cv.visitLabel(finallyLabel1);
1171:
1172:                if (m_isThisAdvisable) {
1173:                    final int registerDepth = callerIndex + 2; // caller is using last register + possible return value
1174:                    createAfterInterceptorInvocations(cv,
1175:                            joinPointInstanceIndex, registerDepth);
1176:                }
1177:                createAfterFinallyAdviceInvocations(cv, isOptimizedJoinPoint,
1178:                        argStartIndex, joinPointInstanceIndex, callerIndex,
1179:                        calleeIndex);
1180:
1181:                Label gotoFinallyLabel = new Label();
1182:                cv.visitJumpInsn(GOTO, gotoFinallyLabel);
1183:
1184:                Label catchLabel = new Label();
1185:                cv.visitLabel(catchLabel);
1186:
1187:                // store the exception
1188:                cv.visitVarInsn(ASTORE, exceptionIndex1);
1189:
1190:                if (m_isThisAdvisable) {
1191:                    createAfterThrowingInterceptorInvocations(cv,
1192:                            joinPointInstanceIndex, exceptionIndex1);
1193:                }
1194:
1195:                // loop over the after throwing advices
1196:                for (int i = m_afterThrowingAdviceMethodInfos.length - 1; i >= 0; i--) {
1197:                    AdviceMethodInfo advice = m_afterThrowingAdviceMethodInfos[i];
1198:
1199:                    // set the exception argument index
1200:                    advice.setSpecialArgumentIndex(exceptionIndex1);
1201:
1202:                    // if (e instanceof TYPE) {...}
1203:                    cv.visitVarInsn(ALOAD, exceptionIndex1);
1204:
1205:                    final String specialArgTypeName = advice
1206:                            .getSpecialArgumentTypeName();
1207:                    if (specialArgTypeName != null) {
1208:                        // after throwing <TYPE>
1209:                        cv.visitTypeInsn(INSTANCEOF, specialArgTypeName);
1210:
1211:                        Label ifInstanceOfLabel = new Label();
1212:                        cv.visitJumpInsn(IFEQ, ifInstanceOfLabel);
1213:
1214:                        // after throwing advice invocation
1215:                        createAfterAdviceInvocation(cv, isOptimizedJoinPoint,
1216:                                advice, joinPointInstanceIndex, argStartIndex,
1217:                                callerIndex, calleeIndex, exceptionIndex1);
1218:
1219:                        cv.visitLabel(ifInstanceOfLabel);
1220:                    } else {
1221:                        // after throwing
1222:                        createAfterAdviceInvocation(cv, isOptimizedJoinPoint,
1223:                                advice, joinPointInstanceIndex, argStartIndex,
1224:                                callerIndex, calleeIndex, INDEX_NOTAVAILABLE);
1225:                    }
1226:                }
1227:
1228:                // rethrow exception
1229:                cv.visitVarInsn(ALOAD, exceptionIndex1);
1230:                cv.visitInsn(ATHROW);
1231:
1232:                // store exception
1233:                Label exceptionLabel = new Label();
1234:                cv.visitLabel(exceptionLabel);
1235:                cv.visitVarInsn(ASTORE, exceptionIndex2);
1236:
1237:                // after finally advice invocation
1238:                Label finallyLabel2 = new Label();
1239:                cv.visitLabel(finallyLabel2);
1240:
1241:                if (m_isThisAdvisable) {
1242:                    final int registerDepth = callerIndex + 2; // caller is using last register + possible return value
1243:                    createAfterInterceptorInvocations(cv,
1244:                            joinPointInstanceIndex, registerDepth);
1245:                }
1246:                createAfterFinallyAdviceInvocations(cv, isOptimizedJoinPoint,
1247:                        argStartIndex, joinPointInstanceIndex, callerIndex,
1248:                        calleeIndex);
1249:
1250:                // rethrow exception
1251:                cv.visitVarInsn(ALOAD, exceptionIndex2);
1252:                cv.visitInsn(ATHROW);
1253:                cv.visitLabel(gotoFinallyLabel);
1254:
1255:                // unwrap if around advice and return in all cases
1256:                if (m_returnType.getSort() != Type.VOID) {
1257:                    if (requiresProceedMethod()) {
1258:                        cv.visitVarInsn(ALOAD, returnValueIndex);
1259:                        AsmHelper.unwrapType(cv, m_returnType);
1260:                    } else {
1261:                        AsmHelper.loadType(cv, returnValueIndex, m_returnType);
1262:                    }
1263:                }
1264:
1265:                AsmHelper.addReturnStatement(cv, m_returnType);
1266:
1267:                // build up the exception table
1268:                cv.visitTryCatchBlock(tryLabel, finallyLabel1, catchLabel,
1269:                        THROWABLE_CLASS_NAME);
1270:                cv.visitTryCatchBlock(tryLabel, finallyLabel1, exceptionLabel,
1271:                        null);
1272:                cv.visitTryCatchBlock(catchLabel, finallyLabel2,
1273:                        exceptionLabel, null);
1274:            }
1275:
1276:            /**
1277:             * @param cv
1278:             * @param isOptimizedJoinPoint
1279:             * @param joinPointInstanceIndex
1280:             * @param argStartIndex
1281:             * @param callerIndex
1282:             * @param calleeIndex
1283:             */
1284:            protected void createPartOfInvokeMethodWithoutAfterThrowingAdviceTypes(
1285:                    final CodeVisitor cv, final boolean isOptimizedJoinPoint,
1286:                    final int joinPointInstanceIndex, final int argStartIndex,
1287:                    final int callerIndex, final int calleeIndex) {
1288:                final int returnValueIndex = (joinPointInstanceIndex != INDEX_NOTAVAILABLE) ? (joinPointInstanceIndex + 1)
1289:                        : callerIndex + 1;
1290:                final int exceptionIndex = returnValueIndex + 1;
1291:
1292:                cv.visitInsn(ACONST_NULL);
1293:                cv.visitVarInsn(ASTORE, returnValueIndex);
1294:
1295:                Label tryLabel = new Label();
1296:                cv.visitLabel(tryLabel);
1297:                if (!requiresProceedMethod()) {
1298:                    // if no around advice then optimize by invoking the target JP directly and no call to proceed()
1299:                    createInlinedJoinPointInvocation(cv, isOptimizedJoinPoint,
1300:                            argStartIndex, joinPointInstanceIndex);
1301:                    int stackIndex = returnValueIndex;//use another int since storeType will update it
1302:                    AsmHelper.storeType(cv, stackIndex, m_returnType);
1303:                    addReturnedValueToJoinPoint(cv, returnValueIndex,
1304:                            joinPointInstanceIndex, false);
1305:                } else {
1306:                    createInvocationToProceedMethod(cv, joinPointInstanceIndex,
1307:                            returnValueIndex);
1308:                }
1309:
1310:                createAfterReturningAdviceInvocations(cv, isOptimizedJoinPoint,
1311:                        argStartIndex, joinPointInstanceIndex, callerIndex,
1312:                        calleeIndex);
1313:
1314:                Label finallyLabel1 = new Label();
1315:                cv.visitLabel(finallyLabel1);
1316:
1317:                createAfterFinallyAdviceInvocations(cv, isOptimizedJoinPoint,
1318:                        argStartIndex, joinPointInstanceIndex, callerIndex,
1319:                        calleeIndex);
1320:
1321:                Label gotoFinallyLabel = new Label();
1322:                cv.visitJumpInsn(GOTO, gotoFinallyLabel);
1323:
1324:                Label exceptionLabel = new Label();
1325:                cv.visitLabel(exceptionLabel);
1326:                cv.visitVarInsn(ASTORE, exceptionIndex);
1327:
1328:                Label finallyLabel2 = new Label();
1329:                cv.visitLabel(finallyLabel2);
1330:
1331:                createAfterFinallyAdviceInvocations(cv, isOptimizedJoinPoint,
1332:                        argStartIndex, joinPointInstanceIndex, callerIndex,
1333:                        calleeIndex);
1334:
1335:                cv.visitVarInsn(ALOAD, exceptionIndex);
1336:                cv.visitInsn(ATHROW);
1337:
1338:                cv.visitLabel(gotoFinallyLabel);
1339:
1340:                // unwrap if around advice and return in all cases
1341:                if (m_returnType.getSort() != Type.VOID) {
1342:                    if (requiresProceedMethod()) {
1343:                        cv.visitVarInsn(ALOAD, returnValueIndex);
1344:                        AsmHelper.unwrapType(cv, m_returnType);
1345:                    } else {
1346:                        AsmHelper.loadType(cv, returnValueIndex, m_returnType);
1347:                    }
1348:                }
1349:
1350:                AsmHelper.addReturnStatement(cv, m_returnType);
1351:
1352:                cv.visitTryCatchBlock(tryLabel, finallyLabel1, exceptionLabel,
1353:                        null);
1354:                cv.visitTryCatchBlock(exceptionLabel, finallyLabel2,
1355:                        exceptionLabel, null);
1356:            }
1357:
1358:            /**
1359:             * @param cv
1360:             * @param isOptimizedJoinPoint
1361:             * @param joinPointInstanceIndex
1362:             * @param argStartIndex
1363:             * @param callerIndex
1364:             * @param calleeIndex
1365:             */
1366:            protected void createPartOfInvokeMethodWithoutAfterFinallyAndAfterThrowingAdviceTypes(
1367:                    final CodeVisitor cv, final boolean isOptimizedJoinPoint,
1368:                    final int joinPointInstanceIndex, final int argStartIndex,
1369:                    final int callerIndex, final int calleeIndex) {
1370:
1371:                final int returnValueIndex = (joinPointInstanceIndex != INDEX_NOTAVAILABLE) ? (joinPointInstanceIndex + 1)
1372:                        : callerIndex + 1;
1373:                if (!requiresProceedMethod()) {
1374:                    // if no around advice then optimize by invoking the target JP directly and no call to proceed()
1375:                    createInlinedJoinPointInvocation(cv, isOptimizedJoinPoint,
1376:                            argStartIndex, joinPointInstanceIndex);
1377:                    int stackIndex = returnValueIndex;//use another int since storeType will update it
1378:                    AsmHelper.storeType(cv, stackIndex, m_returnType);
1379:                    addReturnedValueToJoinPoint(cv, returnValueIndex,
1380:                            joinPointInstanceIndex, false);
1381:                } else {
1382:                    createInvocationToProceedMethod(cv, joinPointInstanceIndex,
1383:                            returnValueIndex);
1384:                }
1385:
1386:                // after returning advice invocations
1387:                createAfterReturningAdviceInvocations(cv, isOptimizedJoinPoint,
1388:                        argStartIndex, joinPointInstanceIndex, callerIndex,
1389:                        calleeIndex);
1390:
1391:                // unwrap if around advice and return in all cases
1392:                if (m_returnType.getSort() != Type.VOID) {
1393:                    if (requiresProceedMethod()) {
1394:                        cv.visitVarInsn(ALOAD, returnValueIndex);
1395:                        AsmHelper.unwrapType(cv, m_returnType);
1396:                    } else {
1397:                        AsmHelper.loadType(cv, returnValueIndex, m_returnType);
1398:                    }
1399:                }
1400:
1401:                AsmHelper.addReturnStatement(cv, m_returnType);
1402:            }
1403:
1404:            /**
1405:             * Creates an invocation to the proceed method.
1406:             *
1407:             * @param cv
1408:             * @param joinPointInstanceIndex
1409:             * @param returnValueIndex
1410:             */
1411:            protected void createInvocationToProceedMethod(
1412:                    final CodeVisitor cv, final int joinPointInstanceIndex,
1413:                    final int returnValueIndex) {
1414:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
1415:                cv.visitMethodInsn(INVOKEVIRTUAL, m_joinPointClassName,
1416:                        PROCEED_METHOD_NAME, PROCEED_METHOD_SIGNATURE);
1417:                cv.visitVarInsn(ASTORE, returnValueIndex);
1418:            }
1419:
1420:            /**
1421:             * Creates an "invocation local" join point instance, e.g. one join point per invocation. Needed for thread-safety
1422:             * when invoking around advice.
1423:             *
1424:             * @param cv
1425:             * @param argStartIndex          index on stack of first target method arg (0 or 1, depends of static target or
1426:             *                               not)
1427:             * @param joinPointInstanceIndex
1428:             * @param callerIndex
1429:             * @param calleeIndex
1430:             */
1431:            protected void createInvocationLocalJoinPointInstance(
1432:                    final CodeVisitor cv, final int argStartIndex,
1433:                    final int joinPointInstanceIndex, final int callerIndex,
1434:                    final int calleeIndex) {
1435:                // create the join point instance
1436:                cv.visitTypeInsn(NEW, m_joinPointClassName);
1437:                cv.visitInsn(DUP);
1438:                cv.visitMethodInsn(INVOKESPECIAL, m_joinPointClassName,
1439:                        INIT_METHOD_NAME, NO_PARAM_RETURN_VOID_SIGNATURE);
1440:
1441:                // store the jp on the stack
1442:                cv.visitVarInsn(ASTORE, joinPointInstanceIndex);
1443:
1444:                // set the argument fields in the join point instance (jp.m_arg<i> = <arg_i>)
1445:                int argStackIndex = argStartIndex;
1446:                for (int i = 0; i < m_fieldNames.length; i++) {
1447:                    String fieldName = m_fieldNames[i];
1448:                    cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
1449:                    Type type = m_argumentTypes[i];
1450:                    argStackIndex = AsmHelper.loadType(cv, argStackIndex, type);
1451:                    cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
1452:                            fieldName, type.getDescriptor());
1453:                }
1454:
1455:                // caller (can be assigned to null)
1456:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
1457:                cv.visitVarInsn(ALOAD, callerIndex);
1458:                cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
1459:                        CALLER_INSTANCE_FIELD_NAME, m_callerClassSignature);
1460:
1461:                // callee (can be not available)
1462:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
1463:                if (calleeIndex != INDEX_NOTAVAILABLE) {
1464:                    cv.visitVarInsn(ALOAD, 0);
1465:                } else {
1466:                    cv.visitInsn(ACONST_NULL);
1467:                }
1468:                cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
1469:                        CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature);
1470:
1471:                if (m_isThisAdvisable) {
1472:                    createInitializationForAdvisableManagement(cv,
1473:                            joinPointInstanceIndex, callerIndex);
1474:                }
1475:            }
1476:
1477:            /**
1478:             * Create the proceed() method.
1479:             */
1480:            protected void createProceedMethod() {
1481:
1482:                CodeVisitor cv = m_cw.visitMethod(ACC_PUBLIC | ACC_FINAL,
1483:                        PROCEED_METHOD_NAME, PROCEED_METHOD_SIGNATURE,
1484:                        new String[] { THROWABLE_CLASS_NAME }, null);
1485:
1486:                if (m_isThisAdvisable) {
1487:                    createAroundInterceptorInvocations(cv);
1488:                }
1489:
1490:                incrementStackFrameCounter(cv);
1491:
1492:                // set up the labels
1493:                Label tryLabel = new Label();
1494:                Label defaultCaseLabel = new Label();
1495:                Label gotoLabel = new Label();
1496:                Label handlerLabel = new Label();
1497:                Label endLabel = new Label();
1498:
1499:                int nrOfCases = m_aroundAdviceMethodInfos.length;
1500:                if (m_isThisAdvisable) {
1501:                    nrOfCases++;
1502:                }
1503:
1504:                Label[] caseLabels = new Label[nrOfCases];
1505:                Label[] returnLabels = new Label[nrOfCases];
1506:                int[] caseNumbers = new int[nrOfCases];
1507:                for (int i = 0; i < caseLabels.length; i++) {
1508:                    caseLabels[i] = new Label();
1509:                    caseNumbers[i] = i;
1510:                }
1511:                for (int i = 0; i < returnLabels.length; i++) {
1512:                    returnLabels[i] = new Label();
1513:                }
1514:
1515:                // start try-catch block
1516:                cv.visitLabel(tryLabel);
1517:
1518:                // start the switch block and set the stackframe as the param to the switch
1519:                cv.visitVarInsn(ALOAD, 0);
1520:                cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
1521:                        STACK_FRAME_COUNTER_FIELD_NAME, I);
1522:                cv.visitLookupSwitchInsn(defaultCaseLabel, caseNumbers,
1523:                        caseLabels);
1524:
1525:                // add one case for each around advice invocation
1526:                for (int i = 0; i < m_aroundAdviceMethodInfos.length; i++) {
1527:                    cv.visitLabel(caseLabels[i]);
1528:
1529:                    // gather advice info
1530:                    AdviceMethodInfo adviceInfo = m_aroundAdviceMethodInfos[i];
1531:
1532:                    Label endInstanceOflabel = beginRuntimeCheck(cv, false, 0,
1533:                            adviceInfo.getAdviceInfo(), -1);
1534:
1535:                    // get the aspect instance
1536:                    loadAspect(cv, NON_OPTIMIZED_JOIN_POINT, 0, adviceInfo
1537:                            .getAspectInfo());
1538:
1539:                    // load the arguments to the advice from the join point instance plus build up the
1540:                    // advice method signature
1541:                    int[] argIndexes = adviceInfo.getAdviceMethodArgIndexes();
1542:                    for (int j = 0; j < argIndexes.length; j++) {
1543:                        int argIndex = argIndexes[j];
1544:                        if (argIndex >= 0) {
1545:                            Type argumentType = m_argumentTypes[argIndex];
1546:                            cv.visitVarInsn(ALOAD, 0);
1547:                            cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
1548:                                    ARGUMENT_FIELD + argIndex, argumentType
1549:                                            .getDescriptor());
1550:                        } else if (argIndex == AdviceInfo.JOINPOINT_ARG
1551:                                || argIndex == AdviceInfo.STATIC_JOINPOINT_ARG
1552:                                || argIndex == AdviceInfo.VALID_NON_AW_AROUND_CLOSURE_TYPE
1553:                                || argIndex == AdviceInfo.CUSTOM_JOIN_POINT_ARG) {
1554:                            cv.visitVarInsn(ALOAD, 0);
1555:                        } else if (argIndex == AdviceInfo.TARGET_ARG) {
1556:                            loadCallee(cv, NON_OPTIMIZED_JOIN_POINT, 0,
1557:                                    INDEX_NOTAVAILABLE);
1558:                            // add a cast if runtime check was used
1559:                            if (adviceInfo.getAdviceInfo()
1560:                                    .hasTargetWithRuntimeCheck()) {
1561:                                cv.visitTypeInsn(CHECKCAST, adviceInfo
1562:                                        .getAdviceInfo()
1563:                                        .getMethodParameterTypes()[j]
1564:                                        .getInternalName());
1565:                            }
1566:                        } else if (argIndex == AdviceInfo.THIS_ARG) {
1567:                            loadCaller(cv, NON_OPTIMIZED_JOIN_POINT, 0,
1568:                                    INDEX_NOTAVAILABLE);
1569:                        } else {
1570:                            throw new Error(
1571:                                    "advice method argument index type is not supported: "
1572:                                            + argIndex);
1573:                        }
1574:                    }
1575:
1576:                    // invoke the advice method
1577:                    cv.visitMethodInsn(INVOKEVIRTUAL, adviceInfo
1578:                            .getAspectInfo().getAspectClassName(), adviceInfo
1579:                            .getAdviceInfo().getMethodName(), adviceInfo
1580:                            .getAdviceInfo().getMethodSignature());
1581:                    cv.visitVarInsn(ASTORE, 1);
1582:
1583:                    // we need to handle the case when the advice was skipped due to runtime check
1584:                    // that is : if (runtimeCheck) { ret = advice() } else { ret = proceed() }
1585:                    if (endInstanceOflabel != null) {
1586:                        Label elseInstanceOfLabel = new Label();
1587:                        cv.visitJumpInsn(GOTO, elseInstanceOfLabel);
1588:                        endRuntimeCheck(cv, adviceInfo.getAdviceInfo(),
1589:                                endInstanceOflabel);
1590:                        cv.visitVarInsn(ALOAD, 0);
1591:                        cv.visitMethodInsn(INVOKESPECIAL, m_joinPointClassName,
1592:                                PROCEED_METHOD_NAME, PROCEED_METHOD_SIGNATURE);
1593:                        cv.visitVarInsn(ASTORE, 1);
1594:                        cv.visitLabel(elseInstanceOfLabel);
1595:                    }
1596:
1597:                    cv.visitLabel(returnLabels[i]);
1598:
1599:                    cv.visitVarInsn(ALOAD, 1);
1600:                    cv.visitInsn(ARETURN);
1601:                }
1602:
1603:                if (m_isThisAdvisable) {
1604:                    int delegationCaseIndex = caseLabels.length - 1;
1605:                    cv.visitLabel(caseLabels[delegationCaseIndex]);
1606:                    cv.visitVarInsn(ALOAD, 0);
1607:                    cv.visitInsn(ICONST_0);
1608:                    cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
1609:                            INTERCEPTOR_INDEX_FIELD_NAME, I);
1610:                    cv.visitVarInsn(ALOAD, 0);
1611:                    cv.visitMethodInsn(INVOKEVIRTUAL, m_joinPointClassName,
1612:                            PROCEED_METHOD_NAME, PROCEED_METHOD_SIGNATURE);
1613:
1614:                    cv.visitLabel(returnLabels[delegationCaseIndex]);
1615:
1616:                    cv.visitInsn(ARETURN);
1617:                }
1618:
1619:                // invoke the target join point in the default case
1620:                cv.visitLabel(defaultCaseLabel);
1621:
1622:                AsmHelper.prepareWrappingOfPrimitiveType(cv, Type
1623:                        .getReturnType(m_calleeMemberDesc));
1624:
1625:                createJoinPointInvocation(cv);
1626:
1627:                Type m_returnType = null;
1628:                if (m_joinPointType != JoinPointType.CONSTRUCTOR_CALL_INT) {
1629:                    m_returnType = Type.getReturnType(m_calleeMemberDesc);
1630:                } else {
1631:                    m_returnType = Type.getType(m_calleeClassSignature);
1632:                }
1633:                AsmHelper.wrapPrimitiveType(cv, m_returnType);
1634:                cv.visitVarInsn(ASTORE, 1);
1635:
1636:                // store it in Rtti return value
1637:                addReturnedValueToJoinPoint(cv, 1, 0, true);
1638:
1639:                // set it as the CALLEE instance for ctor call - TODO refactor somewhere else
1640:                if (m_joinPointType == JoinPointType.CONSTRUCTOR_CALL_INT) {
1641:                    cv.visitVarInsn(ALOAD, 0);
1642:                    cv.visitVarInsn(ALOAD, 1);
1643:                    cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
1644:                            CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature);
1645:                }
1646:
1647:                cv.visitLabel(gotoLabel);
1648:
1649:                cv.visitVarInsn(ALOAD, 1);
1650:                cv.visitInsn(ARETURN);
1651:
1652:                // finally clause
1653:                cv.visitLabel(handlerLabel);
1654:                cv.visitVarInsn(ASTORE, 2);
1655:                cv.visitLabel(endLabel);
1656:
1657:                cv.visitVarInsn(ALOAD, 2);
1658:                cv.visitInsn(ATHROW);
1659:
1660:                // set up the label table
1661:                cv.visitTryCatchBlock(tryLabel, returnLabels[0], handlerLabel,
1662:                        null);
1663:                for (int i = 1; i < caseLabels.length; i++) {
1664:                    Label caseLabel = caseLabels[i];
1665:                    Label returnLabel = returnLabels[i];
1666:                    cv.visitTryCatchBlock(caseLabel, returnLabel, handlerLabel,
1667:                            null);
1668:                }
1669:                cv.visitTryCatchBlock(defaultCaseLabel, gotoLabel,
1670:                        handlerLabel, null);
1671:                cv.visitTryCatchBlock(handlerLabel, endLabel, handlerLabel,
1672:                        null);
1673:                cv.visitMaxs(0, 0);
1674:            }
1675:
1676:            /**
1677:             * Adds before advice invocations.
1678:             *
1679:             * @param cv
1680:             * @param isOptimizedJoinPoint
1681:             * @param argStartIndex          index on stack of first target method arg (0 or 1, depends of static target or
1682:             *                               not)
1683:             * @param joinPointInstanceIndex >= 0 if STATIC_JOIN_POINT is NOT to be used (around advice)
1684:             * @param callerIndex
1685:             * @param calleeIndex
1686:             */
1687:            protected void createBeforeAdviceInvocations(final CodeVisitor cv,
1688:                    final boolean isOptimizedJoinPoint,
1689:                    final int argStartIndex, final int joinPointInstanceIndex, //FIXME redundant -1 with isStaticJP
1690:                    final int callerIndex, final int calleeIndex) {
1691:                for (int i = 0; i < m_beforeAdviceMethodInfos.length; i++) {
1692:                    AdviceMethodInfo adviceMethodInfo = m_beforeAdviceMethodInfos[i];
1693:
1694:                    // runtime check for target() etc
1695:                    Label endInstanceOflabel = beginRuntimeCheck(cv,
1696:                            isOptimizedJoinPoint, joinPointInstanceIndex,
1697:                            adviceMethodInfo.getAdviceInfo(), calleeIndex);
1698:
1699:                    //get the aspect instance
1700:                    loadAspect(cv, isOptimizedJoinPoint,
1701:                            joinPointInstanceIndex, adviceMethodInfo
1702:                                    .getAspectInfo());
1703:
1704:                    AspectDefinition aspectDef = adviceMethodInfo
1705:                            .getAdviceInfo().getAdviceDefinition()
1706:                            .getAspectDefinition();
1707:                    if (aspectDef.isAspectWerkzAspect()) {
1708:                        // AW aspect
1709:                        int[] argIndexes = adviceMethodInfo
1710:                                .getAdviceMethodArgIndexes();
1711:                        // if empty, we consider for now that we have to push JoinPoint for old advice with JoinPoint as sole arg
1712:                        for (int j = 0; j < argIndexes.length; j++) {
1713:                            int argIndex = argIndexes[j];
1714:                            if (argIndex >= 0) {
1715:                                Type argumentType = m_argumentTypes[argIndex];
1716:                                int argStackIndex = AsmHelper
1717:                                        .getRegisterIndexOf(m_argumentTypes,
1718:                                                argIndex)
1719:                                        + argStartIndex;
1720:                                AsmHelper.loadType(cv, argStackIndex,
1721:                                        argumentType);
1722:                            } else if (argIndex == AdviceInfo.JOINPOINT_ARG
1723:                                    || argIndex == AdviceInfo.STATIC_JOINPOINT_ARG) {
1724:                                loadJoinPointInstance(cv, isOptimizedJoinPoint,
1725:                                        joinPointInstanceIndex);
1726:                            } else if (argIndex == AdviceInfo.TARGET_ARG) {
1727:                                loadCallee(cv, isOptimizedJoinPoint,
1728:                                        joinPointInstanceIndex, calleeIndex);
1729:                                // add a cast if runtime check was used
1730:                                if (adviceMethodInfo.getAdviceInfo()
1731:                                        .hasTargetWithRuntimeCheck()) {
1732:                                    cv
1733:                                            .visitTypeInsn(
1734:                                                    CHECKCAST,
1735:                                                    adviceMethodInfo
1736:                                                            .getAdviceInfo()
1737:                                                            .getMethodParameterTypes()[j]
1738:                                                            .getInternalName());
1739:                                }
1740:                            } else if (argIndex == AdviceInfo.THIS_ARG) {
1741:                                loadCaller(cv, isOptimizedJoinPoint,
1742:                                        joinPointInstanceIndex, callerIndex);
1743:                            } else {
1744:                                throw new Error(
1745:                                        "special argument index is not supported: "
1746:                                                + argIndex);
1747:                            }
1748:                        }
1749:                    } else {
1750:                        // non-AW aspect
1751:                        adviceMethodInfo
1752:                                .setJoinPointIndex(joinPointInstanceIndex);
1753:                        for (int j = 0; j < m_aspectModels.length; j++) {
1754:                            AspectModel aspectModel = m_aspectModels[j];
1755:                            if (aspectDef.getAspectModel().equals(
1756:                                    aspectModel.getAspectModelType())) {
1757:                                aspectModel.createBeforeAdviceArgumentHandling(
1758:                                        cv, adviceMethodInfo);
1759:                            }
1760:                        }
1761:                    }
1762:
1763:                    cv.visitMethodInsn(INVOKEVIRTUAL, adviceMethodInfo
1764:                            .getAspectInfo().getAspectClassName(),
1765:                            adviceMethodInfo.getAdviceInfo().getMethodName(),
1766:                            adviceMethodInfo.getAdviceInfo()
1767:                                    .getMethodSignature());
1768:
1769:                    // end label of runtime checks
1770:                    endRuntimeCheck(cv, adviceMethodInfo.getAdviceInfo(),
1771:                            endInstanceOflabel);
1772:                }
1773:
1774:                if (m_isThisAdvisable) {
1775:                    createBeforeInterceptorInvocations(cv,
1776:                            joinPointInstanceIndex, callerIndex + 1);
1777:                }
1778:            }
1779:
1780:            /**
1781:             * Adds after advice invocations.
1782:             *
1783:             * @param cv
1784:             * @param isOptimizedJoinPoint
1785:             * @param argStartIndex          index on stack of first target method arg (0 or 1, depends of static target or
1786:             *                               not)
1787:             * @param joinPointInstanceIndex >= 0 if STATIC_JOIN_POINT is NOT to be used (around advice)
1788:             * @param callerIndex
1789:             * @param calleeIndex
1790:             */
1791:            protected void createAfterFinallyAdviceInvocations(
1792:                    final CodeVisitor cv, final boolean isOptimizedJoinPoint,
1793:                    final int argStartIndex, final int joinPointInstanceIndex,
1794:                    final int callerIndex, final int calleeIndex) {
1795:                // add after advice in reverse order
1796:                for (int i = m_afterFinallyAdviceMethodInfos.length - 1; i >= 0; i--) {
1797:                    AdviceMethodInfo advice = m_afterFinallyAdviceMethodInfos[i];
1798:                    createAfterAdviceInvocation(cv, isOptimizedJoinPoint,
1799:                            advice, joinPointInstanceIndex, argStartIndex,
1800:                            callerIndex, calleeIndex, INDEX_NOTAVAILABLE);
1801:                }
1802:            }
1803:
1804:            /**
1805:             * Adds after returning advice invocations.
1806:             *
1807:             * @param cv
1808:             * @param isOptimizedJoinPoint
1809:             * @param argStartIndex          index on stack of first target method arg (0 or 1, depends of static target or
1810:             *                               not)
1811:             * @param joinPointInstanceIndex >= 0 if STATIC_JOIN_POINT is NOT to be used (around advice)
1812:             * @param callerIndex
1813:             * @param calleeIndex
1814:             */
1815:            protected void createAfterReturningAdviceInvocations(
1816:                    final CodeVisitor cv, final boolean isOptimizedJoinPoint,
1817:                    final int argStartIndex, final int joinPointInstanceIndex,
1818:                    final int callerIndex, final int calleeIndex) {
1819:
1820:                final int returnValueIndex = (joinPointInstanceIndex != INDEX_NOTAVAILABLE) ? (joinPointInstanceIndex + 1)
1821:                        : callerIndex + 1;
1822:
1823:                if (m_isThisAdvisable) {
1824:                    createAfterReturningInterceptorInvocations(cv,
1825:                            joinPointInstanceIndex, returnValueIndex);
1826:                }
1827:
1828:                boolean hasPoppedReturnValueFromStack = false;
1829:                for (int i = m_afterReturningAdviceMethodInfos.length - 1; i >= 0; i--) {
1830:                    AdviceMethodInfo advice = m_afterReturningAdviceMethodInfos[i];
1831:
1832:                    // set the return value index that will be used as arg to advice
1833:                    advice.setSpecialArgumentIndex(returnValueIndex);
1834:
1835:                    String specialArgDesc = advice.getSpecialArgumentTypeDesc();
1836:                    if (specialArgDesc == null) {
1837:                        // after returning
1838:                        createAfterAdviceInvocation(cv, isOptimizedJoinPoint,
1839:                                advice, joinPointInstanceIndex, argStartIndex,
1840:                                callerIndex, calleeIndex, INDEX_NOTAVAILABLE);
1841:                    } else {
1842:                        // after returning <TYPE>
1843:                        if (AsmHelper.isPrimitive(m_returnType)) {
1844:                            if (m_returnType.getDescriptor().equals(
1845:                                    specialArgDesc)) {
1846:                                createAfterAdviceInvocation(cv,
1847:                                        isOptimizedJoinPoint, advice,
1848:                                        joinPointInstanceIndex, argStartIndex,
1849:                                        callerIndex, calleeIndex,
1850:                                        returnValueIndex);
1851:                            }
1852:                        } else {
1853:                            cv.visitVarInsn(ALOAD, returnValueIndex);
1854:
1855:                            cv.visitTypeInsn(INSTANCEOF, advice
1856:                                    .getSpecialArgumentTypeName());
1857:
1858:                            Label label = new Label();
1859:                            cv.visitJumpInsn(IFEQ, label);
1860:
1861:                            createAfterAdviceInvocation(cv,
1862:                                    isOptimizedJoinPoint, advice,
1863:                                    joinPointInstanceIndex, argStartIndex,
1864:                                    callerIndex, calleeIndex, returnValueIndex);
1865:
1866:                            cv.visitLabel(label);
1867:                        }
1868:                    }
1869:                }
1870:
1871:                // need the return value in return operation
1872:                if (!requiresProceedMethod() && hasPoppedReturnValueFromStack) {
1873:                    cv.visitVarInsn(ALOAD, returnValueIndex);
1874:                }
1875:            }
1876:
1877:            /**
1878:             * Adds a single generic after advice invocation.
1879:             *
1880:             * @param cv
1881:             * @param isOptimizedJoinPoint
1882:             * @param adviceMethodInfo
1883:             * @param joinPointInstanceIndex
1884:             * @param argStartIndex
1885:             * @param callerIndex
1886:             * @param calleeIndex
1887:             * @param specialArgIndex        for afterReturning / Throwing when binding is used
1888:             */
1889:            protected void createAfterAdviceInvocation(final CodeVisitor cv,
1890:                    final boolean isOptimizedJoinPoint,
1891:                    final AdviceMethodInfo adviceMethodInfo,
1892:                    final int joinPointInstanceIndex, final int argStartIndex,
1893:                    final int callerIndex, final int calleeIndex,
1894:                    final int specialArgIndex) {
1895:                // runtime check for target() etc
1896:                Label endInstanceOflabel = beginRuntimeCheck(cv,
1897:                        isOptimizedJoinPoint, joinPointInstanceIndex,
1898:                        adviceMethodInfo.getAdviceInfo(), calleeIndex);
1899:
1900:                // get the aspect instance
1901:                loadAspect(cv, isOptimizedJoinPoint, joinPointInstanceIndex,
1902:                        adviceMethodInfo.getAspectInfo());
1903:
1904:                AspectDefinition aspectDef = adviceMethodInfo.getAdviceInfo()
1905:                        .getAdviceDefinition().getAspectDefinition();
1906:                if (aspectDef.isAspectWerkzAspect()) {
1907:                    // AW aspect
1908:                    // load the arguments that should be passed to the advice
1909:                    int[] argIndexes = adviceMethodInfo
1910:                            .getAdviceMethodArgIndexes();
1911:                    for (int j = 0; j < argIndexes.length; j++) {
1912:                        int argIndex = argIndexes[j];
1913:                        if (argIndex >= 0) {
1914:                            Type argumentType = m_argumentTypes[argIndex];
1915:                            int argStackIndex = AsmHelper.getRegisterIndexOf(
1916:                                    m_argumentTypes, argIndex)
1917:                                    + argStartIndex;
1918:                            AsmHelper.loadType(cv, argStackIndex, argumentType);
1919:                        } else if (argIndex == AdviceInfo.JOINPOINT_ARG
1920:                                || argIndex == AdviceInfo.STATIC_JOINPOINT_ARG) {
1921:                            loadJoinPointInstance(cv, isOptimizedJoinPoint,
1922:                                    joinPointInstanceIndex);
1923:                        } else if (argIndex == AdviceInfo.TARGET_ARG) {
1924:                            loadCallee(cv, isOptimizedJoinPoint,
1925:                                    joinPointInstanceIndex, calleeIndex);
1926:                            // add a cast if runtime check was used
1927:                            if (adviceMethodInfo.getAdviceInfo()
1928:                                    .hasTargetWithRuntimeCheck()) {
1929:                                cv.visitTypeInsn(CHECKCAST, adviceMethodInfo
1930:                                        .getAdviceInfo()
1931:                                        .getMethodParameterTypes()[j]
1932:                                        .getInternalName());
1933:                            }
1934:                        } else if (argIndex == AdviceInfo.THIS_ARG) {
1935:                            loadCaller(cv, isOptimizedJoinPoint,
1936:                                    joinPointInstanceIndex, callerIndex);
1937:                        } else if (argIndex == AdviceInfo.SPECIAL_ARGUMENT
1938:                                && specialArgIndex != INDEX_NOTAVAILABLE) {
1939:                            Type argumentType = adviceMethodInfo
1940:                                    .getAdviceInfo().getMethodParameterTypes()[j];
1941:                            AsmHelper.loadType(cv, specialArgIndex,
1942:                                    argumentType);
1943:                            if (adviceMethodInfo.getAdviceInfo()
1944:                                    .getAdviceDefinition().getType().equals(
1945:                                            AdviceType.AFTER_THROWING)) {
1946:                                cv.visitTypeInsn(CHECKCAST, argumentType
1947:                                        .getInternalName());
1948:                            }
1949:                        } else {
1950:                            throw new Error("magic index is not supported: "
1951:                                    + argIndex);
1952:                        }
1953:                    }
1954:                } else {
1955:                    // non-AW aspect
1956:                    adviceMethodInfo.setJoinPointIndex(joinPointInstanceIndex);
1957:                    for (int i = 0; i < m_aspectModels.length; i++) {
1958:                        AspectModel aspectModel = m_aspectModels[i];
1959:                        if (aspectDef.getAspectModel().equals(
1960:                                aspectModel.getAspectModelType())) {
1961:                            aspectModel.createAfterAdviceArgumentHandling(cv,
1962:                                    adviceMethodInfo);
1963:                        }
1964:                    }
1965:                }
1966:
1967:                cv.visitMethodInsn(INVOKEVIRTUAL, adviceMethodInfo
1968:                        .getAspectInfo().getAspectClassName(), adviceMethodInfo
1969:                        .getAdviceInfo().getMethodName(), adviceMethodInfo
1970:                        .getAdviceInfo().getMethodSignature());
1971:
1972:                // end label of runtime checks
1973:                endRuntimeCheck(cv, adviceMethodInfo.getAdviceInfo(),
1974:                        endInstanceOflabel);
1975:            }
1976:
1977:            /**
1978:             * Adds the return value to the RETURNED field.
1979:             *
1980:             * @param cv
1981:             * @param returnValueIndex
1982:             * @param joinPointInstanceIndex
1983:             * @param unwrap                 set to true if already wrapped on the stack (within proceed() code)
1984:             */
1985:            protected void addReturnedValueToJoinPoint(final CodeVisitor cv,
1986:                    final int returnValueIndex,
1987:                    final int joinPointInstanceIndex, final boolean unwrap) {
1988:                if (m_requiresJoinPoint && m_returnType.getSort() != Type.VOID) {
1989:                    if (m_joinPointType == JoinPointType.METHOD_EXECUTION_INT
1990:                            || m_joinPointType == JoinPointType.METHOD_CALL_INT
1991:                            || m_joinPointType == JoinPointType.CONSTRUCTOR_CALL_INT) {
1992:                        //TODO should we do something for field get / set
1993:                        loadJoinPointInstance(cv, NON_OPTIMIZED_JOIN_POINT,
1994:                                joinPointInstanceIndex);
1995:                        if (unwrap && AsmHelper.isPrimitive(m_returnType)) {
1996:                            cv.visitVarInsn(ALOAD, returnValueIndex);
1997:                            AsmHelper.unwrapType(cv, m_returnType);
1998:                        } else {
1999:                            AsmHelper.loadType(cv, returnValueIndex,
2000:                                    m_returnType);
2001:                        }
2002:                        cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2003:                                RETURN_VALUE_FIELD_NAME, m_returnType
2004:                                        .getDescriptor());
2005:                    }
2006:                }
2007:            }
2008:
2009:            /**
2010:             * Loads the join point instance, takes static/non-static join point access into account.
2011:             *
2012:             * @param cv
2013:             * @param isOptimizedJoinPoint
2014:             * @param joinPointInstanceIndex
2015:             */
2016:            protected void loadJoinPointInstance(final CodeVisitor cv,
2017:                    final boolean isOptimizedJoinPoint,
2018:                    final int joinPointInstanceIndex) {
2019:                if (isOptimizedJoinPoint) {
2020:                    cv.visitFieldInsn(GETSTATIC, m_joinPointClassName,
2021:                            OPTIMIZED_JOIN_POINT_INSTANCE_FIELD_NAME, L
2022:                                    + m_joinPointClassName + SEMICOLON);
2023:                } else {
2024:                    cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
2025:                }
2026:            }
2027:
2028:            /**
2029:             * Loads the argument member fields.
2030:             *
2031:             * @param cv
2032:             * @param argStartIndex
2033:             */
2034:            protected void loadArgumentMemberFields(final CodeVisitor cv,
2035:                    final int argStartIndex) {
2036:                int argStackIndex = argStartIndex;
2037:                for (int index = 0; index < m_argumentTypes.length; index++) {
2038:                    Type argumentType = m_argumentTypes[index];
2039:                    argStackIndex = AsmHelper.loadType(cv, argStackIndex,
2040:                            argumentType);
2041:                }
2042:            }
2043:
2044:            /**
2045:             * Loads the arguments.
2046:             *
2047:             * @param cv
2048:             */
2049:            protected void loadArguments(final CodeVisitor cv) {
2050:                for (int i = 0; i < m_fieldNames.length; i++) {
2051:                    String fieldName = m_fieldNames[i];
2052:                    Type argumentType = m_argumentTypes[i];
2053:                    cv.visitVarInsn(ALOAD, 0);
2054:                    cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2055:                            fieldName, argumentType.getDescriptor());
2056:                }
2057:            }
2058:
2059:            /**
2060:             * Resets the stack frame counter.
2061:             *
2062:             * @param cv
2063:             */
2064:            protected void resetStackFrameCounter(final CodeVisitor cv) {
2065:                cv.visitVarInsn(ALOAD, 0);
2066:                cv.visitInsn(ICONST_M1);
2067:                cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2068:                        STACK_FRAME_COUNTER_FIELD_NAME, I);
2069:            }
2070:
2071:            /**
2072:             * Handles the incrementation of the stack frame.
2073:             *
2074:             * @param cv
2075:             */
2076:            protected void incrementStackFrameCounter(final CodeVisitor cv) {
2077:                cv.visitVarInsn(ALOAD, 0);
2078:                cv.visitInsn(DUP);
2079:                cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2080:                        STACK_FRAME_COUNTER_FIELD_NAME, I);
2081:                cv.visitInsn(ICONST_1);
2082:                cv.visitInsn(IADD);
2083:                cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2084:                        STACK_FRAME_COUNTER_FIELD_NAME, I);
2085:            }
2086:
2087:            /**
2088:             * Create and load a structure (f.e. array of Object) where args are stored, before setting the Rtti
2089:             * with it (See addParametersToRttiInstance). The structure is stored at the given stackFreeIndex.
2090:             * <p/>
2091:             * We provide here a default implementation that is suitable for method and constructor call and execution.
2092:             * See createParameterWrappedAt for field get/set and handler compiler (no array of argument needed)
2093:             *
2094:             * @param cv
2095:             * @param stackFreeIndex
2096:             */
2097:            protected final void createArgumentArrayAt(final CodeVisitor cv,
2098:                    final int stackFreeIndex) {
2099:                AsmHelper.loadIntegerConstant(cv, m_fieldNames.length);
2100:                cv.visitTypeInsn(ANEWARRAY, OBJECT_CLASS_NAME);
2101:                cv.visitVarInsn(ASTORE, stackFreeIndex);
2102:
2103:                for (int i = 0; i < m_argumentTypes.length; i++) {
2104:                    cv.visitVarInsn(ALOAD, stackFreeIndex);
2105:                    AsmHelper.loadIntegerConstant(cv, i);
2106:                    AsmHelper.prepareWrappingOfPrimitiveType(cv,
2107:                            m_argumentTypes[i]);
2108:                    cv.visitVarInsn(ALOAD, 0);
2109:                    cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2110:                            ARGUMENT_FIELD + i, m_argumentTypes[i]
2111:                                    .getDescriptor());
2112:                    AsmHelper.wrapPrimitiveType(cv, m_argumentTypes[i]);
2113:                    cv.visitInsn(AASTORE);
2114:                }
2115:            }
2116:
2117:            /**
2118:             * Creates utility methods for the join point (getter, setters etc.).
2119:             */
2120:            protected void createUtilityMethods() {
2121:                CodeVisitor cv;
2122:
2123:                // addMetaData
2124:                {
2125:                    cv = m_cw.visitMethod(ACC_PUBLIC,
2126:                            ADD_META_DATA_METHOD_NAME,
2127:                            ADD_META_DATA_METHOD_SIGNATURE, null, null);
2128:                    cv.visitFieldInsn(GETSTATIC, m_joinPointClassName,
2129:                            META_DATA_FIELD_NAME, MAP_CLASS_SIGNATURE);
2130:                    cv.visitVarInsn(ALOAD, 1);
2131:                    cv.visitVarInsn(ALOAD, 2);
2132:                    cv.visitMethodInsn(INVOKEINTERFACE, MAP_CLASS_NAME,
2133:                            PUT_METHOD_NAME, PUT_METHOD_SIGNATURE);
2134:                    cv.visitInsn(POP);
2135:                    cv.visitInsn(RETURN);
2136:                    cv.visitMaxs(0, 0);
2137:                }
2138:
2139:                // getMetaData
2140:                {
2141:                    cv = m_cw.visitMethod(ACC_PUBLIC,
2142:                            GET_META_DATA_METHOD_NAME,
2143:                            GET_META_DATA_METHOD_SIGNATURE, null, null);
2144:                    cv.visitFieldInsn(GETSTATIC, m_joinPointClassName,
2145:                            META_DATA_FIELD_NAME, MAP_CLASS_SIGNATURE);
2146:                    cv.visitVarInsn(ALOAD, 1);
2147:                    cv.visitMethodInsn(INVOKEINTERFACE, MAP_CLASS_NAME,
2148:                            GET_METHOD_NAME, GET_METHOD_SIGNATURE);
2149:                    cv.visitInsn(ARETURN);
2150:                    cv.visitMaxs(0, 0);
2151:                }
2152:
2153:                // getCallee
2154:                {
2155:                    cv = m_cw.visitMethod(ACC_PUBLIC, GET_CALLEE_METHOD_NAME,
2156:                            NO_PARAMS_SIGNATURE + OBJECT_CLASS_SIGNATURE, null,
2157:                            null);
2158:                    cv.visitVarInsn(ALOAD, 0);
2159:                    cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2160:                            CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature);
2161:                    cv.visitInsn(ARETURN);
2162:                    cv.visitMaxs(0, 0);
2163:                }
2164:
2165:                // getCaller
2166:                {
2167:                    cv = m_cw.visitMethod(ACC_PUBLIC, GET_CALLER_METHOD_NAME,
2168:                            NO_PARAMS_SIGNATURE + OBJECT_CLASS_SIGNATURE, null,
2169:                            null);
2170:                    cv.visitVarInsn(ALOAD, 0);
2171:                    cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2172:                            CALLER_INSTANCE_FIELD_NAME, m_callerClassSignature);
2173:                    cv.visitInsn(ARETURN);
2174:                    cv.visitMaxs(0, 0);
2175:                }
2176:
2177:                // getTarget
2178:                {
2179:                    cv = m_cw.visitMethod(ACC_PUBLIC, GET_TARGET_METHOD_NAME,
2180:                            NO_PARAMS_SIGNATURE + OBJECT_CLASS_SIGNATURE, null,
2181:                            null);
2182:                    cv.visitVarInsn(ALOAD, 0);
2183:                    cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2184:                            CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature);
2185:                    cv.visitInsn(ARETURN);
2186:                    cv.visitMaxs(0, 0);
2187:                }
2188:
2189:                // getThis
2190:                {
2191:                    cv = m_cw.visitMethod(ACC_PUBLIC, GET_THIS_METHOD_NAME,
2192:                            NO_PARAMS_SIGNATURE + OBJECT_CLASS_SIGNATURE, null,
2193:                            null);
2194:                    cv.visitVarInsn(ALOAD, 0);
2195:                    cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2196:                            CALLER_INSTANCE_FIELD_NAME, m_callerClassSignature);
2197:                    cv.visitInsn(ARETURN);
2198:                    cv.visitMaxs(0, 0);
2199:                }
2200:
2201:                // getCallerClass
2202:                {
2203:                    cv = m_cw.visitMethod(ACC_PUBLIC,
2204:                            GET_CALLER_CLASS_METHOD_NAME,
2205:                            GET_CALLER_CLASS_METHOD_SIGNATURE, null, null);
2206:                    cv.visitFieldInsn(GETSTATIC, m_joinPointClassName,
2207:                            THIS_CLASS_FIELD_NAME, CLASS_CLASS_SIGNATURE);
2208:                    cv.visitInsn(ARETURN);
2209:                    cv.visitMaxs(0, 0);
2210:                }
2211:
2212:                // getCalleeClass
2213:                {
2214:                    cv = m_cw.visitMethod(ACC_PUBLIC,
2215:                            GET_CALLEE_CLASS_METHOD_NAME,
2216:                            GET_CALLEE_CLASS_METHOD_SIGNATURE, null, null);
2217:                    cv.visitFieldInsn(GETSTATIC, m_joinPointClassName,
2218:                            TARGET_CLASS_FIELD_NAME, CLASS_CLASS_SIGNATURE);
2219:                    cv.visitInsn(ARETURN);
2220:                    cv.visitMaxs(0, 0);
2221:                }
2222:
2223:                // getTargetClass, deprecated but still there
2224:                {
2225:                    cv = m_cw.visitMethod(ACC_PUBLIC,
2226:                            GET_TARGET_CLASS_METHOD_NAME,
2227:                            GET_TARGET_CLASS_METHOD_SIGNATURE, null, null);
2228:                    cv.visitFieldInsn(GETSTATIC, m_joinPointClassName,
2229:                            TARGET_CLASS_FIELD_NAME, CLASS_CLASS_SIGNATURE);
2230:                    cv.visitInsn(ARETURN);
2231:                    cv.visitMaxs(0, 0);
2232:                }
2233:
2234:                // getType
2235:                {
2236:                    cv = m_cw.visitMethod(ACC_PUBLIC, GET_TYPE_METHOD_NAME,
2237:                            GET_TYPE_METHOD_SIGNATURE, null, null);
2238:                    AsmHelper.loadIntegerConstant(cv, m_joinPointType);
2239:                    cv.visitMethodInsn(INVOKESTATIC, Type.getType(
2240:                            JoinPointType.class).getInternalName(), "fromInt",
2241:                            "(I)"
2242:                                    + Type.getType(JoinPointType.class)
2243:                                            .getDescriptor());
2244:                    cv.visitInsn(ARETURN);
2245:                    cv.visitMaxs(0, 0);
2246:                }
2247:
2248:                // getEnclosingStaticJoinPoint
2249:                {
2250:                    cv = m_cw.visitMethod(ACC_PUBLIC,
2251:                            GET_ENCLOSING_SJP_METHOD_NAME,
2252:                            GET_ENCLOSING_SJP_METHOD_SIGNATURE, null, null);
2253:                    cv.visitVarInsn(ALOAD, 0);
2254:                    cv.visitFieldInsn(GETSTATIC, m_joinPointClassName,
2255:                            ENCLOSING_SJP_FIELD_NAME,
2256:                            ENCLOSING_SJP_FIELD_CLASS_SIGNATURE);
2257:                    cv.visitInsn(ARETURN);
2258:                    cv.visitMaxs(0, 0);
2259:                }
2260:
2261:            }
2262:
2263:            /**
2264:             * Creates the copy method.
2265:             * <p/>
2266:             * TODO refactor and put in subclasses
2267:             */
2268:            protected void createCopyMethod() {
2269:
2270:                CodeVisitor cv = m_cw.visitMethod(ACC_PUBLIC, COPY_METHOD_NAME,
2271:                        COPY_METHOD_SIGNATURE, null, null);
2272:
2273:                // create a new join point instance
2274:                cv.visitTypeInsn(NEW, m_joinPointClassName);
2275:                cv.visitInsn(DUP);
2276:                int joinPointCloneIndex = 1;
2277:                cv.visitMethodInsn(INVOKESPECIAL, m_joinPointClassName,
2278:                        INIT_METHOD_NAME, NO_PARAM_RETURN_VOID_SIGNATURE);
2279:                cv.visitVarInsn(ASTORE, joinPointCloneIndex);
2280:
2281:                // set stack frame index
2282:                cv.visitVarInsn(ALOAD, joinPointCloneIndex);
2283:                cv.visitVarInsn(ALOAD, 0);
2284:                cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2285:                        STACK_FRAME_COUNTER_FIELD_NAME, I);
2286:                cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2287:                        STACK_FRAME_COUNTER_FIELD_NAME, I);
2288:
2289:                if (m_isThisAdvisable) {
2290:                    // set interceptor index
2291:                    cv.visitVarInsn(ALOAD, joinPointCloneIndex);
2292:                    cv.visitVarInsn(ALOAD, 0);
2293:                    cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2294:                            INTERCEPTOR_INDEX_FIELD_NAME, I);
2295:                    cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2296:                            INTERCEPTOR_INDEX_FIELD_NAME, I);
2297:
2298:                    // set array length fields
2299:                    cv.visitVarInsn(ALOAD, joinPointCloneIndex);
2300:                    cv.visitVarInsn(ALOAD, 0);
2301:                    cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2302:                            NR_OF_BEFORE_INTERCEPTORS_FIELD_NAME, I);
2303:                    cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2304:                            NR_OF_BEFORE_INTERCEPTORS_FIELD_NAME, I);
2305:                    cv.visitVarInsn(ALOAD, joinPointCloneIndex);
2306:                    cv.visitVarInsn(ALOAD, 0);
2307:                    cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2308:                            NR_OF_AROUND_INTERCEPTORS_FIELD_NAME, I);
2309:                    cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2310:                            NR_OF_AROUND_INTERCEPTORS_FIELD_NAME, I);
2311:                    cv.visitVarInsn(ALOAD, joinPointCloneIndex);
2312:                    cv.visitVarInsn(ALOAD, 0);
2313:                    cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2314:                            NR_OF_AFTER_INTERCEPTORS_FIELD_NAME, I);
2315:                    cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2316:                            NR_OF_AFTER_INTERCEPTORS_FIELD_NAME, I);
2317:                    cv.visitVarInsn(ALOAD, joinPointCloneIndex);
2318:                    cv.visitVarInsn(ALOAD, 0);
2319:                    cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2320:                            NR_OF_AFTER_RETURNING_INTERCEPTORS_FIELD_NAME, I);
2321:                    cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2322:                            NR_OF_AFTER_RETURNING_INTERCEPTORS_FIELD_NAME, I);
2323:                    cv.visitVarInsn(ALOAD, joinPointCloneIndex);
2324:                    cv.visitVarInsn(ALOAD, 0);
2325:                    cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2326:                            NR_OF_AFTER_THROWING_INTERCEPTORS_FIELD_NAME, I);
2327:                    cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2328:                            NR_OF_AFTER_THROWING_INTERCEPTORS_FIELD_NAME, I);
2329:
2330:                    // set arrays
2331:                    cv.visitVarInsn(ALOAD, joinPointCloneIndex);
2332:                    cv.visitVarInsn(ALOAD, 0);
2333:                    cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2334:                            BEFORE_INTERCEPTORS_FIELD_NAME,
2335:                            BEFORE_ADVICE_ARRAY_CLASS_SIGNATURE);
2336:                    cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2337:                            BEFORE_INTERCEPTORS_FIELD_NAME,
2338:                            BEFORE_ADVICE_ARRAY_CLASS_SIGNATURE);
2339:                    cv.visitVarInsn(ALOAD, joinPointCloneIndex);
2340:                    cv.visitVarInsn(ALOAD, 0);
2341:                    cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2342:                            AROUND_INTERCEPTORS_FIELD_NAME,
2343:                            AROUND_ADVICE_ARRAY_CLASS_SIGNATURE);
2344:                    cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2345:                            AROUND_INTERCEPTORS_FIELD_NAME,
2346:                            AROUND_ADVICE_ARRAY_CLASS_SIGNATURE);
2347:                    cv.visitVarInsn(ALOAD, joinPointCloneIndex);
2348:                    cv.visitVarInsn(ALOAD, 0);
2349:                    cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2350:                            AFTER_INTERCEPTORS_FIELD_NAME,
2351:                            AFTER_ADVICE_ARRAY_CLASS_SIGNATURE);
2352:                    cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2353:                            AFTER_INTERCEPTORS_FIELD_NAME,
2354:                            AFTER_ADVICE_ARRAY_CLASS_SIGNATURE);
2355:                    cv.visitVarInsn(ALOAD, joinPointCloneIndex);
2356:                    cv.visitVarInsn(ALOAD, 0);
2357:                    cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2358:                            AFTER_RETURNING_INTERCEPTORS_FIELD_NAME,
2359:                            AFTER_RETURNING_ADVICE_ARRAY_CLASS_SIGNATURE);
2360:                    cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2361:                            AFTER_RETURNING_INTERCEPTORS_FIELD_NAME,
2362:                            AFTER_RETURNING_ADVICE_ARRAY_CLASS_SIGNATURE);
2363:                    cv.visitVarInsn(ALOAD, joinPointCloneIndex);
2364:                    cv.visitVarInsn(ALOAD, 0);
2365:                    cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2366:                            AFTER_THROWING_INTERCEPTORS_FIELD_NAME,
2367:                            AFTER_THROWING_ADVICE_ARRAY_CLASS_SIGNATURE);
2368:                    cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2369:                            AFTER_THROWING_INTERCEPTORS_FIELD_NAME,
2370:                            AFTER_THROWING_ADVICE_ARRAY_CLASS_SIGNATURE);
2371:                }
2372:
2373:                // set callee
2374:                cv.visitVarInsn(ALOAD, joinPointCloneIndex);
2375:                cv.visitVarInsn(ALOAD, 0);
2376:                cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2377:                        CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature);
2378:                cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2379:                        CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature);
2380:
2381:                // set caller
2382:                cv.visitVarInsn(ALOAD, joinPointCloneIndex);
2383:                cv.visitVarInsn(ALOAD, 0);
2384:                cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2385:                        CALLER_INSTANCE_FIELD_NAME, m_callerClassSignature);
2386:                cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2387:                        CALLER_INSTANCE_FIELD_NAME, m_callerClassSignature);
2388:
2389:                // set the arguments
2390:                for (int i = 0; i < m_fieldNames.length; i++) {
2391:                    String fieldName = m_fieldNames[i];
2392:                    cv.visitVarInsn(ALOAD, joinPointCloneIndex);
2393:                    cv.visitVarInsn(ALOAD, 0);
2394:                    cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2395:                            fieldName, m_argumentTypes[i].getDescriptor());
2396:                    cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2397:                            fieldName, m_argumentTypes[i].getDescriptor());
2398:                }
2399:
2400:                // set the returned field if any
2401:                if (m_returnType.getSort() != Type.VOID) {
2402:                    cv.visitVarInsn(ALOAD, joinPointCloneIndex);
2403:                    cv.visitVarInsn(ALOAD, 0);
2404:                    cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2405:                            RETURN_VALUE_FIELD_NAME, m_returnType
2406:                                    .getDescriptor());
2407:                    cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2408:                            RETURN_VALUE_FIELD_NAME, m_returnType
2409:                                    .getDescriptor());
2410:                }
2411:
2412:                cv.visitVarInsn(ALOAD, joinPointCloneIndex);
2413:                cv.visitInsn(ARETURN);
2414:                cv.visitMaxs(0, 0);
2415:            }
2416:
2417:            /**
2418:             * Build up the signature of the 'invoke' methods.
2419:             *
2420:             * @return
2421:             */
2422:            protected String buildInvokeMethodSignature() {
2423:                StringBuffer invokeDescBuf = new StringBuffer();
2424:                invokeDescBuf.append('(');
2425:                if (m_joinPointType != JoinPointType.CONSTRUCTOR_CALL_INT) {
2426:                    if (!Modifier.isStatic(m_calleeMemberModifiers)) {
2427:                        // callee
2428:                        invokeDescBuf.append(m_calleeClassSignature);
2429:                    }
2430:                }
2431:                // args
2432:                for (int i = 0; i < m_argumentTypes.length; i++) {
2433:                    Type type = m_argumentTypes[i];
2434:                    invokeDescBuf.append(type.getDescriptor());
2435:                }
2436:                // caller
2437:                invokeDescBuf.append(m_callerClassSignature);
2438:                invokeDescBuf.append(')');
2439:                invokeDescBuf.append(m_returnType.getDescriptor());
2440:                return invokeDescBuf.toString();
2441:            }
2442:
2443:            /**
2444:             * Return the number of argument the joinpoint has (excludes JoinPoint, Rtti, this / target) but is only
2445:             * the number of argument we will have in the rtti (advised method/ctor args or 1 for field / handler)
2446:             *
2447:             * @return
2448:             */
2449:            protected final boolean hasArguments() {
2450:                return m_argumentTypes.length > 0;
2451:            }
2452:
2453:            /**
2454:             * Checks if at least one advice is using this or target (bounded or runtime check)
2455:             *
2456:             * @return true if so
2457:             */
2458:            protected boolean requiresThisOrTarget() {
2459:                return m_isThisAdvisable
2460:                        || requiresThisOrTarget(m_aroundAdviceMethodInfos)
2461:                        || requiresThisOrTarget(m_beforeAdviceMethodInfos)
2462:                        || requiresThisOrTarget(m_afterFinallyAdviceMethodInfos)
2463:                        || requiresThisOrTarget(m_afterReturningAdviceMethodInfos)
2464:                        || requiresThisOrTarget(m_afterThrowingAdviceMethodInfos);
2465:            }
2466:
2467:            /**
2468:             * Checks if at least one advice is using the non static JoinPoint explicitly
2469:             *
2470:             * @return true if so
2471:             */
2472:            protected boolean requiresJoinPoint() {
2473:                return m_isThisAdvisable
2474:                        || requiresJoinPoint(m_aroundAdviceMethodInfos)
2475:                        || requiresJoinPoint(m_beforeAdviceMethodInfos)
2476:                        || requiresJoinPoint(m_afterFinallyAdviceMethodInfos)
2477:                        || requiresJoinPoint(m_afterReturningAdviceMethodInfos)
2478:                        || requiresJoinPoint(m_afterThrowingAdviceMethodInfos);
2479:            }
2480:
2481:            /**
2482:             * Checks if at least one advice is using target or this (bounded or runtime check)
2483:             *
2484:             * @param adviceMethodInfos
2485:             * @return true if so
2486:             */
2487:            protected boolean requiresThisOrTarget(
2488:                    final AdviceMethodInfo[] adviceMethodInfos) {
2489:                for (int i = 0; i < adviceMethodInfos.length; i++) {
2490:                    if (adviceMethodInfos[i].requiresThisOrTarget()) {
2491:                        return true;
2492:                    }
2493:                }
2494:                return false;
2495:            }
2496:
2497:            /**
2498:             * Checks if at least one advice is using non static JoinPoint explicitly
2499:             *
2500:             * @param adviceMethodInfos
2501:             * @return true if so
2502:             */
2503:            protected boolean requiresJoinPoint(
2504:                    final AdviceMethodInfo[] adviceMethodInfos) {
2505:                for (int i = 0; i < adviceMethodInfos.length; i++) {
2506:                    if (adviceMethodInfos[i].requiresJoinPoint()) {
2507:                        return true;
2508:                    }
2509:                }
2510:                return false;
2511:            }
2512:
2513:            /**
2514:             * Handles the if case for runtime check (target instanceof, cflow)
2515:             *
2516:             * @param cv
2517:             * @param isOptimizedJoinPoint
2518:             * @param joinPointInstanceIndex
2519:             * @param adviceInfo
2520:             * @return the label for endIf or null if the adviceInfo did not required runtime check
2521:             */
2522:            protected Label beginRuntimeCheck(final CodeVisitor cv,
2523:                    final boolean isOptimizedJoinPoint,
2524:                    final int joinPointInstanceIndex,
2525:                    final AdviceInfo adviceInfo, final int calleeIndex) {
2526:                Label endRuntimeCheckLabel = null;
2527:                if (adviceInfo.hasTargetWithRuntimeCheck()
2528:                        || adviceInfo.getAdviceDefinition()
2529:                                .hasCflowOrCflowBelow()) {
2530:                    endRuntimeCheckLabel = new Label();
2531:                    // create a specific visitor everytime
2532:                    RuntimeCheckVisitor runtimeCheckVisitor = new RuntimeCheckVisitor(
2533:                            this , cv, adviceInfo.getExpressionInfo(),
2534:                            isOptimizedJoinPoint, joinPointInstanceIndex,
2535:                            calleeIndex);
2536:                    runtimeCheckVisitor.pushCheckOnStack(adviceInfo
2537:                            .getExpressionContext());
2538:                    cv.visitJumpInsn(IFEQ, endRuntimeCheckLabel);
2539:                }
2540:                return endRuntimeCheckLabel;
2541:            }
2542:
2543:            /**
2544:             * Ends the ifLabel of a runtime check
2545:             *
2546:             * @param cv
2547:             * @param adviceInfo
2548:             * @param label      if null, then do nothing (means we did not had a runtime check)
2549:             */
2550:            protected void endRuntimeCheck(final CodeVisitor cv,
2551:                    final AdviceInfo adviceInfo, final Label label) {
2552:                if (adviceInfo.hasTargetWithRuntimeCheck()
2553:                        || adviceInfo.getAdviceDefinition()
2554:                                .hasCflowOrCflowBelow()) {
2555:                    cv.visitLabel(label);
2556:                }
2557:            }
2558:
2559:            /**
2560:             * Helper method to load the callee on the stack
2561:             *
2562:             * @param cv
2563:             * @param isOptimizedJoinPoint
2564:             * @param joinPointIndex
2565:             * @param calleeIndex
2566:             */
2567:            public void loadCallee(final CodeVisitor cv,
2568:                    final boolean isOptimizedJoinPoint,
2569:                    final int joinPointIndex, final int calleeIndex) {
2570:                if (isOptimizedJoinPoint) {
2571:                    // grab the callee from the invoke parameters directly
2572:                    cv.visitVarInsn(ALOAD, calleeIndex);
2573:                } else {
2574:                    loadJoinPointInstance(cv, isOptimizedJoinPoint,
2575:                            joinPointIndex);
2576:                    cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2577:                            CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature);
2578:                }
2579:            }
2580:
2581:            /**
2582:             * Helper method to load the caller on the stack
2583:             *
2584:             * @param cv
2585:             * @param isOptimizedJoinPoint
2586:             * @param joinPointIndex
2587:             * @param callerIndex
2588:             */
2589:            protected void loadCaller(final CodeVisitor cv,
2590:                    final boolean isOptimizedJoinPoint,
2591:                    final int joinPointIndex, final int callerIndex) {
2592:                if (isOptimizedJoinPoint) {
2593:                    // grab the callee from the invoke parameters directly
2594:                    cv.visitVarInsn(ALOAD, callerIndex);
2595:                } else {
2596:                    loadJoinPointInstance(cv, isOptimizedJoinPoint,
2597:                            joinPointIndex);
2598:                    cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2599:                            CALLER_INSTANCE_FIELD_NAME, m_callerClassSignature);
2600:                }
2601:            }
2602:
2603:            /**
2604:             * Loads the aspect instance.
2605:             *
2606:             * @param cv
2607:             * @param isOptimizedJoinPoint
2608:             * @param joinPointIndex
2609:             * @param aspectInfo
2610:             */
2611:            protected void loadAspect(final CodeVisitor cv,
2612:                    final boolean isOptimizedJoinPoint,
2613:                    final int joinPointIndex, final AspectInfo aspectInfo) {
2614:                DeploymentModel deploymentModel = aspectInfo
2615:                        .getDeploymentModel();
2616:                if (deploymentModel.equals(DeploymentModel.PER_JVM)
2617:                        || deploymentModel.equals(DeploymentModel.PER_CLASS)) {
2618:                    cv.visitFieldInsn(GETSTATIC, m_joinPointClassName,
2619:                            aspectInfo.getAspectFieldName(), aspectInfo
2620:                                    .getAspectClassSignature());
2621:                } else if (deploymentModel.equals(DeploymentModel.PER_INSTANCE)) {
2622:                    loadJoinPointInstance(cv, isOptimizedJoinPoint,
2623:                            joinPointIndex);
2624:                    cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2625:                            aspectInfo.getAspectFieldName(), aspectInfo
2626:                                    .getAspectClassSignature());
2627:                } else {
2628:                    throw new DefinitionException("deployment model ["
2629:                            + deploymentModel + "] is not supported");
2630:                }
2631:            }
2632:
2633:            /**
2634:             * Creates an invocation to Aspects.aspectOf(..).
2635:             *
2636:             * @param cv
2637:             * @param isOptimizedJoinPoint
2638:             * @param joinPointIndex
2639:             * @param callerIndex
2640:             * @param calleeIndex
2641:             * @param aspectInfo
2642:             */
2643:            public void createInvocationToAspectOf(final CodeVisitor cv,
2644:                    final boolean isOptimizedJoinPoint,
2645:                    final int joinPointIndex, final int callerIndex,
2646:                    final int calleeIndex, final AspectInfo aspectInfo) {
2647:                if (aspectInfo.getDeploymentModel() == DeploymentModel.PER_INSTANCE) {
2648:
2649:                    //generates code: aspectField = (cast) Aspects.aspect$Of(aspectQN, containerClassName, callee)
2650:                    loadJoinPointInstance(cv, isOptimizedJoinPoint,
2651:                            joinPointIndex);
2652:                    cv.visitLdcInsn(aspectInfo.getAspectQualifiedName());
2653:                    if (calleeIndex >= 0) {
2654:                        cv.visitVarInsn(ALOAD, calleeIndex);
2655:                        cv.visitLdcInsn(aspectInfo.getAspectDefinition()
2656:                                .getContainerClassName());
2657:                        cv.visitMethodInsn(INVOKESTATIC, ASPECTS_CLASS_NAME,
2658:                                ASPECT_OF_METHOD_NAME,
2659:                                ASPECT_OF_PER_INSTANCE_METHOD_SIGNATURE);
2660:                    } else {
2661:                        // TODO: should this really happen? we are filtering at early stage now. - REMOVE CODE BLOCK
2662:                        // fallback to perClass
2663:                        //aspectField = (cast) Aspects.aspectOf(aspectQN, containerClass, calleeClass)
2664:                        cv.visitFieldInsn(GETSTATIC, m_joinPointClassName,
2665:                                TARGET_CLASS_FIELD_NAME, CLASS_CLASS_SIGNATURE);
2666:                        cv.visitLdcInsn(aspectInfo.getAspectDefinition()
2667:                                .getContainerClassName());
2668:                        cv.visitMethodInsn(INVOKESTATIC, ASPECTS_CLASS_NAME,
2669:                                ASPECT_OF_METHOD_NAME,
2670:                                ASPECT_OF_PER_CLASS_METHOD_SIGNATURE);
2671:                    }
2672:                    cv
2673:                            .visitTypeInsn(CHECKCAST, aspectInfo
2674:                                    .getAspectClassName());
2675:                    cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2676:                            aspectInfo.getAspectFieldName(), aspectInfo
2677:                                    .getAspectClassSignature());
2678:                }
2679:            }
2680:
2681:            /**
2682:             * Generates code needed for handling Advisable management for the target class.
2683:             *
2684:             * @param cv
2685:             * @param joinPointInstanceIndex
2686:             * @param advisableIndex
2687:             */
2688:            private void createInitializationForAdvisableManagement(
2689:                    final CodeVisitor cv, final int joinPointInstanceIndex,
2690:                    final int advisableIndex) {
2691:                // interceptor index
2692:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
2693:                cv.visitInsn(ICONST_M1);
2694:                cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2695:                        INTERCEPTOR_INDEX_FIELD_NAME, I);
2696:
2697:                initializeAroundInterceptors(cv, joinPointInstanceIndex,
2698:                        advisableIndex);
2699:                initializeBeforeInterceptors(cv, joinPointInstanceIndex,
2700:                        advisableIndex);
2701:                initializeAfterInterceptors(cv, joinPointInstanceIndex,
2702:                        advisableIndex);
2703:                initializeAfterReturningInterceptors(cv,
2704:                        joinPointInstanceIndex, advisableIndex);
2705:                initializeAfterThrowingInterceptors(cv, joinPointInstanceIndex,
2706:                        advisableIndex);
2707:            }
2708:
2709:            /**
2710:             * Handle the around interceptor init.
2711:             *
2712:             * @param cv
2713:             * @param joinPointInstanceIndex
2714:             * @param advisableIndex
2715:             */
2716:            private void initializeAroundInterceptors(final CodeVisitor cv,
2717:                    final int joinPointInstanceIndex, final int advisableIndex) {
2718:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
2719:                cv.visitVarInsn(ALOAD, advisableIndex);
2720:                cv.visitTypeInsn(CHECKCAST, ADVISABLE_CLASS_NAME);
2721:                cv.visitLdcInsn(new Integer(m_joinPointClassName.hashCode()));
2722:                cv.visitMethodInsn(INVOKEINTERFACE, ADVISABLE_CLASS_NAME,
2723:                        GET_AROUND_ADVICE_METHOD_NAME,
2724:                        GET_AROUND_ADVICE_METHOD_SIGNATURE);
2725:                cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2726:                        AROUND_INTERCEPTORS_FIELD_NAME,
2727:                        AROUND_ADVICE_ARRAY_CLASS_SIGNATURE);
2728:
2729:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
2730:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
2731:                cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2732:                        AROUND_INTERCEPTORS_FIELD_NAME,
2733:                        AROUND_ADVICE_ARRAY_CLASS_SIGNATURE);
2734:                cv.visitInsn(ARRAYLENGTH);
2735:                cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2736:                        NR_OF_AROUND_INTERCEPTORS_FIELD_NAME, I);
2737:            }
2738:
2739:            /**
2740:             * Handle the before interceptor init.
2741:             *
2742:             * @param cv
2743:             * @param joinPointInstanceIndex
2744:             * @param advisableIndex
2745:             */
2746:            private void initializeBeforeInterceptors(final CodeVisitor cv,
2747:                    final int joinPointInstanceIndex, final int advisableIndex) {
2748:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
2749:                cv.visitVarInsn(ALOAD, advisableIndex);
2750:                cv.visitTypeInsn(CHECKCAST, ADVISABLE_CLASS_NAME);
2751:                cv.visitLdcInsn(new Integer(m_joinPointClassName.hashCode()));
2752:                cv.visitMethodInsn(INVOKEINTERFACE, ADVISABLE_CLASS_NAME,
2753:                        GET_BEFORE_ADVICE_METHOD_NAME,
2754:                        GET_BEFORE_ADVICE_METHOD_SIGNATURE);
2755:                cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2756:                        BEFORE_INTERCEPTORS_FIELD_NAME,
2757:                        BEFORE_ADVICE_ARRAY_CLASS_SIGNATURE);
2758:
2759:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
2760:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
2761:                cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2762:                        BEFORE_INTERCEPTORS_FIELD_NAME,
2763:                        BEFORE_ADVICE_ARRAY_CLASS_SIGNATURE);
2764:                cv.visitInsn(ARRAYLENGTH);
2765:                cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2766:                        NR_OF_BEFORE_INTERCEPTORS_FIELD_NAME, I);
2767:            }
2768:
2769:            /**
2770:             * Handle the after finally interceptor init.
2771:             *
2772:             * @param cv
2773:             * @param joinPointInstanceIndex
2774:             * @param advisableIndex
2775:             */
2776:            private void initializeAfterInterceptors(final CodeVisitor cv,
2777:                    final int joinPointInstanceIndex, final int advisableIndex) {
2778:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
2779:                cv.visitVarInsn(ALOAD, advisableIndex);
2780:                cv.visitTypeInsn(CHECKCAST, ADVISABLE_CLASS_NAME);
2781:                cv.visitLdcInsn(new Integer(m_joinPointClassName.hashCode()));
2782:                cv.visitMethodInsn(INVOKEINTERFACE, ADVISABLE_CLASS_NAME,
2783:                        GET_AFTER_ADVICE_METHOD_NAME,
2784:                        GET_AFTER_ADVICE_METHOD_SIGNATURE);
2785:                cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2786:                        AFTER_INTERCEPTORS_FIELD_NAME,
2787:                        AFTER_ADVICE_ARRAY_CLASS_SIGNATURE);
2788:
2789:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
2790:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
2791:                cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2792:                        AFTER_INTERCEPTORS_FIELD_NAME,
2793:                        AFTER_ADVICE_ARRAY_CLASS_SIGNATURE);
2794:                cv.visitInsn(ARRAYLENGTH);
2795:                cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2796:                        NR_OF_AFTER_INTERCEPTORS_FIELD_NAME, I);
2797:            }
2798:
2799:            /**
2800:             * Handle the after returning interceptor init.
2801:             *
2802:             * @param cv
2803:             * @param joinPointInstanceIndex
2804:             * @param advisableIndex
2805:             */
2806:            private void initializeAfterReturningInterceptors(
2807:                    final CodeVisitor cv, final int joinPointInstanceIndex,
2808:                    final int advisableIndex) {
2809:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
2810:                cv.visitVarInsn(ALOAD, advisableIndex);
2811:                cv.visitTypeInsn(CHECKCAST, ADVISABLE_CLASS_NAME);
2812:                cv.visitLdcInsn(new Integer(m_joinPointClassName.hashCode()));
2813:                cv.visitMethodInsn(INVOKEINTERFACE, ADVISABLE_CLASS_NAME,
2814:                        GET_AFTER_RETURNING_ADVICE_METHOD_NAME,
2815:                        GET_AFTER_RETURNING_ADVICE_METHOD_SIGNATURE);
2816:                cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2817:                        AFTER_RETURNING_INTERCEPTORS_FIELD_NAME,
2818:                        AFTER_RETURNING_ADVICE_ARRAY_CLASS_SIGNATURE);
2819:
2820:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
2821:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
2822:                cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2823:                        AFTER_RETURNING_INTERCEPTORS_FIELD_NAME,
2824:                        AFTER_RETURNING_ADVICE_ARRAY_CLASS_SIGNATURE);
2825:                cv.visitInsn(ARRAYLENGTH);
2826:                cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2827:                        NR_OF_AFTER_RETURNING_INTERCEPTORS_FIELD_NAME, I);
2828:            }
2829:
2830:            /**
2831:             * Handle the after throwing interceptor init.
2832:             *
2833:             * @param cv
2834:             * @param joinPointInstanceIndex
2835:             * @param advisableIndex
2836:             */
2837:            private void initializeAfterThrowingInterceptors(
2838:                    final CodeVisitor cv, final int joinPointInstanceIndex,
2839:                    final int advisableIndex) {
2840:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
2841:                cv.visitVarInsn(ALOAD, advisableIndex);
2842:                cv.visitTypeInsn(CHECKCAST, ADVISABLE_CLASS_NAME);
2843:                cv.visitLdcInsn(new Integer(m_joinPointClassName.hashCode()));
2844:                cv.visitMethodInsn(INVOKEINTERFACE, ADVISABLE_CLASS_NAME,
2845:                        GET_AFTER_THROWING_ADVICE_METHOD_NAME,
2846:                        GET_AFTER_THROWING_ADVICE_METHOD_SIGNATURE);
2847:                cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2848:                        AFTER_THROWING_INTERCEPTORS_FIELD_NAME,
2849:                        AFTER_THROWING_ADVICE_ARRAY_CLASS_SIGNATURE);
2850:
2851:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
2852:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
2853:                cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2854:                        AFTER_THROWING_INTERCEPTORS_FIELD_NAME,
2855:                        AFTER_THROWING_ADVICE_ARRAY_CLASS_SIGNATURE);
2856:                cv.visitInsn(ARRAYLENGTH);
2857:                cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2858:                        NR_OF_AFTER_THROWING_INTERCEPTORS_FIELD_NAME, I);
2859:            }
2860:
2861:            /**
2862:             * Handles the around interceptor invocations.
2863:             *
2864:             * @param cv
2865:             */
2866:            private void createAroundInterceptorInvocations(final CodeVisitor cv) {
2867:                cv.visitVarInsn(ALOAD, 0);
2868:                cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2869:                        INTERCEPTOR_INDEX_FIELD_NAME, I);
2870:                cv.visitInsn(ICONST_M1);
2871:                Label ifStatementLabel = new Label();
2872:                cv.visitJumpInsn(IF_ICMPEQ, ifStatementLabel);
2873:                cv.visitVarInsn(ALOAD, 0);
2874:                cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2875:                        INTERCEPTOR_INDEX_FIELD_NAME, I);
2876:                cv.visitVarInsn(ALOAD, 0);
2877:                cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2878:                        NR_OF_AROUND_INTERCEPTORS_FIELD_NAME, I);
2879:                cv.visitJumpInsn(IF_ICMPGE, ifStatementLabel);
2880:                cv.visitVarInsn(ALOAD, 0);
2881:                cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2882:                        AROUND_INTERCEPTORS_FIELD_NAME,
2883:                        AROUND_ADVICE_ARRAY_CLASS_SIGNATURE);
2884:                cv.visitVarInsn(ALOAD, 0);
2885:                cv.visitInsn(DUP);
2886:                cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2887:                        INTERCEPTOR_INDEX_FIELD_NAME, I);
2888:                cv.visitInsn(DUP_X1);
2889:                cv.visitInsn(ICONST_1);
2890:                cv.visitInsn(IADD);
2891:                cv.visitFieldInsn(PUTFIELD, m_joinPointClassName,
2892:                        INTERCEPTOR_INDEX_FIELD_NAME, I);
2893:                cv.visitInsn(AALOAD);
2894:                cv.visitVarInsn(ALOAD, 0);
2895:                cv.visitMethodInsn(INVOKEINTERFACE, AROUND_ADVICE_CLASS_NAME,
2896:                        INTERCEPT_INVOKE_METHOD_NAME,
2897:                        AROUND_ADVICE_INVOKE_METHOD_SIGNATURE);
2898:                cv.visitInsn(ARETURN);
2899:                cv.visitLabel(ifStatementLabel);
2900:            }
2901:
2902:            /**
2903:             * Creates invocations fo the before interceptors.
2904:             *
2905:             * @param cv
2906:             * @param joinPointInstanceIndex
2907:             * @param registerDepth
2908:             */
2909:            private void createBeforeInterceptorInvocations(
2910:                    final CodeVisitor cv, final int joinPointInstanceIndex,
2911:                    final int registerDepth) {
2912:                final int loopIndex = registerDepth + 1;
2913:                cv.visitInsn(ICONST_0);
2914:                cv.visitVarInsn(ISTORE, loopIndex);
2915:                Label loopStartLabel = new Label();
2916:                cv.visitLabel(loopStartLabel);
2917:                cv.visitVarInsn(ILOAD, loopIndex);
2918:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
2919:                cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2920:                        NR_OF_BEFORE_INTERCEPTORS_FIELD_NAME, I);
2921:                Label loopCheckCondLabel = new Label();
2922:                cv.visitJumpInsn(IF_ICMPGE, loopCheckCondLabel);
2923:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
2924:                cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2925:                        BEFORE_INTERCEPTORS_FIELD_NAME,
2926:                        BEFORE_ADVICE_ARRAY_CLASS_SIGNATURE);
2927:                cv.visitVarInsn(ILOAD, loopIndex);
2928:                cv.visitInsn(AALOAD);
2929:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
2930:                cv.visitMethodInsn(INVOKEINTERFACE, BEFORE_ADVICE_CLASS_NAME,
2931:                        INTERCEPT_INVOKE_METHOD_NAME,
2932:                        BEFORE_ADVICE_INVOKE_METHOD_SIGNATURE);
2933:                cv.visitIincInsn(loopIndex, 1);
2934:                cv.visitJumpInsn(GOTO, loopStartLabel);
2935:                cv.visitLabel(loopCheckCondLabel);
2936:            }
2937:
2938:            /**
2939:             * Creates invocations fo the after finally interceptors.
2940:             *
2941:             * @param cv
2942:             * @param joinPointInstanceIndex
2943:             * @param registerDepth
2944:             */
2945:            private void createAfterInterceptorInvocations(
2946:                    final CodeVisitor cv, final int joinPointInstanceIndex,
2947:                    final int registerDepth) {
2948:                final int loopIndex = registerDepth + 1;
2949:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
2950:                cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2951:                        NR_OF_AFTER_INTERCEPTORS_FIELD_NAME, I);
2952:                cv.visitInsn(ICONST_1);
2953:                cv.visitInsn(ISUB);
2954:                cv.visitVarInsn(ISTORE, loopIndex);
2955:                Label loopLabel1 = new Label();
2956:                cv.visitLabel(loopLabel1);
2957:                cv.visitVarInsn(ILOAD, loopIndex);
2958:                Label loopLabel2 = new Label();
2959:                cv.visitJumpInsn(IFLT, loopLabel2);
2960:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
2961:                cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2962:                        AFTER_INTERCEPTORS_FIELD_NAME,
2963:                        AFTER_ADVICE_ARRAY_CLASS_SIGNATURE);
2964:                cv.visitVarInsn(ILOAD, loopIndex);
2965:                cv.visitInsn(AALOAD);
2966:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
2967:                cv.visitMethodInsn(INVOKEINTERFACE, AFTER_ADVICE_CLASS_NAME,
2968:                        INTERCEPT_INVOKE_METHOD_NAME,
2969:                        AFTER_ADVICE_INVOKE_METHOD_SIGNATURE);
2970:                cv.visitIincInsn(loopIndex, -1);
2971:                cv.visitJumpInsn(GOTO, loopLabel1);
2972:                cv.visitLabel(loopLabel2);
2973:            }
2974:
2975:            /**
2976:             * Creates invocations fo the after returning interceptors.
2977:             *
2978:             * @param cv
2979:             * @param joinPointInstanceIndex
2980:             * @param returnValueInstanceIndex
2981:             */
2982:            private void createAfterReturningInterceptorInvocations(
2983:                    final CodeVisitor cv, final int joinPointInstanceIndex,
2984:                    final int returnValueInstanceIndex) {
2985:                final int loopIndex = returnValueInstanceIndex + 1;
2986:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
2987:                cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2988:                        NR_OF_AFTER_RETURNING_INTERCEPTORS_FIELD_NAME, I);
2989:                cv.visitInsn(ICONST_1);
2990:                cv.visitInsn(ISUB);
2991:                cv.visitVarInsn(ISTORE, loopIndex);
2992:                Label loopLabel1 = new Label();
2993:                cv.visitLabel(loopLabel1);
2994:                cv.visitVarInsn(ILOAD, loopIndex);
2995:                Label loopLabel2 = new Label();
2996:                cv.visitJumpInsn(IFLT, loopLabel2);
2997:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
2998:                cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
2999:                        AFTER_RETURNING_INTERCEPTORS_FIELD_NAME,
3000:                        AFTER_RETURNING_ADVICE_ARRAY_CLASS_SIGNATURE);
3001:                cv.visitVarInsn(ILOAD, loopIndex);
3002:                cv.visitInsn(AALOAD);
3003:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
3004:                cv.visitVarInsn(ALOAD, returnValueInstanceIndex);
3005:                cv.visitMethodInsn(INVOKEINTERFACE,
3006:                        AFTER_RETURNING_ADVICE_CLASS_NAME,
3007:                        INTERCEPT_INVOKE_METHOD_NAME,
3008:                        AFTER_RETURNING_ADVICE_INVOKE_METHOD_SIGNATURE);
3009:                cv.visitIincInsn(loopIndex, -1);
3010:                cv.visitJumpInsn(GOTO, loopLabel1);
3011:                cv.visitLabel(loopLabel2);
3012:            }
3013:
3014:            /**
3015:             * Creates invocations fo the after returning interceptors.
3016:             *
3017:             * @param cv
3018:             * @param joinPointInstanceIndex
3019:             * @param exceptionInstanceIndex
3020:             */
3021:            private void createAfterThrowingInterceptorInvocations(
3022:                    final CodeVisitor cv, final int joinPointInstanceIndex,
3023:                    final int exceptionInstanceIndex) {
3024:                final int loopIndex = exceptionInstanceIndex + 1;
3025:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
3026:                cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
3027:                        NR_OF_AFTER_THROWING_INTERCEPTORS_FIELD_NAME, I);
3028:                cv.visitInsn(ICONST_1);
3029:                cv.visitInsn(ISUB);
3030:                cv.visitVarInsn(ISTORE, loopIndex);
3031:                Label loopLabel1 = new Label();
3032:                cv.visitLabel(loopLabel1);
3033:                cv.visitVarInsn(ILOAD, loopIndex);
3034:                Label loopLabel2 = new Label();
3035:                cv.visitJumpInsn(IFLT, loopLabel2);
3036:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
3037:                cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
3038:                        AFTER_THROWING_INTERCEPTORS_FIELD_NAME,
3039:                        AFTER_THROWING_ADVICE_ARRAY_CLASS_SIGNATURE);
3040:                cv.visitVarInsn(ILOAD, loopIndex);
3041:                cv.visitInsn(AALOAD);
3042:                cv.visitVarInsn(ALOAD, joinPointInstanceIndex);
3043:                cv.visitVarInsn(ALOAD, exceptionInstanceIndex);
3044:                cv.visitMethodInsn(INVOKEINTERFACE,
3045:                        AFTER_THROWING_ADVICE_CLASS_NAME,
3046:                        INTERCEPT_INVOKE_METHOD_NAME,
3047:                        AFTER_THROWING_ADVICE_INVOKE_METHOD_SIGNATURE);
3048:                cv.visitIincInsn(loopIndex, -1);
3049:                cv.visitJumpInsn(GOTO, loopLabel1);
3050:                cv.visitLabel(loopLabel2);
3051:            }
3052:
3053:            /**
3054:             * Checks if the join point requires a proceed() method.
3055:             *
3056:             * @return
3057:             */
3058:            protected boolean requiresProceedMethod() {
3059:                return m_hasAroundAdvices || m_isThisAdvisable;
3060:            }
3061:
3062:            private static class CustomProceedMethodStruct {
3063:                MethodInfo customProceed;
3064:                int[] adviceToTargetArgs;
3065:
3066:                public CustomProceedMethodStruct(MethodInfo customProceed,
3067:                        int[] adviceToTargetArgs) {
3068:                    this.customProceed = customProceed;
3069:                    this.adviceToTargetArgs = adviceToTargetArgs;
3070:                }
3071:            }
3072:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.