KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > asm > util > TraceMethodVisitor


1 /***
2  * ASM: a very small and fast Java bytecode manipulation framework
3  * Copyright (c) 2000-2005 INRIA, France Telecom
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the copyright holders nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  */

30 package org.objectweb.asm.util;
31
32 import org.objectweb.asm.AnnotationVisitor;
33 import org.objectweb.asm.Attribute;
34 import org.objectweb.asm.MethodVisitor;
35 import org.objectweb.asm.Label;
36 import org.objectweb.asm.Type;
37 import org.objectweb.asm.signature.SignatureReader;
38 import org.objectweb.asm.util.attrs.Traceable;
39
40 import java.util.HashMap JavaDoc;
41
42 /**
43  * A {@link MethodVisitor} that prints a disassembled view of the methods it
44  * visits.
45  *
46  * @author Eric Bruneton
47  */

48 public class TraceMethodVisitor extends TraceAbstractVisitor implements
49         MethodVisitor
50 {
51
52     /**
53      * The {@link MethodVisitor} to which this visitor delegates calls. May be
54      * <tt>null</tt>.
55      */

56     protected MethodVisitor mv;
57
58     /**
59      * Tab for bytecode instructions.
60      */

61     protected String JavaDoc tab2 = " ";
62
63     /**
64      * Tab for table and lookup switch instructions.
65      */

66     protected String JavaDoc tab3 = " ";
67
68     /**
69      * Tab for labels.
70      */

71     protected String JavaDoc ltab = " ";
72
73     /**
74      * The label names. This map associate String values to Label keys.
75      */

76     protected final HashMap JavaDoc labelNames;
77
78     /**
79      * Constructs a new {@link TraceMethodVisitor}.
80      */

81     public TraceMethodVisitor() {
82         this(null);
83     }
84
85     /**
86      * Constructs a new {@link TraceMethodVisitor}.
87      *
88      * @param mv the {@link MethodVisitor} to which this visitor delegates
89      * calls. May be <tt>null</tt>.
90      */

91     public TraceMethodVisitor(final MethodVisitor mv) {
92         this.labelNames = new HashMap JavaDoc();
93         this.mv = mv;
94     }
95
96     // ------------------------------------------------------------------------
97
// Implementation of the MethodVisitor interface
98
// ------------------------------------------------------------------------
99

100     public AnnotationVisitor visitAnnotation(
101         final String JavaDoc desc,
102         final boolean visible)
103     {
104         AnnotationVisitor av = super.visitAnnotation(desc, visible);
105         if (mv != null) {
106             ((TraceAnnotationVisitor) av).av = mv.visitAnnotation(desc, visible);
107         }
108         return av;
109     }
110
111     public void visitAttribute(final Attribute attr) {
112         buf.setLength(0);
113         buf.append(tab).append("ATTRIBUTE ");
114         appendDescriptor(-1, attr.type);
115
116         if (attr instanceof Traceable) {
117             ((Traceable) attr).trace(buf, labelNames);
118         } else {
119             buf.append(" : ").append(attr.toString()).append("\n");
120         }
121
122         text.add(buf.toString());
123         if (mv != null) {
124             mv.visitAttribute(attr);
125         }
126     }
127
128     public AnnotationVisitor visitAnnotationDefault() {
129         text.add(tab2 + "default=");
130         TraceAnnotationVisitor tav = new TraceAnnotationVisitor();
131         text.add(tav.getText());
132         text.add("\n");
133         if (mv != null) {
134             tav.av = mv.visitAnnotationDefault();
135         }
136         return tav;
137     }
138
139     public AnnotationVisitor visitParameterAnnotation(
140         final int parameter,
141         final String JavaDoc desc,
142         final boolean visible)
143     {
144         buf.setLength(0);
145         buf.append(tab2).append('@');
146         appendDescriptor(FIELD_DESCRIPTOR, desc);
147         buf.append('(');
148         text.add(buf.toString());
149         TraceAnnotationVisitor tav = new TraceAnnotationVisitor();
150         text.add(tav.getText());
151         text.add(visible ? ") // parameter " : ") // invisible, parameter ");
152         text.add(new Integer JavaDoc(parameter));
153         text.add("\n");
154         if (mv != null) {
155             tav.av = mv.visitParameterAnnotation(parameter, desc, visible);
156         }
157         return tav;
158     }
159
160     public void visitCode() {
161         if (mv != null) {
162             mv.visitCode();
163         }
164     }
165
166     public void visitInsn(final int opcode) {
167         buf.setLength(0);
168         buf.append(tab2).append(OPCODES[opcode]).append('\n');
169         text.add(buf.toString());
170
171         if (mv != null) {
172             mv.visitInsn(opcode);
173         }
174     }
175
176     public void visitIntInsn(final int opcode, final int operand) {
177         buf.setLength(0);
178         buf.append(tab2)
179                 .append(OPCODES[opcode])
180                 .append(' ')
181                 .append(operand)
182                 .append('\n');
183         text.add(buf.toString());
184
185         if (mv != null) {
186             mv.visitIntInsn(opcode, operand);
187         }
188     }
189
190     public void visitVarInsn(final int opcode, final int var) {
191         buf.setLength(0);
192         buf.append(tab2)
193                 .append(OPCODES[opcode])
194                 .append(' ')
195                 .append(var)
196                 .append('\n');
197         text.add(buf.toString());
198
199         if (mv != null) {
200             mv.visitVarInsn(opcode, var);
201         }
202     }
203
204     public void visitTypeInsn(final int opcode, final String JavaDoc desc) {
205         buf.setLength(0);
206         buf.append(tab2).append(OPCODES[opcode]).append(' ');
207         if (desc.startsWith("[")) {
208             appendDescriptor(FIELD_DESCRIPTOR, desc);
209         } else {
210             appendDescriptor(INTERNAL_NAME, desc);
211         }
212         buf.append('\n');
213         text.add(buf.toString());
214
215         if (mv != null) {
216             mv.visitTypeInsn(opcode, desc);
217         }
218     }
219
220     public void visitFieldInsn(
221         final int opcode,
222         final String JavaDoc owner,
223         final String JavaDoc name,
224         final String JavaDoc desc)
225     {
226         buf.setLength(0);
227         buf.append(tab2).append(OPCODES[opcode]).append(' ');
228         appendDescriptor(INTERNAL_NAME, owner);
229         buf.append('.').append(name).append(" : ");
230         appendDescriptor(FIELD_DESCRIPTOR, desc);
231         buf.append('\n');
232         text.add(buf.toString());
233
234         if (mv != null) {
235             mv.visitFieldInsn(opcode, owner, name, desc);
236         }
237     }
238
239     public void visitMethodInsn(
240         final int opcode,
241         final String JavaDoc owner,
242         final String JavaDoc name,
243         final String JavaDoc desc)
244     {
245         buf.setLength(0);
246         buf.append(tab2).append(OPCODES[opcode]).append(' ');
247         appendDescriptor(INTERNAL_NAME, owner);
248         buf.append('.').append(name).append(' ');
249         appendDescriptor(METHOD_DESCRIPTOR, desc);
250         buf.append('\n');
251         text.add(buf.toString());
252
253         if (mv != null) {
254             mv.visitMethodInsn(opcode, owner, name, desc);
255         }
256     }
257
258     public void visitJumpInsn(final int opcode, final Label label) {
259         buf.setLength(0);
260         buf.append(tab2).append(OPCODES[opcode]).append(' ');
261         appendLabel(label);
262         buf.append('\n');
263         text.add(buf.toString());
264
265         if (mv != null) {
266             mv.visitJumpInsn(opcode, label);
267         }
268     }
269
270     public void visitLabel(final Label label) {
271         buf.setLength(0);
272         buf.append(ltab);
273         appendLabel(label);
274         buf.append('\n');
275         text.add(buf.toString());
276
277         if (mv != null) {
278             mv.visitLabel(label);
279         }
280     }
281
282     public void visitLdcInsn(final Object JavaDoc cst) {
283         buf.setLength(0);
284         buf.append(tab2).append("LDC ");
285         if (cst instanceof String JavaDoc) {
286             if (cst == null) {
287                 buf.append("null");
288             } else if (cst instanceof String JavaDoc) {
289                 AbstractVisitor.appendString(buf, (String JavaDoc) cst);
290             }
291         } else if (cst instanceof Type) {
292             buf.append(((Type) cst).getDescriptor() + ".class");
293         } else {
294             buf.append(cst);
295         }
296         buf.append('\n');
297         text.add(buf.toString());
298
299         if (mv != null) {
300             mv.visitLdcInsn(cst);
301         }
302     }
303
304     public void visitIincInsn(final int var, final int increment) {
305         buf.setLength(0);
306         buf.append(tab2)
307                 .append("IINC ")
308                 .append(var)
309                 .append(' ')
310                 .append(increment)
311                 .append('\n');
312         text.add(buf.toString());
313
314         if (mv != null) {
315             mv.visitIincInsn(var, increment);
316         }
317     }
318
319     public void visitTableSwitchInsn(
320         final int min,
321         final int max,
322         final Label dflt,
323         final Label labels[])
324     {
325         buf.setLength(0);
326         buf.append(tab2).append("TABLESWITCH\n");
327         for (int i = 0; i < labels.length; ++i) {
328             buf.append(tab3).append(min + i).append(": ");
329             appendLabel(labels[i]);
330             buf.append('\n');
331         }
332         buf.append(tab3).append("default: ");
333         appendLabel(dflt);
334         buf.append('\n');
335         text.add(buf.toString());
336
337         if (mv != null) {
338             mv.visitTableSwitchInsn(min, max, dflt, labels);
339         }
340     }
341
342     public void visitLookupSwitchInsn(
343         final Label dflt,
344         final int keys[],
345         final Label labels[])
346     {
347         buf.setLength(0);
348         buf.append(tab2).append("LOOKUPSWITCH\n");
349         for (int i = 0; i < labels.length; ++i) {
350             buf.append(tab3).append(keys[i]).append(": ");
351             appendLabel(labels[i]);
352             buf.append('\n');
353         }
354         buf.append(tab3).append("default: ");
355         appendLabel(dflt);
356         buf.append('\n');
357         text.add(buf.toString());
358
359         if (mv != null) {
360             mv.visitLookupSwitchInsn(dflt, keys, labels);
361         }
362     }
363
364     public void visitMultiANewArrayInsn(final String JavaDoc desc, final int dims) {
365         buf.setLength(0);
366         buf.append(tab2).append("MULTIANEWARRAY ");
367         appendDescriptor(FIELD_DESCRIPTOR, desc);
368         buf.append(' ').append(dims).append('\n');
369         text.add(buf.toString());
370
371         if (mv != null) {
372             mv.visitMultiANewArrayInsn(desc, dims);
373         }
374     }
375
376     public void visitTryCatchBlock(
377         final Label start,
378         final Label end,
379         final Label handler,
380         final String JavaDoc type)
381     {
382         buf.setLength(0);
383         buf.append(tab2).append("TRYCATCHBLOCK ");
384         appendLabel(start);
385         buf.append(' ');
386         appendLabel(end);
387         buf.append(' ');
388         appendLabel(handler);
389         buf.append(' ');
390         appendDescriptor(INTERNAL_NAME, type);
391         buf.append('\n');
392         text.add(buf.toString());
393
394         if (mv != null) {
395             mv.visitTryCatchBlock(start, end, handler, type);
396         }
397     }
398
399     public void visitLocalVariable(
400         final String JavaDoc name,
401         final String JavaDoc desc,
402         final String JavaDoc signature,
403         final Label start,
404         final Label end,
405         final int index)
406     {
407         buf.setLength(0);
408         buf.append(tab2).append("LOCALVARIABLE ").append(name).append(' ');
409         appendDescriptor(FIELD_DESCRIPTOR, desc);
410         buf.append(' ');
411         appendLabel(start);
412         buf.append(' ');
413         appendLabel(end);
414         buf.append(' ').append(index).append('\n');
415
416         if (signature != null) {
417             buf.append(tab2);
418             appendDescriptor(FIELD_SIGNATURE, signature);
419
420             TraceSignatureVisitor sv = new TraceSignatureVisitor(0);
421             SignatureReader r = new SignatureReader(signature);
422             r.acceptType(sv);
423             buf.append(tab2)
424                     .append("// declaration: ")
425                     .append(sv.getDeclaration())
426                     .append('\n');
427         }
428         text.add(buf.toString());
429
430         if (mv != null) {
431             mv.visitLocalVariable(name, desc, signature, start, end, index);
432         }
433     }
434
435     public void visitLineNumber(final int line, final Label start) {
436         buf.setLength(0);
437         buf.append(tab2).append("LINENUMBER ").append(line).append(' ');
438         appendLabel(start);
439         buf.append('\n');
440         text.add(buf.toString());
441
442         if (mv != null) {
443             mv.visitLineNumber(line, start);
444         }
445     }
446
447     public void visitMaxs(final int maxStack, final int maxLocals) {
448         buf.setLength(0);
449         buf.append(tab2)
450                 .append("MAXSTACK = ")
451                 .append(maxStack)
452                 .append('\n')
453                 .append(tab2)
454                 .append("MAXLOCALS = ")
455                 .append(maxLocals)
456                 .append('\n');
457         text.add(buf.toString());
458
459         if (mv != null) {
460             mv.visitMaxs(maxStack, maxLocals);
461         }
462     }
463
464     public void visitEnd() {
465         super.visitEnd();
466
467         if (mv != null) {
468             mv.visitEnd();
469         }
470     }
471
472     // ------------------------------------------------------------------------
473
// Utility methods
474
// ------------------------------------------------------------------------
475

476     /**
477      * Appends the name of the given label to {@link #buf buf}. Creates a new
478      * label name if the given label does not yet have one.
479      *
480      * @param l a label.
481      */

482     protected void appendLabel(final Label l) {
483         String JavaDoc name = (String JavaDoc) labelNames.get(l);
484         if (name == null) {
485             name = "L" + labelNames.size();
486             labelNames.put(l, name);
487         }
488         buf.append(name);
489     }
490 }
491
Popular Tags