Resolves all forward references to this label. This method must be called when this label is added to the bytecode of the method, i.e. when its position becomes known. This method fills in the blanks that where left in the bytecode by each forward reference previously added to this label. @param ow
(
final CodeWriter owner,
final int position,
final byte[] data)
| 235 | */ |
| 236 | |
| 237 | boolean resolve ( |
| 238 | final CodeWriter owner, |
| 239 | final int position, |
| 240 | final byte[] data) |
| 241 | { |
| 242 | if (CodeWriter.CHECK) { |
| 243 | if (this.owner == null) { |
| 244 | this.owner = owner; |
| 245 | } |
| 246 | if (resolved || this.owner != owner) { |
| 247 | throw new IllegalArgumentException(); |
| 248 | } |
| 249 | } |
| 250 | boolean needUpdate = false; |
| 251 | this.resolved = true; |
| 252 | this.position = position; |
| 253 | int i = 0; |
| 254 | while (i < referenceCount) { |
| 255 | int source = srcAndRefPositions[i++]; |
| 256 | int reference = srcAndRefPositions[i++]; |
| 257 | int offset; |
| 258 | if (source >= 0) { |
| 259 | offset = position - source; |
| 260 | if (offset < Short.MIN_VALUE || offset > Short.MAX_VALUE) { |
| 261 | // changes the opcode of the jump instruction, in order to be able to |
| 262 | // find it later (see resizeInstructions in CodeWriter). These |
| 263 | // temporary opcodes are similar to jump instruction opcodes, except |
| 264 | // that the 2 bytes offset is unsigned (and can therefore represent |
| 265 | // values from 0 to 65535, which is sufficient since the size of a |
| 266 | // method is limited to 65535 bytes). |
| 267 | int opcode = data[reference - 1] & 0xFF; |
| 268 | if (opcode <= Constants.JSR) { |
| 269 | // changes IFEQ ... JSR to opcodes 202 to 217 (inclusive) |
| 270 | data[reference - 1] = (byte)(opcode + 49); |
| 271 | } else { |
| 272 | // changes IFNULL and IFNONNULL to opcodes 218 and 219 (inclusive) |
| 273 | data[reference - 1] = (byte)(opcode + 20); |
| 274 | } |
| 275 | needUpdate = true; |
| 276 | } |
| 277 | data[reference++] = (byte)(offset >>> 8); |
| 278 | data[reference] = (byte)offset; |
| 279 | } else { |
| 280 | offset = position + source + 1; |
| 281 | data[reference++] = (byte)(offset >>> 24); |
| 282 | data[reference++] = (byte)(offset >>> 16); |
| 283 | data[reference++] = (byte)(offset >>> 8); |
| 284 | data[reference] = (byte)offset; |
| 285 | } |
| 286 | } |
| 287 | return needUpdate; |
| 288 | } |
| 289 | } |