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/] [attrs/] [StackMapAttribute.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.attrs;
31
 
32
import java.util.ArrayList;
33
import java.util.HashSet;
34
import java.util.Iterator;
35
import java.util.List;
36
import java.util.Set;
37
 
38
import org.objectweb.asm.Attribute;
39
import org.objectweb.asm.ByteVector;
40
import org.objectweb.asm.ClassReader;
41
import org.objectweb.asm.ClassWriter;
42
import org.objectweb.asm.Label;
43
 
44
/**
45
 * StackMapAttribute is used by CDLC preverifier. Definition is given in
46
 * appendix "CLDC Byte Code Typechecker Specification" from CDLC 1.1
47
 * specification. <p> <i>Note that this implementation does not calculate
48
 * StackMapFrame structures from the method bytecode. If method code is changed
49
 * or generated from scratch, then developer is responsible to prepare a correct
50
 * StackMapFrame structures.</i> <p> The format of the stack map in the class
51
 * file is given below. In the following, <ul> <li>if the length of the
52
 * method's byte code1 is 65535 or less, then <tt>uoffset</tt> represents the
53
 * type u2; otherwise <tt>uoffset</tt> represents the type u4.</li> <li>If
54
 * the maximum number of local variables for the method is 65535 or less, then
55
 * <tt>ulocalvar</tt> represents the type u2; otherwise <tt>ulocalvar</tt>
56
 * represents the type u4.</li> <li>If the maximum size of the operand stack
57
 * is 65535 or less, then <tt>ustack</tt> represents the type u2; otherwise
58
 * ustack represents the type u4.</li> </ul>
59
 *
60
 * <pre>
61
 * stack_map { // attribute StackMap
62
 *   u2 attribute_name_index;
63
 *   u4 attribute_length
64
 *   uoffset number_of_entries;
65
 *   stack_map_frame entries[number_of_entries];
66
 * }
67
 * </pre>
68
 *
69
 * Each stack map frame has the following format:
70
 *
71
 * <pre>
72
 * stack_map_frame {
73
 *   uoffset offset;
74
 *   ulocalvar number_of_locals;
75
 *   verification_type_info locals[number_of_locals];
76
 *   ustack number_of_stack_items;
77
 *   verification_type_info stack[number_of_stack_items];
78
 * }
79
 * </pre>
80
 *
81
 * The <tt>verification_type_info</tt> structure consists of a one-byte tag
82
 * followed by zero or more bytes, giving more information about the tag. Each
83
 * <tt>verification_type_info</tt> structure specifies the verification type
84
 * of one or two locations.
85
 *
86
 * <pre>
87
 * union verification_type_info {
88
 *   Top_variable_info;
89
 *   Integer_variable_info;
90
 *   Float_variable_info;
91
 *   Long_variable_info;
92
 *   Double_variable_info;
93
 *   Null_variable_info;
94
 *   UninitializedThis_variable_info;
95
 *   Object_variable_info;
96
 *   Uninitialized_variable_info;
97
 * }
98
 *
99
 * Top_variable_info {
100
 *   u1 tag = ITEM_Top; // 0
101
 * }
102
 *
103
 * Integer_variable_info {
104
 *   u1 tag = ITEM_Integer; // 1
105
 * }
106
 *
107
 * Float_variable_info {
108
 *   u1 tag = ITEM_Float; // 2
109
 * }
110
 *
111
 * Long_variable_info {
112
 *   u1 tag = ITEM_Long; // 4
113
 * }
114
 *
115
 * Double_variable_info {
116
 *   u1 tag = ITEM_Double; // 3
117
 * }
118
 *
119
 * Null_variable_info {
120
 *  u1 tag = ITEM_Null; // 5
121
 * }
122
 *
123
 * UninitializedThis_variable_info {
124
 *   u1 tag = ITEM_UninitializedThis; // 6
125
 * }
126
 *
127
 * Object_variable_info {
128
 *   u1 tag = ITEM_Object; // 7
129
 *   u2 cpool_index;
130
 * }
131
 *
132
 * Uninitialized_variable_info {
133
 *   u1 tag = ITEM_Uninitialized // 8
134
 *   uoffset offset;
135
 * }
136
 * </pre>
137
 *
138
 * @see <a href="http://www.jcp.org/en/jsr/detail?id=139">JSR 139 : Connected
139
 *      Limited Device Configuration 1.1</a>
140
 *
141
 * @author Eugene Kuleshov
142
 */
143
public class StackMapAttribute extends Attribute {
144
 
145
    static final int MAX_SIZE = 65535;
146
 
147
    /**
148
     * A List of <code>StackMapFrame</code> instances.
149
     */
150
    public List frames = new ArrayList();
151
 
152
    public StackMapAttribute() {
153
        super("StackMap");
154
    }
155
 
156
    public StackMapAttribute(List frames) {
157
        this();
158
        this.frames = frames;
159
    }
160
 
161
    public List getFrames() {
162
        return frames;
163
    }
164
 
165
    public StackMapFrame getFrame(Label label) {
166
        for (int i = 0; i < frames.size(); i++) {
167
            StackMapFrame frame = (StackMapFrame) frames.get(i);
168
            if (frame.label == label) {
169
                return frame;
170
            }
171
        }
172
        return null;
173
    }
174
 
175
    public boolean isUnknown() {
176
        return false;
177
    }
178
 
179
    public boolean isCodeAttribute() {
180
        return true;
181
    }
182
 
183
    protected Attribute read(
184
        ClassReader cr,
185
        int off,
186
        int len,
187
        char[] buf,
188
        int codeOff,
189
        Label[] labels)
190
    {
191
        StackMapAttribute attr = new StackMapAttribute();
192
        // note that this is not the size of Code attribute
193
        boolean isExtCodeSize = cr.readInt(codeOff + 4) > MAX_SIZE;
194
        boolean isExtLocals = cr.readUnsignedShort(codeOff + 2) > MAX_SIZE;
195
        boolean isExtStack = cr.readUnsignedShort(codeOff) > MAX_SIZE;
196
 
197
        int size = 0;
198
        if (isExtCodeSize) {
199
            size = cr.readInt(off);
200
            off += 4;
201
        } else {
202
            size = cr.readUnsignedShort(off);
203
            off += 2;
204
        }
205
        for (int i = 0; i < size; i++) {
206
            int offset;
207
            if (isExtCodeSize) {
208
                offset = cr.readInt(off);
209
                off += 4;
210
            } else {
211
                offset = cr.readUnsignedShort(off);
212
                off += 2;
213
            }
214
 
215
            Label label = getLabel(offset, labels);
216
            List locals = new ArrayList();
217
            List stack = new ArrayList();
218
 
219
            off = readTypeInfo(cr,
220
                    off,
221
                    locals,
222
                    labels,
223
                    buf,
224
                    isExtLocals,
225
                    isExtCodeSize);
226
            off = readTypeInfo(cr,
227
                    off,
228
                    stack,
229
                    labels,
230
                    buf,
231
                    isExtStack,
232
                    isExtCodeSize);
233
 
234
            attr.frames.add(new StackMapFrame(label, locals, stack));
235
        }
236
        return attr;
237
    }
238
 
239
    private int readTypeInfo(
240
        ClassReader cr,
241
        int off,
242
        List info,
243
        Label[] labels,
244
        char[] buf,
245
        boolean isExt,
246
        boolean isExtCode)
247
    {
248
        int n = 0;
249
        if (isExt) {
250
            n = cr.readInt(off);
251
            off += 4;
252
        } else {
253
            n = cr.readUnsignedShort(off);
254
            off += 2;
255
        }
256
        for (int j = 0; j < n; j++) {
257
            int itemType = cr.readByte(off++);
258
            StackMapType typeInfo = StackMapType.getTypeInfo(itemType);
259
            info.add(typeInfo);
260
            switch (itemType) {
261
                case StackMapType.ITEM_Object: //
262
                    typeInfo.setObject(cr.readClass(off, buf));
263
                    off += 2;
264
                    break;
265
                case StackMapType.ITEM_Uninitialized: //
266
                    int offset;
267
                    if (isExtCode) {
268
                        offset = cr.readInt(off);
269
                        off += 4;
270
                    } else {
271
                        offset = cr.readUnsignedShort(off);
272
                        off += 2;
273
                    }
274
                    typeInfo.setLabel(getLabel(offset, labels));
275
                    break;
276
            }
277
        }
278
        return off;
279
    }
280
 
281
    private void writeTypeInfo(ByteVector bv, ClassWriter cw, List info, int max)
282
    {
283
        if (max > StackMapAttribute.MAX_SIZE) {
284
            bv.putInt(info.size());
285
        } else {
286
            bv.putShort(info.size());
287
        }
288
        for (int j = 0; j < info.size(); j++) {
289
            StackMapType typeInfo = (StackMapType) info.get(j);
290
            bv.putByte(typeInfo.getType());
291
            switch (typeInfo.getType()) {
292
                case StackMapType.ITEM_Object: //
293
                    bv.putShort(cw.newClass(typeInfo.getObject()));
294
                    break;
295
 
296
                case StackMapType.ITEM_Uninitialized: //
297
                    bv.putShort(typeInfo.getLabel().getOffset());
298
                    break;
299
 
300
            }
301
        }
302
    }
303
 
304
    private Label getLabel(int offset, Label[] labels) {
305
        Label l = labels[offset];
306
        if (l != null) {
307
            return l;
308
        }
309
        return labels[offset] = new Label();
310
    }
311
 
312
    protected ByteVector write(
313
        ClassWriter cw,
314
        byte[] code,
315
        int len,
316
        int maxStack,
317
        int maxLocals)
318
    {
319
        ByteVector bv = new ByteVector();
320
        if (code != null && code.length > MAX_SIZE) { // TODO verify value
321
            bv.putInt(frames.size());
322
        } else {
323
            bv.putShort(frames.size());
324
        }
325
        for (int i = 0; i < frames.size(); i++) {
326
            writeFrame((StackMapFrame) frames.get(i),
327
                    cw,
328
                    maxStack,
329
                    maxLocals,
330
                    bv);
331
        }
332
        return bv;
333
    }
334
 
335
    protected Label[] getLabels() {
336
        HashSet labels = new HashSet();
337
        for (int i = 0; i < frames.size(); i++) {
338
            getFrameLabels((StackMapFrame) frames.get(i), labels);
339
        }
340
        return (Label[]) labels.toArray(new Label[labels.size()]);
341
    }
342
 
343
    private void writeFrame(
344
        StackMapFrame frame,
345
        ClassWriter cw,
346
        int maxStack,
347
        int maxLocals,
348
        ByteVector bv)
349
    {
350
        bv.putShort(frame.label.getOffset());
351
        writeTypeInfo(bv, cw, frame.locals, maxLocals);
352
        writeTypeInfo(bv, cw, frame.stack, maxStack);
353
    }
354
 
355
    private void getFrameLabels(StackMapFrame frame, Set labels) {
356
        labels.add(frame.label);
357
        getTypeInfoLabels(labels, frame.locals);
358
        getTypeInfoLabels(labels, frame.stack);
359
    }
360
 
361
    private void getTypeInfoLabels(Set labels, List info) {
362
        for (Iterator it = info.iterator(); it.hasNext();) {
363
            StackMapType typeInfo = (StackMapType) it.next();
364
            if (typeInfo.getType() == StackMapType.ITEM_Uninitialized) {
365
                labels.add(typeInfo.getLabel());
366
            }
367
        }
368
    }
369
 
370
    public String toString() {
371
        StringBuffer sb = new StringBuffer("StackMap[");
372
        for (int i = 0; i < frames.size(); i++) {
373
            sb.append('\n').append('[').append(frames.get(i)).append(']');
374
        }
375
        sb.append("\n]");
376
        return sb.toString();
377
    }
378
}

powered by: WebSVN 2.1.0

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