001: /*
002: * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
003: * Distributed under the terms of either:
004: * - the common development and distribution license (CDDL), v1.0; or
005: * - the GNU Lesser General Public License, v2.1 or later
006: * $Id: ResumableClassAdapter.java 3794 2007-06-19 17:50:38Z gbevin $
007: */
008: package com.uwyn.rife.continuations.instrument;
009:
010: import com.uwyn.rife.asm.*;
011:
012: import com.uwyn.rife.continuations.ContinuationConfigInstrument;
013: import com.uwyn.rife.continuations.instrument.ContinuationDebug;
014: import com.uwyn.rife.continuations.instrument.MetricsClassVisitor;
015: import com.uwyn.rife.continuations.instrument.NoOpAnnotationVisitor;
016: import com.uwyn.rife.continuations.instrument.ResumableMethodAdapter;
017: import com.uwyn.rife.continuations.instrument.TypesClassVisitor;
018: import java.util.logging.Level;
019:
020: import static com.uwyn.rife.continuations.instrument.ContinuationDebug.*;
021:
022: class ResumableClassAdapter implements ClassVisitor {
023: private ContinuationConfigInstrument mConfig = null;
024: private MetricsClassVisitor mMetrics = null;
025: private TypesClassVisitor mTypes = null;
026:
027: private String mClassName = null;
028: private String mEntryMethodName = null;
029: private String mEntryMethodDesc = null;
030: private ClassVisitor mClassVisitor = null;
031: private boolean mAdapt = false;
032: private NoOpAnnotationVisitor mAnnotationVisitor = new NoOpAnnotationVisitor();
033:
034: ResumableClassAdapter(ContinuationConfigInstrument config,
035: MetricsClassVisitor metrics, TypesClassVisitor types,
036: String className, ClassVisitor classVisitor) {
037: mConfig = config;
038: mMetrics = metrics;
039: mTypes = types;
040:
041: mClassName = className;
042: mEntryMethodName = config.getEntryMethodName();
043: mEntryMethodDesc = Type.getMethodDescriptor(config
044: .getEntryMethodReturnType(), config
045: .getEntryMethodArgumentTypes());
046: mClassVisitor = classVisitor;
047: mAdapt = (classVisitor != null);
048: }
049:
050: public void visit(int version, int access, String name,
051: String signature, String super Name, String[] interfaces) {
052: ///CLOVER:OFF
053: if (ContinuationDebug.LOGGER.isLoggable(Level.FINEST))
054: ContinuationDebug.LOGGER
055: .finest("Class:visit ("
056: + access
057: + ", \""
058: + name
059: + "\", \""
060: + signature
061: + "\", \""
062: + super Name
063: + "\", "
064: + (null == interfaces ? null : join(
065: interfaces, ",")) + ")");
066: ///CLOVER:ON
067:
068: if (mAdapt) {
069: mClassVisitor.visit(version, access, name, signature,
070: super Name, interfaces);
071: }
072: }
073:
074: public FieldVisitor visitField(int access, String name,
075: String desc, String signature, Object value) {
076: ///CLOVER:OFF
077: if (ContinuationDebug.LOGGER.isLoggable(Level.FINEST))
078: ContinuationDebug.LOGGER
079: .finest("Class:visitField (" + access
080: + ", \"" + name + "\", \"" + desc + "\", "
081: + signature + ", " + value + ")");
082: ///CLOVER:ON
083:
084: if (mAdapt) {
085: return mClassVisitor.visitField(access, name, desc,
086: signature, value);
087: }
088:
089: return null;
090: }
091:
092: public MethodVisitor visitMethod(int access, String name,
093: String desc, String signature, String[] exceptions) {
094: ///CLOVER:OFF
095: if (ContinuationDebug.LOGGER.isLoggable(Level.FINEST))
096: ContinuationDebug.LOGGER
097: .finest("Class:visitMethod ("
098: + access
099: + ", \""
100: + name
101: + "\", \""
102: + desc
103: + "\", \""
104: + signature
105: + "\", "
106: + (null == exceptions ? null : join(
107: exceptions, ",")) + ")");
108: ///CLOVER:ON
109:
110: // only adapt the processElement method
111: if (mEntryMethodName.equals(name)
112: && mEntryMethodDesc.equals(desc)) {
113: if (mAdapt) {
114: if (!mMetrics.makeResumable()) {
115: return new ResumableMethodAdapter(mConfig, null,
116: mClassVisitor.visitMethod(access, name,
117: desc, signature, exceptions),
118: mClassName, false, -1, 0);
119: } else {
120: return new ResumableMethodAdapter(mConfig, mTypes,
121: mClassVisitor.visitMethod(access, name,
122: desc, signature, exceptions),
123: mClassName, true, mMetrics.getMaxLocals(),
124: mMetrics.getPauseCount());
125: }
126: } else {
127: return new ResumableMethodAdapter(mConfig, null, null,
128: null, false, -1, 0);
129: }
130: }
131:
132: if (null == mClassVisitor) {
133: return null;
134: } else {
135: return new MethodAdapter(mClassVisitor.visitMethod(access,
136: name, desc, signature, exceptions));
137: }
138: }
139:
140: public void visitInnerClass(String name, String outerName,
141: String innerName, int access) {
142: ///CLOVER:OFF
143: if (ContinuationDebug.LOGGER.isLoggable(Level.FINEST))
144: ContinuationDebug.LOGGER
145: .finest("Class:visitInnerClass (\"" + name
146: + "\", \"" + outerName + "\", \""
147: + innerName + ", " + access + ")");
148: ///CLOVER:ON
149:
150: if (mAdapt) {
151: mClassVisitor.visitInnerClass(name, outerName, innerName,
152: access);
153: }
154: }
155:
156: public void visitAttribute(Attribute attr) {
157: ///CLOVER:OFF
158: if (ContinuationDebug.LOGGER.isLoggable(Level.FINEST))
159: ContinuationDebug.LOGGER
160: .finest("Class:visitAttribute (" + attr
161: + ")");
162: ///CLOVER:ON
163:
164: if (mAdapt) {
165: mClassVisitor.visitAttribute(attr);
166: }
167: }
168:
169: public void visitSource(String source, String debug) {
170: ///CLOVER:OFF
171: if (ContinuationDebug.LOGGER.isLoggable(Level.FINEST))
172: ContinuationDebug.LOGGER
173: .finest("Class:visitSource (\""
174: + source + "\", \"" + debug + "\")");
175: ///CLOVER:ON
176:
177: if (mAdapt) {
178: mClassVisitor.visitSource(source, debug);
179: }
180: }
181:
182: public void visitOuterClass(String owner, String name, String desc) {
183: ///CLOVER:OFF
184: if (ContinuationDebug.LOGGER.isLoggable(Level.FINEST))
185: ContinuationDebug.LOGGER
186: .finest("Class:visitOuterClass (\"" + owner
187: + "\", \"" + name + "\", \"" + desc + "\")");
188: ///CLOVER:ON
189:
190: if (mAdapt) {
191: mClassVisitor.visitOuterClass(owner, name, desc);
192: }
193: }
194:
195: public AnnotationVisitor visitAnnotation(String desc,
196: boolean visible) {
197: ///CLOVER:OFF
198: if (ContinuationDebug.LOGGER.isLoggable(Level.FINEST))
199: ContinuationDebug.LOGGER
200: .finest("Class:visitAnnotation (\"" + desc
201: + "\", " + visible + ")");
202: ///CLOVER:ON
203:
204: if (mAdapt) {
205: return mClassVisitor.visitAnnotation(desc, visible);
206: }
207:
208: return mAnnotationVisitor;
209: }
210:
211: public void visitEnd() {
212: ///CLOVER:OFF
213: if (ContinuationDebug.LOGGER.isLoggable(Level.FINEST))
214: ContinuationDebug.LOGGER
215: .finest("Class:visitEnd ()");
216: ///CLOVER:ON
217:
218: if (mAdapt) {
219: mClassVisitor.visitEnd();
220: }
221: }
222: }
|