public void visitBranchInstruction(
      Clazz clazz,
      Method method,
      CodeAttribute codeAttribute,
      int offset,
      BranchInstruction branchInstruction) {
    byte opcode = branchInstruction.opcode;

    // Evaluate the target instruction blocks.
    evaluateInstructionBlock(clazz, method, codeAttribute, offset + branchInstruction.branchOffset);

    // Evaluate the instructions after a subroutine branch.
    if (opcode == InstructionConstants.OP_JSR || opcode == InstructionConstants.OP_JSR_W) {
      // We assume subroutine calls (jsr and jsr_w instructions) don't
      // change the stack, other than popping the return value.
      stackSize -= 1;

      evaluateInstructionBlock(
          clazz, method, codeAttribute, offset + branchInstruction.length(offset));
    }

    // Some branch instructions always end the current instruction block.
    exitInstructionBlock =
        opcode == InstructionConstants.OP_GOTO
            || opcode == InstructionConstants.OP_GOTO_W
            || opcode == InstructionConstants.OP_JSR
            || opcode == InstructionConstants.OP_JSR_W;
  }
Exemplo n.º 2
0
  public void visitBranchInstruction(
      Clazz clazz,
      Method method,
      CodeAttribute codeAttribute,
      int offset,
      BranchInstruction branchInstruction) {
    // Check if the instruction is an unconditional goto instruction.
    byte opcode = branchInstruction.opcode;
    if (opcode == InstructionConstants.OP_GOTO || opcode == InstructionConstants.OP_GOTO_W) {
      // Check if the goto instruction points to another simple goto
      // instruction.
      int branchOffset = branchInstruction.branchOffset;
      int targetOffset = offset + branchOffset;

      if (branchOffset != branchInstruction.length(offset)
          && !codeAttributeEditor.isModified(offset)
          && !codeAttributeEditor.isModified(targetOffset)) {
        Instruction targetInstruction = InstructionFactory.create(codeAttribute.code, targetOffset);

        if (targetInstruction.opcode == InstructionConstants.OP_GOTO) {
          // Simplify the goto instruction.
          int targetBranchOffset = ((BranchInstruction) targetInstruction).branchOffset;

          Instruction newBranchInstruction =
              new BranchInstruction(opcode, (branchOffset + targetBranchOffset));
          codeAttributeEditor.replaceInstruction(offset, newBranchInstruction);

          // Visit the instruction, if required.
          if (extraInstructionVisitor != null) {
            extraInstructionVisitor.visitBranchInstruction(
                clazz, method, codeAttribute, offset, branchInstruction);
          }
        }
      }
    }
  }