OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [tools/] [external/] [asm/] [org/] [objectweb/] [asm/] [util/] [TraceClassVisitor.java] - Blame information for rev 779

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 779 jeremybenn
/***
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 java.io.FileInputStream;
33
import java.io.PrintWriter;
34
 
35
import org.objectweb.asm.AnnotationVisitor;
36
import org.objectweb.asm.Attribute;
37
import org.objectweb.asm.ClassReader;
38
import org.objectweb.asm.ClassVisitor;
39
import org.objectweb.asm.MethodVisitor;
40
import org.objectweb.asm.Opcodes;
41
import org.objectweb.asm.FieldVisitor;
42
import org.objectweb.asm.signature.SignatureReader;
43
 
44
/**
45
 * A {@link ClassVisitor} that prints a disassembled view of the classes it
46
 * visits. This class visitor can be used alone (see the {@link #main main}
47
 * method) to disassemble a class. It can also be used in the middle of class
48
 * visitor chain to trace the class that is visited at a given point in this
49
 * chain. This may be uselful for debugging purposes. <p> The trace printed when
50
 * visiting the <tt>Hello</tt> class is the following: <p> <blockquote>
51
 *
52
 * <pre>
53
 * // class version 49.0 (49)
54
 * // access flags 33
55
 * public class Hello {
56
 *
57
 *  // compiled from: Hello.java
58
 *
59
 *   // access flags 1
60
 *   public &lt;init&gt; ()V
61
 *     ALOAD 0
62
 *     INVOKESPECIAL java/lang/Object &lt;init&gt; ()V
63
 *     RETURN
64
 *     MAXSTACK = 1
65
 *     MAXLOCALS = 1
66
 *
67
 *   // access flags 9
68
 *   public static main ([Ljava/lang/String;)V
69
 *     GETSTATIC java/lang/System out Ljava/io/PrintStream;
70
 *     LDC &quot;hello&quot;
71
 *     INVOKEVIRTUAL java/io/PrintStream println (Ljava/lang/String;)V
72
 *     RETURN
73
 *     MAXSTACK = 2
74
 *     MAXLOCALS = 1
75
 * }
76
 * </pre>
77
 *
78
 * </blockquote> where <tt>Hello</tt> is defined by: <p> <blockquote>
79
 *
80
 * <pre>
81
 * public class Hello {
82
 *
83
 *     public static void main(String[] args) {
84
 *         System.out.println(&quot;hello&quot;);
85
 *     }
86
 * }
87
 * </pre>
88
 *
89
 * </blockquote>
90
 *
91
 * @author Eric Bruneton
92
 * @author Eugene Kuleshov
93
 */
94
public class TraceClassVisitor extends TraceAbstractVisitor implements
95
        ClassVisitor
