001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tc.aspectwerkz.transform.inlining.compiler;
005:
006: import com.tc.asm.MethodVisitor;
007: import com.tc.asm.Type;
008:
009: import com.tc.aspectwerkz.transform.TransformationUtil;
010:
011: import java.lang.reflect.Modifier;
012:
013: /**
014: * A compiler that compiles/generates a class that represents a specific join point, a class which invokes the advices
015: * and the target join point statically.
016: *
017: * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
018: * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur </a>
019: */
020: public class ConstructorExecutionJoinPointCompiler extends
021: AbstractJoinPointCompiler {
022:
023: /**
024: * Creates a new join point compiler instance.
025: *
026: * @param model
027: */
028: ConstructorExecutionJoinPointCompiler(
029: final CompilationInfo.Model model) {
030: super (model);
031: }
032:
033: /**
034: * Creates join point specific fields.
035: */
036: protected void createJoinPointSpecificFields() {
037: String[] fieldNames = null;
038: // create the method argument fields
039: Type[] argumentTypes = Type
040: .getArgumentTypes(m_calleeMemberDesc);
041: fieldNames = new String[argumentTypes.length];
042: for (int i = 0; i < argumentTypes.length; i++) {
043: Type argumentType = argumentTypes[i];
044: String fieldName = ARGUMENT_FIELD + i;
045: fieldNames[i] = fieldName;
046: m_cw.visitField(ACC_PRIVATE, fieldName, argumentType
047: .getDescriptor(), null, null);
048: }
049: m_fieldNames = fieldNames;
050:
051: m_cw.visitField(ACC_PRIVATE + ACC_STATIC, SIGNATURE_FIELD_NAME,
052: CONSTRUCTOR_SIGNATURE_IMPL_CLASS_SIGNATURE, null, null);
053: }
054:
055: /**
056: * Creates the signature for the join point.
057: * <p/>
058: * FIXME signature field should NOT be of type Signature but of the specific type (update all refs as well)
059: *
060: * @param cv
061: */
062: protected void createSignature(final MethodVisitor cv) {
063: cv.visitFieldInsn(GETSTATIC, m_joinPointClassName,
064: TARGET_CLASS_FIELD_NAME_IN_JP, CLASS_CLASS_SIGNATURE);
065: cv.visitLdcInsn(new Integer(m_joinPointHash));
066:
067: cv.visitMethodInsn(INVOKESTATIC, SIGNATURE_FACTORY_CLASS,
068: NEW_CONSTRUCTOR_SIGNATURE_METHOD_NAME,
069: NEW_CONSTRUCTOR_SIGNATURE_METHOD_SIGNATURE);
070: cv.visitFieldInsn(PUTSTATIC, m_joinPointClassName,
071: SIGNATURE_FIELD_NAME,
072: CONSTRUCTOR_SIGNATURE_IMPL_CLASS_SIGNATURE);
073: }
074:
075: /**
076: * Optimized implementation that does not retrieve the parameters from the join point instance but is passed
077: * directly to the method from the input parameters in the 'invoke' method. Can only be used if no around advice
078: * exists.
079: *
080: * @param cv
081: * @param input
082: */
083: protected void createInlinedJoinPointInvocation(
084: final MethodVisitor cv, final CompilerInput input) {
085:
086: // load the target instance (arg0 else not available for static target)
087: if (!Modifier.isStatic(m_calleeMemberModifiers)) {
088: cv.visitVarInsn(ALOAD, 0);
089: }
090:
091: loadArgumentMemberFields(cv, input.argStartIndex);
092: String bodyName = TransformationUtil
093: .getConstructorBodyMethodName(m_calleeClassName);
094: String bodyDesc = TransformationUtil
095: .getConstructorBodyMethodSignature(m_calleeMemberDesc,
096: m_calleeClassName);
097: cv.visitMethodInsn(INVOKESTATIC, m_calleeClassName, bodyName,
098: bodyDesc);
099: }
100:
101: /**
102: * Creates a call to the target join point, the parameter(s) to the join point are retrieved from the invocation
103: * local join point instance.
104: *
105: * @param cv
106: */
107: protected void createJoinPointInvocation(final MethodVisitor cv) {
108:
109: // load the target instance member field unless calleeMember is static
110: if (!Modifier.isStatic(m_calleeMemberModifiers)) {
111: cv.visitVarInsn(ALOAD, 0);
112: cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
113: CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature);
114: }
115:
116: loadArguments(cv);
117: String bodyName = TransformationUtil
118: .getConstructorBodyMethodName(m_calleeClassName);
119: String bodyDesc = TransformationUtil
120: .getConstructorBodyMethodSignature(m_calleeMemberDesc,
121: m_calleeClassName);
122: cv.visitMethodInsn(INVOKESTATIC, m_calleeClassName, bodyName,
123: bodyDesc);
124: }
125:
126: /**
127: * Returns the join points return type.
128: *
129: * @return
130: */
131: protected Type getJoinPointReturnType() {
132: return Type.getReturnType(m_calleeMemberDesc);
133: }
134:
135: /**
136: * Returns the join points argument type(s).
137: *
138: * @return
139: */
140: protected Type[] getJoinPointArgumentTypes() {
141: return Type.getArgumentTypes(m_calleeMemberDesc);
142: }
143:
144: /**
145: * Creates the getRtti method
146: */
147: protected void createGetRttiMethod() {
148: MethodVisitor cv = m_cw.visitMethod(ACC_PUBLIC,
149: GET_RTTI_METHOD_NAME, GET_RTTI_METHOD_SIGNATURE, null,
150: null);
151:
152: // new CtorRttiImpl( .. )
153: cv.visitTypeInsn(NEW, CONSTRUCTOR_RTTI_IMPL_CLASS_NAME);
154: cv.visitInsn(DUP);
155: cv.visitFieldInsn(GETSTATIC, m_joinPointClassName,
156: SIGNATURE_FIELD_NAME,
157: CONSTRUCTOR_SIGNATURE_IMPL_CLASS_SIGNATURE);
158: cv.visitVarInsn(ALOAD, 0);
159: cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
160: CALLER_INSTANCE_FIELD_NAME, m_callerClassSignature);
161: cv.visitVarInsn(ALOAD, 0);
162: cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
163: CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature);
164: cv.visitMethodInsn(INVOKESPECIAL,
165: CONSTRUCTOR_RTTI_IMPL_CLASS_NAME, INIT_METHOD_NAME,
166: CONSTRUCTOR_RTTI_IMPL_INIT_SIGNATURE);
167:
168: // set the arguments
169: cv.visitInsn(DUP);
170: createArgumentArrayAt(cv, 1);
171: cv.visitVarInsn(ALOAD, 1);
172: cv.visitMethodInsn(INVOKEVIRTUAL,
173: CONSTRUCTOR_RTTI_IMPL_CLASS_NAME,
174: SET_PARAMETER_VALUES_METHOD_NAME,
175: SET_PARAMETER_VALUES_METHOD_SIGNATURE);
176:
177: cv.visitInsn(ARETURN);
178: cv.visitMaxs(0, 0);
179: }
180:
181: /**
182: * Creates the getSignature method.
183: */
184: protected void createGetSignatureMethod() {
185: MethodVisitor cv = m_cw.visitMethod(ACC_PUBLIC,
186: GET_SIGNATURE_METHOD_NAME,
187: GET_SIGNATURE_METHOD_SIGNATURE, null, null);
188: cv.visitFieldInsn(GETSTATIC, m_joinPointClassName,
189: SIGNATURE_FIELD_NAME,
190: CONSTRUCTOR_SIGNATURE_IMPL_CLASS_SIGNATURE);
191: cv.visitInsn(ARETURN);
192: cv.visitMaxs(0, 0);
193: }
194: }
|