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: import com.tc.aspectwerkz.transform.inlining.AsmHelper;
011: import com.tc.aspectwerkz.transform.inlining.compiler.AbstractJoinPointCompiler;
012:
013: import java.lang.reflect.Modifier;
014:
015: /**
016: * A compiler that compiles/generates a class that represents a specific join point, a class which invokes the advices
017: * and the target join point statically.
018: *
019: * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
020: * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur </a>
021: */
022: public class FieldSetJoinPointCompiler extends
023: AbstractJoinPointCompiler {
024:
025: /**
026: * Creates a new join point compiler instance.
027: *
028: * @param model
029: */
030: FieldSetJoinPointCompiler(final CompilationInfo.Model model) {
031: super (model);
032: }
033:
034: /**
035: * Creates join point specific fields.
036: */
037: protected void createJoinPointSpecificFields() {
038: String[] fieldNames = null;
039: // create the field argument field
040: Type fieldType = Type.getType(m_calleeMemberDesc);
041: fieldNames = new String[1];
042: String fieldName = ARGUMENT_FIELD + 0;
043: fieldNames[0] = fieldName;
044: m_cw.visitField(ACC_PRIVATE, fieldName, fieldType
045: .getDescriptor(), null, null);
046: m_fieldNames = fieldNames;
047:
048: m_cw.visitField(ACC_PRIVATE + ACC_STATIC, SIGNATURE_FIELD_NAME,
049: FIELD_SIGNATURE_IMPL_CLASS_SIGNATURE, null, null);
050: }
051:
052: /**
053: * Creates the signature for the join point.
054: * <p/>
055: * FIXME signature field should NOT be of type Signature but of the specific type (update all refs as well)
056: *
057: * @param cv
058: */
059: protected void createSignature(final MethodVisitor cv) {
060: cv.visitFieldInsn(GETSTATIC, m_joinPointClassName,
061: TARGET_CLASS_FIELD_NAME_IN_JP, CLASS_CLASS_SIGNATURE);
062: cv.visitLdcInsn(new Integer(m_joinPointHash));
063:
064: cv.visitMethodInsn(INVOKESTATIC, SIGNATURE_FACTORY_CLASS,
065: NEW_FIELD_SIGNATURE_METHOD_NAME,
066: NEW_FIELD_SIGNATURE_METHOD_SIGNATURE);
067: cv.visitFieldInsn(PUTSTATIC, m_joinPointClassName,
068: SIGNATURE_FIELD_NAME,
069: FIELD_SIGNATURE_IMPL_CLASS_SIGNATURE);
070: }
071:
072: /**
073: * Optimized implementation that does not retrieve the parameters from the join point instance but is passed
074: * directly to the method from the input parameters in the 'invoke' method. Can only be used if no around advice
075: * exists.
076: *
077: * @param cv
078: * @param input
079: */
080: protected void createInlinedJoinPointInvocation(
081: final MethodVisitor cv, final CompilerInput input) {
082:
083: // load the target instance (arg0 else not available for static target)
084: if (!Modifier.isStatic(m_calleeMemberModifiers)) {
085: cv.visitVarInsn(ALOAD, 0);
086: }
087:
088: loadArgumentMemberFields(cv, input.argStartIndex);
089:
090: // do we have a public field ? If so don't use the wrappers
091: if (Modifier.isPublic(m_calleeMemberModifiers)) {
092: if (Modifier.isStatic(m_calleeMemberModifiers)) {
093: cv.visitFieldInsn(PUTSTATIC, m_calleeClassName,
094: m_calleeMemberName, m_calleeMemberDesc);
095: } else {
096: cv.visitFieldInsn(PUTFIELD, m_calleeClassName,
097: m_calleeMemberName, m_calleeMemberDesc);
098: }
099: } else {
100: String joinPointName = null; // can be prefixed
101: joinPointName = m_calleeMemberName;
102: joinPointName = TransformationUtil.getWrapperMethodName(
103: joinPointName, m_calleeMemberDesc,
104: m_calleeClassName, PUTFIELD_WRAPPER_METHOD_PREFIX);
105: StringBuffer sig = new StringBuffer();
106: sig.append('(');
107: sig.append(m_calleeMemberDesc);
108: sig.append(')');
109: sig.append('V');
110: if (Modifier.isStatic(m_calleeMemberModifiers)) {
111: cv.visitMethodInsn(INVOKESTATIC, m_calleeClassName,
112: joinPointName, sig.toString());
113: } else {
114: cv.visitMethodInsn(INVOKEVIRTUAL, m_calleeClassName,
115: joinPointName, sig.toString());
116: }
117: }
118:
119: AsmHelper.addDefaultValue(cv, m_argumentTypes[0]);
120: }
121:
122: /**
123: * Creates a call to the target join point, the parameter(s) to the join point are retrieved from the invocation
124: * local join point instance.
125: *
126: * @param cv
127: */
128: protected void createJoinPointInvocation(final MethodVisitor cv) {
129:
130: // load the target instance member field unless calleeMember is static
131: if (!Modifier.isStatic(m_calleeMemberModifiers)) {
132: cv.visitVarInsn(ALOAD, 0);
133: cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
134: CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature);
135: }
136:
137: loadArguments(cv);
138:
139: // do we have a public field ? If so don't use the wrappers
140: if (Modifier.isPublic(m_calleeMemberModifiers)) {
141: if (Modifier.isStatic(m_calleeMemberModifiers)) {
142: cv.visitFieldInsn(PUTSTATIC, m_calleeClassName,
143: m_calleeMemberName, m_calleeMemberDesc);
144: } else {
145: cv.visitFieldInsn(PUTFIELD, m_calleeClassName,
146: m_calleeMemberName, m_calleeMemberDesc);
147: }
148: } else {
149: String joinPointName = TransformationUtil
150: .getWrapperMethodName(m_calleeMemberName,
151: m_calleeMemberDesc, m_calleeClassName,
152: PUTFIELD_WRAPPER_METHOD_PREFIX);
153: StringBuffer putFieldWrapperDesc = new StringBuffer();
154: putFieldWrapperDesc.append('(');
155: putFieldWrapperDesc.append(m_calleeMemberDesc);
156: putFieldWrapperDesc.append(')');
157: putFieldWrapperDesc.append('V');
158: if (Modifier.isStatic(m_calleeMemberModifiers)) {
159: cv.visitMethodInsn(INVOKESTATIC, m_calleeClassName,
160: joinPointName, putFieldWrapperDesc.toString());
161: } else {
162: cv.visitMethodInsn(INVOKEVIRTUAL, m_calleeClassName,
163: joinPointName, putFieldWrapperDesc.toString());
164: }
165: }
166:
167: AsmHelper.addDefaultValue(cv, m_argumentTypes[0]);
168: }
169:
170: /**
171: * Returns the join points return type.
172: *
173: * @return
174: */
175: protected Type getJoinPointReturnType() {
176: return Type.getType(m_calleeMemberDesc);
177: }
178:
179: /**
180: * Returns the join points argument type(s).
181: *
182: * @return
183: */
184: protected Type[] getJoinPointArgumentTypes() {
185: return new Type[] { Type.getType(m_calleeMemberDesc) };
186: }
187:
188: /**
189: * Creates the getRtti method
190: */
191: protected void createGetRttiMethod() {
192: MethodVisitor cv = m_cw.visitMethod(ACC_PUBLIC,
193: GET_RTTI_METHOD_NAME, GET_RTTI_METHOD_SIGNATURE, null,
194: null);
195:
196: // new FieldRttiImpl( .. )
197: cv.visitTypeInsn(NEW, FIELD_RTTI_IMPL_CLASS_NAME);
198: cv.visitInsn(DUP);
199: cv.visitFieldInsn(GETSTATIC, m_joinPointClassName,
200: SIGNATURE_FIELD_NAME,
201: FIELD_SIGNATURE_IMPL_CLASS_SIGNATURE);
202: cv.visitVarInsn(ALOAD, 0);
203: cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
204: CALLER_INSTANCE_FIELD_NAME, m_callerClassSignature);
205: cv.visitVarInsn(ALOAD, 0);
206: cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
207: CALLEE_INSTANCE_FIELD_NAME, m_calleeClassSignature);
208: cv.visitMethodInsn(INVOKESPECIAL, FIELD_RTTI_IMPL_CLASS_NAME,
209: INIT_METHOD_NAME, FIELD_RTTI_IMPL_INIT_SIGNATURE);
210:
211: // set the value
212: cv.visitInsn(DUP);
213: if (AsmHelper.isPrimitive(m_returnType)) {
214: AsmHelper.prepareWrappingOfPrimitiveType(cv, m_returnType);
215: cv.visitVarInsn(ALOAD, 0);
216: cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
217: RETURN_VALUE_FIELD_NAME, m_returnType
218: .getDescriptor());
219: AsmHelper.wrapPrimitiveType(cv, m_returnType);
220: } else {
221: cv.visitVarInsn(ALOAD, 0);
222: cv.visitFieldInsn(GETFIELD, m_joinPointClassName,
223: RETURN_VALUE_FIELD_NAME, m_returnType
224: .getDescriptor());
225: }
226: cv.visitMethodInsn(INVOKEVIRTUAL, FIELD_RTTI_IMPL_CLASS_NAME,
227: SET_FIELD_VALUE_METHOD_NAME,
228: SET_FIELD_VALUE_METHOD_SIGNATURE);
229:
230: cv.visitInsn(ARETURN);
231: cv.visitMaxs(0, 0);
232: }
233:
234: /**
235: * Creates the getSignature method.
236: */
237: protected void createGetSignatureMethod() {
238: MethodVisitor cv = m_cw.visitMethod(ACC_PUBLIC,
239: GET_SIGNATURE_METHOD_NAME,
240: GET_SIGNATURE_METHOD_SIGNATURE, null, null);
241: cv.visitFieldInsn(GETSTATIC, m_joinPointClassName,
242: SIGNATURE_FIELD_NAME,
243: FIELD_SIGNATURE_IMPL_CLASS_SIGNATURE);
244: cv.visitInsn(ARETURN);
245: cv.visitMaxs(0, 0);
246: }
247: }
|