1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.bcel.classfile;
18
19 import java.io.DataInputStream;
20 import java.io.DataOutputStream;
21 import java.io.IOException;
22 import org.apache.bcel.Constants;
23
24 /***
25 * This class represents colection of local variables in a
26 * method. This attribute is contained in the <em>Code</em> attribute.
27 *
28 * @version $Id: LocalVariableTable.java 386056 2006-03-15 11:31:56Z tcurdt $
29 * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
30 * @see Code
31 * @see LocalVariable
32 */
33 public class LocalVariableTable extends Attribute {
34
35 private int local_variable_table_length;
36 private LocalVariable[] local_variable_table;
37
38
39 /***
40 * Initialize from another object. Note that both objects use the same
41 * references (shallow copy). Use copy() for a physical copy.
42 */
43 public LocalVariableTable(LocalVariableTable c) {
44 this(c.getNameIndex(), c.getLength(), c.getLocalVariableTable(), c.getConstantPool());
45 }
46
47
48 /***
49 * @param name_index Index in constant pool to `LocalVariableTable'
50 * @param length Content length in bytes
51 * @param local_variable_table Table of local variables
52 * @param constant_pool Array of constants
53 */
54 public LocalVariableTable(int name_index, int length, LocalVariable[] local_variable_table,
55 ConstantPool constant_pool) {
56 super(Constants.ATTR_LOCAL_VARIABLE_TABLE, name_index, length, constant_pool);
57 setLocalVariableTable(local_variable_table);
58 }
59
60
61 /***
62 * Construct object from file stream.
63 * @param name_index Index in constant pool
64 * @param length Content length in bytes
65 * @param file Input stream
66 * @param constant_pool Array of constants
67 * @throws IOException
68 */
69 LocalVariableTable(int name_index, int length, DataInputStream file, ConstantPool constant_pool)
70 throws IOException {
71 this(name_index, length, (LocalVariable[]) null, constant_pool);
72 local_variable_table_length = (file.readUnsignedShort());
73 local_variable_table = new LocalVariable[local_variable_table_length];
74 for (int i = 0; i < local_variable_table_length; i++) {
75 local_variable_table[i] = new LocalVariable(file, constant_pool);
76 }
77 }
78
79
80 /***
81 * Called by objects that are traversing the nodes of the tree implicitely
82 * defined by the contents of a Java class. I.e., the hierarchy of methods,
83 * fields, attributes, etc. spawns a tree of objects.
84 *
85 * @param v Visitor object
86 */
87 public void accept( Visitor v ) {
88 v.visitLocalVariableTable(this);
89 }
90
91
92 /***
93 * Dump local variable table attribute to file stream in binary format.
94 *
95 * @param file Output file stream
96 * @throws IOException
97 */
98 public final void dump( DataOutputStream file ) throws IOException {
99 super.dump(file);
100 file.writeShort(local_variable_table_length);
101 for (int i = 0; i < local_variable_table_length; i++) {
102 local_variable_table[i].dump(file);
103 }
104 }
105
106
107 /***
108 * @return Array of local variables of method.
109 */
110 public final LocalVariable[] getLocalVariableTable() {
111 return local_variable_table;
112 }
113
114
115 /***
116 * @return first matching variable using index
117 *
118 * @param index the variable slot
119 *
120 * @return the first LocalVariable that matches the slot or null if not found
121 *
122 * @deprecated since 5.2 because multiple variables can share the
123 * same slot, use getLocalVariable(int index, int pc) instead.
124 */
125 public final LocalVariable getLocalVariable( int index ) {
126 for (int i = 0; i < local_variable_table_length; i++) {
127 if (local_variable_table[i].getIndex() == index) {
128 return local_variable_table[i];
129 }
130 }
131 return null;
132 }
133
134
135 /***
136 * @return matching variable using index when variable is used at supplied pc
137 *
138 * @param index the variable slot
139 * @param pc the current pc that this variable is alive
140 *
141 * @return the LocalVariable that matches or null if not found
142 */
143 public final LocalVariable getLocalVariable( int index, int pc ) {
144 for (int i = 0; i < local_variable_table_length; i++) {
145 if (local_variable_table[i].getIndex() == index) {
146 int start_pc = local_variable_table[i].getStartPC();
147 int end_pc = start_pc + local_variable_table[i].getLength();
148 if ((pc >= start_pc) && (pc < end_pc)) {
149 return local_variable_table[i];
150 }
151 }
152 }
153 return null;
154 }
155
156
157 public final void setLocalVariableTable( LocalVariable[] local_variable_table ) {
158 this.local_variable_table = local_variable_table;
159 local_variable_table_length = (local_variable_table == null)
160 ? 0
161 : local_variable_table.length;
162 }
163
164
165 /***
166 * @return String representation.
167 */
168 public final String toString() {
169 StringBuffer buf = new StringBuffer("");
170 for (int i = 0; i < local_variable_table_length; i++) {
171 buf.append(local_variable_table[i].toString());
172 if (i < local_variable_table_length - 1) {
173 buf.append('\n');
174 }
175 }
176 return buf.toString();
177 }
178
179
180 /***
181 * @return deep copy of this attribute
182 */
183 public Attribute copy( ConstantPool _constant_pool ) {
184 LocalVariableTable c = (LocalVariableTable) clone();
185 c.local_variable_table = new LocalVariable[local_variable_table_length];
186 for (int i = 0; i < local_variable_table_length; i++) {
187 c.local_variable_table[i] = local_variable_table[i].copy();
188 }
189 c.constant_pool = _constant_pool;
190 return c;
191 }
192
193
194 public final int getTableLength() {
195 return local_variable_table_length;
196 }
197 }