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/] [ASMifierClassVisitor.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.ClassReader;
37
import org.objectweb.asm.ClassVisitor;
38
import org.objectweb.asm.FieldVisitor;
39
import org.objectweb.asm.MethodVisitor;
40
import org.objectweb.asm.Opcodes;
41
import org.objectweb.asm.Type;
42
 
43
/**
44
 * A {@link ClassVisitor} that prints the ASM code that generates the classes it
45
 * visits. This class visitor can be used to quickly write ASM code to generate
46
 * some given bytecode: <ul> <li>write the Java source code equivalent to the
47
 * bytecode you want to generate;</li> <li>compile it with <tt>javac</tt>;</li>
48
 * <li>make a {@link ASMifierClassVisitor} visit this compiled class (see the
49
 * {@link #main main} method);</li> <li>edit the generated source code, if
50
 * necessary.</li> </ul> The source code printed when visiting the
51
 * <tt>Hello</tt> class is the following: <p> <blockquote>
52
 *
53
 * <pre>
54
 * import org.objectweb.asm.*;
55
 *
56
 * public class HelloDump implements Opcodes {
57
 *
58
 *     public static byte[] dump() throws Exception {
59
 *
60
 *         ClassWriter cw = new ClassWriter(false);
61
 *         FieldVisitor fv;
62
 *         MethodVisitor mv;
63
 *         AnnotationVisitor av0;
64
 *
65
 *         cw.visit(49,
66
 *                 ACC_PUBLIC + ACC_SUPER,
67
 *                 &quot;Hello&quot;,
68
 *                 null,
69
 *                 &quot;java/lang/Object&quot;,
70
 *                 null);
71
 *
72
 *         cw.visitSource(&quot;Hello.java&quot;, null);
73
 *
74
 *         {
75
 *             mv = cw.visitMethod(ACC_PUBLIC, &quot;&lt;init&gt;&quot;, &quot;()V&quot;, null, null);
76
 *             mv.visitVarInsn(ALOAD, 0);
77
 *             mv.visitMethodInsn(INVOKESPECIAL,
78
 *                     &quot;java/lang/Object&quot;,
79
 *                     &quot;&lt;init&gt;&quot;,
80
 *                     &quot;()V&quot;);
81
 *             mv.visitInsn(RETURN);
82
 *             mv.visitMaxs(1, 1);
83
 *             mv.visitEnd();
84
 *         }
85
 *         {
86
 *             mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC,
87
 *                     &quot;main&quot;,
88
 *                     &quot;([Ljava/lang/String;)V&quot;,
89
 *                     null,
90
 *                     null);
91
 *             mv.visitFieldInsn(GETSTATIC,
92
 *                     &quot;java/lang/System&quot;,
93
 *                     &quot;out&quot;,
94
 *                     &quot;Ljava/io/PrintStream;&quot;);
95
 *             mv.visitLdcInsn(&quot;hello&quot;);
96
 *             mv.visitMethodInsn(INVOKEVIRTUAL,
97
 *                     &quot;java/io/PrintStream&quot;,
98
 *                     &quot;println&quot;,
99
 *                     &quot;(Ljava/lang/String;)V&quot;);
100
 *             mv.visitInsn(RETURN);
101
 *             mv.visitMaxs(2, 1);
102
 *             mv.visitEnd();
103
 *         }
104
 *         cw.visitEnd();
105
 *
106
 *         return cw.toByteArray();
107
 *     }
108
 * }
109
 *
110
 * </pre>
111
 *
112
 * </blockquote> where <tt>Hello</tt> is defined by: <p> <blockquote>
113
 *
114
 * <pre>
115
 * public class Hello {
116
 *
117
 *     public static void main(String[] args) {
118
 *         System.out.println(&quot;hello&quot;);
119
 *     }
120
 * }
121
 * </pre>
122
 *
123
 * </blockquote>
124
 *
125
 * @author Eric Bruneton
126
 * @author Eugene Kuleshov
127
 */
128
public class ASMifierClassVisitor extends ASMifierAbstractVisitor implements
129
        ClassVisitor
130
{
131
 
132
    /**
133
     * Pseudo access flag used to distinguish class access flags.
134
     */
135
    private final static int ACCESS_CLASS = 262144;
136
 
137
    /**
138
     * Pseudo access flag used to distinguish field access flags.
139
     */
140
    private final static int ACCESS_FIELD = 524288;
141
 
142
    /**
143
     * Pseudo access flag used to distinguish inner class flags.
144
     */
145
    private static final int ACCESS_INNER = 1048576;
146
 
147
    /**
148
     * The print writer to be used to print the class.
149
     */
150
    protected final PrintWriter pw;
151
 
152
    /**
153
     * Prints the ASM source code to generate the given class to the standard
154
     * output. <p> Usage: ASMifierClassVisitor [-debug] &lt;fully qualified
155
     * class name or class file name&gt;
156
     *
157
     * @param args the command line arguments.
158
     *
159
     * @throws Exception if the class cannot be found, or if an IO exception
160
     *         occurs.
161
     */
162
    public static void main(final String[] args) throws Exception {
163
        int i = 0;
164
        boolean skipDebug = true;
165
 
166
        boolean ok = true;
167
        if (args.length < 1 || args.length > 2) {
168
            ok = false;
169
        }
170
        if (ok && args[0].equals("-debug")) {
171
            i = 1;
172
            skipDebug = false;
173
            if (args.length != 2) {
174
                ok = false;
175
            }
176
        }
177
        if (!ok) {
178
            System.err.println("Prints the ASM code to generate the given class.");
179
            System.err.println("Usage: ASMifierClassVisitor [-debug] "
180
                    + "<fully qualified class name or class file name>");
181
            return;
182
        }
183
        ClassReader cr;
184
        if (args[i].endsWith(".class") || args[i].indexOf('\\') > -1
185
                || args[i].indexOf('/') > -1) {
186
            cr = new ClassReader(new FileInputStream(args[i]));
187
        } else {
188
            cr = new ClassReader(args[i]);
189
        }
190
        cr.accept(new ASMifierClassVisitor(new PrintWriter(System.out)),
191
                getDefaultAttributes(),
192
                skipDebug);
193
    }
194
 
195
    /**
196
     * Constructs a new {@link ASMifierClassVisitor} object.
197
     *
198
     * @param pw the print writer to be used to print the class.
199
     */
200
    public ASMifierClassVisitor(final PrintWriter pw) {
201
        super("cw");
202
        this.pw = pw;
203
    }
204
 
205
    // ------------------------------------------------------------------------
206
    // Implementation of the ClassVisitor interface
207
    // ------------------------------------------------------------------------
208
 
209
    public void visit(
210
        final int version,
211
        final int access,
212
        final String name,
213
        final String signature,
214
        final String superName,
215
        final String[] interfaces)
216
    {
217
        String simpleName;
218
        int n = name.lastIndexOf('/');
219
        if (n != -1) {
220
            text.add("package asm." + name.substring(0, n).replace('/', '.')
221
                    + ";\n");
222
            simpleName = name.substring(n + 1);
223
        } else {
224
            simpleName = name;
225
        }
226
        text.add("import java.util.*;\n");
227
        text.add("import org.objectweb.asm.*;\n");
228
        text.add("import org.objectweb.asm.attrs.*;\n");
229
        text.add("public class " + simpleName + "Dump implements Opcodes {\n\n");
230
        text.add("public static byte[] dump () throws Exception {\n\n");
231
        text.add("ClassWriter cw = new ClassWriter(false);\n");
232
        text.add("FieldVisitor fv;\n");
233
        text.add("MethodVisitor mv;\n");
234
        text.add("AnnotationVisitor av0;\n\n");
235
 
236
        buf.setLength(0);
237
        buf.append("cw.visit(");
238
        switch (version) {
239
            case Opcodes.V1_1:
240
                buf.append("V1_1");
241
                break;
242
            case Opcodes.V1_2:
243
                buf.append("V1_2");
244
                break;
245
            case Opcodes.V1_3:
246
                buf.append("V1_3");
247
                break;
248
            case Opcodes.V1_4:
249
                buf.append("V1_4");
250
                break;
251
            case Opcodes.V1_5:
252
                buf.append("V1_5");
253
                break;
254
            case Opcodes.V1_6:
255
                buf.append("V1_6");
256
                break;
257
            default:
258
                buf.append(version);
259
                break;
260
        }
261
        buf.append(", ");
262
        appendAccess(access | ACCESS_CLASS);
263
        buf.append(", ");
264
        appendConstant(name);
265
        buf.append(", ");
266
        appendConstant(signature);
267
        buf.append(", ");
268
        appendConstant(superName);
269
        buf.append(", ");
270
        if (interfaces != null && interfaces.length > 0) {
271
            buf.append("new String[] {");
272
            for (int i = 0; i < interfaces.length; ++i) {
273
                buf.append(i == 0 ? " " : ", ");
274
                appendConstant(interfaces[i]);
275
            }
276
            buf.append(" }");
277
        } else {
278
            buf.append("null");
279
        }
280
        buf.append(");\n\n");
281
        text.add(buf.toString());
282
    }
283
 
284
    public void visitSource(final String file, final String debug) {
285
        buf.setLength(0);
286
        buf.append("cw.visitSource(");
287
        appendConstant(file);
288
        buf.append(", ");
289
        appendConstant(debug);
290
        buf.append(");\n\n");
291
        text.add(buf.toString());
292
    }
293
 
294
    public void visitOuterClass(
295
        final String owner,
296
        final String name,
297
        final String desc)
298
    {
299
        buf.setLength(0);
300
        buf.append("cw.visitOuterClass(");
301
        appendConstant(owner);
302
        buf.append(", ");
303
        appendConstant(name);
304
        buf.append(", ");
305
        appendConstant(desc);
306
        buf.append(");\n\n");
307
        text.add(buf.toString());
308
    }
309
 
310
    public void visitInnerClass(
311
        final String name,
312
        final String outerName,
313
        final String innerName,
314
        final int access)
315
    {
316
        buf.setLength(0);
317
        buf.append("cw.visitInnerClass(");
318
        appendConstant(name);
319
        buf.append(", ");
320
        appendConstant(outerName);
321
        buf.append(", ");
322
        appendConstant(innerName);
323
        buf.append(", ");
324
        appendAccess(access | ACCESS_INNER);
325
        buf.append(");\n\n");
326
        text.add(buf.toString());
327
    }
328
 
329
    public FieldVisitor visitField(
330
        final int access,
331
        final String name,
332
        final String desc,
333
        final String signature,
334
        final Object value)
335
    {
336
        buf.setLength(0);
337
        buf.append("{\n");
338
        buf.append("fv = cw.visitField(");
339
        appendAccess(access | ACCESS_FIELD);
340
        buf.append(", ");
341
        appendConstant(name);
342
        buf.append(", ");
343
        appendConstant(desc);
344
        buf.append(", ");
345
        appendConstant(signature);
346
        buf.append(", ");
347
        appendConstant(value);
348
        buf.append(");\n");
349
        text.add(buf.toString());
350
        ASMifierFieldVisitor aav = new ASMifierFieldVisitor();
351
        text.add(aav.getText());
352
        text.add("}\n");
353
        return aav;
354
    }
355
 
356
    public MethodVisitor visitMethod(
357
        final int access,
358
        final String name,
359
        final String desc,
360
        final String signature,
361
        final String[] exceptions)
362
    {
363
        buf.setLength(0);
364
        buf.append("{\n");
365
        buf.append("mv = cw.visitMethod(");
366
        appendAccess(access);
367
        buf.append(", ");
368
        appendConstant(name);
369
        buf.append(", ");
370
        appendConstant(desc);
371
        buf.append(", ");
372
        appendConstant(signature);
373
        buf.append(", ");
374
        if (exceptions != null && exceptions.length > 0) {
375
            buf.append("new String[] {");
376
            for (int i = 0; i < exceptions.length; ++i) {
377
                buf.append(i == 0 ? " " : ", ");
378
                appendConstant(exceptions[i]);
379
            }
380
            buf.append(" }");
381
        } else {
382
            buf.append("null");
383
        }
384
        buf.append(");\n");
385
        text.add(buf.toString());
386
        ASMifierMethodVisitor acv = new ASMifierMethodVisitor();
387
        text.add(acv.getText());
388
        text.add("}\n");
389
        return acv;
390
    }
391
 
392
    public AnnotationVisitor visitAnnotation(
393
        final String desc,
394
        final boolean visible)
395
    {
396
        buf.setLength(0);
397
        buf.append("{\n");
398
        buf.append("av0 = cw.visitAnnotation(");
399
        appendConstant(desc);
400
        buf.append(", ");
401
        buf.append(visible);
402
        buf.append(");\n");
403
        text.add(buf.toString());
404
        ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(0);
405
        text.add(av.getText());
406
        text.add("}\n");
407
        return av;
408
    }
409
 
410
    public void visitEnd() {
411
        text.add("cw.visitEnd();\n\n");
412
        text.add("return cw.toByteArray();\n");
413
        text.add("}\n");
414
        text.add("}\n");
415
        printList(pw, text);
416
        pw.flush();
417
    }
418
 
419
    // ------------------------------------------------------------------------
420
    // Utility methods
421
    // ------------------------------------------------------------------------
422
 
423
    /**
424
     * Appends a string representation of the given access modifiers to {@link
425
     * #buf buf}.
426
     *
427
     * @param access some access modifiers.
428
     */
429
    void appendAccess(final int access) {
430
        boolean first = true;
431
        if ((access & Opcodes.ACC_PUBLIC) != 0) {
432
            buf.append("ACC_PUBLIC");
433
            first = false;
434
        }
435
        if ((access & Opcodes.ACC_PRIVATE) != 0) {
436
            if (!first) {
437
                buf.append(" + ");
438
            }
439
            buf.append("ACC_PRIVATE");
440
            first = false;
441
        }
442
        if ((access & Opcodes.ACC_PROTECTED) != 0) {
443
            if (!first) {
444
                buf.append(" + ");
445
            }
446
            buf.append("ACC_PROTECTED");
447
            first = false;
448
        }
449
        if ((access & Opcodes.ACC_FINAL) != 0) {
450
            if (!first) {
451
                buf.append(" + ");
452
            }
453
            buf.append("ACC_FINAL");
454
            first = false;
455
        }
456
        if ((access & Opcodes.ACC_STATIC) != 0) {
457
            if (!first) {
458
                buf.append(" + ");
459
            }
460
            buf.append("ACC_STATIC");
461
            first = false;
462
        }
463
        if ((access & Opcodes.ACC_SYNCHRONIZED) != 0) {
464
            if (!first) {
465
                buf.append(" + ");
466
            }
467
            if ((access & ACCESS_CLASS) != 0) {
468
                buf.append("ACC_SUPER");
469
            } else {
470
                buf.append("ACC_SYNCHRONIZED");
471
            }
472
            first = false;
473
        }
474
        if ((access & Opcodes.ACC_VOLATILE) != 0
475
                && (access & ACCESS_FIELD) != 0)
476
        {
477
            if (!first) {
478
                buf.append(" + ");
479
            }
480
            buf.append("ACC_VOLATILE");
481
            first = false;
482
        }
483
        if ((access & Opcodes.ACC_BRIDGE) != 0 && (access & ACCESS_CLASS) == 0
484
                && (access & ACCESS_FIELD) == 0)
485
        {
486
            if (!first) {
487
                buf.append(" + ");
488
            }
489
            buf.append("ACC_BRIDGE");
490
            first = false;
491
        }
492
        if ((access & Opcodes.ACC_VARARGS) != 0 && (access & ACCESS_CLASS) == 0
493
                && (access & ACCESS_FIELD) == 0)
494
        {
495
            if (!first) {
496
                buf.append(" + ");
497
            }
498
            buf.append("ACC_VARARGS");
499
            first = false;
500
        }
501
        if ((access & Opcodes.ACC_TRANSIENT) != 0
502
                && (access & ACCESS_FIELD) != 0)
503
        {
504
            if (!first) {
505
                buf.append(" + ");
506
            }
507
            buf.append("ACC_TRANSIENT");
508
            first = false;
509
        }
510
        if ((access & Opcodes.ACC_NATIVE) != 0 && (access & ACCESS_CLASS) == 0
511
                && (access & ACCESS_FIELD) == 0)
512
        {
513
            if (!first) {
514
                buf.append(" + ");
515
            }
516
            buf.append("ACC_NATIVE");
517
            first = false;
518
        }
519
        if ((access & Opcodes.ACC_ENUM) != 0
520
                && ((access & ACCESS_CLASS) != 0
521
                        || (access & ACCESS_FIELD) != 0 || (access & ACCESS_INNER) != 0))
522
        {
523
            if (!first) {
524
                buf.append(" + ");
525
            }
526
            buf.append("ACC_ENUM");
527
            first = false;
528
        }
529
        if ((access & Opcodes.ACC_ANNOTATION) != 0
530
                && ((access & ACCESS_CLASS) != 0))
531
        {
532
            if (!first) {
533
                buf.append(" + ");
534
            }
535
            buf.append("ACC_ANNOTATION");
536
            first = false;
537
        }
538
        if ((access & Opcodes.ACC_ABSTRACT) != 0) {
539
            if (!first) {
540
                buf.append(" + ");
541
            }
542
            buf.append("ACC_ABSTRACT");
543
            first = false;
544
        }
545
        if ((access & Opcodes.ACC_INTERFACE) != 0) {
546
            if (!first) {
547
                buf.append(" + ");
548
            }
549
            buf.append("ACC_INTERFACE");
550
            first = false;
551
        }
552
        if ((access & Opcodes.ACC_STRICT) != 0) {
553
            if (!first) {
554
                buf.append(" + ");
555
            }
556
            buf.append("ACC_STRICT");
557
            first = false;
558
        }
559
        if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
560
            if (!first) {
561
                buf.append(" + ");
562
            }
563
            buf.append("ACC_SYNTHETIC");
564
            first = false;
565
        }
566
        if ((access & Opcodes.ACC_DEPRECATED) != 0) {
567
            if (!first) {
568
                buf.append(" + ");
569
            }
570
            buf.append("ACC_DEPRECATED");
571
            first = false;
572
        }
573
        if (first) {
574
            buf.append("0");
575
        }
576
    }
577
 
578
    /**
579
     * Appends a string representation of the given constant to the given
580
     * buffer.
581
     *
582
     * @param buf a string buffer.
583
     * @param cst an {@link java.lang.Integer Integer}, {@link java.lang.Float
584
     *        Float}, {@link java.lang.Long Long},
585
     *        {@link java.lang.Double Double} or {@link String String} object.
586
     *        May be <tt>null</tt>.
587
     */
588
    static void appendConstant(final StringBuffer buf, final Object cst) {
589
        if (cst == null) {
590
            buf.append("null");
591
        } else if (cst instanceof String) {
592
            AbstractVisitor.appendString(buf, (String) cst);
593
        } else if (cst instanceof Type) {
594
            buf.append("Type.getType(\"")
595
                    .append(((Type) cst).getDescriptor())
596
                    .append("\")");
597
        } else if (cst instanceof Integer) {
598
            buf.append("new Integer(").append(cst).append(")");
599
        } else if (cst instanceof Float) {
600
            buf.append("new Float(\"").append(cst).append("\")");
601
        } else if (cst instanceof Long) {
602
            buf.append("new Long(").append(cst).append("L)");
603
        } else if (cst instanceof Double) {
604
            buf.append("new Double(\"").append(cst).append("\")");
605
        }
606
    }
607
}

powered by: WebSVN 2.1.0

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