KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > go > trove > classfile > LocalVariableTableAttr


1 /* ====================================================================
2  * Trove - Copyright (c) 1997-2000 Walt Disney Internet Group
3  * ====================================================================
4  * The Tea Software License, Version 1.1
5  *
6  * Copyright (c) 2000 Walt Disney Internet Group. All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Walt Disney Internet Group (http://opensource.go.com/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Tea", "TeaServlet", "Kettle", "Trove" and "BeanDoc" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact opensource@dig.com.
31  *
32  * 5. Products derived from this software may not be called "Tea",
33  * "TeaServlet", "Kettle" or "Trove", nor may "Tea", "TeaServlet",
34  * "Kettle", "Trove" or "BeanDoc" appear in their name, without prior
35  * written permission of the Walt Disney Internet Group.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE WALT DISNEY INTERNET GROUP OR ITS
41  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
42  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
43  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
44  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
45  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
47  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48  * ====================================================================
49  *
50  * For more information about Tea, please see http://opensource.go.com/.
51  */

52
53 package com.go.trove.classfile;
54
55 import java.util.*;
56 import java.io.*;
57
58 /******************************************************************************
59  * This class corresponds to the LocalVariableTable_attribute structure as
60  * defined in section 4.7.7 of <i>The Java Virtual Machine Specification</i>.
61  *
62  * @author Brian S O'Neill
63  * @version
64  * <!--$$Revision:--> 20 <!-- $-->, <!--$$JustDate:--> 00/11/27 <!-- $-->
65  */

