List<FieldInfo> getters = TypeUtils.computeGetters(clazz, aliasMap, false);
String className = getGenClassName(clazz);
ClassWriter cw = new ClassWriter();
cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, className, "java/lang/Object",
new String[] { "com/alibaba/fastjson/serializer/ObjectSerializer" });
{
FieldVisitor fw = cw.visitField(ACC_PRIVATE, "nature", getDesc(JavaBeanSerializer.class));
fw.visitEnd();
}
for (FieldInfo fieldInfo : getters) {
{
FieldVisitor fw = cw.visitField(ACC_PUBLIC, fieldInfo.getName() + "_asm_fieldPrefix",
"Ljava/lang/reflect/Type;");
fw.visitEnd();
}
FieldVisitor fw = cw.visitField(ACC_PUBLIC, fieldInfo.getName() + "_asm_fieldType",
"Ljava/lang/reflect/Type;");
fw.visitEnd();
}
MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
mw.visitVarInsn(ALOAD, 0);
mw.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
// mw.visitFieldInsn(PUTFIELD, context.getClassName(), fieldInfo.getName() + "_asm_prefix__", "[C");
for (FieldInfo fieldInfo : getters) {
mw.visitVarInsn(ALOAD, 0);
mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc(fieldInfo.getDeclaringClass())));
if (fieldInfo.getMethod() != null) {
mw.visitLdcInsn(fieldInfo.getMethod().getName());
mw.visitMethodInsn(INVOKESTATIC, getType(ASMUtils.class), "getMethodType",
"(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/reflect/Type;");
} else {
mw.visitLdcInsn(fieldInfo.getField().getName());
mw.visitMethodInsn(INVOKESTATIC, getType(ASMUtils.class), "getFieldType",
"(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/reflect/Type;");
}
mw.visitFieldInsn(PUTFIELD, className, fieldInfo.getName() + "_asm_fieldType", "Ljava/lang/reflect/Type;");
}
mw.visitInsn(RETURN);
mw.visitMaxs(4, 4);
mw.visitEnd();
{
Context context = new Context(className);
mw = cw.visitMethod(ACC_PUBLIC,
"write",
"(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;)V",
null, new String[] { "java/io/IOException" });
mw.visitVarInsn(ALOAD, context.serializer()); // serializer
mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "getWriter",
"()" + getDesc(SerializeWriter.class));
mw.visitVarInsn(ASTORE, context.var("out"));
JSONType jsonType = clazz.getAnnotation(JSONType.class);
if (jsonType == null || jsonType.alphabetic()) {
Label _else = new Label();
mw.visitVarInsn(ALOAD, context.var("out"));
mw.visitFieldInsn(GETSTATIC, getType(SerializerFeature.class), "SortField",
"L" + getType(SerializerFeature.class) + ";");
mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "isEnabled",
"(" + "L" + getType(SerializerFeature.class) + ";" + ")Z");
mw.visitJumpInsn(IFEQ, _else);
mw.visitVarInsn(ALOAD, 0);
mw.visitVarInsn(ALOAD, 1);
mw.visitVarInsn(ALOAD, 2);
mw.visitVarInsn(ALOAD, 3);
mw.visitVarInsn(ALOAD, context.paramFieldType());
mw.visitMethodInsn(INVOKEVIRTUAL, className, "write1",
"(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;)V");
mw.visitInsn(RETURN);
mw.visitLabel(_else);
}
mw.visitVarInsn(ALOAD, context.obj()); // obj
mw.visitTypeInsn(CHECKCAST, getType(clazz)); // serializer
mw.visitVarInsn(ASTORE, context.var("entity")); // obj
generateWriteMethod(clazz, mw, getters, context);
mw.visitInsn(RETURN);
mw.visitMaxs(5, context.getVariantCount() + 1);
mw.visitEnd();
}
List<FieldInfo> sortedGetters = TypeUtils.computeGetters(clazz, aliasMap, true);
{
// sortField support
Context context = new Context(className);
mw = cw.visitMethod(ACC_PUBLIC,
"write1",
"(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;)V",
null, new String[] { "java/io/IOException" });
mw.visitVarInsn(ALOAD, context.serializer()); // serializer
mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "getWriter",
"()" + getDesc(SerializeWriter.class));
mw.visitVarInsn(ASTORE, context.var("out"));
mw.visitVarInsn(ALOAD, context.obj()); // obj
mw.visitTypeInsn(CHECKCAST, getType(clazz)); // serializer
mw.visitVarInsn(ASTORE, context.var("entity")); // obj
generateWriteMethod(clazz, mw, sortedGetters, context);
mw.visitInsn(RETURN);
mw.visitMaxs(5, context.getVariantCount() + 1);
mw.visitEnd();
}
// writeAsArray
{
Context context = new Context(className);
mw = cw.visitMethod(ACC_PUBLIC,
"writeAsArray",
"(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;)V",
null, new String[] { "java/io/IOException" });
mw.visitVarInsn(ALOAD, context.serializer()); // serializer
mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "getWriter",
"()" + getDesc(SerializeWriter.class));
mw.visitVarInsn(ASTORE, context.var("out"));
mw.visitVarInsn(ALOAD, context.obj()); // obj
mw.visitTypeInsn(CHECKCAST, getType(clazz)); // serializer
mw.visitVarInsn(ASTORE, context.var("entity")); // obj
generateWriteAsArray(clazz, mw, sortedGetters, context);
mw.visitInsn(RETURN);
mw.visitMaxs(5, context.getVariantCount() + 1);
mw.visitEnd();
}
byte[] code = cw.toByteArray();
//
// org.apache.commons.io.IOUtils.write(code, new java.io.FileOutputStream(
// "/usr/alibaba/workspace-3.7/fastjson-asm/target/classes/"
// + className + ".class"));