use of com.alibaba.fastjson.asm.ClassWriter in project fastjson by alibaba.
the class ASMDeserializerFactory method createJavaBeanDeserializer.
public ObjectDeserializer createJavaBeanDeserializer(ParserConfig config, JavaBeanInfo beanInfo) throws Exception {
Class<?> clazz = beanInfo.clazz;
if (clazz.isPrimitive()) {
throw new IllegalArgumentException("not support type :" + clazz.getName());
}
String className = "FastjsonASMDeserializer_" + seed.incrementAndGet() + "_" + clazz.getSimpleName();
String packageName = ASMDeserializerFactory.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, type(JavaBeanDeserializer.class), null);
_init(cw, new Context(classNameType, config, beanInfo, 3));
_createInstance(cw, new Context(classNameType, config, beanInfo, 3));
_deserialze(cw, new Context(classNameType, config, beanInfo, 5));
_deserialzeArrayMapping(cw, new Context(classNameType, config, beanInfo, 4));
byte[] code = cw.toByteArray();
Class<?> exampleClass = defineClassPublic(classNameFull, code, 0, code.length);
Constructor<?> constructor = exampleClass.getConstructor(ParserConfig.class, JavaBeanInfo.class);
Object instance = constructor.newInstance(config, beanInfo);
return (ObjectDeserializer) instance;
}
use of com.alibaba.fastjson.asm.ClassWriter in project fastjson by alibaba.
the class TestASM method test_1.
public void test_1() throws Exception {
ClassWriter cw = new ClassWriter();
cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, "DateSerializer", "java/lang/Object", new String[] { "com/alibaba/fastjson/serializer/ObjectSerializer" });
MethodVisitor mw = new MethodWriter(cw, ACC_PUBLIC, "<init>", "()V", null, null);
mw.visitVarInsn(ALOAD, 0);
mw.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
mw.visitInsn(RETURN);
mw.visitMaxs(1, 1);
mw.visitEnd();
mw = new MethodWriter(cw, ACC_PUBLIC, "write", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;)V", null, new String[] { "java/io/IOException" });
// serializer
mw.visitVarInsn(ALOAD, 1);
mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JSONSerializer", "getWriter", "()Lcom/alibaba/fastjson/serializer/SerializeWriter;");
// out
mw.visitVarInsn(ASTORE, 3);
// obj
mw.visitVarInsn(ALOAD, 2);
// serializer
mw.visitTypeInsn(CHECKCAST, getCastType(Entity.class));
// obj
mw.visitVarInsn(ASTORE, 4);
// out
mw.visitVarInsn(ALOAD, 3);
mw.visitLdcInsn("{");
mw.visitMethodInsn(INVOKEVIRTUAL, getCastType(SerializeWriter.class), "writeString", "(Ljava/lang/String;)V");
// out
mw.visitVarInsn(ALOAD, 3);
mw.visitLdcInsn("\"id\":");
mw.visitMethodInsn(INVOKEVIRTUAL, getCastType(SerializeWriter.class), "write", "(Ljava/lang/String;)V");
// out
mw.visitVarInsn(ALOAD, 3);
// entity
mw.visitVarInsn(ALOAD, 4);
mw.visitMethodInsn(INVOKEVIRTUAL, getCastType(Entity.class), "getId", "()I");
mw.visitMethodInsn(INVOKEVIRTUAL, getCastType(SerializeWriter.class), "writeInt", "(I)V");
// out
mw.visitVarInsn(ALOAD, 3);
mw.visitLdcInsn("\",name\":");
mw.visitMethodInsn(INVOKEVIRTUAL, getCastType(SerializeWriter.class), "write", "(Ljava/lang/String;)V");
// out
mw.visitVarInsn(ALOAD, 3);
// entity
mw.visitVarInsn(ALOAD, 4);
mw.visitMethodInsn(INVOKEVIRTUAL, getCastType(Entity.class), "getName", "()Ljava/lang/String;");
mw.visitMethodInsn(INVOKEVIRTUAL, getCastType(SerializeWriter.class), "writeString", "(Ljava/lang/String;)V");
mw.visitInsn(RETURN);
mw.visitMaxs(3, 16);
mw.visitEnd();
byte[] code = cw.toByteArray();
FileOutputStream fos = new FileOutputStream("Example.class");
fos.write(code);
fos.close();
MyClassLoader loader = new MyClassLoader(com.alibaba.fastjson.serializer.ObjectSerializer.class.getClassLoader());
Class<?> exampleClass = loader.defineClassF("DateSerializer", code, 0, code.length);
Method[] methods = exampleClass.getMethods();
Object instance = exampleClass.newInstance();
SerializeWriter out = new SerializeWriter();
JSONSerializer serializer = new JSONSerializer(out);
Entity obj = new Entity();
methods[0].invoke(instance, serializer, obj);
System.out.println(out.toString());
}
use of com.alibaba.fastjson.asm.ClassWriter 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;
}
Aggregations