66 class LocalVariableTableAttr extends Attribute {
67     private List mEntries = new ArrayList(10);
68     private List mCleanEntries;
69     private int mRangeCount;
70     
71     public LocalVariableTableAttr(ConstantPool cp) {
72         super(cp, LOCAL_VARIABLE_TABLE);
73     }
74     
75     /**
76      * Add an entry into the LocalVariableTableAttr.
77      */

78     public void addEntry(LocalVariable localVar) {
79         String JavaDoc varName = localVar.getName();
80         if (varName != null) {
81             ConstantUTFInfo name = ConstantUTFInfo.make(mCp, varName);
82             ConstantUTFInfo descriptor =
83                 ConstantUTFInfo.make(mCp, localVar.getType().toString());
84
85             mEntries.add(new Entry(localVar, name, descriptor));
86         }
87
88         mCleanEntries = null;
89     }
90     
91     public int getLength() {
92         clean();
93         return 2 + 10 * mRangeCount;
94     }
95     
96     public void writeDataTo(DataOutput dout) throws IOException {
97         dout.writeShort(mRangeCount);
98
99         int size = mCleanEntries.size();
100         for (int i=0; i<size; i++) {
101             Entry entry = (Entry)mEntries.get(i);
102             LocalVariable localVar = entry.mLocalVar;
103
104             SortedSet ranges = localVar.getLocationRangeSet();
105
106             int name_index = entry.mName.getIndex();
107             int descriptor_index = entry.mDescriptor.getIndex();
108             int index = localVar.getNumber();
109
110             check("local variable table entry name index", name_index);
111             check("local variable table entry descriptor index",
112                   descriptor_index);
113             check("local variable table entry index", index);
114
115             Iterator it = ranges.iterator();
116             while (it.hasNext()) {
117                 LocationRange range = (LocationRange)it.next();
118
119                 Location startLocation = range.getStartLocation();
120                 Location endLocation = range.getEndLocation();
121
122                 int start_pc = startLocation.getLocation();
123                 int length = endLocation.getLocation() - start_pc - 1;
124
125                 check("local variable table entry start PC", start_pc);
126
127                 dout.writeShort(start_pc);
128                 dout.writeShort(length);
129                 dout.writeShort(name_index);
130                 dout.writeShort(descriptor_index);
131                 dout.writeShort(index);
132             }
133         }
134     }
135
136     private void check(String JavaDoc type, int addr) throws RuntimeException JavaDoc {
137         if (addr < 0 || addr > 65535) {
138             throw new RuntimeException JavaDoc("Value for " + type + " out of " +
139                                        "valid range: " + addr);
140         }
141     }
142
143     private void clean() {
144         if (mCleanEntries != null) {
145             return;
146         }
147
148         // Clean out entries that are incomplete or bogus.
149

150         int size = mEntries.size();
151         mCleanEntries = new ArrayList(size);
152         mRangeCount = 0;
153
154     outer:
155         for (int i=0; i<size; i++) {
156             Entry entry = (Entry)mEntries.get(i);
157             LocalVariable localVar = entry.mLocalVar;
158
159             SortedSet ranges = localVar.getLocationRangeSet();
160             if (ranges == null || ranges.size() == 0) {
161                 continue;
162             }
163
164             Iterator it = ranges.iterator();
165             while (it.hasNext()) {
166                 LocationRange range = (LocationRange)it.next();
167
168                 Location startLocation = range.getStartLocation();
169                 Location endLocation = range.getEndLocation();
170
171                 if (startLocation == null || endLocation == null) {
172                     continue outer;
173                 }
174
175                 int start_pc = startLocation.getLocation();
176                 int length = endLocation.getLocation() - start_pc - 1;
177
178                 if (length < 0) {
179                     continue outer;
180                 }
181             }
182             
183             mCleanEntries.add(entry);
184             mRangeCount += entry.getRangeCount();
185         }
186     }
187
188     static Attribute define(ConstantPool cp,
189                             String JavaDoc name,
190                             int length,
191                             DataInput din) throws IOException {
192
193         LocalVariableTableAttr locals = new LocalVariableTableAttr(cp);
194
195         int size = din.readUnsignedShort();
196         for (int i=0; i<size; i++) {
197             int start_pc = din.readUnsignedShort();
198             int end_pc = start_pc + din.readUnsignedShort() + 1;
199             int name_index = din.readUnsignedShort();
200             int descriptor_index = din.readUnsignedShort();
201             final int index = din.readUnsignedShort();
202
203             final ConstantUTFInfo varName =
204                 (ConstantUTFInfo)cp.getConstant(name_index);
205             final ConstantUTFInfo varDesc =
206                 (ConstantUTFInfo)cp.getConstant(descriptor_index);
207
208             final Location startLocation = new FixedLocation(start_pc);
209             final Location endLocation = new FixedLocation(end_pc);
210
211             SortedSet ranges = new TreeSet();
212             ranges.add(new LocationRangeImpl(startLocation, endLocation));
213             final SortedSet fRanges =
214                 Collections.unmodifiableSortedSet(ranges);
215
216             LocalVariable localVar = new LocalVariable() {
217                 private String JavaDoc mName;
218                 private TypeDescriptor mType;
219
220                 {
221                     mName = varName.getValue();
222                     mType = TypeDescriptor.parseTypeDesc(varDesc.getValue());
223                 }
224
225                 public String JavaDoc getName() {
226                     return mName;
227                 }
228
229                 public void setName(String JavaDoc name) {
230                     mName = name;
231                 }
232
233                 public TypeDescriptor getType() {
234                     return mType;
235                 }
236                 
237                 public boolean isDoubleWord() {
238                     Class JavaDoc clazz = mType.getClassArg();
239                     return (clazz == double.class || clazz == long.class);
240                 }
241                 
242                 public int getNumber() {
243                     return index;
244                 }
245
246                 public SortedSet getLocationRangeSet() {
247                     return fRanges;
248                 }
249             };
250
251             Entry entry = new Entry(localVar, varName, varDesc);
252             locals.mEntries.add(entry);
253         }
254
255         return locals;
256     }
257
258     private static class Entry {
259         public LocalVariable mLocalVar;
260         public ConstantUTFInfo mName;
261         public ConstantUTFInfo mDescriptor;
262
263         public Entry(LocalVariable localVar,
264                      ConstantUTFInfo name, ConstantUTFInfo descriptor) {
265
266             mLocalVar = localVar;
267             mName = name;
268             mDescriptor = descriptor;
269         }
270
271         public int getRangeCount() {
272             return mLocalVar.getLocationRangeSet().size();
273         }
274     }
275 }
276
Popular Tags