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