001: /**************************************************************************************
002: * Copyright (c) Jonas BonŽr, Alexandre Vasseur. All rights reserved. *
003: * http://aspectwerkz.codehaus.org *
004: * ---------------------------------------------------------------------------------- *
005: * The software in this package is published under the terms of the LGPL license *
006: * a copy of which has been included with this distribution in the license.txt file. *
007: **************************************************************************************/package org.codehaus.aspectwerkz.transform.inlining.compiler;
008:
009: import org.objectweb.asm.CodeVisitor;
010: import org.objectweb.asm.Type;
011:
012: /**
013: * A compiler that compiles/generates a class that represents a specific join point, a class which invokes the advices
014: * and the target join point statically.
015: * <p/>
016: * In this case, CALLEE is the catched exception instance itself.
017: *
018: * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
019: * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur </a>
020: */
021: public class HandlerJoinPointCompiler extends AbstractJoinPointCompiler {
022:
023: /**
024: * Creates a new join point compiler instance.
025: *
026: * @param model
027: */
028: HandlerJoinPointCompiler(final CompilationInfo.Model model) {
029: super (model);
030: }
031:
032: /**
033: * Creates join point specific fields.
034: */
035: protected void createJoinPointSpecificFields() {
036: // create the field argument field
037: String[] fieldNames = null;
038: Type fieldType = Type.getType(m_calleeClassSignature);
039: fieldNames = new String[1];
040: String fieldName = ARGUMENT_FIELD + 0;
041: fieldNames[0] = fieldName;
042: m_cw.visitField(ACC_PRIVATE, fieldName, fieldType
043: .getDescriptor(), null, null);
044: m_fieldNames = fieldNames;
045: m_cw.visitField(ACC_PRIVATE + ACC_STATIC, SIGNATURE_FIELD_NAME,
046: HANDLER_SIGNATURE_IMPL_CLASS_SIGNATURE, null, null);
047: }
048:
049: /**
050: * Creates the signature for the join point.
051: *
052: * @param cv
053: */
054: protected void createSignature(final CodeVisitor cv) {
055: cv.visitFieldInsn(GETSTATIC, m_joinPointClassName,
056: TARGET_CLASS_FIELD_NAME, CLASS_CLASS_SIGNATURE);
057:
058: cv.visitMethodInsn(INVOKESTATIC, SIGNATURE_FACTORY_CLASS,
059: NEW_CATCH_CLAUSE_SIGNATURE_METHOD_NAME,
060: NEW_HANDLER_SIGNATURE_METHOD_SIGNATURE);
061: cv.visitFieldInsn(PUTSTATIC, m_joinPointClassName,
062: SIGNATURE_FIELD_NAME,
063: HANDLER_SIGNATURE_IMPL_CLASS_SIGNATURE);
064:
065: }
066:
067: /**
068: * Optimized implementation that does not retrieve the parameters from the join point instance but is passed
069: * directly to the method from the input parameters in the 'invoke' method. Can only be used if no around advice
070: * exists.
071: *
072: * @param cv
073: * @param argStartIndex index on stack of first target method arg (0 or 1, depends of static target or not)
074: */
075: protected void createInlinedJoinPointInvocation(
076: final CodeVisitor cv, final boolean isOptimizedJoinPoint,
077: final int argStartIndex, final int joinPointIndex) {
078: // load the exception
079: cv.visitVarInsn(ALOAD, 0);//TODO if changed perhaps load CALLEE instead that host the exception ?
080: }
081:
082: /**
083: * Creates a call to the target join point, the parameter(s) to the join point are retrieved from the invocation
084: * local join point instance.
085: *
086: * @param cv
087: */
088: protected void createJoinPointInvocation(final CodeVisitor cv) {
089: cv.visitInsn(ACONST_NULL);
090: }
091:
092: /**
093: * Returns the join points return type.
094: *
095: * @return
096: */
097: protected Type getJoinPointReturnType() {
098: return Type.getType(m_calleeClassSignature);
099: }
100:
101: /**
102: * Returns the join points argument type(s).
103: *
104: * @return
105: */
106: protected Type[] getJoinPointArgumentTypes() {
107: return new Type[] { Type.getType(m_calleeClassSignature) };//TODO should callee be arg instead ? to bind it later ?
108: }
109:
110: /**
111: * Creates the getRtti method
112: */
113: protected void createGetRttiMethod() {
114: CodeVisitor cv = m_cw.visitMethod(ACC_PUBLIC,
115: GET_RTTI_METHOD_NAME, GET_RTTI_METHOD_SIGNATURE, null,
116: null);
117:
118: // new CtorRttiImpl( .. )
119: cv.visitTypeInsn(NEW, HANDLER_RTTI_IMPL_CLASS_NAME);
120: cv.visitInsn(DUP);
121: cv.visitFieldInsn(GETSTATIC, m_joinPointClassName,
122: SIGNATURE_FIELD_NAME,
123: HANDLER_SIGNATURE_IMPL_CLASS_SIGNATURE);
124: cv.visitVarInsn(ALOAD, 0);
125: cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
126: CALLER_INSTANCE_FIELD_NAME, m_callerClassSignature);
127: cv.visitVarInsn(ALOAD, 0);
128: cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
129: CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature);
130: cv.visitMethodInsn(INVOKESPECIAL, HANDLER_RTTI_IMPL_CLASS_NAME,
131: INIT_METHOD_NAME, HANDLER_RTTI_IMPL_INIT_SIGNATURE);
132:
133: cv.visitInsn(ARETURN);
134: cv.visitMaxs(0, 0);
135: }
136:
137: /**
138: * Creates the getSignature method.
139: */
140: protected void createGetSignatureMethod() {
141: CodeVisitor cv = m_cw.visitMethod(ACC_PUBLIC,
142: GET_SIGNATURE_METHOD_NAME,
143: GET_SIGNATURE_METHOD_SIGNATURE, null, null);
144: cv.visitFieldInsn(GETSTATIC, m_joinPointClassName,
145: SIGNATURE_FIELD_NAME,
146: HANDLER_SIGNATURE_IMPL_CLASS_SIGNATURE);
147: cv.visitInsn(ARETURN);
148: cv.visitMaxs(0, 0);
149: }
150: }
|