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