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/] [AnnotationWriter.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;
31
 
32
/**
33
 * An {@link AnnotationVisitor} that generates annotations in bytecode form.
34
 *
35
 * @author Eric Bruneton
36
 * @author Eugene Kuleshov
37
 */
38
final class AnnotationWriter implements AnnotationVisitor {
39
 
40
    /**
41
     * The class writer to which this annotation must be added.
42
     */
43
    private final ClassWriter cw;
44
 
45
    /**
46
     * The number of values in this annotation.
47
     */
48
    private int size;
49
 
50
    /**
51
     * <tt>true<tt> if values are named, <tt>false</tt> otherwise. Annotation
52
     * writers used for annotation default and annotation arrays use unnamed
53
     * values.
54
     */
55
    private final boolean named;
56
 
57
    /**
58
     * The annotation values in bytecode form. This byte vector only contains
59
     * the values themselves, i.e. the number of values must be stored as a
60
     * unsigned short just before these bytes.
61
     */
62
    private final ByteVector bv;
63
 
64
    /**
65
     * The byte vector to be used to store the number of values of this
66
     * annotation. See {@link #bv}.
67
     */
68
    private final ByteVector parent;
69
 
70
    /**
71
     * Where the number of values of this annotation must be stored in
72
     * {@link #parent}.
73
     */
74
    private final int offset;
75
 
76
    /**
77
     * Next annotation writer. This field is used to store annotation lists.
78
     */
79
    AnnotationWriter next;
80
 
81
    /**
82
     * Previous annotation writer. This field is used to store annotation lists.
83
     */
84
    AnnotationWriter prev;
85
 
86
    // ------------------------------------------------------------------------
87
    // Constructor
88
    // ------------------------------------------------------------------------
89
 
90
    /**
91
     * Constructs a new {@link AnnotationWriter}.
92
     *
93
     * @param cw the class writer to which this annotation must be added.
94
     * @param named <tt>true<tt> if values are named, <tt>false</tt> otherwise.
95
     * @param bv where the annotation values must be stored.
96
     * @param parent where the number of annotation values must be stored.
97
     * @param offset where in <tt>parent</tt> the number of annotation values must
98
     *      be stored.
99
     */
100
    AnnotationWriter(
101
        final ClassWriter cw,
102
        final boolean named,
103
        final ByteVector bv,
104
        final ByteVector parent,
105
        final int offset)
106
    {
107
        this.cw = cw;
108
        this.named = named;
109
        this.bv = bv;
110
        this.parent = parent;
111
        this.offset = offset;
112
    }
113
 
114
    // ------------------------------------------------------------------------
115
    // Implementation of the AnnotationVisitor interface
116
    // ------------------------------------------------------------------------
117
 
118
    public void visit(final String name, final Object value) {
119
        ++size;
120
        if (named) {
121
            bv.putShort(cw.newUTF8(name));
122
        }
123
        if (value instanceof String) {
124
            bv.put12('s', cw.newUTF8((String) value));
125
        } else if (value instanceof Byte) {
126
            bv.put12('B', cw.newInteger(((Byte) value).byteValue()).index);
127
        } else if (value instanceof Boolean) {
128
            int v = ((Boolean) value).booleanValue() ? 1 : 0;
129
            bv.put12('Z', cw.newInteger(v).index);
130
        } else if (value instanceof Character) {
131
            bv.put12('C', cw.newInteger(((Character) value).charValue()).index);
132
        } else if (value instanceof Short) {
133
            bv.put12('S', cw.newInteger(((Short) value).shortValue()).index);
134
        } else if (value instanceof Type) {
135
            bv.put12('c', cw.newUTF8(((Type) value).getDescriptor()));
136
        } else if (value instanceof byte[]) {
137
            byte[] v = (byte[]) value;
138
            bv.put12('[', v.length);
139
            for (int i = 0; i < v.length; i++) {
140
                bv.put12('B', cw.newInteger(v[i]).index);
141
            }
142
        } else if (value instanceof boolean[]) {
143
            boolean[] v = (boolean[]) value;
144
            bv.put12('[', v.length);
145
            for (int i = 0; i < v.length; i++) {
146
                bv.put12('Z', cw.newInteger(v[i] ? 1 : 0).index);
147
            }
148
        } else if (value instanceof short[]) {
149
            short[] v = (short[]) value;
150
            bv.put12('[', v.length);
151
            for (int i = 0; i < v.length; i++) {
152
                bv.put12('S', cw.newInteger(v[i]).index);
153
            }
154
        } else if (value instanceof char[]) {
155
            char[] v = (char[]) value;
156
            bv.put12('[', v.length);
157
            for (int i = 0; i < v.length; i++) {
158
                bv.put12('C', cw.newInteger(v[i]).index);
159
            }
160
        } else if (value instanceof int[]) {
161
            int[] v = (int[]) value;
162
            bv.put12('[', v.length);
163
            for (int i = 0; i < v.length; i++) {
164
                bv.put12('I', cw.newInteger(v[i]).index);
165
            }
166
        } else if (value instanceof long[]) {
167
            long[] v = (long[]) value;
168
            bv.put12('[', v.length);
169
            for (int i = 0; i < v.length; i++) {
170
                bv.put12('J', cw.newLong(v[i]).index);
171
            }
172
        } else if (value instanceof float[]) {
173
            float[] v = (float[]) value;
174
            bv.put12('[', v.length);
175
            for (int i = 0; i < v.length; i++) {
176
                bv.put12('F', cw.newFloat(v[i]).index);
177
            }
178
        } else if (value instanceof double[]) {
179
            double[] v = (double[]) value;
180
            bv.put12('[', v.length);
181
            for (int i = 0; i < v.length; i++) {
182
                bv.put12('D', cw.newDouble(v[i]).index);
183
            }
184
        } else {
185
            Item i = cw.newConstItem(value);
186
            bv.put12(".s.IFJDCS".charAt(i.type), i.index);
187
        }
188
    }
189
 
190
    public void visitEnum(
191
        final String name,
192
        final String desc,
193
        final String value)
194
    {
195
        ++size;
196
        if (named) {
197
            bv.putShort(cw.newUTF8(name));
198
        }
199
        bv.put12('e', cw.newUTF8(desc)).putShort(cw.newUTF8(value));
200
    }
201
 
202
    public AnnotationVisitor visitAnnotation(
203
        final String name,
204
        final String desc)
205
    {
206
        ++size;
207
        if (named) {
208
            bv.putShort(cw.newUTF8(name));
209
        }
210
        // write tag and type, and reserve space for values count
211
        bv.put12('@', cw.newUTF8(desc)).putShort(0);
212
        return new AnnotationWriter(cw, true, bv, bv, bv.length - 2);
213
    }
214
 
215
    public AnnotationVisitor visitArray(final String name) {
216
        ++size;
217
        if (named) {
218
            bv.putShort(cw.newUTF8(name));
219
        }
220
        // write tag, and reserve space for array size
221
        bv.put12('[', 0);
222
        return new AnnotationWriter(cw, false, bv, bv, bv.length - 2);
223
    }
224
 
225
    public void visitEnd() {
226
        if (parent != null) {
227
            byte[] data = parent.data;
228
            data[offset] = (byte) (size >>> 8);
229
            data[offset + 1] = (byte) size;
230
        }
231
    }
232
 
233
    // ------------------------------------------------------------------------
234
    // Utility methods
235
    // ------------------------------------------------------------------------
236
 
237
    /**
238
     * Returns the size of this annotation writer list.
239
     *
240
     * @return the size of this annotation writer list.
241
     */
242
    int getSize() {
243
        int size = 0;
244
        AnnotationWriter aw = this;
245
        while (aw != null) {
246
            size += aw.bv.length;
247
            aw = aw.next;
248
        }
249
        return size;
250
    }
251
 
252
    /**
253
     * Puts the annotations of this annotation writer list into the given byte
254
     * vector.
255
     *
256
     * @param out where the annotations must be put.
257
     */
258
    void put(final ByteVector out) {
259
        int n = 0;
260
        int size = 2;
261
        AnnotationWriter aw = this;
262
        AnnotationWriter last = null;
263
        while (aw != null) {
264
            ++n;
265
            size += aw.bv.length;
266
            aw.visitEnd(); // in case user forgot to call visitEnd
267
            aw.prev = last;
268
            last = aw;
269
            aw = aw.next;
270
        }
271
        out.putInt(size);
272
        out.putShort(n);
273
        aw = last;
274
        while (aw != null) {
275
            out.putByteArray(aw.bv.data, 0, aw.bv.length);
276
            aw = aw.prev;
277
        }
278
    }
279
 
280
    /**
281
     * Puts the given annotation lists into the given byte vector.
282
     *
283
     * @param panns an array of annotation writer lists.
284
     * @param out where the annotations must be put.
285
     */
286
    static void put(final AnnotationWriter[] panns, final ByteVector out) {
287
        int size = 1 + 2 * panns.length;
288
        for (int i = 0; i < panns.length; ++i) {
289
            size += panns[i] == null ? 0 : panns[i].getSize();
290
        }
291
        out.putInt(size).putByte(panns.length);
292
        for (int i = 0; i < panns.length; ++i) {
293
            AnnotationWriter aw = panns[i];
294
            AnnotationWriter last = null;
295
            int n = 0;
296
            while (aw != null) {
297
                ++n;
298
                aw.visitEnd(); // in case user forgot to call visitEnd
299
                aw.prev = last;
300
                last = aw;
301
                aw = aw.next;
302
            }
303
            out.putShort(n);
304
            aw = last;
305
            while (aw != null) {
306
                out.putByteArray(aw.bv.data, 0, aw.bv.length);
307
                aw = aw.prev;
308
            }
309
        }
310
    }
311
}

powered by: WebSVN 2.1.0

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