KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > classfile > StackMapFrame


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.classfile;
21
22 import java.io.DataInputStream JavaDoc;
23 import java.io.IOException JavaDoc;
24
25 /**
26  * A stack map frame, as defined by a StackMapTable attribute. A stack map
27  * frame is defined by the Java Virtual Machine Specification, section 4.8.4,
28  * as a C-like union of stack frame descriptions. To map this union to Java
29  * classes, this class is abstract and has a separate public subclass for each
30  * union member. The stack map frame type can be determined either by the
31  * its <code>frame_type</code> or using an instanceof test.
32  *
33  * @author tball
34  */

35 public abstract class StackMapFrame {
36     int frameType;
37     
38     static StackMapFrame[] loadStackMapTable(DataInputStream JavaDoc in, ConstantPool pool)
39       throws IOException JavaDoc {
40         int n = in.readUnsignedShort();
41         StackMapFrame[] entries = new StackMapFrame[n];
42         for (int i = 0; i < n; i++) {
43             int tag = in.readUnsignedByte();
44             StackMapFrame frame;
45             if (tag >= 0 && tag <= 63)
46                 frame = new SameFrame(tag);
47             else if (tag >= 64 && tag <= 127) {
48                 VerificationTypeInfo typeInfo =
49                     VerificationTypeInfo.loadVerificationTypeInfo(in, pool);
50                 frame = new SameLocals1StackItemFrame(tag, typeInfo);
51             }
52             else if (tag >= 128 && tag <= 246)
53                 throw new InvalidClassFormatException("reserved stack map frame tag used: " + tag);
54             else if (tag == 247) {
55                 int offset = in.readUnsignedShort();
56                 VerificationTypeInfo typeInfo =
57                     VerificationTypeInfo.loadVerificationTypeInfo(in, pool);
58                 frame = new SameLocals1StackItemFrameExtended(tag, offset, typeInfo);
59             }
60             else if (tag >= 248 && tag <= 250) {
61                 int offset = in.readUnsignedShort();
62                 frame = new ChopFrame(tag, offset);
63             }
64             else if (tag == 251) {
65                 int offset = in.readUnsignedShort();
66                 frame = new SameFrameExtended(tag, offset);
67             }
68             else if (tag >= 252 && tag <= 254)
69                 frame = makeAppendFrame(tag, in, pool);
70             else /* tag == 255 */
71                 frame = makeFullFrame(in, pool);
72             entries[i] = frame;
73         }
74         return entries;
75     }
76     
77     private static AppendFrame makeAppendFrame(int tag, DataInputStream JavaDoc in, ConstantPool pool)
78       throws IOException JavaDoc {
79         int offset = in.readUnsignedShort();
80         VerificationTypeInfo[] locals = new VerificationTypeInfo[tag - 251];
81         for (int i = 0; i < locals.length; i++)
82             locals[i] = VerificationTypeInfo.loadVerificationTypeInfo(in, pool);
83         return new AppendFrame(tag, offset, locals);
84     }
85     
86     private static FullFrame makeFullFrame(DataInputStream JavaDoc in, ConstantPool pool)
87       throws IOException JavaDoc {
88         int offset = in.readUnsignedShort();
89         int n = in.readUnsignedShort();
90         VerificationTypeInfo[] locals = new VerificationTypeInfo[n];
91         for (int i = 0; i < locals.length; i++)
92             locals[i] = VerificationTypeInfo.loadVerificationTypeInfo(in, pool);
93         n = in.readUnsignedShort();
94         VerificationTypeInfo[] stackItems = new VerificationTypeInfo[n];
95         for (int i = 0; i < stackItems.length; i++)
96             stackItems[i] = VerificationTypeInfo.loadVerificationTypeInfo(in, pool);
97         return new FullFrame(255, offset, locals, stackItems);
98     }
99     
100     /** Creates new StackMapFrame */
101     StackMapFrame(int tag) {
102         frameType = tag;
103     }
104
105     /**
106      * Returns the frame_type for this frame. As documented in the JVM specification,
107      * different tag ranges define different frame_type values.
108      */

109     public final int getFrameType() {
110         return frameType;
111     }
112     
113     /**
114      * Returns the <code>offset_delta</code> for this frame type. From the
115      * Java Virtual Machine Specification, section 4.8.4:
116      * <br/><br/>
117      * "Each stack_map_frame structure specifies the type state at a particular
118      * byte code offset. Each frame type specifies (explicitly or implicitly) a
119      * value, <code>offset_delta</code>, that is used to calulate the actual byte
120      * code offset at which it applies. The byte code offset at which the frame
121      * applies is given by adding <code>1 + offset_delta</code> to the offset of
122      * the previous frame, unless the previous frame is the initial frame of
123      * the method, in which case the byte code offset is <code>offset_delta</code>."
124      */

125     public abstract int getOffsetDelta();
126         
127    /**
128      * A frame type of <code>same_frame</code>, which means that the frame
129      * has exactly the same locals as the previous stack map frame and that
130      * the number of stack items is zero.
131      */

132     public static final class SameFrame extends StackMapFrame {
133         SameFrame(int tag) {
134             super(tag);
135         }
136         
137         /**
138          * The <code>offset_delta</code> value for the frame is the value
139          * of the tag item, frame_type.
140          */

141         public int getOffsetDelta() {
142             return frameType;
143         }
144     }
145     
146     /**
147      * A frame type of <code>same_locals_1_stack_item_frame</code>, which means
148      * that the frame has exactly the same locals as the previous stack map
149      * frame and that the number of stack items is 1.
150      */

151     public static final class SameLocals1StackItemFrame extends StackMapFrame {
152         VerificationTypeInfo typeInfo;
153         SameLocals1StackItemFrame(int tag, VerificationTypeInfo typeInfo) {
154             super(tag);
155             this.typeInfo = typeInfo;
156         }
157  
158         /**
159          * The <code>offset_delta</code> value for the frame is the value
160          * <code>(frame_type - 64)</code>.
161          */

162         public int getOffsetDelta() {
163             return frameType - 64;
164         }
165         
166         /**
167          * Returns the verification type info for the single stack item
168          * referenced by this frame.
169          */

170         public VerificationTypeInfo getVerificationTypeInfo() {
171             return typeInfo;
172         }
173     }
174     
175     /**
176      * A frame type of <code>same_locals_1_stack_item_frame_extended</code>,
177      * which means that the frame has exactly the same locals as the previous
178      * stack map frame and that the number of stack items is 1.
179      */

180     public static final class SameLocals1StackItemFrameExtended extends StackMapFrame {
181         int offset;
182         VerificationTypeInfo typeInfo;
183         SameLocals1StackItemFrameExtended(int tag, int offset, VerificationTypeInfo typeInfo) {
184             super(tag);
185             this.offset = offset;
186             this.typeInfo = typeInfo;
187         }
188         
189         /**
190          * Returns the <code>offset_delta</code> for this frame type.
191          */

192         public int getOffsetDelta() {
193             return offset;
194         }
195         
196         /**
197          * Returns the verification type info for the single stack item for
198          * this frame.
199          */

200         public VerificationTypeInfo getVerificationTypeInfo() {
201             return typeInfo;
202         }
203     }
204     
205     /**
206      * A frame type of <code>chop_frame</code>, which means that the operand
207      * stack is empty and the current locals are the same as the locals in
208      * the previous frame, except that the <i>k</i> last locals are absent.
209      * The value of <i>k</i> is given by the formula <code>251-frame_type</code>.
210      */

211     public static final class ChopFrame extends StackMapFrame {
212         int offset;
213         ChopFrame(int tag, int offset) {
214             super(tag);
215             this.offset = offset;
216         }
217         
218         /**
219          * Returns the <code>offset_delta</code> for this frame type.
220          */

221         public int getOffsetDelta() {
222             return offset;
223         }
224     }
225     
226     /**
227      * A frame type of <code>same_frame_extended</code>, which means the frame
228      * has exactly the same locals as the previous stack map frame and that the
229      * number of stack items is zero.
230      */

231     public static final class SameFrameExtended extends StackMapFrame {
232         int offset;
233         SameFrameExtended(int tag, int offset) {
234             super(tag);
235             this.offset = offset;
236         }
237         
238         /**
239          * Returns the <code>offset_delta</code> for this frame type.
240          */

241         public int getOffsetDelta() {
242             return offset;
243         }
244     }
245     
246     /**
247      * A frame type of <code>append_frame</code>, which means that the operand
248      * stack is empty and the current locals are the same as the locals in the
249      * previous frame, except that <i>k</i> additional locals are defined. The
250      * value of <i>k</i> is given by the formula <code>frame_type-251</code>.
251      */

252     public static final class AppendFrame extends StackMapFrame {
253         int offset;
254         VerificationTypeInfo[] locals;
255         AppendFrame(int tag, int offset, VerificationTypeInfo[] locals) {
256             super(tag);
257             this.offset = offset;
258             this.locals = locals;
259         }
260         
261         /**
262          * Returns the <code>offset_delta</code> for this frame type.
263          */

264         public int getOffsetDelta() {
265             return offset;
266         }
267         
268         /**
269          * Returns the verification type info for this frame's set of
270          * locals.
271          */

272         public VerificationTypeInfo[] getLocals() {
273             return locals.clone();
274         }
275     }
276     
277     /**
278      * A frame type of <code>full_frame</code>, which declares all of its
279      * locals and stack items.
280      */

281     public static final class FullFrame extends StackMapFrame {
282         int offset;
283         VerificationTypeInfo[] locals;
284         VerificationTypeInfo[] stackItems;
285         FullFrame(int tag, int offset, VerificationTypeInfo[] locals,
286                   VerificationTypeInfo[] stackItems) {
287             super(tag);
288             this.offset = offset;
289             this.locals = locals;
290             this.stackItems = stackItems;
291         }
292         
293         /**
294          * Returns the <code>offset_delta</code> for this frame type.
295          */

296         public int getOffsetDelta() {
297             return offset;
298         }
299         
300         /**
301          * Returns the verification type info for this frame's set of
302          * locals.
303          */

304         public VerificationTypeInfo[] getLocals() {
305             return locals.clone();
306         }
307         
308         /**
309          * Returns the verification type info for this frame's set of
310          * stack items.
311          */

312         public VerificationTypeInfo[] getStackItems() {
313             return stackItems.clone();
314         }
315     }
316 }
317
Popular Tags