96
{
97
 
98
    /**
99
     * The {@link ClassVisitor} to which this visitor delegates calls. May be
100
     * <tt>null</tt>.
101
     */
102
    protected final ClassVisitor cv;
103
 
104
    /**
105
     * The print writer to be used to print the class.
106
     */
107
    protected final PrintWriter pw;
108
 
109
    /**
110
     * Prints a disassembled view of the given class to the standard output. <p>
111
     * Usage: TraceClassVisitor [-debug] &lt;fully qualified class name or class
112
     * file name &gt;
113
     *
114
     * @param args the command line arguments.
115
     *
116
     * @throws Exception if the class cannot be found, or if an IO exception
117
     *         occurs.
118
     */
119
    public static void main(final String[] args) throws Exception {
120
        int i = 0;
121
        boolean skipDebug = true;
122
 
123
        boolean ok = true;
124
        if (args.length < 1 || args.length > 2) {
125
            ok = false;
126
        }
127
        if (ok && args[0].equals("-debug")) {
128
            i = 1;
129
            skipDebug = false;
130
            if (args.length != 2) {
131
                ok = false;
132
            }
133
        }
134
        if (!ok) {
135
            System.err.println("Prints a disassembled view of the given class.");
136
            System.err.println("Usage: TraceClassVisitor [-debug] "
137
                    + "<fully qualified class name or class file name>");
138
            return;
139
        }
140
        ClassReader cr;
141
        if (args[i].endsWith(".class") || args[i].indexOf('\\') > -1
142
                || args[i].indexOf('/') > -1)
143
        {
144
            cr = new ClassReader(new FileInputStream(args[i]));
145
        } else {
146
            cr = new ClassReader(args[i]);
147
        }
148
        cr.accept(new TraceClassVisitor(new PrintWriter(System.out)),
149
                getDefaultAttributes(),
150
                skipDebug);
151
    }
152
 
153
    /**
154
     * Constructs a new {@link TraceClassVisitor}.
155
     *
156
     * @param pw the print writer to be used to print the class.
157
     */
158
    public TraceClassVisitor(final PrintWriter pw) {
159
        this(null, pw);
160
    }
161
 
162
    /**
163
     * Constructs a new {@link TraceClassVisitor}.
164
     *
165
     * @param cv the {@link ClassVisitor} to which this visitor delegates calls.
166
     *        May be <tt>null</tt>.
167
     * @param pw the print writer to be used to print the class.
168
     */
169
    public TraceClassVisitor(final ClassVisitor cv, final PrintWriter pw) {
170
        this.cv = cv;
171
        this.pw = pw;
172
    }
173
 
174
    // ------------------------------------------------------------------------
175
    // Implementation of the ClassVisitor interface
176
    // ------------------------------------------------------------------------
177
 
178
    public void visit(
179
        final int version,
180
        final int access,
181
        final String name,
182
        final String signature,
183
        final String superName,
184
        final String[] interfaces)
185
    {
186
        int major = version & 0xFFFF;
187
        int minor = version >>> 16;
188
        buf.setLength(0);
189
        buf.append("// class version ")
190
                .append(major)
191
                .append('.')
192
                .append(minor)
193
                .append(" (")
194
                .append(version)
195
                .append(")\n");
196
        if ((access & Opcodes.ACC_DEPRECATED) != 0) {
197
            buf.append("// DEPRECATED\n");
198
        }
199
        buf.append("// access flags ").append(access).append('\n');
200
 
201
        appendDescriptor(CLASS_SIGNATURE, signature);
202
        if (signature != null) {
203
            TraceSignatureVisitor sv = new TraceSignatureVisitor(access);
204
            SignatureReader r = new SignatureReader(signature);
205
            r.accept(sv);
206
            buf.append("// declaration: ")
207
                    .append(name)
208
                    .append(sv.getDeclaration())
209
                    .append('\n');
210
        }
211
 
212
        appendAccess(access & ~Opcodes.ACC_SUPER);
213
        if ((access & Opcodes.ACC_ANNOTATION) != 0) {
214
            buf.append("@interface ");
215
        } else if ((access & Opcodes.ACC_INTERFACE) != 0) {
216
            buf.append("interface ");
217
        } else if ((access & Opcodes.ACC_ENUM) != 0) {
218
            buf.append("enum ");
219
        } else {
220
            buf.append("class ");
221
        }
222
        appendDescriptor(INTERNAL_NAME, name);
223
 
224
        if (superName != null && !superName.equals("java/lang/Object")) {
225
            buf.append(" extends ");
226
            appendDescriptor(INTERNAL_NAME, superName);
227
            buf.append(' ');
228
        }
229
        if (interfaces != null && interfaces.length > 0) {
230
            buf.append(" implements ");
231
            for (int i = 0; i < interfaces.length; ++i) {
232
                appendDescriptor(INTERNAL_NAME, interfaces[i]);
233
                buf.append(' ');
234
            }
235
        }
236
        buf.append(" {\n\n");
237
 
238
        text.add(buf.toString());
239
 
240
        if (cv != null) {
241
            cv.visit(version, access, name, signature, superName, interfaces);
242
        }
243
    }
244
 
245
    public void visitSource(final String file, final String debug) {
246
        buf.setLength(0);
247
        if (file != null) {
248
            buf.append(tab)
249
                    .append("// compiled from: ")
250
                    .append(file)
251
                    .append('\n');
252
        }
253
        if (debug != null) {
254
            buf.append(tab)
255
                    .append("// debug info: ")
256
                    .append(debug)
257
                    .append('\n');
258
        }
259
        if (buf.length() > 0) {
260
            text.add(buf.toString());
261
        }
262
 
263
        if (cv != null) {
264
            cv.visitSource(file, debug);
265
        }
266
    }
267
 
268
    public void visitOuterClass(
269
        final String owner,
270
        final String name,
271
        final String desc)
272
    {
273
        buf.setLength(0);
274
        buf.append(tab).append("OUTERCLASS ");
275
        appendDescriptor(INTERNAL_NAME, owner);
276
        // if enclosing name is null, so why should we show this info?
277
        if (name != null) {
278
            buf.append(' ').append(name).append(' ');
279
        } else {
280
            buf.append(' ');
281
        }
282
        appendDescriptor(METHOD_DESCRIPTOR, desc);
283
        buf.append('\n');
284
        text.add(buf.toString());
285
 
286
        if (cv != null) {
287
            cv.visitOuterClass(owner, name, desc);
288
        }
289
    }
290
 
291
    public AnnotationVisitor visitAnnotation(
292
        final String desc,
293
        final boolean visible)
294
    {
295
        text.add("\n");
296
        AnnotationVisitor tav = super.visitAnnotation(desc, visible);
297
        if (cv != null) {
298
            ((TraceAnnotationVisitor) tav).av = cv.visitAnnotation(desc,
299
                    visible);
300
        }
301
        return tav;
302
    }
303
 
304
    public void visitAttribute(final Attribute attr) {
305
        text.add("\n");
306
        super.visitAttribute(attr);
307
 
308
        if (cv != null) {
309
            cv.visitAttribute(attr);
310
        }
311
    }
312
 
313
    public void visitInnerClass(
314
        final String name,
315
        final String outerName,
316
        final String innerName,
317
        final int access)
318
    {
319
        buf.setLength(0);
320
        buf.append(tab).append("// access flags ").append(access
321
                & ~Opcodes.ACC_SUPER).append('\n');
322
        buf.append(tab);
323
        appendAccess(access);
324
        buf.append("INNERCLASS ");
325
        if ((access & Opcodes.ACC_ENUM) != 0) {
326
            buf.append("enum ");
327
        }
328
        appendDescriptor(INTERNAL_NAME, name);
329
        buf.append(' ');
330
        appendDescriptor(INTERNAL_NAME, outerName);
331
        buf.append(' ');
332
        appendDescriptor(INTERNAL_NAME, innerName);
333
        buf.append('\n');
334
        text.add(buf.toString());
335
 
336
        if (cv != null) {
337
            cv.visitInnerClass(name, outerName, innerName, access);
338
        }
339
    }
340
 
341
    public FieldVisitor visitField(
342
        final int access,
343
        final String name,
344
        final String desc,
345
        final String signature,
346
        final Object value)
347
    {
348
        buf.setLength(0);
349
        buf.append('\n');
350
        if ((access & Opcodes.ACC_DEPRECATED) != 0) {
351
            buf.append(tab).append("// DEPRECATED\n");
352
        }
353
        buf.append(tab).append("// access flags ").append(access).append('\n');
354
        if (signature != null) {
355
            buf.append(tab);
356
            appendDescriptor(FIELD_SIGNATURE, signature);
357
 
358
            TraceSignatureVisitor sv = new TraceSignatureVisitor(0);
359
            SignatureReader r = new SignatureReader(signature);
360
            r.acceptType(sv);
361
            buf.append(tab)
362
                    .append("// declaration: ")
363
                    .append(sv.getDeclaration())
364
                    .append('\n');
365
        }
366
 
367
        buf.append(tab);
368
        appendAccess(access);
369
        if ((access & Opcodes.ACC_ENUM) != 0) {
370
            buf.append("enum ");
371
        }
372
 
373
        appendDescriptor(FIELD_DESCRIPTOR, desc);
374
        buf.append(' ').append(name);
375
        if (value != null) {
376
            buf.append(" = ");
377
            if (value instanceof String) {
378
                buf.append("\"").append(value).append("\"");
379
            } else {
380
                buf.append(value);
381
            }
382
        }
383
 
384
        buf.append('\n');
385
        text.add(buf.toString());
386
 
387
        TraceFieldVisitor tav = createTraceFieldVisitor();
388
        text.add(tav.getText());
389
 
390
        if (cv != null) {
391
            tav.fv = cv.visitField(access, name, desc, signature, value);
392
        }
393
 
394
        return tav;
395
    }
396
 
397
    public MethodVisitor visitMethod(
398
        final int access,
399
        final String name,
400
        final String desc,
401
        final String signature,
402
        final String[] exceptions)
403
    {
404
        buf.setLength(0);
405
        buf.append('\n');
406
        if ((access & Opcodes.ACC_DEPRECATED) != 0) {
407
            buf.append(tab).append("// DEPRECATED\n");
408
        }
409
        buf.append(tab).append("// access flags ").append(access).append('\n');
410
        buf.append(tab);
411
        appendDescriptor(METHOD_SIGNATURE, signature);
412
 
413
        if (signature != null) {
414
            TraceSignatureVisitor v = new TraceSignatureVisitor(0);
415
            SignatureReader r = new SignatureReader(signature);
416
            r.accept(v);
417
            String genericDecl = v.getDeclaration();
418
            String genericReturn = v.getReturnType();
419
            String genericExceptions = v.getExceptions();
420
 
421
            buf.append(tab)
422
                    .append("// declaration: ")
423
                    .append(genericReturn)
424
                    .append(' ')
425
                    .append(name)
426
                    .append(genericDecl);
427
            if (genericExceptions != null) {
428
                buf.append(" throws ").append(genericExceptions);
429
            }
430
            buf.append('\n');
431
        }
432
 
433
        appendAccess(access);
434
        if ((access & Opcodes.ACC_NATIVE) != 0) {
435
            buf.append("native ");
436
        }
437
        if ((access & Opcodes.ACC_VARARGS) != 0) {
438
            buf.append("varargs ");
439
        }
440
        if ((access & Opcodes.ACC_BRIDGE) != 0) {
441
            buf.append("bridge ");
442
        }
443
 
444
        buf.append(name);
445
        appendDescriptor(METHOD_DESCRIPTOR, desc);
446
        if (exceptions != null && exceptions.length > 0) {
447
            buf.append(" throws ");
448
            for (int i = 0; i < exceptions.length; ++i) {
449
                appendDescriptor(INTERNAL_NAME, exceptions[i]);
450
                buf.append(' ');
451
            }
452
        }
453
 
454
        buf.append('\n');
455
        text.add(buf.toString());
456
 
457
        TraceMethodVisitor tcv = createTraceMethodVisitor();
458
        text.add(tcv.getText());
459
 
460
        if (cv != null) {
461
            tcv.mv = cv.visitMethod(access, name, desc, signature, exceptions);
462
        }
463
 
464
        return tcv;
465
    }
466
 
467
    public void visitEnd() {
468
        text.add("}\n");
469
 
470
        printList(pw, text);
471
        pw.flush();
472
 
473
        if (cv != null) {
474
            cv.visitEnd();
475
        }
476
    }
477
 
478
    // ------------------------------------------------------------------------
479
    // Utility methods
480
    // ------------------------------------------------------------------------
481
 
482
    protected TraceFieldVisitor createTraceFieldVisitor() {
483
        return new TraceFieldVisitor();
484
    }
485
 
486
    protected TraceMethodVisitor createTraceMethodVisitor() {
487
        return new TraceMethodVisitor();
488
    }
489
 
490
    /**
491
     * Appends a string representation of the given access modifiers to {@link
492
     * #buf buf}.
493
     *
494
     * @param access some access modifiers.
495
     */
496
    private void appendAccess(final int access) {
497
        if ((access & Opcodes.ACC_PUBLIC) != 0) {
498
            buf.append("public ");
499
        }
500
        if ((access & Opcodes.ACC_PRIVATE) != 0) {
501
            buf.append("private ");
502
        }
503
        if ((access & Opcodes.ACC_PROTECTED) != 0) {
504
            buf.append("protected ");
505
        }
506
        if ((access & Opcodes.ACC_FINAL) != 0) {
507
            buf.append("final ");
508
        }
509
        if ((access & Opcodes.ACC_STATIC) != 0) {
510
            buf.append("static ");
511
        }
512
        if ((access & Opcodes.ACC_SYNCHRONIZED) != 0) {
513
            buf.append("synchronized ");
514
        }
515
        if ((access & Opcodes.ACC_VOLATILE) != 0) {
516
            buf.append("volatile ");
517
        }
518
        if ((access & Opcodes.ACC_TRANSIENT) != 0) {
519
            buf.append("transient ");
520
        }
521
        // if ((access & Constants.ACC_NATIVE) != 0) {
522
        // buf.append("native ");
523
        // }
524
        if ((access & Opcodes.ACC_ABSTRACT) != 0) {
525
            buf.append("abstract ");
526
        }
527
        if ((access & Opcodes.ACC_STRICT) != 0) {
528
            buf.append("strictfp ");
529
        }
530
        if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
531
            buf.append("synthetic ");
532
        }
533
    }
534
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.