jodd-proxetta/src/main/java/jodd/asm7/Frame.java
static void putAbstractType(
      final SymbolTable symbolTable, final int abstractType, final ByteVector output) {
    int arrayDimensions = (abstractType & Frame.DIM_MASK) >> DIM_SHIFT;
    if (arrayDimensions == 0) {
      int typeValue = abstractType & VALUE_MASK;
      switch (abstractType & KIND_MASK) {
        case CONSTANT_KIND:
          output.putByte(typeValue);
          break;
        case REFERENCE_KIND:
          output
              .putByte(ITEM_OBJECT)
              .putShort(symbolTable.addConstantClass(symbolTable.getType(typeValue).value).index);
          break;
        case UNINITIALIZED_KIND:
          output.putByte(ITEM_UNINITIALIZED).putShort((int) symbolTable.getType(typeValue).data);
          break;
        default:
          throw new AssertionError();
      }
    } else {
      // Case of an array type, we need to build its descriptor first.
      StringBuilder typeDescriptor = new StringBuilder();
      while (arrayDimensions-- > 0) {
        typeDescriptor.append('[');
      }
      if ((abstractType & KIND_MASK) == REFERENCE_KIND) {
        typeDescriptor
            .append('L')
            .append(symbolTable.getType(abstractType & VALUE_MASK).value)
            .append(';');
      } else {
        switch (abstractType & VALUE_MASK) {
          case Frame.ITEM_ASM_BOOLEAN:
            typeDescriptor.append('Z');
            break;
          case Frame.ITEM_ASM_BYTE:
            typeDescriptor.append('B');
            break;
          case Frame.ITEM_ASM_CHAR:
            typeDescriptor.append('C');
            break;
          case Frame.ITEM_ASM_SHORT:
            typeDescriptor.append('S');
            break;
          case Frame.ITEM_INTEGER:
            typeDescriptor.append('I');
            break;
          case Frame.ITEM_FLOAT:
            typeDescriptor.append('F');
            break;
          case Frame.ITEM_LONG:
            typeDescriptor.append('J');
            break;
          case Frame.ITEM_DOUBLE:
            typeDescriptor.append('D');
            break;
          default:
            throw new AssertionError();
        }
      }
      output
          .putByte(ITEM_OBJECT)
          .putShort(symbolTable.addConstantClass(typeDescriptor.toString()).index);
    }
  }
static void putAbstractType(
      final SymbolTable symbolTable, final int abstractType, final ByteVector output) {
    int arrayDimensions = (abstractType & Frame.DIM_MASK) >> DIM_SHIFT;
    if (arrayDimensions == 0) {
      int typeValue = abstractType & VALUE_MASK;
      switch (abstractType & KIND_MASK) {
        case CONSTANT_KIND:
          output.putByte(typeValue);
          break;
        case REFERENCE_KIND:
          output
              .putByte(ITEM_OBJECT)
              .putShort(symbolTable.addConstantClass(symbolTable.getType(typeValue).value).index);
          break;
        case UNINITIALIZED_KIND:
          output.putByte(ITEM_UNINITIALIZED).putShort((int) symbolTable.getType(typeValue).data);
          break;
        default:
          throw new AssertionError();
      }
    } else {
      // Case of an array type, we need to build its descriptor first.
      StringBuilder typeDescriptor = new StringBuilder();
      while (arrayDimensions-- > 0) {
        typeDescriptor.append('[');
      }
      if ((abstractType & KIND_MASK) == REFERENCE_KIND) {
        typeDescriptor
            .append('L')
            .append(symbolTable.getType(abstractType & VALUE_MASK).value)
            .append(';');
      } else {
        switch (abstractType & VALUE_MASK) {
          case Frame.ITEM_ASM_BOOLEAN:
            typeDescriptor.append('Z');
            break;
          case Frame.ITEM_ASM_BYTE:
            typeDescriptor.append('B');
            break;
          case Frame.ITEM_ASM_CHAR:
            typeDescriptor.append('C');
            break;
          case Frame.ITEM_ASM_SHORT:
            typeDescriptor.append('S');
            break;
          case Frame.ITEM_INTEGER:
            typeDescriptor.append('I');
            break;
          case Frame.ITEM_FLOAT:
            typeDescriptor.append('F');
            break;
          case Frame.ITEM_LONG:
            typeDescriptor.append('J');
            break;
          case Frame.ITEM_DOUBLE:
            typeDescriptor.append('D');
            break;
          default:
            throw new AssertionError();
        }
      }
      output
          .putByte(ITEM_OBJECT)
          .putShort(symbolTable.addConstantClass(typeDescriptor.toString()).index);
    }
  }
Put the given abstract type in the given ByteVector, using the JVMS verification_type_info
format used in StackMapTable attributes.

@param symbolTable the type table to use to lookup and store type {@link Symbol}.
@param abstractType an abstract type, restricted to {@link Frame#CONSTANT_KIND}, {@link
Frame#REFERENCE_KIND} or {@link Frame#UNINITIALIZED_KIND} types.
@param output where the abstract type must be put.
@see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.4">JVMS
4.7.4</a>