content: package com.alibaba.json.test;
  
  import java.io.FileOutputStream;
  import java.lang.reflect.Method;
  
  import junit.framework.TestCase;
  
  import com.alibaba.fastjson.JSON;
  import com.alibaba.fastjson.asm.ClassWriter;
  import com.alibaba.fastjson.asm.MethodVisitor;
  import com.alibaba.fastjson.asm.Opcodes;
  import com.alibaba.fastjson.serializer.JSONSerializer;
  import com.alibaba.fastjson.serializer.SerializeWriter;
  import com.alibaba.json.test.benchmark.encode.EishayEncode;
  
  public class TestASM extends TestCase implements Opcodes {
  
      // public void test_0() throws Exception {
      //
      // ClassWriter cw = new ClassWriter(0);
      // cw.visit(V1_1, ACC_PUBLIC, "Example", null, "java/lang/Object", null);
      //
      // MethodVisitor mw = cw.visitMethod(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 = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
      // mw.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
      // mw.visitLdcInsn("Hello world!");
      // mw.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
      // mw.visitInsn(RETURN);
      // mw.visitMaxs(2, 2);
      // mw.visitEnd();
      // byte[] code = cw.toByteArray();
      // FileOutputStream fos = new FileOutputStream("Example.class");
      // fos.write(code);
      // fos.close();
      //
      // MyClassLoader loader = new MyClassLoader();
      //
      // Class exampleClass = loader.defineClassF("Example", code, 0, code.length);
      // exampleClass.getMethods()[0].invoke(null, new Object[] { null });
      // }
  
      public void test_asm() throws Exception {
          String text = JSON.toJSONString(EishayEncode.mediaContent);
          System.out.println(text);
      }
      
      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 = cw.visitMethod(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 = cw.visitMethod(ACC_PUBLIC, "write", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;)V", null, new String[] { "java/io/IOException" });
  
          mw.visitVarInsn(ALOAD, 1); // serializer
          mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JSONSerializer", "getWriter", "()Lcom/alibaba/fastjson/serializer/SerializeWriter;");
          mw.visitVarInsn(ASTORE, 3); // out
  
          mw.visitVarInsn(ALOAD, 2); // obj
          mw.visitTypeInsn(CHECKCAST, getCastType(Entity.class)); // serializer
          mw.visitVarInsn(ASTORE, 4); // obj
          
          mw.visitVarInsn(ALOAD, 3); // out
          mw.visitLdcInsn("{");
          mw.visitMethodInsn(INVOKEVIRTUAL, getCastType(SerializeWriter.class), "writeString", "(Ljava/lang/String;)V");
          
          mw.visitVarInsn(ALOAD, 3); // out
          mw.visitLdcInsn("\"id\":");
          mw.visitMethodInsn(INVOKEVIRTUAL, getCastType(SerializeWriter.class), "write", "(Ljava/lang/String;)V");
          
          mw.visitVarInsn(ALOAD, 3); // out
          mw.visitVarInsn(ALOAD, 4); // entity
          mw.visitMethodInsn(INVOKEVIRTUAL, getCastType(Entity.class), "getId", "()I");
          mw.visitMethodInsn(INVOKEVIRTUAL, getCastType(SerializeWriter.class), "writeInt", "(I)V");
          
          mw.visitVarInsn(ALOAD, 3); // out
          mw.visitLdcInsn("\",name\":");
          mw.visitMethodInsn(INVOKEVIRTUAL, getCastType(SerializeWriter.class), "write", "(Ljava/lang/String;)V");
          
          mw.visitVarInsn(ALOAD, 3); // out
          mw.visitVarInsn(ALOAD, 4); // entity
          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());
      }
  
      String getCastType(Class<?> returnType) {
          if (returnType.isPrimitive()) {
              return getWrapperType(returnType);
          } else {
              return getAsmTypeAsString(returnType, false);
          }
      }
  
      private String getWrapperType(Class<?> type) {
          if (Integer.TYPE.equals(type)) {
              return Integer.class.getCanonicalName().replaceAll("\\.", "/");
          } else if (Boolean.TYPE.equals(type)) {
              return Boolean.class.getCanonicalName().replaceAll("\\.", "/");
          } else if (Character.TYPE.equals(type)) {
              return Character.class.getCanonicalName().replaceAll("\\.", "/");
          } else if (Byte.TYPE.equals(type)) {
              return Byte.class.getCanonicalName().replaceAll("\\.", "/");
          } else if (Short.TYPE.equals(type)) {
              return Short.class.getCanonicalName().replaceAll("\\.", "/");
          } else if (Float.TYPE.equals(type)) {
              return Float.class.getCanonicalName().replaceAll("\\.", "/");
          } else if (Long.TYPE.equals(type)) {
              return Long.class.getCanonicalName().replaceAll("\\.", "/");
          } else if (Double.TYPE.equals(type)) {
              return Double.class.getCanonicalName().replaceAll("\\.", "/");
          } else if (Void.TYPE.equals(type)) {
              return Void.class.getCanonicalName().replaceAll("\\.", "/");
          }
  
          throw new IllegalStateException("Type: " + type.getCanonicalName() + " is not a primitive type");
      }
  
      public String getAsmTypeAsString(Class<?> parameterType, boolean wrap) {
          if (parameterType.isArray()) {
              if (parameterType.getComponentType().isPrimitive()) {
                  Class<?> componentType = parameterType.getComponentType();
                  return "[" + getPrimitiveLetter(componentType);
              } else {
                  return "[" + getAsmTypeAsString(parameterType.getComponentType(), true);
              }
          } else {
              if (!parameterType.isPrimitive()) {
                  String clsName = parameterType.getCanonicalName();
  
                  if (parameterType.isMemberClass()) {
                      int lastDot = clsName.lastIndexOf(".");
                      clsName = clsName.substring(0, lastDot) + "$" + clsName.substring(lastDot + 1);
                  }
                  if (wrap) {
                      return "L" + clsName.replaceAll("\\.", "/") + ";";
                  } else {
                      return clsName.replaceAll("\\.", "/");
                  }
              } else {
                  return getPrimitiveLetter(parameterType);
              }
          }
      }
  
      private String getPrimitiveLetter(Class<?> type) {
          if (Integer.TYPE.equals(type)) {
              return "I";
          } else if (Void.TYPE.equals(type)) {
              return "V";
          } else if (Boolean.TYPE.equals(type)) {
              return "Z";
          } else if (Character.TYPE.equals(type)) {
              return "C";
          } else if (Byte.TYPE.equals(type)) {
              return "B";
          } else if (Short.TYPE.equals(type)) {
              return "S";
          } else if (Float.TYPE.equals(type)) {
              return "F";
          } else if (Long.TYPE.equals(type)) {
              return "J";
          } else if (Double.TYPE.equals(type)) {
              return "D";
          }
  
          throw new IllegalStateException("Type: " + type.getCanonicalName() + " is not a primitive type");
      }
  
      public static class Entity {
  
          private int    id;
          private String name;
  
          public int getId() {
              return id;
          }
  
          public void setId(int id) {
              this.id = id;
          }
  
          public String getName() {
              return name;
          }
  
          public void setName(String name) {
              this.name = name;
          }
  
      }
  
      public static class MyClassLoader extends ClassLoader {
  
          public MyClassLoader(ClassLoader parent){
              super(parent);
          }
  
          public Class<?> defineClassF(String name, byte[] b, int off, int len) throws ClassFormatError {
              return defineClass(name, b, off, len, null);
          }
      }
  
      public static class Foo {
  
          public void execute() {
              System.out.println("Hello World");
          }
      }
  
  }
  