Ejemplo n.º 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;
  }
Ejemplo n.º 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;
    }
  }
Ejemplo n.º 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;
 }
Ejemplo n.º 4
0
 // marked return could be either non-local or local in case of labeled lambda self-returns
 public static boolean isMarkedReturn(@NotNull AbstractInsnNode returnIns) {
   if (!isReturnOpcode(returnIns.getOpcode())) {
     return false;
   }
   AbstractInsnNode globalFlag = returnIns.getPrevious();
   return globalFlag instanceof MethodInsnNode
       && NON_LOCAL_RETURN.equals(((MethodInsnNode) globalFlag).owner);
 }
Ejemplo n.º 5
0
 @Override
 public AnnotationVisitor visitInsnAnnotation(
     int typeRef, TypePath typePath, String desc, boolean visible) {
   // Finds the last real instruction, i.e. the instruction targeted by
   // this annotation.
   AbstractInsnNode insn = instructions.getLast();
   while (insn.getOpcode() == -1) {
     insn = insn.getPrevious();
   }
   // Adds the annotation to this instruction.
   TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc);
   if (visible) {
     if (insn.visibleTypeAnnotations == null) {
       insn.visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
     }
     insn.visibleTypeAnnotations.add(an);
   } else {
     if (insn.invisibleTypeAnnotations == null) {
       insn.invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
     }
     insn.invisibleTypeAnnotations.add(an);
   }
   return an;
 }