обернуть существующий код метода в блок try-finally - PullRequest
0 голосов
/ 24 апреля 2020

Я новичок в ASM, и я использовал приведенный ниже код, чтобы поместить метод try-finally inside И он работает нормально, но я хочу super.visitInsn(opcode) внутри блока finally. Как мне этого добиться? Я пытался много раз, но я не могу понять, как это реализовать

  private Label m_currentBeginLabel;
  private boolean m_isInOriginalCode = true;

  protected void execBeforeMethodCode() {
    // Code at the beginning of the method and not in a try block
  }

  protected void execVisitTryBlockBegin() {
    // Code at the beginning of each try block
  }

  protected void execVisitFinallyBlock() {
    // Code in each finally block
  }

  @Override
  public void visitCode() {
      super.visitCode();
    try {
         System.out.println("Inside my visit try block code.."); 
      m_isInOriginalCode = false;
      execBeforeMethodCode();
      beginTryFinallyBlock();
    }
    finally {
      m_isInOriginalCode = true;
    }
  }

  protected void beginTryFinallyBlock() {
    m_currentBeginLabel = new Label();
    visitLabel(m_currentBeginLabel);
    execVisitTryBlockBegin();
  }

  @Override
  public void visitInsn(int opcode) {
    if (m_isInOriginalCode && isReturnOpcode(opcode)){
      try {
        m_isInOriginalCode = false;
        completeTryFinallyBlock();

        super.visitInsn(opcode);

        beginTryFinallyBlock();
      }
      finally {
        m_isInOriginalCode = true;
      }
    }
    else {
      super.visitInsn(opcode);
    }
  }

  protected void completeTryFinallyBlock() {
    Label l1 = new Label();
    visitTryCatchBlock(m_currentBeginLabel, l1, l1, null);
    Label l2 = new Label();
    visitJumpInsn(GOTO, l2);
    visitLabel(l1);
    // visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/Throwable" });
    visitVarInsn(ASTORE, 1);

    execVisitFinallyBlock();

    visitVarInsn(ALOAD, 1);
    super.visitInsn(ATHROW);
    visitLabel(l2);
    // visitFrame(Opcodes.F_SAME, 0, null, 0, null);

    execVisitFinallyBlock();
  }

   protected boolean isReturnOpcode(int opcode) {
     return opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN;
   }
...