use of com.alibaba.fastjson.asm.Label in project fastjson by alibaba.
the class ASMSerializerFactory method createJavaBeanSerializer.
public JavaBeanSerializer createJavaBeanSerializer(SerializeBeanInfo beanInfo) throws Exception {
Class<?> clazz = beanInfo.beanType;
if (clazz.isPrimitive()) {
throw new JSONException("unsupportd class " + clazz.getName());
}
JSONType jsonType = clazz.getAnnotation(JSONType.class);
FieldInfo[] unsortedGetters = beanInfo.fields;
;
for (FieldInfo fieldInfo : unsortedGetters) {
if (//
fieldInfo.field == null && //
fieldInfo.method != null && fieldInfo.method.getDeclaringClass().isInterface()) {
return new JavaBeanSerializer(clazz);
}
}
FieldInfo[] getters = beanInfo.sortedFields;
boolean nativeSorted = beanInfo.sortedFields == beanInfo.fields;
if (getters.length > 256) {
return new JavaBeanSerializer(clazz);
}
for (FieldInfo getter : getters) {
if (!ASMUtils.checkName(getter.getMember().getName())) {
return new JavaBeanSerializer(clazz);
}
}
String className = "ASMSerializer_" + seed.incrementAndGet() + "_" + clazz.getSimpleName();
String packageName = ASMSerializerFactory.class.getPackage().getName();
String classNameType = packageName.replace('.', '/') + "/" + className;
String classNameFull = packageName + "." + className;
ClassWriter cw = new ClassWriter();
//
cw.visit(//
V1_5, //
ACC_PUBLIC + ACC_SUPER, //
classNameType, //
JavaBeanSerializer, //
new String[] { ObjectSerializer });
for (FieldInfo fieldInfo : getters) {
if (//
fieldInfo.fieldClass.isPrimitive() || //|| fieldInfo.fieldClass.isEnum() //
fieldInfo.fieldClass == String.class) {
continue;
}
//
new FieldWriter(cw, ACC_PUBLIC, fieldInfo.name + "_asm_fieldType", "Ljava/lang/reflect/Type;").visitEnd();
if (List.class.isAssignableFrom(fieldInfo.fieldClass)) {
new FieldWriter(cw, ACC_PUBLIC, fieldInfo.name + "_asm_list_item_ser_", //
ObjectSerializer_desc).visitEnd();
}
//
new FieldWriter(cw, ACC_PUBLIC, fieldInfo.name + "_asm_ser_", ObjectSerializer_desc).visitEnd();
}
MethodVisitor mw = new MethodWriter(cw, ACC_PUBLIC, "<init>", "(" + desc(SerializeBeanInfo.class) + ")V", null, null);
mw.visitVarInsn(ALOAD, 0);
mw.visitVarInsn(ALOAD, 1);
mw.visitMethodInsn(INVOKESPECIAL, JavaBeanSerializer, "<init>", "(" + desc(SerializeBeanInfo.class) + ")V");
// init _asm_fieldType
for (int i = 0; i < getters.length; ++i) {
FieldInfo fieldInfo = getters[i];
if (//
fieldInfo.fieldClass.isPrimitive() || // || fieldInfo.fieldClass.isEnum() //
fieldInfo.fieldClass == String.class) {
continue;
}
mw.visitVarInsn(ALOAD, 0);
if (fieldInfo.method != null) {
mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc(fieldInfo.declaringClass)));
mw.visitLdcInsn(fieldInfo.method.getName());
mw.visitMethodInsn(INVOKESTATIC, type(ASMUtils.class), "getMethodType", "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/reflect/Type;");
} else {
mw.visitVarInsn(ALOAD, 0);
mw.visitLdcInsn(i);
mw.visitMethodInsn(INVOKESPECIAL, JavaBeanSerializer, "getFieldType", "(I)Ljava/lang/reflect/Type;");
}
mw.visitFieldInsn(PUTFIELD, classNameType, fieldInfo.name + "_asm_fieldType", "Ljava/lang/reflect/Type;");
}
mw.visitInsn(RETURN);
mw.visitMaxs(4, 4);
mw.visitEnd();
boolean DisableCircularReferenceDetect = false;
if (jsonType != null) {
for (SerializerFeature featrues : jsonType.serialzeFeatures()) {
if (featrues == SerializerFeature.DisableCircularReferenceDetect) {
DisableCircularReferenceDetect = true;
break;
}
}
}
// 2 writeNonContext
for (int i = 0; i < 3; ++i) {
String methodName;
boolean nonContext = DisableCircularReferenceDetect;
boolean writeDirect = false;
if (i == 0) {
methodName = "write";
writeDirect = true;
} else if (i == 1) {
methodName = "writeNormal";
} else {
writeDirect = true;
nonContext = true;
methodName = "writeDirectNonContext";
}
Context context = new Context(getters, beanInfo, classNameType, writeDirect, nonContext);
mw = new //
MethodWriter(//
cw, //
ACC_PUBLIC, //
methodName, "(L" + JSONSerializer + //
";Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V", //
null, //
new String[] { "java/io/IOException" });
{
Label endIf_ = new Label();
mw.visitVarInsn(ALOAD, Context.obj);
//serializer.writeNull();
mw.visitJumpInsn(IFNONNULL, endIf_);
mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitMethodInsn(INVOKEVIRTUAL, JSONSerializer, "writeNull", "()V");
mw.visitInsn(RETURN);
mw.visitLabel(endIf_);
}
mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitFieldInsn(GETFIELD, JSONSerializer, "out", SerializeWriter_desc);
mw.visitVarInsn(ASTORE, context.var("out"));
if (//
(!nativeSorted) && !context.writeDirect) {
if (jsonType == null || jsonType.alphabetic()) {
Label _else = new Label();
mw.visitVarInsn(ALOAD, context.var("out"));
mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "isSortField", "()Z");
mw.visitJumpInsn(IFNE, _else);
mw.visitVarInsn(ALOAD, 0);
mw.visitVarInsn(ALOAD, 1);
mw.visitVarInsn(ALOAD, 2);
mw.visitVarInsn(ALOAD, 3);
mw.visitVarInsn(ALOAD, 4);
mw.visitVarInsn(ILOAD, 5);
mw.visitMethodInsn(INVOKEVIRTUAL, classNameType, "writeUnsorted", "(L" + JSONSerializer + ";Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V");
mw.visitInsn(RETURN);
mw.visitLabel(_else);
}
}
// isWriteDoubleQuoteDirect
if (context.writeDirect && !nonContext) {
Label _direct = new Label();
Label _directElse = new Label();
mw.visitVarInsn(ALOAD, 0);
mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitMethodInsn(INVOKEVIRTUAL, JavaBeanSerializer, "writeDirect", "(L" + JSONSerializer + ";)Z");
mw.visitJumpInsn(IFNE, _directElse);
mw.visitVarInsn(ALOAD, 0);
mw.visitVarInsn(ALOAD, 1);
mw.visitVarInsn(ALOAD, 2);
mw.visitVarInsn(ALOAD, 3);
mw.visitVarInsn(ALOAD, 4);
mw.visitVarInsn(ILOAD, 5);
mw.visitMethodInsn(INVOKEVIRTUAL, classNameType, "writeNormal", "(L" + JSONSerializer + ";Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V");
mw.visitInsn(RETURN);
mw.visitLabel(_directElse);
mw.visitVarInsn(ALOAD, context.var("out"));
mw.visitLdcInsn(SerializerFeature.DisableCircularReferenceDetect.mask);
mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "isEnabled", "(I)Z");
mw.visitJumpInsn(IFEQ, _direct);
mw.visitVarInsn(ALOAD, 0);
mw.visitVarInsn(ALOAD, 1);
mw.visitVarInsn(ALOAD, 2);
mw.visitVarInsn(ALOAD, 3);
mw.visitVarInsn(ALOAD, 4);
mw.visitVarInsn(ILOAD, 5);
mw.visitMethodInsn(INVOKEVIRTUAL, classNameType, "writeDirectNonContext", "(L" + JSONSerializer + ";Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V");
mw.visitInsn(RETURN);
mw.visitLabel(_direct);
}
// obj
mw.visitVarInsn(ALOAD, Context.obj);
// serializer
mw.visitTypeInsn(CHECKCAST, type(clazz));
// obj
mw.visitVarInsn(ASTORE, context.var("entity"));
generateWriteMethod(clazz, mw, getters, context);
mw.visitInsn(RETURN);
mw.visitMaxs(7, context.variantIndex + 2);
mw.visitEnd();
}
if (!nativeSorted) {
// sortField support
Context context = new Context(getters, beanInfo, classNameType, false, DisableCircularReferenceDetect);
mw = new MethodWriter(cw, ACC_PUBLIC, "writeUnsorted", "(L" + JSONSerializer + ";Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V", null, new String[] { "java/io/IOException" });
mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitFieldInsn(GETFIELD, JSONSerializer, "out", SerializeWriter_desc);
mw.visitVarInsn(ASTORE, context.var("out"));
// obj
mw.visitVarInsn(ALOAD, Context.obj);
// serializer
mw.visitTypeInsn(CHECKCAST, type(clazz));
// obj
mw.visitVarInsn(ASTORE, context.var("entity"));
generateWriteMethod(clazz, mw, unsortedGetters, context);
mw.visitInsn(RETURN);
mw.visitMaxs(7, context.variantIndex + 2);
mw.visitEnd();
}
// 2 writeAsArrayNonContext
for (int i = 0; i < 3; ++i) {
String methodName;
boolean nonContext = DisableCircularReferenceDetect;
boolean writeDirect = false;
if (i == 0) {
methodName = "writeAsArray";
writeDirect = true;
} else if (i == 1) {
methodName = "writeAsArrayNormal";
} else {
writeDirect = true;
nonContext = true;
methodName = "writeAsArrayNonContext";
}
Context context = new Context(getters, beanInfo, classNameType, writeDirect, nonContext);
mw = new MethodWriter(cw, ACC_PUBLIC, methodName, "(L" + JSONSerializer + ";Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V", null, new String[] { "java/io/IOException" });
mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitFieldInsn(GETFIELD, JSONSerializer, "out", SerializeWriter_desc);
mw.visitVarInsn(ASTORE, context.var("out"));
// obj
mw.visitVarInsn(ALOAD, Context.obj);
// serializer
mw.visitTypeInsn(CHECKCAST, type(clazz));
// obj
mw.visitVarInsn(ASTORE, context.var("entity"));
generateWriteAsArray(clazz, mw, getters, context);
mw.visitInsn(RETURN);
mw.visitMaxs(7, context.variantIndex + 2);
mw.visitEnd();
}
byte[] code = cw.toByteArray();
Class<?> exampleClass = classLoader.defineClassPublic(classNameFull, code, 0, code.length);
Constructor<?> constructor = exampleClass.getConstructor(SerializeBeanInfo.class);
Object instance = constructor.newInstance(beanInfo);
return (JavaBeanSerializer) instance;
}
use of com.alibaba.fastjson.asm.Label in project fastjson by alibaba.
the class ASMSerializerFactory method _enum.
private void _enum(Class<?> clazz, MethodVisitor mw, FieldInfo fieldInfo, Context context) {
Label _not_null = new Label();
Label _end_if = new Label();
Label _end = new Label();
_nameApply(mw, fieldInfo, context, _end);
_get(mw, context, fieldInfo);
// cast
mw.visitTypeInsn(CHECKCAST, "java/lang/Enum");
mw.visitVarInsn(ASTORE, context.var("enum"));
_filters(mw, fieldInfo, context, _end);
mw.visitVarInsn(ALOAD, context.var("enum"));
mw.visitJumpInsn(IFNONNULL, _not_null);
_if_write_null(mw, fieldInfo, context);
mw.visitJumpInsn(GOTO, _end_if);
mw.visitLabel(_not_null);
if (context.writeDirect) {
mw.visitVarInsn(ALOAD, context.var("out"));
mw.visitVarInsn(ILOAD, context.var("seperator"));
mw.visitVarInsn(ALOAD, Context.fieldName);
mw.visitVarInsn(ALOAD, context.var("enum"));
mw.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Enum", "name", "()Ljava/lang/String;");
mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "writeFieldValueStringWithDoubleQuote", "(CLjava/lang/String;Ljava/lang/String;)V");
} else {
mw.visitVarInsn(ALOAD, context.var("out"));
mw.visitVarInsn(ILOAD, context.var("seperator"));
mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "write", "(I)V");
mw.visitVarInsn(ALOAD, context.var("out"));
mw.visitVarInsn(ALOAD, Context.fieldName);
mw.visitInsn(ICONST_0);
mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "writeFieldName", "(Ljava/lang/String;Z)V");
mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitVarInsn(ALOAD, context.var("enum"));
mw.visitVarInsn(ALOAD, Context.fieldName);
mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc((Class<?>) fieldInfo.fieldClass)));
mw.visitLdcInsn(fieldInfo.serialzeFeatures);
mw.visitMethodInsn(INVOKEVIRTUAL, JSONSerializer, "writeWithFieldName", "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V");
}
_seperator(mw, context);
mw.visitLabel(_end_if);
mw.visitLabel(_end);
}
use of com.alibaba.fastjson.asm.Label in project fastjson by alibaba.
the class ASMSerializerFactory method generateWriteMethod.
private void generateWriteMethod(Class<?> clazz, MethodVisitor mw, FieldInfo[] getters, Context context) throws Exception {
// if (serializer.containsReference(object)) {
Label end = new Label();
int size = getters.length;
if (!context.writeDirect) {
// pretty format not byte code optimized
Label endSupper_ = new Label();
Label supper_ = new Label();
mw.visitVarInsn(ALOAD, context.var("out"));
mw.visitLdcInsn(SerializerFeature.PrettyFormat.mask);
mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "isEnabled", "(I)Z");
mw.visitJumpInsn(IFNE, supper_);
boolean hasMethod = false;
for (FieldInfo getter : getters) {
if (getter.method != null) {
hasMethod = true;
}
}
if (hasMethod) {
mw.visitVarInsn(ALOAD, context.var("out"));
mw.visitLdcInsn(SerializerFeature.IgnoreErrorGetter.mask);
mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "isEnabled", "(I)Z");
mw.visitJumpInsn(IFEQ, endSupper_);
} else {
mw.visitJumpInsn(GOTO, endSupper_);
}
mw.visitLabel(supper_);
mw.visitVarInsn(ALOAD, 0);
mw.visitVarInsn(ALOAD, 1);
mw.visitVarInsn(ALOAD, 2);
mw.visitVarInsn(ALOAD, 3);
mw.visitVarInsn(ALOAD, 4);
mw.visitVarInsn(ILOAD, 5);
mw.visitMethodInsn(INVOKESPECIAL, JavaBeanSerializer, "write", "(L" + JSONSerializer + ";Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V");
mw.visitInsn(RETURN);
mw.visitLabel(endSupper_);
}
if (!context.nonContext) {
Label endRef_ = new Label();
// /////
// this
mw.visitVarInsn(ALOAD, 0);
mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitVarInsn(ALOAD, Context.obj);
mw.visitVarInsn(ILOAD, Context.features);
mw.visitMethodInsn(INVOKEVIRTUAL, JavaBeanSerializer, "writeReference", "(L" + JSONSerializer + ";Ljava/lang/Object;I)Z");
mw.visitJumpInsn(IFEQ, endRef_);
mw.visitInsn(RETURN);
mw.visitLabel(endRef_);
}
final String writeAsArrayMethodName;
if (context.writeDirect) {
if (context.nonContext) {
writeAsArrayMethodName = "writeAsArrayNonContext";
} else {
writeAsArrayMethodName = "writeAsArray";
}
} else {
writeAsArrayMethodName = "writeAsArrayNormal";
}
if ((context.beanInfo.features & SerializerFeature.BeanToArray.mask) == 0) {
Label endWriteAsArray_ = new Label();
mw.visitVarInsn(ALOAD, context.var("out"));
mw.visitLdcInsn(SerializerFeature.BeanToArray.mask);
mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "isEnabled", "(I)Z");
mw.visitJumpInsn(IFEQ, endWriteAsArray_);
// /////
// this
mw.visitVarInsn(ALOAD, 0);
mw.visitVarInsn(ALOAD, Context.serializer);
// obj
mw.visitVarInsn(ALOAD, 2);
// fieldObj
mw.visitVarInsn(ALOAD, 3);
// fieldType
mw.visitVarInsn(ALOAD, 4);
// features
mw.visitVarInsn(ILOAD, 5);
//
mw.visitMethodInsn(//
INVOKEVIRTUAL, //
context.className, //
writeAsArrayMethodName, "(L" + JSONSerializer + ";Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V");
mw.visitInsn(RETURN);
mw.visitLabel(endWriteAsArray_);
} else {
// this
mw.visitVarInsn(ALOAD, 0);
mw.visitVarInsn(ALOAD, Context.serializer);
// obj
mw.visitVarInsn(ALOAD, 2);
// fieldObj
mw.visitVarInsn(ALOAD, 3);
// fieldType
mw.visitVarInsn(ALOAD, 4);
// features
mw.visitVarInsn(ILOAD, 5);
//
mw.visitMethodInsn(//
INVOKEVIRTUAL, //
context.className, //
writeAsArrayMethodName, "(L" + JSONSerializer + ";Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V");
mw.visitInsn(RETURN);
}
if (!context.nonContext) {
mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitMethodInsn(INVOKEVIRTUAL, JSONSerializer, "getContext", "()" + SerialContext_desc);
mw.visitVarInsn(ASTORE, context.var("parent"));
mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitVarInsn(ALOAD, context.var("parent"));
mw.visitVarInsn(ALOAD, Context.obj);
mw.visitVarInsn(ALOAD, Context.paramFieldName);
mw.visitLdcInsn(context.beanInfo.features);
mw.visitMethodInsn(INVOKEVIRTUAL, JSONSerializer, "setContext", "(" + SerialContext_desc + "Ljava/lang/Object;Ljava/lang/Object;I)V");
}
// SEPERATO
if (!context.writeDirect) {
Label end_ = new Label();
Label else_ = new Label();
Label writeClass_ = new Label();
mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitVarInsn(ALOAD, Context.paramFieldType);
mw.visitVarInsn(ALOAD, Context.obj);
mw.visitMethodInsn(INVOKEVIRTUAL, JSONSerializer, "isWriteClassName", "(Ljava/lang/reflect/Type;Ljava/lang/Object;)Z");
mw.visitJumpInsn(IFEQ, else_);
// IFNULL
mw.visitVarInsn(ALOAD, Context.paramFieldType);
mw.visitVarInsn(ALOAD, Context.obj);
mw.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;");
mw.visitJumpInsn(IF_ACMPEQ, else_);
mw.visitLabel(writeClass_);
mw.visitVarInsn(ALOAD, context.var("out"));
mw.visitVarInsn(BIPUSH, '{');
mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "write", "(I)V");
mw.visitVarInsn(ALOAD, 0);
mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitVarInsn(ALOAD, Context.obj);
mw.visitMethodInsn(INVOKEVIRTUAL, JavaBeanSerializer, "writeClassName", "(L" + JSONSerializer + ";Ljava/lang/Object;)V");
mw.visitVarInsn(BIPUSH, ',');
mw.visitJumpInsn(GOTO, end_);
mw.visitLabel(else_);
mw.visitVarInsn(BIPUSH, '{');
mw.visitLabel(end_);
} else {
mw.visitVarInsn(BIPUSH, '{');
}
mw.visitVarInsn(ISTORE, context.var("seperator"));
if (!context.writeDirect) {
_before(mw, context);
}
if (!context.writeDirect) {
mw.visitVarInsn(ALOAD, context.var("out"));
mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "isNotWriteDefaultValue", "()Z");
mw.visitVarInsn(ISTORE, context.var("notWriteDefaultValue"));
mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitVarInsn(ALOAD, 0);
mw.visitMethodInsn(INVOKEVIRTUAL, JSONSerializer, "checkValue", "(" + SerializeFilterable_desc + ")Z");
mw.visitVarInsn(ISTORE, context.var("checkValue"));
mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitVarInsn(ALOAD, 0);
mw.visitMethodInsn(INVOKEVIRTUAL, JSONSerializer, "hasNameFilters", "(" + SerializeFilterable_desc + ")Z");
mw.visitVarInsn(ISTORE, context.var("hasNameFilters"));
}
for (int i = 0; i < size; ++i) {
FieldInfo property = getters[i];
Class<?> propertyClass = property.fieldClass;
mw.visitLdcInsn(property.name);
mw.visitVarInsn(ASTORE, Context.fieldName);
if (//
propertyClass == byte.class || //
propertyClass == short.class || propertyClass == int.class) {
_int(clazz, mw, property, context, context.var(propertyClass.getName()), 'I');
} else if (propertyClass == long.class) {
_long(clazz, mw, property, context);
} else if (propertyClass == float.class) {
_float(clazz, mw, property, context);
} else if (propertyClass == double.class) {
_double(clazz, mw, property, context);
} else if (propertyClass == boolean.class) {
_int(clazz, mw, property, context, context.var("boolean"), 'Z');
} else if (propertyClass == char.class) {
_int(clazz, mw, property, context, context.var("char"), 'C');
} else if (propertyClass == String.class) {
_string(clazz, mw, property, context);
} else if (propertyClass == BigDecimal.class) {
_decimal(clazz, mw, property, context);
} else if (List.class.isAssignableFrom(propertyClass)) {
_list(clazz, mw, property, context);
} else if (propertyClass.isEnum()) {
_enum(clazz, mw, property, context);
} else {
_object(clazz, mw, property, context);
}
}
if (!context.writeDirect) {
_after(mw, context);
}
Label _else = new Label();
Label _end_if = new Label();
mw.visitVarInsn(ILOAD, context.var("seperator"));
mw.visitIntInsn(BIPUSH, '{');
mw.visitJumpInsn(IF_ICMPNE, _else);
mw.visitVarInsn(ALOAD, context.var("out"));
mw.visitVarInsn(BIPUSH, '{');
mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "write", "(I)V");
mw.visitLabel(_else);
mw.visitVarInsn(ALOAD, context.var("out"));
mw.visitVarInsn(BIPUSH, '}');
mw.visitMethodInsn(INVOKEVIRTUAL, SerializeWriter, "write", "(I)V");
mw.visitLabel(_end_if);
mw.visitLabel(end);
if (!context.nonContext) {
mw.visitVarInsn(ALOAD, Context.serializer);
mw.visitVarInsn(ALOAD, context.var("parent"));
mw.visitMethodInsn(INVOKEVIRTUAL, JSONSerializer, "setContext", "(" + SerialContext_desc + ")V");
}
}
use of com.alibaba.fastjson.asm.Label in project fastjson by alibaba.
the class ASMDeserializerFactory method _getCollectionFieldItemDeser.
private void _getCollectionFieldItemDeser(Context context, MethodVisitor mw, FieldInfo fieldInfo, Class<?> itemType) {
Label notNull_ = new Label();
mw.visitVarInsn(ALOAD, 0);
mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_list_item_deser__", desc(ObjectDeserializer.class));
mw.visitJumpInsn(IFNONNULL, notNull_);
mw.visitVarInsn(ALOAD, 0);
mw.visitVarInsn(ALOAD, 1);
mw.visitMethodInsn(INVOKEVIRTUAL, DefaultJSONParser, "getConfig", "()" + desc(ParserConfig.class));
mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc(itemType)));
mw.visitMethodInsn(INVOKEVIRTUAL, type(ParserConfig.class), "getDeserializer", "(Ljava/lang/reflect/Type;)" + desc(ObjectDeserializer.class));
mw.visitFieldInsn(PUTFIELD, context.className, fieldInfo.name + "_asm_list_item_deser__", desc(ObjectDeserializer.class));
mw.visitLabel(notNull_);
mw.visitVarInsn(ALOAD, 0);
mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_list_item_deser__", desc(ObjectDeserializer.class));
}
use of com.alibaba.fastjson.asm.Label in project fastjson by alibaba.
the class ASMDeserializerFactory method _deserialze.
private void _deserialze(ClassWriter cw, Context context) {
if (context.fieldInfoList.length == 0) {
return;
}
for (FieldInfo fieldInfo : context.fieldInfoList) {
Class<?> fieldClass = fieldInfo.fieldClass;
Type fieldType = fieldInfo.fieldType;
if (fieldClass == char.class) {
return;
}
if (Collection.class.isAssignableFrom(fieldClass)) {
if (fieldType instanceof ParameterizedType) {
Type itemType = ((ParameterizedType) fieldType).getActualTypeArguments()[0];
if (itemType instanceof Class) {
continue;
} else {
return;
}
} else {
return;
}
}
}
JavaBeanInfo beanInfo = context.beanInfo;
context.fieldInfoList = beanInfo.sortedFields;
MethodVisitor mw = new MethodWriter(cw, ACC_PUBLIC, "deserialze", "(L" + DefaultJSONParser + ";Ljava/lang/reflect/Type;Ljava/lang/Object;I)Ljava/lang/Object;", null, null);
Label reset_ = new Label();
Label super_ = new Label();
Label return_ = new Label();
Label end_ = new Label();
defineVarLexer(context, mw);
{
Label next_ = new Label();
// isSupportArrayToBean
mw.visitVarInsn(ALOAD, context.var("lexer"));
mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "token", "()I");
mw.visitLdcInsn(JSONToken.LBRACKET);
mw.visitJumpInsn(IF_ICMPNE, next_);
if ((beanInfo.parserFeatures & Feature.SupportArrayToBean.mask) == 0) {
mw.visitVarInsn(ALOAD, context.var("lexer"));
mw.visitVarInsn(ILOAD, 4);
mw.visitLdcInsn(Feature.SupportArrayToBean.mask);
mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "isEnabled", "(II)Z");
mw.visitJumpInsn(IFEQ, next_);
}
mw.visitVarInsn(ALOAD, 0);
mw.visitVarInsn(ALOAD, Context.parser);
mw.visitVarInsn(ALOAD, 2);
mw.visitVarInsn(ALOAD, 3);
//mw.visitVarInsn(ALOAD, 5);
mw.visitInsn(ACONST_NULL);
//
mw.visitMethodInsn(//
INVOKESPECIAL, //
context.className, //
"deserialzeArrayMapping", "(L" + DefaultJSONParser + ";Ljava/lang/reflect/Type;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
mw.visitInsn(ARETURN);
mw.visitLabel(next_);
// deserialzeArrayMapping
}
mw.visitVarInsn(ALOAD, context.var("lexer"));
mw.visitLdcInsn(Feature.SortFeidFastMatch.mask);
mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "isEnabled", "(I)Z");
mw.visitJumpInsn(IFEQ, super_);
mw.visitVarInsn(ALOAD, context.var("lexer"));
mw.visitLdcInsn(context.clazz.getName());
mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanType", "(Ljava/lang/String;)I");
mw.visitLdcInsn(com.alibaba.fastjson.parser.JSONLexerBase.NOT_MATCH);
mw.visitJumpInsn(IF_ICMPEQ, super_);
// parser
mw.visitVarInsn(ALOAD, 1);
mw.visitMethodInsn(INVOKEVIRTUAL, DefaultJSONParser, "getContext", "()" + desc(ParseContext.class));
mw.visitVarInsn(ASTORE, context.var("mark_context"));
// ParseContext context = parser.getContext();
mw.visitInsn(ICONST_0);
mw.visitVarInsn(ISTORE, context.var("matchedCount"));
_createInstance(context, mw);
{
// parser
mw.visitVarInsn(ALOAD, 1);
mw.visitMethodInsn(INVOKEVIRTUAL, DefaultJSONParser, "getContext", "()" + desc(ParseContext.class));
mw.visitVarInsn(ASTORE, context.var("context"));
// parser
mw.visitVarInsn(ALOAD, 1);
mw.visitVarInsn(ALOAD, context.var("context"));
mw.visitVarInsn(ALOAD, context.var("instance"));
// fieldName
mw.visitVarInsn(ALOAD, 3);
//
mw.visitMethodInsn(//
INVOKEVIRTUAL, //
DefaultJSONParser, //
"setContext", "(" + desc(ParseContext.class) + "Ljava/lang/Object;Ljava/lang/Object;)" + desc(ParseContext.class));
mw.visitVarInsn(ASTORE, context.var("childContext"));
}
mw.visitVarInsn(ALOAD, context.var("lexer"));
mw.visitFieldInsn(GETFIELD, JSONLexerBase, "matchStat", "I");
mw.visitLdcInsn(com.alibaba.fastjson.parser.JSONLexerBase.END);
mw.visitJumpInsn(IF_ICMPEQ, return_);
// UNKOWN
mw.visitInsn(ICONST_0);
mw.visitIntInsn(ISTORE, context.var("matchStat"));
int fieldListSize = context.fieldInfoList.length;
for (int i = 0; i < fieldListSize; i += 32) {
mw.visitInsn(ICONST_0);
mw.visitVarInsn(ISTORE, context.var("_asm_flag_" + (i / 32)));
}
mw.visitVarInsn(ALOAD, context.var("lexer"));
mw.visitLdcInsn(Feature.InitStringFieldAsEmpty.mask);
mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "isEnabled", "(I)Z");
mw.visitIntInsn(ISTORE, context.var("initStringFieldAsEmpty"));
// declare and init
for (int i = 0; i < fieldListSize; ++i) {
FieldInfo fieldInfo = context.fieldInfoList[i];
Class<?> fieldClass = fieldInfo.fieldClass;
if (//
fieldClass == boolean.class || //
fieldClass == byte.class || //
fieldClass == short.class || fieldClass == int.class) {
mw.visitInsn(ICONST_0);
mw.visitVarInsn(ISTORE, context.var(fieldInfo.name + "_asm"));
} else if (fieldClass == long.class) {
mw.visitInsn(LCONST_0);
mw.visitVarInsn(LSTORE, context.var(fieldInfo.name + "_asm", 2));
} else if (fieldClass == float.class) {
mw.visitInsn(FCONST_0);
mw.visitVarInsn(FSTORE, context.var(fieldInfo.name + "_asm"));
} else if (fieldClass == double.class) {
mw.visitInsn(DCONST_0);
mw.visitVarInsn(DSTORE, context.var(fieldInfo.name + "_asm", 2));
} else {
if (fieldClass == String.class) {
Label flagEnd_ = new Label();
Label flagElse_ = new Label();
mw.visitVarInsn(ILOAD, context.var("initStringFieldAsEmpty"));
mw.visitJumpInsn(IFEQ, flagElse_);
_setFlag(mw, context, i);
mw.visitVarInsn(ALOAD, context.var("lexer"));
mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "stringDefaultValue", "()Ljava/lang/String;");
mw.visitJumpInsn(GOTO, flagEnd_);
mw.visitLabel(flagElse_);
mw.visitInsn(ACONST_NULL);
mw.visitLabel(flagEnd_);
} else {
mw.visitInsn(ACONST_NULL);
}
// cast
mw.visitTypeInsn(CHECKCAST, type(fieldClass));
mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm"));
}
}
for (int i = 0; i < fieldListSize; ++i) {
FieldInfo fieldInfo = context.fieldInfoList[i];
Class<?> fieldClass = fieldInfo.fieldClass;
Type fieldType = fieldInfo.fieldType;
Label notMatch_ = new Label();
if (fieldClass == boolean.class) {
mw.visitVarInsn(ALOAD, context.var("lexer"));
mw.visitVarInsn(ALOAD, 0);
mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C");
mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldBoolean", "([C)Z");
mw.visitVarInsn(ISTORE, context.var(fieldInfo.name + "_asm"));
} else if (fieldClass == byte.class) {
mw.visitVarInsn(ALOAD, context.var("lexer"));
mw.visitVarInsn(ALOAD, 0);
mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C");
mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldInt", "([C)I");
mw.visitVarInsn(ISTORE, context.var(fieldInfo.name + "_asm"));
} else if (fieldClass == short.class) {
mw.visitVarInsn(ALOAD, context.var("lexer"));
mw.visitVarInsn(ALOAD, 0);
mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C");
mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldInt", "([C)I");
mw.visitVarInsn(ISTORE, context.var(fieldInfo.name + "_asm"));
} else if (fieldClass == int.class) {
mw.visitVarInsn(ALOAD, context.var("lexer"));
mw.visitVarInsn(ALOAD, 0);
mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C");
mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldInt", "([C)I");
mw.visitVarInsn(ISTORE, context.var(fieldInfo.name + "_asm"));
} else if (fieldClass == long.class) {
mw.visitVarInsn(ALOAD, context.var("lexer"));
mw.visitVarInsn(ALOAD, 0);
mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C");
mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldLong", "([C)J");
mw.visitVarInsn(LSTORE, context.var(fieldInfo.name + "_asm", 2));
} else if (fieldClass == float.class) {
mw.visitVarInsn(ALOAD, context.var("lexer"));
mw.visitVarInsn(ALOAD, 0);
mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C");
mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldFloat", "([C)F");
mw.visitVarInsn(FSTORE, context.var(fieldInfo.name + "_asm"));
} else if (fieldClass == double.class) {
mw.visitVarInsn(ALOAD, context.var("lexer"));
mw.visitVarInsn(ALOAD, 0);
mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C");
mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldDouble", "([C)D");
mw.visitVarInsn(DSTORE, context.var(fieldInfo.name + "_asm", 2));
} else if (fieldClass == String.class) {
mw.visitVarInsn(ALOAD, context.var("lexer"));
mw.visitVarInsn(ALOAD, 0);
mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C");
mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldString", "([C)Ljava/lang/String;");
mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm"));
} else if (fieldClass == int[].class) {
mw.visitVarInsn(ALOAD, context.var("lexer"));
mw.visitVarInsn(ALOAD, 0);
mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C");
mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldIntArray", "([C)[I");
mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm"));
} else if (fieldClass == float[].class) {
mw.visitVarInsn(ALOAD, context.var("lexer"));
mw.visitVarInsn(ALOAD, 0);
mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C");
mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldFloatArray", "([C)[F");
mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm"));
} else if (fieldClass == float[][].class) {
mw.visitVarInsn(ALOAD, context.var("lexer"));
mw.visitVarInsn(ALOAD, 0);
mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C");
mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldFloatArray2", "([C)[[F");
mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm"));
} else if (fieldClass.isEnum()) {
mw.visitVarInsn(ALOAD, 0);
mw.visitVarInsn(ALOAD, context.var("lexer"));
mw.visitVarInsn(ALOAD, 0);
mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C");
_getFieldDeser(context, mw, fieldInfo);
mw.visitMethodInsn(INVOKEVIRTUAL, type(JavaBeanDeserializer.class), "scanEnum", "(L" + JSONLexerBase + ";[C" + desc(ObjectDeserializer.class) + ")Ljava/lang/Enum;");
// cast
mw.visitTypeInsn(CHECKCAST, type(fieldClass));
mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm"));
// } else if (fieldClass.isEnum()) {
// mw.visitVarInsn(ALOAD, context.var("lexer"));
// mw.visitVarInsn(ALOAD, 0);
// mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C");
// Label enumNull_ = new Label();
// mw.visitInsn(ACONST_NULL);
// mw.visitTypeInsn(CHECKCAST, type(fieldClass)); // cast
// mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm"));
//
// mw.visitVarInsn(ALOAD, 1);
//
// mw.visitMethodInsn(INVOKEVIRTUAL, DefaultJSONParser, "getSymbolTable", "()" + desc(SymbolTable.class));
//
// mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldSymbol",
// "([C" + desc(SymbolTable.class) + ")Ljava/lang/String;");
// mw.visitInsn(DUP);
// mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm_enumName"));
//
// mw.visitJumpInsn(IFNULL, enumNull_);
//
// mw.visitVarInsn(ALOAD, context.var(fieldInfo.name + "_asm_enumName"));
// mw.visitMethodInsn(INVOKEVIRTUAL, type(String.class), "length", "()I");
// mw.visitJumpInsn(IFEQ, enumNull_);
//
// mw.visitVarInsn(ALOAD, context.var(fieldInfo.name + "_asm_enumName"));
// mw.visitMethodInsn(INVOKESTATIC, type(fieldClass), "valueOf",
// "(Ljava/lang/String;)" + desc(fieldClass));
// mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm"));
// mw.visitLabel(enumNull_);
} else if (Collection.class.isAssignableFrom(fieldClass)) {
mw.visitVarInsn(ALOAD, context.var("lexer"));
mw.visitVarInsn(ALOAD, 0);
mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_prefix__", "[C");
Class<?> itemClass = TypeUtils.getCollectionItemClass(fieldType);
if (itemClass == String.class) {
// cast
mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc(fieldClass)));
mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFieldStringArray", "([CLjava/lang/Class;)" + desc(Collection.class));
mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm"));
} else {
_deserialze_list_obj(context, mw, reset_, fieldInfo, fieldClass, itemClass, i);
if (i == fieldListSize - 1) {
_deserialize_endCheck(context, mw, reset_);
}
continue;
}
} else {
_deserialze_obj(context, mw, reset_, fieldInfo, fieldClass, i);
if (i == fieldListSize - 1) {
_deserialize_endCheck(context, mw, reset_);
}
continue;
}
mw.visitVarInsn(ALOAD, context.var("lexer"));
mw.visitFieldInsn(GETFIELD, JSONLexerBase, "matchStat", "I");
Label flag_ = new Label();
// mw.visitInsn(DUP);
mw.visitJumpInsn(IFLE, flag_);
_setFlag(mw, context, i);
mw.visitLabel(flag_);
mw.visitVarInsn(ALOAD, context.var("lexer"));
mw.visitFieldInsn(GETFIELD, JSONLexerBase, "matchStat", "I");
mw.visitInsn(DUP);
mw.visitVarInsn(ISTORE, context.var("matchStat"));
mw.visitLdcInsn(com.alibaba.fastjson.parser.JSONLexerBase.NOT_MATCH);
mw.visitJumpInsn(IF_ICMPEQ, reset_);
mw.visitVarInsn(ALOAD, context.var("lexer"));
mw.visitFieldInsn(GETFIELD, JSONLexerBase, "matchStat", "I");
mw.visitJumpInsn(IFLE, notMatch_);
// increment matchedCount
mw.visitVarInsn(ILOAD, context.var("matchedCount"));
mw.visitInsn(ICONST_1);
mw.visitInsn(IADD);
mw.visitVarInsn(ISTORE, context.var("matchedCount"));
mw.visitVarInsn(ALOAD, context.var("lexer"));
mw.visitFieldInsn(GETFIELD, JSONLexerBase, "matchStat", "I");
mw.visitLdcInsn(com.alibaba.fastjson.parser.JSONLexerBase.END);
mw.visitJumpInsn(IF_ICMPEQ, end_);
mw.visitLabel(notMatch_);
if (i == fieldListSize - 1) {
mw.visitVarInsn(ALOAD, context.var("lexer"));
mw.visitFieldInsn(GETFIELD, JSONLexerBase, "matchStat", "I");
mw.visitLdcInsn(com.alibaba.fastjson.parser.JSONLexerBase.END);
mw.visitJumpInsn(IF_ICMPNE, reset_);
}
}
// endFor
mw.visitLabel(end_);
if (!context.clazz.isInterface() && !Modifier.isAbstract(context.clazz.getModifiers())) {
_batchSet(context, mw);
}
mw.visitLabel(return_);
_setContext(context, mw);
mw.visitVarInsn(ALOAD, context.var("instance"));
Method buildMethod = context.beanInfo.buildMethod;
if (buildMethod != null) {
mw.visitMethodInsn(INVOKEVIRTUAL, type(context.getInstClass()), buildMethod.getName(), "()" + desc(buildMethod.getReturnType()));
}
mw.visitInsn(ARETURN);
mw.visitLabel(reset_);
_batchSet(context, mw);
mw.visitVarInsn(ALOAD, 0);
mw.visitVarInsn(ALOAD, 1);
mw.visitVarInsn(ALOAD, 2);
mw.visitVarInsn(ALOAD, 3);
mw.visitVarInsn(ALOAD, context.var("instance"));
mw.visitVarInsn(ILOAD, 4);
int flagSize = (fieldListSize / 32);
if (fieldListSize != 0 && (fieldListSize % 32) != 0) {
flagSize += 1;
}
if (flagSize == 1) {
mw.visitInsn(ICONST_1);
} else {
mw.visitIntInsn(BIPUSH, flagSize);
}
mw.visitIntInsn(NEWARRAY, T_INT);
for (int i = 0; i < flagSize; ++i) {
mw.visitInsn(DUP);
if (i == 0) {
mw.visitInsn(ICONST_0);
} else if (i == 1) {
mw.visitInsn(ICONST_1);
} else {
mw.visitIntInsn(BIPUSH, i);
}
mw.visitVarInsn(ILOAD, context.var("_asm_flag_" + i));
mw.visitInsn(IASTORE);
}
mw.visitMethodInsn(INVOKEVIRTUAL, type(JavaBeanDeserializer.class), "parseRest", "(L" + DefaultJSONParser + ";Ljava/lang/reflect/Type;Ljava/lang/Object;Ljava/lang/Object;I[I)Ljava/lang/Object;");
// cast
mw.visitTypeInsn(CHECKCAST, type(context.clazz));
mw.visitInsn(ARETURN);
mw.visitLabel(super_);
mw.visitVarInsn(ALOAD, 0);
mw.visitVarInsn(ALOAD, 1);
mw.visitVarInsn(ALOAD, 2);
mw.visitVarInsn(ALOAD, 3);
mw.visitVarInsn(ILOAD, 4);
//
mw.visitMethodInsn(//
INVOKESPECIAL, //
type(JavaBeanDeserializer.class), //
"deserialze", "(L" + DefaultJSONParser + ";Ljava/lang/reflect/Type;Ljava/lang/Object;I)Ljava/lang/Object;");
mw.visitInsn(ARETURN);
mw.visitMaxs(10, context.variantIndex);
mw.visitEnd();
}
Aggregations