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 java.io.DataOutputStream;
22 import java.io.IOException;
23
24 import org.apache.bcel.util.ByteSequence;
25
26
27
28
29
30
31
32 public abstract class BranchInstruction extends Instruction implements InstructionTargeter {
33
34
35
36
37 static void notifyTarget(final InstructionHandle oldIh, final InstructionHandle newIh, final InstructionTargeter t) {
38 if (oldIh != null) {
39 oldIh.removeTargeter(t);
40 }
41 if (newIh != null) {
42 newIh.addTargeter(t);
43 }
44 }
45
46
47
48
49 @Deprecated
50 protected int index;
51
52
53
54
55 @Deprecated
56 protected InstructionHandle target;
57
58
59
60
61 @Deprecated
62 protected int position;
63
64
65
66
67 BranchInstruction() {
68 }
69
70
71
72
73
74
75
76 protected BranchInstruction(final short opcode, final InstructionHandle target) {
77 super(opcode, (short) 3);
78 setTarget(target);
79 }
80
81
82
83
84 @Override
85 public boolean containsTarget(final InstructionHandle ih) {
86 return target == ih;
87 }
88
89
90
91
92 @Override
93 void dispose() {
94 setTarget(null);
95 index = -1;
96 position = -1;
97 }
98
99
100
101
102
103
104 @Override
105 public void dump(final DataOutputStream out) throws IOException {
106 out.writeByte(super.getOpcode());
107 index = getTargetOffset();
108 if (!isValidShort(index)) {
109 throw new ClassGenException("Branch target offset too large for short: " + index);
110 }
111 out.writeShort(index);
112 }
113
114
115
116
117 public final int getIndex() {
118 return index;
119 }
120
121
122
123
124
125 protected int getPosition() {
126 return position;
127 }
128
129
130
131
132 public InstructionHandle getTarget() {
133 return target;
134 }
135
136
137
138
139 protected int getTargetOffset() {
140 return getTargetOffset(target);
141 }
142
143
144
145
146
147 protected int getTargetOffset(final InstructionHandle target) {
148 if (target == null) {
149 throw new ClassGenException("Target of " + super.toString(true) + " is invalid null handle");
150 }
151 final int t = target.getPosition();
152 if (t < 0) {
153 throw new ClassGenException("Invalid branch target position offset for " + super.toString(true) + ":" + t + ":" + target);
154 }
155 return t - position;
156 }
157
158
159
160
161
162
163
164
165 @Override
166 protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException {
167 super.setLength(3);
168 index = bytes.readShort();
169 }
170
171
172
173
174
175 protected void setIndex(final int index) {
176 this.index = index;
177 }
178
179
180
181
182
183 protected void setPosition(final int position) {
184 this.position = position;
185 }
186
187
188
189
190
191
192 public void setTarget(final InstructionHandle target) {
193 notifyTarget(this.target, target, this);
194 this.target = target;
195 }
196
197
198
199
200
201
202
203
204
205
206 @Override
207 public String toString(final boolean verbose) {
208 final String s = super.toString(verbose);
209 String t = "null";
210 if (target != null) {
211 if (verbose) {
212 if (target.getInstruction() == this) {
213 t = "<points to itself>";
214 } else if (target.getInstruction() == null) {
215 t = "<null instruction!!!?>";
216 } else {
217
218
219
220 t = "" + target.getPosition();
221 }
222 } else {
223 index = target.getPosition();
224
225
226 t = "" + index;
227 }
228 }
229 return s + " -> " + t;
230 }
231
232
233
234
235
236
237
238
239
240
241 protected int updatePosition(final int offset, final int maxOffset) {
242 position += offset;
243 return 0;
244 }
245
246
247
248
249
250 @Override
251 public void updateTarget(final InstructionHandle oldIh, final InstructionHandle newIh) {
252 if (target != oldIh) {
253 throw new ClassGenException("Not targeting " + oldIh + ", but " + target);
254 }
255 setTarget(newIh);
256 }
257
258 }