Sets the bytecode offset of this label to the given value and resolves the forward references to this label, if any. This method must be called when this label is added to the bytecode of the method, i.e. when its bytecode offset becomes known. This method fills in the blanks that where left in the
(final byte[] code, final int bytecodeOffset)
| 442 | * bytes instead of 2), in ClassReader. |
| 443 | */ |
| 444 | final boolean resolve(final byte[] code, final int bytecodeOffset) { |
| 445 | this.flags |= FLAG_RESOLVED; |
| 446 | this.bytecodeOffset = bytecodeOffset; |
| 447 | if (forwardReferences == null) { |
| 448 | return false; |
| 449 | } |
| 450 | boolean hasAsmInstructions = false; |
| 451 | for (int i = forwardReferences[0]; i > 0; i -= 2) { |
| 452 | final int sourceInsnBytecodeOffset = forwardReferences[i - 1]; |
| 453 | final int reference = forwardReferences[i]; |
| 454 | final int relativeOffset = bytecodeOffset - sourceInsnBytecodeOffset; |
| 455 | int handle = reference & FORWARD_REFERENCE_HANDLE_MASK; |
| 456 | if ((reference & FORWARD_REFERENCE_TYPE_MASK) == FORWARD_REFERENCE_TYPE_SHORT) { |
| 457 | if (relativeOffset < Short.MIN_VALUE || relativeOffset > Short.MAX_VALUE) { |
| 458 | // Change the opcode of the jump instruction, in order to be able to find it later in |
| 459 | // ClassReader. These ASM specific opcodes are similar to jump instruction opcodes, except |
| 460 | // that the 2 bytes offset is unsigned (and can therefore represent values from 0 to |
| 461 | // 65535, which is sufficient since the size of a method is limited to 65535 bytes). |
| 462 | int opcode = code[sourceInsnBytecodeOffset] & 0xFF; |
| 463 | if (opcode < Opcodes.IFNULL) { |
| 464 | // Change IFEQ ... JSR to ASM_IFEQ ... ASM_JSR. |
| 465 | code[sourceInsnBytecodeOffset] = (byte) (opcode + Constants.ASM_OPCODE_DELTA); |
| 466 | } else { |
| 467 | // Change IFNULL and IFNONNULL to ASM_IFNULL and ASM_IFNONNULL. |
| 468 | code[sourceInsnBytecodeOffset] = (byte) (opcode + Constants.ASM_IFNULL_OPCODE_DELTA); |
| 469 | } |
| 470 | hasAsmInstructions = true; |
| 471 | } |
| 472 | code[handle++] = (byte) (relativeOffset >>> 8); |
| 473 | code[handle] = (byte) relativeOffset; |
| 474 | } else { |
| 475 | code[handle++] = (byte) (relativeOffset >>> 24); |
| 476 | code[handle++] = (byte) (relativeOffset >>> 16); |
| 477 | code[handle++] = (byte) (relativeOffset >>> 8); |
| 478 | code[handle] = (byte) relativeOffset; |
| 479 | } |
| 480 | } |
| 481 | return hasAsmInstructions; |
| 482 | } |
| 483 | |
| 484 | // ----------------------------------------------------------------------------------------------- |
| 485 | // Methods related to subroutines |
no outgoing calls
no test coverage detected