1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.bcel.generic;
18
19 import org.apache.bcel.Const;
20 import org.apache.bcel.classfile.LocalVariable;
21
22
23
24
25
26
27
28
29 public class LocalVariableGen implements InstructionTargeter, NamedAndTyped, Cloneable {
30
31 private int index;
32 private String name;
33 private Type type;
34 private InstructionHandle start;
35 private InstructionHandle end;
36 private int origIndex;
37 private boolean liveToEnd;
38
39
40
41
42
43
44
45
46
47
48
49 public LocalVariableGen(final int index, final String name, final Type type, final InstructionHandle start, final InstructionHandle end) {
50 if (index < 0 || index > Const.MAX_SHORT) {
51 throw new ClassGenException("Invalid index: " + index);
52 }
53 this.name = name;
54 this.type = type;
55 this.index = index;
56 setStart(start);
57 setEnd(end);
58 this.origIndex = index;
59 this.liveToEnd = end == null;
60 }
61
62
63
64
65
66
67
68
69
70
71
72
73 public LocalVariableGen(final int index, final String name, final Type type, final InstructionHandle start, final InstructionHandle end,
74 final int origIndex) {
75 this(index, name, type, start, end);
76 this.origIndex = origIndex;
77 }
78
79 @Override
80 public Object clone() {
81 try {
82 return super.clone();
83 } catch (final CloneNotSupportedException e) {
84 throw new UnsupportedOperationException("Clone Not Supported", e);
85 }
86 }
87
88
89
90
91 @Override
92 public boolean containsTarget(final InstructionHandle ih) {
93 return start == ih || end == ih;
94 }
95
96
97
98
99 void dispose() {
100 setStart(null);
101 setEnd(null);
102 }
103
104
105
106
107 @Override
108 public boolean equals(final Object o) {
109 if (!(o instanceof LocalVariableGen)) {
110 return false;
111 }
112 final LocalVariableGen l = (LocalVariableGen) o;
113 return l.index == index && l.start == start && l.end == end;
114 }
115
116 public InstructionHandle getEnd() {
117 return end;
118 }
119
120 public int getIndex() {
121 return index;
122 }
123
124 public boolean getLiveToEnd() {
125 return liveToEnd;
126 }
127
128
129
130
131
132
133
134
135
136
137
138
139
140 public LocalVariable getLocalVariable(final ConstantPoolGen cp) {
141 int startPc = 0;
142 int length = 0;
143 if (start != null && end != null) {
144 startPc = start.getPosition();
145 length = end.getPosition() - startPc;
146 if (end.getNext() == null && liveToEnd) {
147 length += end.getInstruction().getLength();
148 }
149 }
150 final int nameIndex = cp.addUtf8(name);
151 final int signatureIndex = cp.addUtf8(type.getSignature());
152 return new LocalVariable(startPc, length, nameIndex, signatureIndex, index, cp.getConstantPool(), origIndex);
153 }
154
155 @Override
156 public String getName() {
157 return name;
158 }
159
160 public int getOrigIndex() {
161 return origIndex;
162 }
163
164 public InstructionHandle getStart() {
165 return start;
166 }
167
168 @Override
169 public Type getType() {
170 return type;
171 }
172
173 @Override
174 public int hashCode() {
175
176
177 return name.hashCode() ^ type.hashCode();
178 }
179
180 public void setEnd(final InstructionHandle end) {
181 BranchInstruction.notifyTarget(this.end, end, this);
182 this.end = end;
183 }
184
185 public void setIndex(final int index) {
186 this.index = index;
187 }
188
189 public void setLiveToEnd(final boolean liveToEnd) {
190 this.liveToEnd = liveToEnd;
191 }
192
193 @Override
194 public void setName(final String name) {
195 this.name = name;
196 }
197
198 public void setStart(final InstructionHandle start) {
199 BranchInstruction.notifyTarget(this.start, start, this);
200 this.start = start;
201 }
202
203 @Override
204 public void setType(final Type type) {
205 this.type = type;
206 }
207
208 @Override
209 public String toString() {
210 return "LocalVariableGen(" + name + ", " + type + ", " + start + ", " + end + ")";
211 }
212
213
214
215
216
217 @Override
218 public void updateTarget(final InstructionHandle oldIh, final InstructionHandle newIh) {
219 boolean targeted = false;
220 if (start == oldIh) {
221 targeted = true;
222 setStart(newIh);
223 }
224 if (end == oldIh) {
225 targeted = true;
226 setEnd(newIh);
227 }
228 if (!targeted) {
229 throw new ClassGenException("Not targeting " + oldIh + ", but {" + start + ", " + end + "}");
230 }
231 }
232 }