in core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterCreatorASM.java [1071:1365]
private void writeFieldValueDirectJSONB(
long objectFeatures,
String classNameType,
MethodWriterContext mwc,
FieldWriter fieldWriter,
int i,
MethodWriter mw,
int BYTES,
int OFFSET,
int OBJECT,
int FEATURES,
int SYMBOL_TABLE,
boolean writeFieldName
) {
Class fieldClass = fieldWriter.fieldClass;
boolean field_var_index = isFieldVarIndex(mwc, fieldWriter);
Integer FIELD_VALUE = null;
Label endFieldValue_ = null;
if (!fieldClass.isPrimitive() || writeFieldName) {
endFieldValue_ = new Label();
if (field_var_index) {
FIELD_VALUE = mwc.var("field_" + i);
} else {
FIELD_VALUE = mwc.var(fieldClass);
genGetObject(mwc, fieldWriter, i, OBJECT);
mw.storeLocal(fieldClass, FIELD_VALUE);
}
}
boolean pop = false;
if ((Collection.class.isAssignableFrom(fieldClass) || fieldClass.isArray())
&& !mwc.disableReferenceDetect()
) {
int REF_PATH = mwc.var("REF_PATH");
if (endFieldValue_ == null) {
endFieldValue_ = new Label();
}
Label endDetect_ = new Label();
pop = true;
/*
* if (fieldValue == null) {
* goto endDetect_;
* }
*
* if (jsonWriter.isEnabled(JSONWriter.Feature.ReferenceDetection)) {
* goto endDetect_;
* }
*/
mw.aload(FIELD_VALUE);
mw.ifnull(endDetect_);
mwc.genIsEnabled(JSONWriter.Feature.ReferenceDetection.mask, endDetect_);
mw.aload(JSON_WRITER);
mw.aload(THIS);
mw.getfield(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_);
if (writeFieldName) {
gwFieldNameDirectJSONB(classNameType, fieldWriter, i, mwc, BYTES, OFFSET);
}
/*
* offset = JSONB.IO.writeReference(bytes, offset, refPath, jsonWriter);
*/
mw.aload(BYTES);
mw.iload(OFFSET);
mw.aload(REF_PATH);
mw.aload(JSON_WRITER);
mw.invokestatic(TYPE_JSONB_IO, "writeReference", METHOD_DESC_IO_WRITE_REFERENCE, true);
mw.istore(OFFSET);
mw.aload(JSON_WRITER);
mw.aload(FIELD_VALUE);
mw.invokevirtual(TYPE_JSON_WRITER, "popPath0", "(Ljava/lang/Object;)V");
mw.goto_(endFieldValue_);
mw.visitLabel(endDetect_);
}
if (writeFieldName) {
if (!fieldClass.isPrimitive()) {
Label L_NOT_NULL = new Label();
mw.iload(mwc.var(WRITE_NULLS));
mw.ifne(L_NOT_NULL);
mw.aload(FIELD_VALUE);
mw.ifnull(endFieldValue_);
mw.visitLabel(L_NOT_NULL);
} else {
int WRITE_DEFAULT_VALUE = mwc.var(NOT_WRITE_DEFAULT_VALUE);
Label L_NOT_DEFAULT_VALUE = new Label();
if (fieldClass == byte.class || fieldClass == short.class || fieldClass == int.class || fieldClass == boolean.class) {
mw.iload(FIELD_VALUE);
mw.ifne(L_NOT_DEFAULT_VALUE);
mw.iload(WRITE_DEFAULT_VALUE);
mw.ifne(endFieldValue_);
mw.visitLabel(L_NOT_DEFAULT_VALUE);
} else if (fieldClass == long.class) {
mw.lload(FIELD_VALUE);
mw.lconst_0();
mw.lcmp();
mw.ifne(L_NOT_DEFAULT_VALUE);
mw.iload(WRITE_DEFAULT_VALUE);
mw.ifne(endFieldValue_);
mw.visitLabel(L_NOT_DEFAULT_VALUE);
}
}
gwFieldNameDirectJSONB(classNameType, fieldWriter, i, mwc, BYTES, OFFSET);
}
if (Collection.class.isAssignableFrom(fieldClass)) {
/*
* offset = JSONB.IO.checkAndWriteTypeName(bytes, offset, object, fieldClass, jsonWriter);
*/
mw.aload(BYTES);
mw.iload(OFFSET);
mw.aload(FIELD_VALUE);
mw.aload(THIS);
mw.getfield(classNameType, fieldWriter(i), DESC_FIELD_WRITER);
mw.getfield(TYPE_FIELD_WRITER, "fieldClass", "Ljava/lang/Class;");
mw.aload(JSON_WRITER);
String methodDesc = "([BILjava/lang/Object;Ljava/lang/Class;" + DESC_JSON_WRITER + ")I";
mw.invokestatic(TYPE_JSONB_IO, "checkAndWriteTypeName", methodDesc, true);
mw.istore(OFFSET);
}
if (fieldWriter instanceof FieldWriterEnum) {
/*
* if (fieldValue != null && symbolTable != null) {
* offset = fieldWriterN.writeEnumValueJSONB(bytes, off, fieldValue, symbolTable, features);
* goto endFieldValue_;
* }
*/
Label L0 = new Label();
mw.aload(FIELD_VALUE);
mw.ifnull(L0);
mw.aload(SYMBOL_TABLE);
mw.ifnull(L0);
mw.aload(THIS);
mw.getfield(classNameType, fieldWriter(i), DESC_FIELD_WRITER);
mw.aload(BYTES);
mw.iload(OFFSET);
mw.aload(FIELD_VALUE);
mw.aload(SYMBOL_TABLE);
mw.lload(FEATURES);
String methodDesc = "([BILjava/lang/Enum;" + DESC_SYMBOL + "J)I";
mw.invokevirtual(TYPE_FIELD_WRITER, "writeEnumValueJSONB", methodDesc);
mw.istore(OFFSET);
mw.goto_(endFieldValue_);
mw.visitLabel(L0);
}
mw.aload(BYTES);
mw.iload(OFFSET);
if (FIELD_VALUE != null) {
mw.loadLocal(fieldClass, FIELD_VALUE);
} else {
genGetObject(mwc, fieldWriter, i, OBJECT);
}
String methodName;
String methodDesc;
if (fieldClass == boolean.class) {
methodName = "writeBoolean";
methodDesc = "([BIZ)I";
} else if (fieldClass == byte.class) {
methodName = "writeInt8";
methodDesc = "([BIB)I";
} else if (fieldClass == short.class) {
methodName = "writeInt16";
methodDesc = "([BIS)I";
} else if (fieldClass == int.class) {
methodName = "writeInt32";
methodDesc = "([BII)I";
} else if (fieldClass == long.class) {
methodName = "writeInt64";
methodDesc = "([BIJ)I";
} else if (fieldClass == float.class) {
methodName = "writeFloat";
methodDesc = "([BIF)I";
} else if (fieldClass == double.class) {
methodName = "writeDouble";
methodDesc = "([BID)I";
} else if (fieldClass == Boolean.class) {
methodName = "writeBoolean";
methodDesc = "([BILjava/lang/Boolean;)I";
} else if (fieldClass == Byte.class) {
methodName = "writeInt8";
methodDesc = "([BILjava/lang/Byte;J)I";
} else if (fieldClass == Short.class) {
methodName = "writeInt16";
methodDesc = "([BILjava/lang/Short;J)I";
} else if (fieldClass == Integer.class) {
methodName = "writeInt32";
methodDesc = "([BILjava/lang/Integer;J)I";
} else if (fieldClass == Long.class) {
methodName = "writeInt64";
methodDesc = "([BILjava/lang/Long;J)I";
} else if (fieldClass == Float.class) {
methodName = "writeFloat";
methodDesc = "([BILjava/lang/Float;J)I";
} else if (fieldClass == Double.class) {
methodName = "writeDouble";
methodDesc = "([BILjava/lang/Double;J)I";
} else if (fieldClass == String.class) {
methodName = "writeString";
methodDesc = "([BILjava/lang/String;)I";
} else if (fieldWriter instanceof FieldWriterEnum) {
methodName = "writeEnum";
methodDesc = "([BILjava/lang/Enum;J)I";
} else if (fieldClass == UUID.class) {
methodName = "writeUUID";
methodDesc = "([BILjava/util/UUID;)I";
} else if (fieldClass == LocalDate.class) {
methodName = "writeLocalDate";
methodDesc = "([BILjava/time/LocalDate;)I";
} else if (fieldClass == LocalTime.class) {
methodName = "writeLocalTime";
methodDesc = "([BILjava/time/LocalTime;)I";
} else if (fieldClass == LocalDateTime.class) {
methodName = "writeLocalDateTime";
methodDesc = "([BILjava/time/LocalDateTime;)I";
} else if (fieldClass == OffsetDateTime.class) {
methodName = "writeOffsetDateTime";
methodDesc = "([BILjava/time/OffsetDateTime;)I";
} else if (fieldClass == OffsetTime.class) {
methodName = "writeOffsetTime";
methodDesc = "([BILjava/time/OffsetTime;)I";
} else if (fieldClass == Instant.class) {
methodName = "writeInstant";
methodDesc = "([BILjava/time/Instant;)I";
} else if (fieldClass == String[].class) {
methodName = "writeString";
methodDesc = "([BI[Ljava/lang/String;J)I";
} else if (Collection.class.isAssignableFrom(fieldClass)) {
Class<?> itemClass = fieldWriter.getItemClass();
if (itemClass == String.class) {
methodName = "writeString";
methodDesc = "([BILjava/util/Collection;J)I";
} else if (itemClass == Long.class) {
methodName = "writeInt64";
methodDesc = "([BILjava/util/Collection;J)I";
} else {
throw new JSONException("assert error " + fieldClass.getName());
}
} else {
throw new JSONException("assert error " + fieldClass.getName());
}
boolean needFeatures = fieldClass == Float.class
|| fieldClass == Double.class
|| fieldClass == Byte.class
|| fieldClass == Short.class
|| fieldClass == Integer.class
|| fieldClass == Long.class
|| fieldClass == String[].class
|| Collection.class.isAssignableFrom(fieldClass)
|| fieldWriter instanceof FieldWriterEnum;
if (needFeatures) {
mw.lload(FEATURES);
long fieldFeatures = objectFeatures | fieldWriter.features;
if (fieldFeatures != 0) {
mw.visitLdcInsn(fieldFeatures);
mw.lor();
}
}
mw.invokestatic(TYPE_JSONB_IO, methodName, methodDesc, true);
mw.istore(OFFSET);
if (endFieldValue_ != null) {
if (pop) {
mw.aload(JSON_WRITER);
mw.aload(FIELD_VALUE);
mw.invokevirtual(TYPE_JSON_WRITER, "popPath0", "(Ljava/lang/Object;)V");
}
mw.visitLabel(endFieldValue_);
}
}