예제 #1
0
  @NotNull
  // process local and global returns (local substituted with goto end-label global kept unchanged)
  public static List<PointForExternalFinallyBlocks> processReturns(
      @NotNull MethodNode node,
      @NotNull LabelOwner labelOwner,
      boolean remapReturn,
      Label endLabel) {
    if (!remapReturn) {
      return Collections.emptyList();
    }
    List<PointForExternalFinallyBlocks> result = new ArrayList<PointForExternalFinallyBlocks>();
    InsnList instructions = node.instructions;
    AbstractInsnNode insnNode = instructions.getFirst();
    while (insnNode != null) {
      if (InlineCodegenUtil.isReturnOpcode(insnNode.getOpcode())) {
        AbstractInsnNode previous = insnNode.getPrevious();
        MethodInsnNode flagNode;
        boolean isLocalReturn = true;
        String labelName = null;
        if (previous != null
            && previous instanceof MethodInsnNode
            && InlineCodegenUtil.NON_LOCAL_RETURN.equals(((MethodInsnNode) previous).owner)) {
          flagNode = (MethodInsnNode) previous;
          labelName = flagNode.name;
        }

        if (labelName != null) {
          isLocalReturn = labelOwner.isMyLabel(labelName);
          // remove global return flag
          if (isLocalReturn) {
            instructions.remove(previous);
          }
        }

        if (isLocalReturn && endLabel != null) {
          LabelNode labelNode = (LabelNode) endLabel.info;
          JumpInsnNode jumpInsnNode = new JumpInsnNode(Opcodes.GOTO, labelNode);
          instructions.insert(insnNode, jumpInsnNode);
          instructions.remove(insnNode);
          insnNode = jumpInsnNode;
        }

        // genetate finally block before nonLocalReturn flag/return/goto
        result.add(
            new PointForExternalFinallyBlocks(
                isLocalReturn ? insnNode : insnNode.getPrevious(),
                getReturnType(insnNode.getOpcode())));
      }
      insnNode = insnNode.getNext();
    }
    return result;
  }
예제 #2
0
  private static void removeClosureAssertions(MethodNode node) {
    AbstractInsnNode cur = node.instructions.getFirst();
    while (cur != null && cur.getNext() != null) {
      AbstractInsnNode next = cur.getNext();
      if (next.getType() == AbstractInsnNode.METHOD_INSN) {
        MethodInsnNode methodInsnNode = (MethodInsnNode) next;
        if (methodInsnNode.name.equals("checkParameterIsNotNull")
            && methodInsnNode.owner.equals(IntrinsicMethods.INTRINSICS_CLASS_NAME)) {
          AbstractInsnNode prev = cur.getPrevious();

          assert cur.getOpcode() == Opcodes.LDC
              : "checkParameterIsNotNull should go after LDC but " + cur;
          assert prev.getOpcode() == Opcodes.ALOAD
              : "checkParameterIsNotNull should be invoked on local var but " + prev;

          node.instructions.remove(prev);
          node.instructions.remove(cur);
          cur = next.getNext();
          node.instructions.remove(next);
          next = cur;
        }
      }
      cur = next;
    }
  }
예제 #3
0
 private static boolean isEmptyTryInterval(@NotNull TryCatchBlockNode tryCatchBlockNode) {
   LabelNode start = tryCatchBlockNode.start;
   AbstractInsnNode end = tryCatchBlockNode.end;
   while (end != start && end instanceof LabelNode) {
     end = end.getPrevious();
   }
   return start == end;
 }