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