KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javassist > bytecode > LocalVariableAttribute


1 /*
2  * Javassist, a Java-bytecode translator toolkit.
3  * Copyright (C) 1999-2005 Shigeru Chiba. All Rights Reserved.
4  *
5  * The contents of this file are subject to the Mozilla Public License Version
6  * 1.1 (the "License"); you may not use this file except in compliance with
7  * the License. Alternatively, the contents of this file may be used under
8  * the terms of the GNU Lesser General Public License Version 2.1 or later.
9  *
10  * Software distributed under the License is distributed on an "AS IS" basis,
11  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12  * for the specific language governing rights and limitations under the
13  * License.
14  */

15
16 package javassist.bytecode;
17
18 import java.io.DataInputStream JavaDoc;
19 import java.io.IOException JavaDoc;
20 import java.util.Map JavaDoc;
21
22 /**
23  * <code>LocalVariableTable_attribute</code> or
24  * <code>LocalVariableTypeTable_attribute</code>.
25  */

26 public class LocalVariableAttribute extends AttributeInfo {
27     /**
28      * The name of this attribute <code>"LocalVariableTable"</code>.
29      */

30     public static final String JavaDoc tag = "LocalVariableTable";
31
32     /**
33      * The name of the attribute <code>"LocalVariableTypeTable"</code>.
34      */

35     public static final String JavaDoc typeTag = "LocalVariableTypeTable";
36
37     /**
38      * Constructs an empty LocalVariableTable.
39      */

40     public LocalVariableAttribute(ConstPool cp) {
41         super(cp, tag, new byte[2]);
42         ByteArray.write16bit(0, info, 0);
43     }
44
45     LocalVariableAttribute(ConstPool cp, int n, DataInputStream JavaDoc in)
46         throws IOException JavaDoc
47     {
48         super(cp, n, in);
49     }
50
51     private LocalVariableAttribute(ConstPool cp, byte[] i) {
52         super(cp, tag, i);
53     }
54
55     /**
56      * Appends a new entry to <code>local_variable_table</code>.
57      *
58      * @param startPc <code>start_pc</code>
59      * @param length <code>length</code>
60      * @param nameIndex <code>name_index</code>
61      * @param descriptorIndex <code>descriptor_index</code>
62      * @param index <code>index</code>
63      */

64     public void addEntry(int startPc, int length, int nameIndex,
65                          int descriptorIndex, int index) {
66         int size = info.length;
67         byte[] newInfo = new byte[size + 10];
68         ByteArray.write16bit(tableLength() + 1, newInfo, 0);
69         for (int i = 2; i < size; ++i)
70             newInfo[i] = info[i];
71
72         ByteArray.write16bit(startPc, newInfo, size);
73         ByteArray.write16bit(length, newInfo, size + 2);
74         ByteArray.write16bit(nameIndex, newInfo, size + 4);
75         ByteArray.write16bit(descriptorIndex, newInfo, size + 6);
76         ByteArray.write16bit(index, newInfo, size + 8);
77         info = newInfo;
78     }
79
80     /**
81      * Returns <code>local_variable_table_length</code>.
82      * This represents the number of entries in the table.
83      */

84     public int tableLength() {
85         return ByteArray.readU16bit(info, 0);
86     }
87
88     /**
89      * Returns <code>local_variable_table[i].start_pc</code>.
90      * This represents the index into the code array from which the local
91      * variable is effective.
92      *
93      * @param i the i-th entry.
94      */

95     public int startPc(int i) {
96         return ByteArray.readU16bit(info, i * 10 + 2);
97     }
98
99     /**
100      * Returns <code>local_variable_table[i].length</code>.
101      * This represents the length of the code region in which the local
102      * variable is effective.
103      *
104      * @param i the i-th entry.
105      */

106     public int codeLength(int i) {
107         return ByteArray.readU16bit(info, i * 10 + 4);
108     }
109
110     /**
111      * Adjusts start_pc and length if bytecode is inserted in a method body.
112      */

113     void shiftPc(int where, int gapLength, boolean exclusive) {
114         int n = tableLength();
115         for (int i = 0; i < n; ++i) {
116             int pos = i * 10 + 2;
117             int pc = ByteArray.readU16bit(info, pos);
118             int len = ByteArray.readU16bit(info, pos + 2);
119
120             /* if pc == 0, then the local variable is a method parameter.
121              */

122             if (pc > where || (exclusive && pc == where && pc != 0))
123                 ByteArray.write16bit(pc + gapLength, info, pos);
124             else if (pc + len > where)
125                 ByteArray.write16bit(len + gapLength, info, pos + 2);
126         }
127     }
128
129     /**
130      * Returns the value of <code>local_variable_table[i].name_index</code>.
131      * This represents the name of the local variable.
132      *
133      * @param i the i-th entry.
134      */

135     public int nameIndex(int i) {
136         return ByteArray.readU16bit(info, i * 10 + 6);
137     }
138
139     /**
140      * Returns the name of the local variable
141      * specified by <code>local_variable_table[i].name_index</code>.
142      *
143      * @param i the i-th entry.
144      */

145     public String JavaDoc variableName(int i) {
146         return getConstPool().getUtf8Info(nameIndex(i));
147     }
148
149     /**
150      * Returns the value of
151      * <code>local_variable_table[i].descriptor_index</code>.
152      * This represents the type descriptor of the local variable.
153      * <p>
154      * If this attribute represents a LocalVariableTypeTable attribute,
155      * this method returns the value of
156      * <code>local_variable_type_table[i].signature_index</code>.
157      * It represents the type of the local variable.
158      *
159      * @param i the i-th entry.
160      */

161     public int descriptorIndex(int i) {
162         return ByteArray.readU16bit(info, i * 10 + 8);
163     }
164
165     /**
166      * This method is equivalent to <code>descriptorIndex()</code>.
167      * If this attribute represents a LocalVariableTypeTable attribute,
168      * this method should be used instead of <code>descriptorIndex()</code>
169      * since the method name is more appropriate.
170      *
171      * @param i the i-th entry.
172      * @see #descriptorIndex(int)
173      */

174     public int signatureIndex(int i) {
175         return descriptorIndex(i);
176     }
177
178     /**
179      * Returns the type descriptor of the local variable
180      * specified by <code>local_variable_table[i].descriptor_index</code>.
181      * <p>
182      * If this attribute represents a LocalVariableTypeTable attribute,
183      * this method returns the type signature of the local variable
184      * specified by <code>local_variable_type_table[i].signature_index</code>.
185       *
186      * @param i the i-th entry.
187      */

188     public String JavaDoc descriptor(int i) {
189         return getConstPool().getUtf8Info(descriptorIndex(i));
190     }
191
192     /**
193      * This method is equivalent to <code>descriptor()</code>.
194      * If this attribute represents a LocalVariableTypeTable attribute,
195      * this method should be used instead of <code>descriptor()</code>
196      * since the method name is more appropriate.
197      *
198      * @param i the i-th entry.
199      * @see #descriptor(int)
200      */

201     public String JavaDoc signature(int i) {
202         return descriptor(i);
203     }
204
205     /**
206      * Returns <code>local_variable_table[i].index</code>.
207      * This represents the index of the local variable.
208      *
209      * @param i the i-th entry.
210      */

211     public int index(int i) {
212         return ByteArray.readU16bit(info, i * 10 + 10);
213     }
214
215     /**
216      * Makes a copy.
217      *
218      * @param newCp the constant pool table used by the new copy.
219      * @param classnames should be null.
220      */

221     public AttributeInfo copy(ConstPool newCp, Map JavaDoc classnames) {
222         byte[] src = get();
223         byte[] dest = new byte[src.length];
224         ConstPool cp = getConstPool();
225         LocalVariableAttribute attr = new LocalVariableAttribute(newCp, dest);
226         int n = ByteArray.readU16bit(src, 0);
227         ByteArray.write16bit(n, dest, 0);
228         int j = 2;
229         for (int i = 0; i < n; ++i) {
230             int start = ByteArray.readU16bit(src, j);
231             int len = ByteArray.readU16bit(src, j + 2);
232             int name = ByteArray.readU16bit(src, j + 4);
233             int type = ByteArray.readU16bit(src, j + 6);
234             int index = ByteArray.readU16bit(src, j + 8);
235
236             ByteArray.write16bit(start, dest, j);
237             ByteArray.write16bit(len, dest, j + 2);
238             if (name != 0)
239                 name = cp.copy(name, newCp, null);
240
241             ByteArray.write16bit(name, dest, j + 4);
242
243             if (type != 0)
244                 type = cp.copy(type, newCp, null);
245
246             ByteArray.write16bit(type, dest, j + 6);
247             ByteArray.write16bit(index, dest, j + 8);
248             j += 10;
249         }
250
251         return attr;
252     }
253 }
254
Popular Tags