public void visitFrame()

in src/main/java/com/amazon/corretto/hotpatch/org/objectweb/asm/MethodWriter.java [731:858]


  public void visitFrame(
      final int type,
      final int numLocal,
      final Object[] local,
      final int numStack,
      final Object[] stack) {
    if (compute == COMPUTE_ALL_FRAMES) {
      return;
    }

    if (compute == COMPUTE_INSERTED_FRAMES) {
      if (currentBasicBlock.frame == null) {
        // This should happen only once, for the implicit first frame (which is explicitly visited
        // in ClassReader if the EXPAND_ASM_INSNS option is used - and COMPUTE_INSERTED_FRAMES
        // can't be set if EXPAND_ASM_INSNS is not used).
        currentBasicBlock.frame = new CurrentFrame(currentBasicBlock);
        currentBasicBlock.frame.setInputFrameFromDescriptor(
            symbolTable, accessFlags, descriptor, numLocal);
        currentBasicBlock.frame.accept(this);
      } else {
        if (type == Opcodes.F_NEW) {
          currentBasicBlock.frame.setInputFrameFromApiFormat(
              symbolTable, numLocal, local, numStack, stack);
        }
        // If type is not F_NEW then it is F_INSERT by hypothesis, and currentBlock.frame contains
        // the stack map frame at the current instruction, computed from the last F_NEW frame and
        // the bytecode instructions in between (via calls to CurrentFrame#execute).
        currentBasicBlock.frame.accept(this);
      }
    } else if (type == Opcodes.F_NEW) {
      if (previousFrame == null) {
        int argumentsSize = Type.getArgumentsAndReturnSizes(descriptor) >> 2;
        Frame implicitFirstFrame = new Frame(new Label());
        implicitFirstFrame.setInputFrameFromDescriptor(
            symbolTable, accessFlags, descriptor, argumentsSize);
        implicitFirstFrame.accept(this);
      }
      currentLocals = numLocal;
      int frameIndex = visitFrameStart(code.length, numLocal, numStack);
      for (int i = 0; i < numLocal; ++i) {
        currentFrame[frameIndex++] = Frame.getAbstractTypeFromApiFormat(symbolTable, local[i]);
      }
      for (int i = 0; i < numStack; ++i) {
        currentFrame[frameIndex++] = Frame.getAbstractTypeFromApiFormat(symbolTable, stack[i]);
      }
      visitFrameEnd();
    } else {
      if (symbolTable.getMajorVersion() < Opcodes.V1_6) {
        throw new IllegalArgumentException("Class versions V1_5 or less must use F_NEW frames.");
      }
      int offsetDelta;
      if (stackMapTableEntries == null) {
        stackMapTableEntries = new ByteVector();
        offsetDelta = code.length;
      } else {
        offsetDelta = code.length - previousFrameOffset - 1;
        if (offsetDelta < 0) {
          if (type == Opcodes.F_SAME) {
            return;
          } else {
            throw new IllegalStateException();
          }
        }
      }

      switch (type) {
        case Opcodes.F_FULL:
          currentLocals = numLocal;
          stackMapTableEntries.putByte(Frame.FULL_FRAME).putShort(offsetDelta).putShort(numLocal);
          for (int i = 0; i < numLocal; ++i) {
            putFrameType(local[i]);
          }
          stackMapTableEntries.putShort(numStack);
          for (int i = 0; i < numStack; ++i) {
            putFrameType(stack[i]);
          }
          break;
        case Opcodes.F_APPEND:
          currentLocals += numLocal;
          stackMapTableEntries.putByte(Frame.SAME_FRAME_EXTENDED + numLocal).putShort(offsetDelta);
          for (int i = 0; i < numLocal; ++i) {
            putFrameType(local[i]);
          }
          break;
        case Opcodes.F_CHOP:
          currentLocals -= numLocal;
          stackMapTableEntries.putByte(Frame.SAME_FRAME_EXTENDED - numLocal).putShort(offsetDelta);
          break;
        case Opcodes.F_SAME:
          if (offsetDelta < 64) {
            stackMapTableEntries.putByte(offsetDelta);
          } else {
            stackMapTableEntries.putByte(Frame.SAME_FRAME_EXTENDED).putShort(offsetDelta);
          }
          break;
        case Opcodes.F_SAME1:
          if (offsetDelta < 64) {
            stackMapTableEntries.putByte(Frame.SAME_LOCALS_1_STACK_ITEM_FRAME + offsetDelta);
          } else {
            stackMapTableEntries
                .putByte(Frame.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED)
                .putShort(offsetDelta);
          }
          putFrameType(stack[0]);
          break;
        default:
          throw new IllegalArgumentException();
      }

      previousFrameOffset = code.length;
      ++stackMapTableNumberOfEntries;
    }

    if (compute == COMPUTE_MAX_STACK_AND_LOCAL_FROM_FRAMES) {
      relativeStackSize = numStack;
      for (int i = 0; i < numStack; ++i) {
        if (stack[i] == Opcodes.LONG || stack[i] == Opcodes.DOUBLE) {
          relativeStackSize++;
        }
      }
      if (relativeStackSize > maxRelativeStackSize) {
        maxRelativeStackSize = relativeStackSize;
      }
    }

    maxStack = Math.max(maxStack, numStack);
    maxLocals = Math.max(maxLocals, currentLocals);
  }