private void genReadFieldValueList()

in core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderCreatorASM.java [3826:4124]


    private void genReadFieldValueList(
            FieldReader fieldReader,
            String classNameType,
            MethodWriterContext mwc,
            int OBJECT,
            int i,
            boolean arrayMapping,
            Class objectClass,
            Class fieldClass,
            Type fieldType,
            long fieldFeatures,
            Type itemType,
            String TYPE_FIELD_CLASS,
            ObjectReadContext context,
            boolean fieldBased
    ) {
        boolean jsonb = mwc.jsonb;
        if (itemType == null) {
            itemType = Object.class;
        }

        Class itemClass = TypeUtils.getMapping(itemType);
        String ITEM_OBJECT_READER = fieldItemObjectReader(i);
        MethodWriter mw = mwc.mw;

        int LIST;
        if (context.objectReaderAdapter instanceof ObjectReaderNoneDefaultConstructor) {
            LIST = mwc.var(fieldReader);
        } else {
            LIST = mwc.var(fieldClass);
        }
        Integer AUTO_TYPE_OBJECT_READER = mwc.var(ObjectReader.class);

        String LIST_TYPE = fieldClass.isInterface() ? "java/util/ArrayList" : TYPE_FIELD_CLASS;

        Label loadList_ = new Label(), listNotNull_ = new Label(), listInitEnd_ = new Label();

        boolean initCapacity = JVM_VERSION == 8 && "java/util/ArrayList".equals(LIST_TYPE);
        int ITEM_CNT = mwc.var("ITEM_CNT");

        if (jsonb) {
            if (!context.disableAutoType()) {
                Label checkAutoTypeNull_ = new Label();

                mw.aload(THIS);
                mw.getfield(classNameType, fieldReader(i), DESC_FIELD_READER);
                mw.aload(JSON_READER);
                mw.invokevirtual(TYPE_FIELD_READE, "checkObjectAutoType", METHOD_DESC_CHECK_ARRAY_AUTO_TYPE);
                mw.dup();
                mw.astore(AUTO_TYPE_OBJECT_READER);
                mw.ifnull(checkAutoTypeNull_);

                mw.aload(AUTO_TYPE_OBJECT_READER);
                mw.aload(JSON_READER);
                gwGetFieldType(classNameType, mw, i, fieldType);
                mw.visitLdcInsn(fieldReader.fieldName);
                mw.visitLdcInsn(fieldFeatures);
                mw.invokeinterface(TYPE_OBJECT_READER, "readJSONBObject", METHOD_DESC_READ_OBJECT);
                mw.checkcast(TYPE_FIELD_CLASS);
                mw.astore(LIST);
                mw.goto_(loadList_);

                mw.visitLabel(checkAutoTypeNull_);
            }

            mw.aload(JSON_READER);
            mw.invokevirtual(TYPE_JSON_READER, "startArray", "()I");
            mw.dup();
            mw.istore(ITEM_CNT);
            mw.visitLdcInsn(-1);
            mw.if_icmpne(listNotNull_);

            mw.aconst_null();
            mw.astore(LIST);
            mw.goto_(loadList_);

            mw.visitLabel(listNotNull_);

            if (fieldReader.method == null && fieldReader.field != null) {
                long fieldOffset = UNSAFE.objectFieldOffset(fieldReader.field);
                mw.getstatic(TYPE_UNSAFE_UTILS, "UNSAFE", "Lsun/misc/Unsafe;");
                mw.aload(OBJECT);
                mw.visitLdcInsn(fieldOffset);
                mw.invokevirtual("sun/misc/Unsafe", "getObject", "(Ljava/lang/Object;J)Ljava/lang/Object;");
                mw.dup();
                mw.checkcast(TYPE_FIELD_CLASS);
                mw.astore(LIST);
                Label listNull_ = new Label();
                mw.ifnull(listNull_);

                mw.aload(LIST);
                mw.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;");
                mw.getstatic("java/util/Collections", "EMPTY_LIST", "Ljava/util/List;");
                mw.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;");
                mw.if_acmpne(listInitEnd_);
                mw.visitLabel(listNull_);
            }

            mw.new_(LIST_TYPE);
            mw.dup();
            if (initCapacity) {
                mw.iload(ITEM_CNT);
                mw.invokespecial(LIST_TYPE, "<init>", "(I)V");
            } else {
                mw.invokespecial(LIST_TYPE, "<init>", "()V");
            }
            mw.astore(LIST);
            mw.visitLabel(listInitEnd_);
        } else {
            Label match_ = new Label(), skipValue_ = new Label(), loadNull_ = new Label();

            mw.aload(JSON_READER);
            mw.invokevirtual(TYPE_JSON_READER, "nextIfNull", "()Z");
            mw.ifne(loadNull_);

            mw.aload(JSON_READER);
            mw.invokevirtual(TYPE_JSON_READER, "nextIfArrayStart", "()Z");
            mw.ifne(match_);

            if (itemClass == String.class) {
                mw.aload(JSON_READER);
                mw.invokevirtual(TYPE_JSON_READER, "isString", "()Z");
                mw.ifeq(skipValue_);

                mw.new_(LIST_TYPE);
                mw.dup();
                if (initCapacity) {
                    mw.visitLdcInsn(10);
                    mw.invokespecial(LIST_TYPE, "<init>", "(I)V");
                } else {
                    mw.invokespecial(LIST_TYPE, "<init>", "()V");
                }
                mw.astore(LIST);

                mw.aload(JSON_READER);
                mw.invokevirtual(TYPE_JSON_READER, "nextIfNullOrEmptyString", "()Z");
                mw.ifne(loadList_);

                mw.aload(LIST);
                mw.aload(JSON_READER);
                if (itemClass == String.class) {
                    mw.invokevirtual(TYPE_JSON_READER, "readString", "()Ljava/lang/String;");
                }
                mw.invokeinterface("java/util/List", "add", "(Ljava/lang/Object;)Z");
                mw.pop();

                mw.goto_(loadList_);
            } else if (itemType instanceof Class) {
                mw.aload(JSON_READER);
                mw.invokevirtual(TYPE_JSON_READER, "nextIfNullOrEmptyString", "()Z");
                mw.ifne(loadNull_);

                // nextIfNullOrEmptyString
                mw.new_(LIST_TYPE);
                mw.dup();
                if (initCapacity) {
                    mw.visitLdcInsn(10);
                    mw.invokespecial(LIST_TYPE, "<init>", "(I)V");
                } else {
                    mw.invokespecial(LIST_TYPE, "<init>", "()V");
                }
                mw.astore(LIST);

                mw.aload(JSON_READER);
                mw.aload(LIST);
                mw.visitLdcInsn((Class) itemType);
                mw.invokevirtual(TYPE_JSON_READER, "readArray", "(Ljava/util/List;Ljava/lang/reflect/Type;)V");

                mw.goto_(loadList_);
            }

            mw.visitLabel(skipValue_);
            mw.aload(JSON_READER);
            mw.invokevirtual(TYPE_JSON_READER, "skipValue", "()V");

            mw.visitLabel(loadNull_);
            mw.aconst_null();
            mw.astore(LIST);
            mw.goto_(loadList_);

            mw.visitLabel(match_);
            mw.new_(LIST_TYPE);
            mw.dup();
            if (initCapacity) {
                mw.visitLdcInsn(10);
                mw.invokespecial(LIST_TYPE, "<init>", "(I)V");
            } else {
                mw.invokespecial(LIST_TYPE, "<init>", "()V");
            }
            mw.astore(LIST);
        }

        int J = mwc.var("J");
        Label for_start_j_ = new Label(), for_end_j_ = new Label(), for_inc_j_ = new Label();
        mw.iconst_0();
        mw.istore(J);

        mw.visitLabel(for_start_j_);

        if (jsonb) {
            // j < item_cnt
            mw.iload(J);
            mw.iload(ITEM_CNT);
            mw.if_icmpge(for_end_j_);
        } else {
            mw.aload(JSON_READER);
            mw.invokevirtual(TYPE_JSON_READER, "nextIfArrayEnd", "()Z");
            mw.ifne(for_end_j_);
        }

        if (itemType == String.class) {
            mw.aload(LIST);
            mw.aload(JSON_READER);
            mw.invokevirtual(TYPE_JSON_READER, "readString", "()Ljava/lang/String;");
        } else if (itemType == Integer.class) {
            mw.aload(LIST);
            mw.aload(JSON_READER);
            mw.invokevirtual(TYPE_JSON_READER, "readInt32", "()Ljava/lang/Integer;");
        } else if (itemType == Long.class) {
            mw.aload(LIST);
            mw.aload(JSON_READER);
            mw.invokevirtual(TYPE_JSON_READER, "readInt64", "()Ljava/lang/Long;");
        } else {
            Label notNull_ = new Label();

            mw.aload(THIS);
            mw.getfield(classNameType, ITEM_OBJECT_READER, DESC_OBJECT_READER);
            mw.ifnonnull(notNull_);

            mw.aload(THIS);
            mw.aload(THIS);
            mw.getfield(classNameType, fieldReader(i), DESC_FIELD_READER);
            mw.aload(JSON_READER);
            mw.invokevirtual(TYPE_FIELD_READE, "getItemObjectReader", METHOD_DESC_GET_ITEM_OBJECT_READER);

            mw.putfield(classNameType, ITEM_OBJECT_READER, DESC_OBJECT_READER);

            mw.visitLabel(notNull_);

            if (!context.disableReferenceDetect()) {
                mw.aload(JSON_READER);
                mw.aload(LIST);
                mw.iload(J);
                mw.invokevirtual(TYPE_JSON_READER, "readReference", "(Ljava/util/List;I)Z");
                mw.ifne(for_inc_j_);
            }
            mw.aload(LIST);

            Label readObject_ = new Label(), readObjectEnd_ = new Label();
            if (arrayMapping) {
                mw.aload(JSON_READER);
                mw.invokevirtual(TYPE_JSON_READER, "isArray", "()Z");
                mw.ifeq(readObject_);

                mw.aload(THIS);
                mw.getfield(classNameType, ITEM_OBJECT_READER, DESC_OBJECT_READER);

                mw.aload(JSON_READER);
                gwGetFieldType(classNameType, mw, i, fieldType);
                mw.visitLdcInsn(fieldReader.fieldName);
                mw.lload(FEATURES);
                mw.invokeinterface(
                        TYPE_OBJECT_READER,
                        jsonb ? "readArrayMappingJSONBObject" : "readArrayMappingObject",
                        METHOD_DESC_READ_OBJECT);

                mw.goto_(readObjectEnd_);

                mw.visitLabel(readObject_);
            }

            mw.aload(THIS);
            mw.getfield(classNameType, ITEM_OBJECT_READER, DESC_OBJECT_READER);

            mw.aload(JSON_READER);
            gwGetFieldType(classNameType, mw, i, fieldType);
            mw.visitLdcInsn(fieldReader.fieldName);
            mw.lload(FEATURES);
            mw.invokeinterface(
                    TYPE_OBJECT_READER,
                    jsonb ? "readJSONBObject" : "readObject",
                    METHOD_DESC_READ_OBJECT);

            if (arrayMapping) {
                mw.visitLabel(readObjectEnd_);
            }
        }
        mw.invokeinterface("java/util/List", "add", "(Ljava/lang/Object;)Z");
        mw.pop();

        mw.visitLabel(for_inc_j_);
        mw.visitIincInsn(J, 1);
        mw.goto_(for_start_j_);

        mw.visitLabel(for_end_j_);

        mw.visitLabel(loadList_);
        mw.aload(LIST);
    }