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_);
}