Source Code Cross Referenced for AbstractJoinPointCompiler.java in  » Net » Terracotta » com » tc » 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 » Net » Terracotta » com.tc.aspectwerkz.transform.inlining.compiler 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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