private void gwFieldValueObject()

in core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterCreatorASM.java [2550:2871]


    private void gwFieldValueObject(
            MethodWriterContext mwc,
            FieldWriter fieldWriter,
            int OBJECT,
            int i,
            boolean jsonb
    ) {
        Class<?> fieldClass = fieldWriter.fieldClass;
        Type fieldType = fieldWriter.fieldType;
        String fieldName = fieldWriter.fieldName;

        boolean disableReferenceDetect = mwc.disableReferenceDetect();

        boolean refDetection = (!disableReferenceDetect) && !ObjectWriterProvider.isNotReferenceDetect(fieldClass);
        int FIELD_VALUE = mwc.var(fieldClass);

        Integer REF_PATH = null;
        if (refDetection) {
            REF_PATH = mwc.var("REF_PATH");
        }

        long features = fieldWriter.features | mwc.objectFeatures;
        MethodWriter mw = mwc.mw;

        Label null_ = new Label(), notNull_ = new Label();

        if (fieldWriter.unwrapped() || (fieldWriter.features & WriteNonStringValueAsString.mask) != 0) {
            mw.aload(THIS);
            mw.getfield(mwc.classNameType, fieldWriter(i), DESC_FIELD_WRITER);
            mw.aload(JSON_WRITER);
            mw.aload(OBJECT);
            mw.invokevirtual(TYPE_FIELD_WRITER,
                    "write", METHOD_DESC_FIELD_WRITE_OBJECT);
            mw.pop();
            mw.goto_(notNull_);
        }

        if (fieldWriter.backReference) {
            mw.aload(JSON_WRITER);
            mw.aload(OBJECT);
            mw.invokevirtual(TYPE_JSON_WRITER, "containsReference", "(Ljava/lang/Object;)Z");
            mw.ifne(notNull_);
        }

        genGetObject(mwc, fieldWriter, i, OBJECT);
        mw.dup();
        mw.astore(FIELD_VALUE);
        mw.ifnull(null_);

        if (Map.class.isAssignableFrom(fieldClass)) {
            Label ignoreEmptyEnd_ = null;
            if ((fieldWriter.features & IgnoreEmpty.mask) == 0) {
                ignoreEmptyEnd_ = new Label();
                mwc.genIsEnabled(IgnoreEmpty.mask, ignoreEmptyEnd_);
            }

            mw.aload(FIELD_VALUE);
            mw.invokeinterface("java/util/Map", "isEmpty", "()Z");
            mw.ifne(notNull_);

            if (ignoreEmptyEnd_ != null) {
                mw.visitLabel(ignoreEmptyEnd_);
            }
        }

        if (!Serializable.class.isAssignableFrom(fieldClass) && fieldClass != List.class) {
            mw.aload(JSON_WRITER);
            if (!fieldWriter.isFieldClassSerializable()) {
                mw.invokevirtual(TYPE_JSON_WRITER, "isIgnoreNoneSerializable", "()Z");
            } else {
                mw.aload(FIELD_VALUE);
                mw.invokevirtual(TYPE_JSON_WRITER, "isIgnoreNoneSerializable", "(Ljava/lang/Object;)Z");
            }
            mw.ifne(notNull_);
        }

        if (refDetection) {
            Label endDetect_ = new Label(), refSetPath_ = new Label();

            int REF_DETECT = mwc.var("REF_DETECT");

            if (fieldClass == Object.class) {
                mw.aload(JSON_WRITER);
                mw.aload(FIELD_VALUE);
                mw.invokevirtual(TYPE_JSON_WRITER, "isRefDetect", "(Ljava/lang/Object;)Z");
            } else {
                mwc.genIsEnabled(JSONWriter.Feature.ReferenceDetection.mask, null);
            }
            mw.dup();
            mw.istore(REF_DETECT);
            mw.ifeq(endDetect_);

            if (fieldClass.isAssignableFrom(mwc.objectClass)) {
                mw.aload(OBJECT);
                mw.aload(FIELD_VALUE);
                mw.if_acmpne(refSetPath_);

                gwFieldName(mwc, fieldWriter, i);

                mw.aload(JSON_WRITER);
                mw.visitLdcInsn("..");
                mw.invokevirtual(TYPE_JSON_WRITER, "writeReference", "(Ljava/lang/String;)V");

                mw.goto_(notNull_);

                mw.visitLabel(refSetPath_);
            }

            mw.aload(JSON_WRITER);
            mw.aload(THIS);
            mw.getfield(mwc.classNameType, fieldWriter(i), DESC_FIELD_WRITER);
            mw.aload(FIELD_VALUE);
            mw.invokevirtual(TYPE_JSON_WRITER, "setPath0", METHOD_DESC_SET_PATH2);
            mw.dup();
            mw.astore(REF_PATH);
            mw.ifnull(endDetect_);

            gwFieldName(mwc, fieldWriter, i);

            mw.aload(JSON_WRITER);
            mw.aload(REF_PATH);
            mw.invokevirtual(TYPE_JSON_WRITER, "writeReference", METHOD_DESC_WRITE_REFERENCE);

            mw.aload(JSON_WRITER);
            mw.aload(FIELD_VALUE);
            mw.invokevirtual(TYPE_JSON_WRITER, "popPath0", "(Ljava/lang/Object;)V");
            mw.goto_(null_);

            mw.visitLabel(endDetect_);

            if ("this$0".equals(fieldName) || "this$1".equals(fieldName) || "this$2".equals(fieldName)) {
                mw.iload(REF_DETECT);
                mw.ifeq(null_);
            }
        }

        if (Object[].class.isAssignableFrom(fieldClass)) {
            Label notWriteEmptyArrayEnd_ = new Label();
            mwc.genIsEnabled(JSONWriter.Feature.NotWriteEmptyArray.mask, notWriteEmptyArrayEnd_);

            mw.aload(FIELD_VALUE);
            mw.checkcast("[Ljava/lang/Object;");
            mw.arraylength();
            mw.ifne(notWriteEmptyArrayEnd_);

            mw.goto_(notNull_);

            mw.visitLabel(notWriteEmptyArrayEnd_);
        } else if (Collection.class.isAssignableFrom(fieldClass)) {
            Label notWriteEmptyArrayEnd_ = new Label();
            if ((features & NotWriteEmptyArray.mask) == 0) {
                mwc.genIsEnabled(JSONWriter.Feature.NotWriteEmptyArray.mask, notWriteEmptyArrayEnd_);
            }

            mw.aload(FIELD_VALUE);
            mw.checkcast("java/util/Collection");
            mw.invokeinterface("java/util/Collection", "isEmpty", "()Z");
            mw.ifeq(notWriteEmptyArrayEnd_);

            mw.goto_(notNull_);

            mw.visitLabel(notWriteEmptyArrayEnd_);
        }

        // writeFieldName(w);
        gwFieldName(mwc, fieldWriter, i);

        Class itemClass = fieldWriter.getItemClass();
        if (fieldClass == BigDecimal.class) {
            mw.aload(JSON_WRITER);
            mw.aload(FIELD_VALUE);
            mw.visitLdcInsn(features);
            if (fieldWriter.decimalFormat != null) {
                mw.aload(THIS);
                mw.getfield(mwc.classNameType, fieldWriter(i), DESC_FIELD_WRITER);
                mw.getfield(TYPE_FIELD_WRITER, "decimalFormat", "Ljava/text/DecimalFormat;");
            } else {
                mw.aconst_null();
            }
            mw.invokevirtual(TYPE_JSON_WRITER, "writeDecimal", "(Ljava/math/BigDecimal;JLjava/text/DecimalFormat;)V");
        } else if (fieldClass == BigInteger.class) {
            mw.aload(JSON_WRITER);
            mw.aload(FIELD_VALUE);
            if (features == 0) {
                mw.invokevirtual(TYPE_JSON_WRITER, "writeBigInt", "(Ljava/math/BigInteger;)V");
            } else {
                mw.visitLdcInsn(features);
                mw.invokevirtual(TYPE_JSON_WRITER, "writeBigInt", "(Ljava/math/BigInteger;J)V");
            }
        } else if (fieldClass == UUID.class) {
            mw.aload(JSON_WRITER);
            mw.aload(FIELD_VALUE);
            mw.invokevirtual(TYPE_JSON_WRITER, "writeUUID", "(Ljava/util/UUID;)V");
        } else if (fieldClass == LocalDate.class
                && fieldWriter.format == null
                && mwc.provider.getObjectWriter(LocalDate.class) == ObjectWriterImplLocalDate.INSTANCE
        ) {
            mw.aload(JSON_WRITER);
            mw.aload(FIELD_VALUE);
            mw.invokevirtual(TYPE_JSON_WRITER, "writeLocalDate", "(Ljava/time/LocalDate;)V");
        } else if (fieldClass == OffsetDateTime.class
                && fieldWriter.format == null
                && mwc.provider.getObjectWriter(OffsetDateTime.class) == ObjectWriterImplOffsetDateTime.INSTANCE
        ) {
            mw.aload(JSON_WRITER);
            mw.aload(FIELD_VALUE);
            mw.invokevirtual(TYPE_JSON_WRITER, "writeOffsetDateTime", "(Ljava/time/OffsetDateTime;)V");
        } else if (fieldClass == String[].class) {
            mw.aload(JSON_WRITER);
            mw.aload(FIELD_VALUE);
            mw.invokevirtual(TYPE_JSON_WRITER, "writeString", "([Ljava/lang/String;)V");
        } else if (fieldClass == List.class && (itemClass == String.class || itemClass == Integer.class || itemClass == Long.class)) {
            gwListSimpleType(mwc, i, mw, fieldClass, itemClass, FIELD_VALUE);
        } else {
            // fw.getObjectWriter(w, value.getClass());
            mw.aload(THIS);
            mw.getfield(mwc.classNameType, fieldWriter(i), DESC_FIELD_WRITER);
            mw.aload(JSON_WRITER);
            mw.aload(FIELD_VALUE);
            mw.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;");

            mw.invokevirtual(TYPE_FIELD_WRITER,
                    "getObjectWriter", METHOD_DESC_GET_OBJECT_WRITER);

            // objectWriter.write(jw, ctx, value);
            mw.aload(JSON_WRITER);
            mw.aload(FIELD_VALUE);
            mw.visitLdcInsn(fieldName);
            mwc.loadFieldType(i, fieldType);
            mw.visitLdcInsn(features);

            String writeMethod;
            if (jsonb) {
                writeMethod = (features & JSONWriter.Feature.BeanToArray.mask) != 0 ? "writeArrayMappingJSONB" : "writeJSONB";
            } else {
                writeMethod = (features & JSONWriter.Feature.BeanToArray.mask) != 0 ? "writeArrayMapping" : "write";
            }
            mw.invokeinterface(
                    TYPE_OBJECT_WRITER,
                    writeMethod,
                    METHOD_DESC_WRITE_OBJECT);
        }

        if (refDetection) {
            int REF_DETECT = mwc.var("REF_DETECT");

            Label endDetect_ = new Label();

            mw.iload(REF_DETECT);
            mw.ifeq(endDetect_);

            mw.aload(JSON_WRITER);
            mw.aload(FIELD_VALUE);
            mw.invokevirtual(TYPE_JSON_WRITER, "popPath0", "(Ljava/lang/Object;)V");

            mw.visitLabel(endDetect_);
        }

        mw.goto_(notNull_);

        mw.visitLabel(null_);

        // if (!jw.isWriteNulls())
        if ((features & JSONWriter.Feature.WriteNulls.mask) == 0) {
            long nullFeatures = JSONWriter.Feature.WriteNulls.mask;
            if (fieldClass == AtomicLongArray.class
                    || fieldClass == AtomicIntegerArray.class
                    || Collection.class.isAssignableFrom(fieldClass)
                    || fieldClass.isArray()) {
                nullFeatures |= WriteNullListAsEmpty.mask;
                nullFeatures |= NullAsDefaultValue.mask;
            } else if (Number.class.isAssignableFrom(fieldClass)) {
                nullFeatures |= WriteNullNumberAsZero.mask;
                nullFeatures |= NullAsDefaultValue.mask;
            } else if (fieldClass == Boolean.class) {
                nullFeatures |= WriteNullBooleanAsFalse.mask;
                nullFeatures |= NullAsDefaultValue.mask;
            } else if (fieldClass == String.class) {
                nullFeatures |= WriteNullStringAsEmpty.mask;
                nullFeatures |= NullAsDefaultValue.mask;
            } else {
                nullFeatures |= NullAsDefaultValue.mask;
            }
            mwc.genIsEnabled(nullFeatures, notNull_);
//            mw.iload(mwc.var(WRITE_NULLS));
//            mw.ifeq(notNull_);
        }

        // writeFieldName(w);
        gwFieldName(mwc, fieldWriter, i);

        // jw.writeNull
        mw.aload(JSON_WRITER);
        String WRITE_NULL_METHOD;
        String WRITE_NULL_DESC = "()V";
        if (fieldClass == AtomicLongArray.class
                || fieldClass == AtomicIntegerArray.class
                || Collection.class.isAssignableFrom(fieldClass)
                || fieldClass.isArray()) {
            WRITE_NULL_METHOD = "writeArrayNull";
        } else if (fieldClass == Float.class
                || fieldClass == Double.class
                || fieldClass == BigDecimal.class) {
            WRITE_NULL_METHOD = "writeDecimalNull";
        } else if (Number.class.isAssignableFrom(fieldClass)) {
            WRITE_NULL_METHOD = "writeNumberNull";
        } else if (fieldClass == Boolean.class) {
            WRITE_NULL_METHOD = "writeBooleanNull";
        } else if (fieldClass == String.class
                || fieldClass == Appendable.class
                || fieldClass == StringBuffer.class
                || fieldClass == StringBuilder.class) {
            WRITE_NULL_METHOD = "writeStringNull";
        } else {
            WRITE_NULL_METHOD = "writeObjectNull";
            WRITE_NULL_DESC = "(Ljava/lang/Class;)V";
            mwc.loadFieldClass(i, fieldClass);
        }
        mw.invokevirtual(TYPE_JSON_WRITER, WRITE_NULL_METHOD, WRITE_NULL_DESC);

        mw.visitLabel(notNull_);
    }