PageRenderTime 57ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/java/com/alibaba/fastjson/serializer/ASMSerializerFactory.java

https://bitbucket.org/xiejuntao/xdesktop
Java | 1179 lines | 885 code | 260 blank | 34 comment | 153 complexity | aca7597cca92aff3e3bd0e15a1f1c418 MD5 | raw file
  1. package com.alibaba.fastjson.serializer;
  2. import static com.alibaba.fastjson.util.ASMUtils.getDesc;
  3. import static com.alibaba.fastjson.util.ASMUtils.getType;
  4. import java.lang.reflect.Method;
  5. import java.lang.reflect.Modifier;
  6. import java.lang.reflect.ParameterizedType;
  7. import java.lang.reflect.Type;
  8. import java.math.BigDecimal;
  9. import java.util.Collection;
  10. import java.util.HashMap;
  11. import java.util.List;
  12. import java.util.Map;
  13. import java.util.concurrent.atomic.AtomicLong;
  14. import com.alibaba.fastjson.JSONException;
  15. import com.alibaba.fastjson.annotation.JSONField;
  16. import com.alibaba.fastjson.asm.ClassWriter;
  17. import com.alibaba.fastjson.asm.FieldVisitor;
  18. import com.alibaba.fastjson.asm.Label;
  19. import com.alibaba.fastjson.asm.MethodVisitor;
  20. import com.alibaba.fastjson.asm.Opcodes;
  21. import com.alibaba.fastjson.util.ASMClassLoader;
  22. import com.alibaba.fastjson.util.ASMUtils;
  23. import com.alibaba.fastjson.util.FieldInfo;
  24. import com.alibaba.fastjson.util.TypeUtils;
  25. public class ASMSerializerFactory implements Opcodes {
  26. private ASMClassLoader classLoader = new ASMClassLoader();
  27. public ObjectSerializer createJavaBeanSerializer(Class<?> clazz) throws Exception {
  28. return createJavaBeanSerializer(clazz, (Map<String, String>) null);
  29. }
  30. private final AtomicLong seed = new AtomicLong();
  31. public String getGenClassName(Class<?> clazz) {
  32. return "Serializer_" + seed.incrementAndGet();
  33. }
  34. public boolean isExternalClass(Class<?> clazz) {
  35. return classLoader.isExternalClass(clazz);
  36. }
  37. static class Context {
  38. private final String className;
  39. public Context(String className){
  40. this.className = className;
  41. }
  42. private int variantIndex = 8;
  43. private Map<String, Integer> variants = new HashMap<String, Integer>();
  44. public int serializer() {
  45. return 1;
  46. }
  47. public String getClassName() {
  48. return className;
  49. }
  50. public int obj() {
  51. return 2;
  52. }
  53. public int paramFieldName() {
  54. return 3;
  55. }
  56. public int paramFieldType() {
  57. return 4;
  58. }
  59. public int fieldName() {
  60. return 5;
  61. }
  62. public int original() {
  63. return 6;
  64. }
  65. public int processValue() {
  66. return 7;
  67. }
  68. public int getVariantCount() {
  69. return variantIndex;
  70. }
  71. public int var(String name) {
  72. Integer i = variants.get(name);
  73. if (i == null) {
  74. variants.put(name, variantIndex++);
  75. }
  76. i = variants.get(name);
  77. return i.intValue();
  78. }
  79. public int var(String name, int increment) {
  80. Integer i = variants.get(name);
  81. if (i == null) {
  82. variants.put(name, variantIndex);
  83. variantIndex += increment;
  84. }
  85. i = variants.get(name);
  86. return i.intValue();
  87. }
  88. }
  89. public ObjectSerializer createJavaBeanSerializer(Class<?> clazz, Map<String, String> aliasMap) throws Exception {
  90. if (clazz.isPrimitive()) {
  91. throw new JSONException("unsupportd class " + clazz.getName());
  92. }
  93. List<FieldInfo> getters = TypeUtils.computeGetters(clazz, aliasMap, false);
  94. String className = getGenClassName(clazz);
  95. ClassWriter cw = new ClassWriter();
  96. cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, className, "java/lang/Object",
  97. new String[] { "com/alibaba/fastjson/serializer/ObjectSerializer" });
  98. {
  99. FieldVisitor fw = cw.visitField(ACC_PRIVATE, "nature", getDesc(JavaBeanSerializer.class));
  100. fw.visitEnd();
  101. }
  102. for (FieldInfo fieldInfo : getters) {
  103. {
  104. FieldVisitor fw = cw.visitField(ACC_PUBLIC, fieldInfo.getName() + "_asm_fieldPrefix",
  105. "Ljava/lang/reflect/Type;");
  106. fw.visitEnd();
  107. }
  108. FieldVisitor fw = cw.visitField(ACC_PUBLIC, fieldInfo.getName() + "_asm_fieldType",
  109. "Ljava/lang/reflect/Type;");
  110. fw.visitEnd();
  111. }
  112. MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
  113. mw.visitVarInsn(ALOAD, 0);
  114. mw.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
  115. // mw.visitFieldInsn(PUTFIELD, context.getClassName(), fieldInfo.getName() + "_asm_prefix__", "[C");
  116. for (FieldInfo fieldInfo : getters) {
  117. mw.visitVarInsn(ALOAD, 0);
  118. mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc(fieldInfo.getDeclaringClass())));
  119. if (fieldInfo.getMethod() != null) {
  120. mw.visitLdcInsn(fieldInfo.getMethod().getName());
  121. mw.visitMethodInsn(INVOKESTATIC, getType(ASMUtils.class), "getMethodType",
  122. "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/reflect/Type;");
  123. } else {
  124. mw.visitLdcInsn(fieldInfo.getField().getName());
  125. mw.visitMethodInsn(INVOKESTATIC, getType(ASMUtils.class), "getFieldType",
  126. "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/reflect/Type;");
  127. }
  128. mw.visitFieldInsn(PUTFIELD, className, fieldInfo.getName() + "_asm_fieldType", "Ljava/lang/reflect/Type;");
  129. }
  130. mw.visitInsn(RETURN);
  131. mw.visitMaxs(4, 4);
  132. mw.visitEnd();
  133. {
  134. Context context = new Context(className);
  135. mw = cw.visitMethod(ACC_PUBLIC,
  136. "write",
  137. "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;)V",
  138. null, new String[] { "java/io/IOException" });
  139. mw.visitVarInsn(ALOAD, context.serializer()); // serializer
  140. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "getWriter",
  141. "()" + getDesc(SerializeWriter.class));
  142. mw.visitVarInsn(ASTORE, context.var("out"));
  143. Label _else = new Label();
  144. mw.visitVarInsn(ALOAD, context.var("out"));
  145. mw.visitFieldInsn(GETSTATIC, getType(SerializerFeature.class), "SortField",
  146. "L" + getType(SerializerFeature.class) + ";");
  147. mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "isEnabled",
  148. "(" + "L" + getType(SerializerFeature.class) + ";" + ")Z");
  149. mw.visitJumpInsn(IFEQ, _else);
  150. mw.visitVarInsn(ALOAD, 0);
  151. mw.visitVarInsn(ALOAD, 1);
  152. mw.visitVarInsn(ALOAD, 2);
  153. mw.visitVarInsn(ALOAD, 3);
  154. mw.visitVarInsn(ALOAD, context.paramFieldType());
  155. mw.visitMethodInsn(INVOKEVIRTUAL, className, "write1",
  156. "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;)V");
  157. mw.visitInsn(RETURN);
  158. mw.visitLabel(_else);
  159. mw.visitVarInsn(ALOAD, context.obj()); // obj
  160. mw.visitTypeInsn(CHECKCAST, getType(clazz)); // serializer
  161. mw.visitVarInsn(ASTORE, context.var("entity")); // obj
  162. generateWriteMethod(clazz, mw, getters, context);
  163. mw.visitInsn(RETURN);
  164. mw.visitMaxs(5, context.getVariantCount() + 1);
  165. mw.visitEnd();
  166. }
  167. {
  168. List<FieldInfo> sortedGetters = TypeUtils.computeGetters(clazz, aliasMap, true);
  169. // sortField support
  170. Context context = new Context(className);
  171. mw = cw.visitMethod(ACC_PUBLIC,
  172. "write1",
  173. "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;)V",
  174. null, new String[] { "java/io/IOException" });
  175. mw.visitVarInsn(ALOAD, context.serializer()); // serializer
  176. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "getWriter",
  177. "()" + getDesc(SerializeWriter.class));
  178. mw.visitVarInsn(ASTORE, context.var("out"));
  179. mw.visitVarInsn(ALOAD, context.obj()); // obj
  180. mw.visitTypeInsn(CHECKCAST, getType(clazz)); // serializer
  181. mw.visitVarInsn(ASTORE, context.var("entity")); // obj
  182. generateWriteMethod(clazz, mw, sortedGetters, context);
  183. mw.visitInsn(RETURN);
  184. mw.visitMaxs(5, context.getVariantCount() + 1);
  185. mw.visitEnd();
  186. }
  187. byte[] code = cw.toByteArray();
  188. //
  189. // org.apache.commons.io.IOUtils.write(code, new java.io.FileOutputStream(
  190. // "/usr/alibaba/workspace-3.7/fastjson-asm/target/classes/"
  191. // + className + ".class"));
  192. Class<?> exampleClass = classLoader.defineClassPublic(className, code, 0, code.length);
  193. Object instance = exampleClass.newInstance();
  194. return (ObjectSerializer) instance;
  195. }
  196. private void generateWriteMethod(Class<?> clazz, MethodVisitor mw, List<FieldInfo> getters, Context context)
  197. throws Exception {
  198. Label end = new Label();
  199. int size = getters.size();
  200. {
  201. // 格式化输出不走asm 优化
  202. Label endFormat_ = new Label();
  203. Label notNull_ = new Label();
  204. mw.visitVarInsn(ALOAD, context.var("out"));
  205. mw.visitFieldInsn(GETSTATIC, getType(SerializerFeature.class), "PrettyFormat",
  206. "L" + getType(SerializerFeature.class) + ";");
  207. mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "isEnabled",
  208. "(" + "L" + getType(SerializerFeature.class) + ";" + ")Z");
  209. mw.visitJumpInsn(IFEQ, endFormat_);
  210. mw.visitVarInsn(ALOAD, 0);
  211. mw.visitFieldInsn(GETFIELD, context.getClassName(), "nature", getDesc(JavaBeanSerializer.class));
  212. mw.visitJumpInsn(IFNONNULL, notNull_);
  213. initNature(clazz, mw, context);
  214. // /////
  215. mw.visitLabel(notNull_);
  216. mw.visitVarInsn(ALOAD, 0);
  217. mw.visitFieldInsn(GETFIELD, context.getClassName(), "nature", getDesc(JavaBeanSerializer.class));
  218. mw.visitVarInsn(ALOAD, 1);
  219. mw.visitVarInsn(ALOAD, 2);
  220. mw.visitVarInsn(ALOAD, 3);
  221. mw.visitVarInsn(ALOAD, 4);
  222. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JavaBeanSerializer.class), "write",
  223. "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;)V");
  224. mw.visitInsn(RETURN);
  225. mw.visitLabel(endFormat_);
  226. }
  227. {
  228. // if (serializer.containsReference(object)) {
  229. Label endRef_ = new Label();
  230. Label notNull_ = new Label();
  231. mw.visitVarInsn(ALOAD, context.serializer());
  232. mw.visitVarInsn(ALOAD, context.obj());
  233. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "containsReference",
  234. "(Ljava/lang/Object;)Z");
  235. mw.visitJumpInsn(IFEQ, endRef_);
  236. mw.visitVarInsn(ALOAD, 0);
  237. mw.visitFieldInsn(GETFIELD, context.getClassName(), "nature", getDesc(JavaBeanSerializer.class));
  238. mw.visitJumpInsn(IFNONNULL, notNull_);
  239. initNature(clazz, mw, context);
  240. // /////
  241. mw.visitLabel(notNull_);
  242. mw.visitVarInsn(ALOAD, 0);
  243. mw.visitFieldInsn(GETFIELD, context.getClassName(), "nature", getDesc(JavaBeanSerializer.class));
  244. mw.visitVarInsn(ALOAD, 1);
  245. mw.visitVarInsn(ALOAD, 2);
  246. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JavaBeanSerializer.class), "writeReference",
  247. "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;)V");
  248. mw.visitInsn(RETURN);
  249. mw.visitLabel(endRef_);
  250. }
  251. {
  252. mw.visitVarInsn(ALOAD, context.serializer());
  253. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "getContext",
  254. "()Lcom/alibaba/fastjson/serializer/SerialContext;");
  255. mw.visitVarInsn(ASTORE, context.var("parent"));
  256. mw.visitVarInsn(ALOAD, context.serializer());
  257. mw.visitVarInsn(ALOAD, context.var("parent"));
  258. mw.visitVarInsn(ALOAD, context.obj());
  259. mw.visitVarInsn(ALOAD, context.paramFieldName());
  260. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "setContext",
  261. "(Lcom/alibaba/fastjson/serializer/SerialContext;Ljava/lang/Object;Ljava/lang/Object;)V");
  262. }
  263. // SEPERATO
  264. {
  265. Label end_ = new Label();
  266. Label else_ = new Label();
  267. Label writeClass_ = new Label();
  268. // mw.visitVarInsn(ALOAD, context.var("out"));
  269. // mw.visitFieldInsn(GETSTATIC, getType(SerializerFeature.class), "WriteClassName",
  270. // "L" + getType(SerializerFeature.class) + ";");
  271. // mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "isEnabled",
  272. // "(" + "L" + getType(SerializerFeature.class) + ";" + ")Z");
  273. // mw.visitJumpInsn(IFEQ, else_);
  274. mw.visitVarInsn(ALOAD, context.serializer());
  275. mw.visitVarInsn(ALOAD, context.paramFieldType());
  276. mw.visitVarInsn(ALOAD, context.obj());
  277. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "isWriteClassName",
  278. "(Ljava/lang/reflect/Type;Ljava/lang/Object;)Z");
  279. mw.visitJumpInsn(IFEQ, else_);
  280. // mw.visitVarInsn(ALOAD, context.paramFieldType());
  281. // mw.visitJumpInsn(IFNULL, writeClass_);
  282. // IFNULL
  283. mw.visitVarInsn(ALOAD, context.paramFieldType());
  284. mw.visitVarInsn(ALOAD, context.obj());
  285. mw.visitMethodInsn(INVOKEVIRTUAL, getType(Object.class), "getClass", "()Ljava/lang/Class;");
  286. mw.visitJumpInsn(IF_ACMPEQ, else_);
  287. mw.visitLabel(writeClass_);
  288. mw.visitVarInsn(ALOAD, context.var("out"));
  289. mw.visitLdcInsn("{\"@type\":\"" + clazz.getName() + "\"");
  290. mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "write", "(Ljava/lang/String;)V");
  291. mw.visitVarInsn(BIPUSH, ',');
  292. mw.visitJumpInsn(GOTO, end_);
  293. mw.visitLabel(else_);
  294. mw.visitVarInsn(BIPUSH, '{');
  295. mw.visitLabel(end_);
  296. }
  297. mw.visitVarInsn(ISTORE, context.var("seperator"));
  298. for (int i = 0; i < size; ++i) {
  299. FieldInfo property = getters.get(i);
  300. Class<?> propertyClass = property.getFieldClass();
  301. mw.visitLdcInsn(property.getName());
  302. mw.visitVarInsn(ASTORE, context.fieldName());
  303. if (propertyClass == byte.class) {
  304. _byte(clazz, mw, property, context);
  305. } else if (propertyClass == short.class) {
  306. _short(clazz, mw, property, context);
  307. } else if (propertyClass == int.class) {
  308. _int(clazz, mw, property, context);
  309. } else if (propertyClass == long.class) {
  310. _long(clazz, mw, property, context);
  311. } else if (propertyClass == float.class) {
  312. _float(clazz, mw, property, context);
  313. } else if (propertyClass == double.class) {
  314. _double(clazz, mw, property, context);
  315. } else if (propertyClass == boolean.class) {
  316. _boolean(clazz, mw, property, context);
  317. } else if (propertyClass == char.class) {
  318. _char(clazz, mw, property, context);
  319. } else if (propertyClass == String.class) {
  320. _string(clazz, mw, property, context);
  321. } else if (propertyClass == BigDecimal.class) {
  322. _decimal(clazz, mw, property, context);
  323. } else if (List.class.isAssignableFrom(propertyClass)) {
  324. _list(clazz, mw, property, context);
  325. // _object(clazz, mw, property, context);
  326. } else if (propertyClass.isEnum()) {
  327. _enum(clazz, mw, property, context);
  328. } else {
  329. _object(clazz, mw, property, context);
  330. }
  331. }
  332. Label _if = new Label();
  333. Label _else = new Label();
  334. Label _end_if = new Label();
  335. mw.visitLabel(_if);
  336. // if (seperator == '{')
  337. mw.visitVarInsn(ILOAD, context.var("seperator"));
  338. mw.visitIntInsn(BIPUSH, '{');
  339. mw.visitJumpInsn(IF_ICMPNE, _else);
  340. mw.visitVarInsn(ALOAD, context.var("out"));
  341. mw.visitLdcInsn("{}");
  342. mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "write", "(Ljava/lang/String;)V");
  343. mw.visitJumpInsn(GOTO, _end_if);
  344. mw.visitLabel(_else);
  345. mw.visitVarInsn(ALOAD, context.var("out"));
  346. mw.visitVarInsn(BIPUSH, '}');
  347. mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "write", "(C)V");
  348. mw.visitLabel(_end_if);
  349. mw.visitLabel(end);
  350. mw.visitVarInsn(ALOAD, context.serializer());
  351. mw.visitVarInsn(ALOAD, context.var("parent"));
  352. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "setContext",
  353. "(Lcom/alibaba/fastjson/serializer/SerialContext;)V");
  354. }
  355. private void initNature(Class<?> clazz, MethodVisitor mw, Context context) {
  356. mw.visitVarInsn(ALOAD, 0);
  357. mw.visitTypeInsn(NEW, getType(JavaBeanSerializer.class));
  358. mw.visitInsn(DUP);
  359. mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc(clazz)));
  360. mw.visitMethodInsn(INVOKESPECIAL, getType(JavaBeanSerializer.class), "<init>", "(" + getDesc(Class.class)
  361. + ")V");
  362. mw.visitFieldInsn(PUTFIELD, context.getClassName(), "nature", getDesc(JavaBeanSerializer.class));
  363. }
  364. private void _object(Class<?> clazz, MethodVisitor mw, FieldInfo property, Context context) {
  365. Label _end = new Label();
  366. _nameApply(mw, property, context, _end);
  367. _get(mw, context, property);
  368. mw.visitVarInsn(ASTORE, context.var("object"));
  369. _filters(mw, property, context, _end);
  370. _writeObject(mw, property, context, _end);
  371. mw.visitLabel(_end);
  372. }
  373. private void _enum(Class<?> clazz, MethodVisitor mw, FieldInfo property, Context context) {
  374. boolean writeEnumUsingToString = false;
  375. JSONField annotation = property.getAnnotation(JSONField.class);
  376. if (annotation != null) {
  377. for (SerializerFeature feature : annotation.serialzeFeatures()) {
  378. if (feature == SerializerFeature.WriteEnumUsingToString) {
  379. writeEnumUsingToString = true;
  380. }
  381. }
  382. }
  383. Label _not_null = new Label();
  384. Label _end_if = new Label();
  385. Label _end = new Label();
  386. _nameApply(mw, property, context, _end);
  387. _get(mw, context, property);
  388. mw.visitTypeInsn(CHECKCAST, getType(Enum.class)); // cast
  389. mw.visitVarInsn(ASTORE, context.var("enum"));
  390. _filters(mw, property, context, _end);
  391. mw.visitVarInsn(ALOAD, context.var("enum"));
  392. mw.visitJumpInsn(IFNONNULL, _not_null);
  393. _if_write_null(mw, property, context);
  394. mw.visitJumpInsn(GOTO, _end_if);
  395. mw.visitLabel(_not_null);
  396. mw.visitVarInsn(ALOAD, context.var("out"));
  397. mw.visitVarInsn(ILOAD, context.var("seperator"));
  398. mw.visitVarInsn(ALOAD, context.fieldName());
  399. mw.visitVarInsn(ALOAD, context.var("enum"));
  400. if (writeEnumUsingToString) {
  401. mw.visitMethodInsn(INVOKEVIRTUAL, getType(Object.class), "toString", "()Ljava/lang/String;");
  402. mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldValue",
  403. "(CLjava/lang/String;Ljava/lang/String;)V");
  404. } else {
  405. mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldValue",
  406. "(CLjava/lang/String;L" + getType(Enum.class) + ";)V");
  407. }
  408. _seperator(mw, context);
  409. mw.visitLabel(_end_if);
  410. mw.visitLabel(_end);
  411. }
  412. private void _long(Class<?> clazz, MethodVisitor mw, FieldInfo property, Context context) {
  413. Label _end = new Label();
  414. _nameApply(mw, property, context, _end);
  415. _get(mw, context, property);
  416. mw.visitVarInsn(LSTORE, context.var("long", 2));
  417. _filters(mw, property, context, _end);
  418. mw.visitVarInsn(ALOAD, context.var("out"));
  419. mw.visitVarInsn(ILOAD, context.var("seperator"));
  420. mw.visitVarInsn(ALOAD, context.fieldName());
  421. mw.visitVarInsn(LLOAD, context.var("long", 2));
  422. mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldValue", "(CLjava/lang/String;J)V");
  423. _seperator(mw, context);
  424. mw.visitLabel(_end);
  425. }
  426. private void _float(Class<?> clazz, MethodVisitor mw, FieldInfo property, Context context) {
  427. Label _end = new Label();
  428. _nameApply(mw, property, context, _end);
  429. _get(mw, context, property);
  430. mw.visitVarInsn(FSTORE, context.var("float"));
  431. _filters(mw, property, context, _end);
  432. mw.visitVarInsn(ALOAD, context.var("out"));
  433. mw.visitVarInsn(ILOAD, context.var("seperator"));
  434. mw.visitVarInsn(ALOAD, context.fieldName());
  435. mw.visitVarInsn(FLOAD, context.var("float"));
  436. mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldValue", "(CLjava/lang/String;F)V");
  437. _seperator(mw, context);
  438. mw.visitLabel(_end);
  439. }
  440. private void _double(Class<?> clazz, MethodVisitor mw, FieldInfo property, Context context) {
  441. Label _end = new Label();
  442. _nameApply(mw, property, context, _end);
  443. _get(mw, context, property);
  444. mw.visitVarInsn(DSTORE, context.var("double", 2));
  445. _filters(mw, property, context, _end);
  446. mw.visitVarInsn(ALOAD, context.var("out"));
  447. mw.visitVarInsn(ILOAD, context.var("seperator"));
  448. mw.visitVarInsn(ALOAD, context.fieldName());
  449. mw.visitVarInsn(DLOAD, context.var("double", 2));
  450. mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldValue", "(CLjava/lang/String;D)V");
  451. _seperator(mw, context);
  452. mw.visitLabel(_end);
  453. }
  454. private void _char(Class<?> clazz, MethodVisitor mw, FieldInfo property, Context context) {
  455. Label _end = new Label();
  456. _nameApply(mw, property, context, _end);
  457. _get(mw, context, property);
  458. mw.visitVarInsn(ISTORE, context.var("char"));
  459. _filters(mw, property, context, _end);
  460. mw.visitVarInsn(ALOAD, context.var("out"));
  461. mw.visitVarInsn(ILOAD, context.var("seperator"));
  462. mw.visitVarInsn(ALOAD, context.fieldName());
  463. mw.visitVarInsn(ILOAD, context.var("char"));
  464. mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldValue", "(CLjava/lang/String;C)V");
  465. _seperator(mw, context);
  466. mw.visitLabel(_end);
  467. }
  468. private void _boolean(Class<?> clazz, MethodVisitor mw, FieldInfo property, Context context) {
  469. Label _end = new Label();
  470. _nameApply(mw, property, context, _end);
  471. _get(mw, context, property);
  472. mw.visitVarInsn(ISTORE, context.var("boolean"));
  473. _filters(mw, property, context, _end);
  474. mw.visitVarInsn(ALOAD, context.var("out"));
  475. mw.visitVarInsn(ILOAD, context.var("seperator"));
  476. mw.visitVarInsn(ALOAD, context.fieldName());
  477. mw.visitVarInsn(ILOAD, context.var("boolean"));
  478. mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldValue", "(CLjava/lang/String;Z)V");
  479. _seperator(mw, context);
  480. mw.visitLabel(_end);
  481. }
  482. private void _get(MethodVisitor mw, Context context, FieldInfo property) {
  483. Method method = property.getMethod();
  484. if (method != null) {
  485. mw.visitVarInsn(ALOAD, context.var("entity"));
  486. mw.visitMethodInsn(INVOKEVIRTUAL, getType(method.getDeclaringClass()), method.getName(), getDesc(method));
  487. } else {
  488. mw.visitVarInsn(ALOAD, context.var("entity"));
  489. mw.visitFieldInsn(GETFIELD, getType(property.getDeclaringClass()), property.getName(),
  490. getDesc(property.getFieldClass()));
  491. }
  492. }
  493. private void _byte(Class<?> clazz, MethodVisitor mw, FieldInfo property, Context context) {
  494. Label _end = new Label();
  495. _nameApply(mw, property, context, _end);
  496. _get(mw, context, property);
  497. mw.visitVarInsn(ISTORE, context.var("byte"));
  498. _filters(mw, property, context, _end);
  499. mw.visitVarInsn(ALOAD, context.var("out"));
  500. mw.visitVarInsn(ILOAD, context.var("seperator"));
  501. mw.visitVarInsn(ALOAD, context.fieldName());
  502. mw.visitVarInsn(ILOAD, context.var("byte"));
  503. mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldValue", "(CLjava/lang/String;I)V");
  504. _seperator(mw, context);
  505. mw.visitLabel(_end);
  506. }
  507. private void _short(Class<?> clazz, MethodVisitor mw, FieldInfo property, Context context) {
  508. Label _end = new Label();
  509. _nameApply(mw, property, context, _end);
  510. _get(mw, context, property);
  511. mw.visitVarInsn(ISTORE, context.var("short"));
  512. _filters(mw, property, context, _end);
  513. mw.visitVarInsn(ALOAD, context.var("out"));
  514. mw.visitVarInsn(ILOAD, context.var("seperator"));
  515. mw.visitVarInsn(ALOAD, context.fieldName());
  516. mw.visitVarInsn(ILOAD, context.var("short"));
  517. mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldValue", "(CLjava/lang/String;I)V");
  518. _seperator(mw, context);
  519. mw.visitLabel(_end);
  520. }
  521. private void _int(Class<?> clazz, MethodVisitor mw, FieldInfo property, Context context) {
  522. Label _end = new Label();
  523. _nameApply(mw, property, context, _end);
  524. _get(mw, context, property);
  525. mw.visitVarInsn(ISTORE, context.var("int"));
  526. _filters(mw, property, context, _end);
  527. mw.visitVarInsn(ALOAD, context.var("out"));
  528. mw.visitVarInsn(ILOAD, context.var("seperator"));
  529. mw.visitVarInsn(ALOAD, context.fieldName());
  530. mw.visitVarInsn(ILOAD, context.var("int"));
  531. mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldValue", "(CLjava/lang/String;I)V");
  532. _seperator(mw, context);
  533. mw.visitLabel(_end);
  534. }
  535. private void _decimal(Class<?> clazz, MethodVisitor mw, FieldInfo property, Context context) {
  536. Label _end = new Label();
  537. _nameApply(mw, property, context, _end);
  538. _get(mw, context, property);
  539. mw.visitVarInsn(ASTORE, context.var("decimal"));
  540. _filters(mw, property, context, _end);
  541. Label _if = new Label();
  542. Label _else = new Label();
  543. Label _end_if = new Label();
  544. mw.visitLabel(_if);
  545. // if (decimalValue == null) {
  546. mw.visitVarInsn(ALOAD, context.var("decimal"));
  547. mw.visitJumpInsn(IFNONNULL, _else);
  548. _if_write_null(mw, property, context);
  549. mw.visitJumpInsn(GOTO, _end_if);
  550. mw.visitLabel(_else); // else { out.writeFieldValue(seperator, fieldName, fieldValue)
  551. mw.visitVarInsn(ALOAD, context.var("out"));
  552. mw.visitVarInsn(ILOAD, context.var("seperator"));
  553. mw.visitVarInsn(ALOAD, context.fieldName());
  554. mw.visitVarInsn(ALOAD, context.var("decimal"));
  555. mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldValue",
  556. "(CLjava/lang/String;Ljava/math/BigDecimal;)V");
  557. _seperator(mw, context);
  558. mw.visitJumpInsn(GOTO, _end_if);
  559. mw.visitLabel(_end_if);
  560. mw.visitLabel(_end);
  561. }
  562. private void _string(Class<?> clazz, MethodVisitor mw, FieldInfo property, Context context) {
  563. Label _end = new Label();
  564. _nameApply(mw, property, context, _end);
  565. _get(mw, context, property);
  566. mw.visitVarInsn(ASTORE, context.var("string"));
  567. _filters(mw, property, context, _end);
  568. Label _else = new Label();
  569. Label _end_if = new Label();
  570. // if (value == null) {
  571. mw.visitVarInsn(ALOAD, context.var("string"));
  572. mw.visitJumpInsn(IFNONNULL, _else);
  573. _if_write_null(mw, property, context);
  574. mw.visitJumpInsn(GOTO, _end_if);
  575. mw.visitLabel(_else); // else { out.writeFieldValue(seperator, fieldName, fieldValue)
  576. mw.visitVarInsn(ALOAD, context.var("out"));
  577. mw.visitVarInsn(ILOAD, context.var("seperator"));
  578. mw.visitVarInsn(ALOAD, context.fieldName());
  579. mw.visitVarInsn(ALOAD, context.var("string"));
  580. mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldValue",
  581. "(CLjava/lang/String;Ljava/lang/String;)V");
  582. _seperator(mw, context);
  583. mw.visitLabel(_end_if);
  584. mw.visitLabel(_end);
  585. }
  586. private void _list(Class<?> clazz, MethodVisitor mw, FieldInfo property, Context context) {
  587. Type propertyType = property.getFieldType();
  588. Type elementType;
  589. if (propertyType instanceof Class) {
  590. elementType = Object.class;
  591. } else {
  592. elementType = ((ParameterizedType) propertyType).getActualTypeArguments()[0];
  593. }
  594. Class<?> elementClass = null;
  595. if (elementType instanceof Class<?>) {
  596. elementClass = (Class<?>) elementType;
  597. }
  598. Label _end = new Label();
  599. Label _if = new Label();
  600. Label _else = new Label();
  601. Label _end_if = new Label();
  602. mw.visitLabel(_if);
  603. _nameApply(mw, property, context, _end);
  604. _get(mw, context, property);
  605. mw.visitTypeInsn(CHECKCAST, getType(List.class)); // cast
  606. mw.visitVarInsn(ASTORE, context.var("list"));
  607. _filters(mw, property, context, _end);
  608. mw.visitVarInsn(ALOAD, context.var("list"));
  609. mw.visitJumpInsn(IFNONNULL, _else);
  610. _if_write_null(mw, property, context);
  611. mw.visitJumpInsn(GOTO, _end_if);
  612. mw.visitLabel(_else); // else {
  613. mw.visitVarInsn(ALOAD, context.var("out"));
  614. mw.visitVarInsn(ILOAD, context.var("seperator"));
  615. mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "write", "(C)V");
  616. mw.visitVarInsn(ALOAD, context.var("out"));
  617. mw.visitVarInsn(ALOAD, context.fieldName());
  618. mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldName", "(Ljava/lang/String;)V");
  619. //
  620. mw.visitVarInsn(ALOAD, context.var("list"));
  621. mw.visitMethodInsn(INVOKEINTERFACE, getType(List.class), "size", "()I");
  622. mw.visitVarInsn(ISTORE, context.var("int"));
  623. Label _if_3 = new Label();
  624. Label _else_3 = new Label();
  625. Label _end_if_3 = new Label();
  626. mw.visitLabel(_if_3);
  627. mw.visitVarInsn(ILOAD, context.var("int"));
  628. mw.visitInsn(ICONST_0);
  629. mw.visitJumpInsn(IF_ICMPNE, _else_3);
  630. mw.visitVarInsn(ALOAD, context.var("out"));
  631. mw.visitLdcInsn("[]");
  632. mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "write", "(Ljava/lang/String;)V");
  633. mw.visitJumpInsn(GOTO, _end_if_3);
  634. mw.visitLabel(_else_3);
  635. {
  636. mw.visitVarInsn(ALOAD, context.serializer());
  637. mw.visitVarInsn(ALOAD, context.var("list"));
  638. mw.visitVarInsn(ALOAD, context.fieldName());
  639. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "setContext",
  640. "(Ljava/lang/Object;Ljava/lang/Object;)V");
  641. }
  642. {
  643. mw.visitVarInsn(ALOAD, context.var("out"));
  644. mw.visitVarInsn(BIPUSH, '[');
  645. mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "write", "(C)V");
  646. // list_serializer = null
  647. mw.visitInsn(ACONST_NULL);
  648. mw.visitTypeInsn(CHECKCAST, getType(ObjectSerializer.class)); // cast to string
  649. mw.visitVarInsn(ASTORE, context.var("list_ser"));
  650. Label _for = new Label();
  651. Label _end_for = new Label();
  652. mw.visitInsn(ICONST_0);
  653. mw.visitVarInsn(ISTORE, context.var("i"));
  654. // for (; i < list.size() -1; ++i) {
  655. mw.visitLabel(_for);
  656. mw.visitVarInsn(ILOAD, context.var("i"));
  657. mw.visitVarInsn(ILOAD, context.var("int"));
  658. mw.visitInsn(ICONST_1);
  659. mw.visitInsn(ISUB);
  660. mw.visitJumpInsn(IF_ICMPGE, _end_for); // i < list.size - 1
  661. if (elementType == String.class) {
  662. // out.write((String)list.get(i));
  663. mw.visitVarInsn(ALOAD, context.var("out"));
  664. mw.visitVarInsn(ALOAD, context.var("list"));
  665. mw.visitVarInsn(ILOAD, context.var("i"));
  666. mw.visitMethodInsn(INVOKEINTERFACE, getType(List.class), "get", "(I)Ljava/lang/Object;");
  667. mw.visitTypeInsn(CHECKCAST, getType(String.class)); // cast to string
  668. mw.visitVarInsn(BIPUSH, ',');
  669. mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeString",
  670. "(Ljava/lang/String;C)V");
  671. } else {
  672. mw.visitVarInsn(ALOAD, context.serializer());
  673. mw.visitVarInsn(ALOAD, context.var("list"));
  674. mw.visitVarInsn(ILOAD, context.var("i"));
  675. mw.visitMethodInsn(INVOKEINTERFACE, getType(List.class), "get", "(I)Ljava/lang/Object;");
  676. mw.visitVarInsn(ILOAD, context.var("i"));
  677. mw.visitMethodInsn(INVOKESTATIC, getType(Integer.class), "valueOf", "(I)Ljava/lang/Integer;");
  678. if (elementClass != null && Modifier.isPublic(elementClass.getModifiers())) {
  679. mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc((Class<?>) elementType)));
  680. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "writeWithFieldName",
  681. "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;)V");
  682. } else {
  683. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "writeWithFieldName",
  684. "(Ljava/lang/Object;Ljava/lang/Object;)V");
  685. }
  686. mw.visitVarInsn(ALOAD, context.var("out"));
  687. mw.visitVarInsn(BIPUSH, ',');
  688. mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "write", "(C)V");
  689. }
  690. mw.visitIincInsn(context.var("i"), 1);
  691. mw.visitJumpInsn(GOTO, _for);
  692. mw.visitLabel(_end_for);
  693. if (elementType == String.class) {
  694. // out.write((String)list.get(size - 1));
  695. mw.visitVarInsn(ALOAD, context.var("out"));
  696. mw.visitVarInsn(ALOAD, context.var("list"));
  697. mw.visitVarInsn(ILOAD, context.var("int"));
  698. mw.visitInsn(ICONST_1);
  699. mw.visitInsn(ISUB);
  700. mw.visitMethodInsn(INVOKEINTERFACE, getType(List.class), "get", "(I)Ljava/lang/Object;");
  701. mw.visitTypeInsn(CHECKCAST, getType(String.class)); // cast to string
  702. mw.visitVarInsn(BIPUSH, ']');
  703. mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeString",
  704. "(Ljava/lang/String;C)V");
  705. } else {
  706. mw.visitVarInsn(ALOAD, context.serializer());
  707. mw.visitVarInsn(ALOAD, context.var("list"));
  708. mw.visitVarInsn(ILOAD, context.var("i"));
  709. mw.visitMethodInsn(INVOKEINTERFACE, getType(List.class), "get", "(I)Ljava/lang/Object;");
  710. mw.visitVarInsn(ILOAD, context.var("i"));
  711. mw.visitMethodInsn(INVOKESTATIC, getType(Integer.class), "valueOf", "(I)Ljava/lang/Integer;");
  712. if (elementClass != null && Modifier.isPublic(elementClass.getModifiers())) {
  713. mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc((Class<?>) elementType)));
  714. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "writeWithFieldName",
  715. "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;)V");
  716. } else {
  717. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "writeWithFieldName",
  718. "(Ljava/lang/Object;Ljava/lang/Object;)V");
  719. }
  720. mw.visitVarInsn(ALOAD, context.var("out"));
  721. mw.visitVarInsn(BIPUSH, ']');
  722. mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "write", "(C)V");
  723. }
  724. }
  725. {
  726. mw.visitVarInsn(ALOAD, context.serializer());
  727. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "popContext", "()V");
  728. }
  729. mw.visitLabel(_end_if_3);
  730. _seperator(mw, context);
  731. mw.visitLabel(_end_if);
  732. mw.visitLabel(_end);
  733. }
  734. private void _filters(MethodVisitor mw, FieldInfo property, Context context, Label _end) {
  735. if (property.getField() != null) {
  736. if (Modifier.isTransient(property.getField().getModifiers())) {
  737. mw.visitVarInsn(ALOAD, context.var("out"));
  738. mw.visitFieldInsn(GETSTATIC, getType(SerializerFeature.class), "SkipTransientField",
  739. "L" + getType(SerializerFeature.class) + ";");
  740. mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "isEnabled",
  741. "(" + "L" + getType(SerializerFeature.class) + ";" + ")Z");
  742. // if true
  743. mw.visitJumpInsn(IFNE, _end);
  744. }
  745. }
  746. _apply(mw, property, context);
  747. mw.visitJumpInsn(IFEQ, _end);
  748. _processKey(mw, property, context);
  749. Label _else_processKey = new Label();
  750. _processValue(mw, property, context);
  751. mw.visitVarInsn(ALOAD, context.original());
  752. mw.visitVarInsn(ALOAD, context.processValue());
  753. mw.visitJumpInsn(IF_ACMPEQ, _else_processKey);
  754. _writeObject(mw, property, context, _end);
  755. mw.visitJumpInsn(GOTO, _end);
  756. mw.visitLabel(_else_processKey);
  757. }
  758. private void _nameApply(MethodVisitor mw, FieldInfo property, Context context, Label _end) {
  759. mw.visitVarInsn(ALOAD, context.serializer());
  760. mw.visitVarInsn(ALOAD, context.obj());
  761. mw.visitVarInsn(ALOAD, context.fieldName());
  762. mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "applyName",
  763. "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;)Z");
  764. mw.visitJumpInsn(IFEQ, _end);
  765. }
  766. private void _writeObject(MethodVisitor mw, FieldInfo fieldInfo, Context context, Label _end) {
  767. String format = null;
  768. JSONField annotation = fieldInfo.getAnnotation(JSONField.class);
  769. if (annotation != null) {
  770. format = annotation.format();
  771. if (format.trim().length() == 0) {
  772. format = null;
  773. }
  774. }
  775. Label _not_null = new Label();
  776. mw.visitVarInsn(ALOAD, context.processValue());
  777. mw.visitJumpInsn(IFNONNULL, _not_null); // if (obj == null)
  778. _if_write_null(mw, fieldInfo, context);
  779. mw.visitJumpInsn(GOTO, _end);
  780. mw.visitLabel(_not_null);
  781. // writeFieldNullNumber
  782. mw.visitVarInsn(ALOAD, context.var("out"));
  783. mw.visitVarInsn(ILOAD, context.var("seperator"));
  784. mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "write", "(C)V");
  785. // out.writeFieldName("fieldName")
  786. mw.visitVarInsn(ALOAD, context.var("out"));
  787. mw.visitVarInsn(ALOAD, context.fieldName());
  788. mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldName", "(Ljava/lang/String;)V");
  789. // serializer.write(obj)
  790. mw.visitVarInsn(ALOAD, context.serializer()); // serializer
  791. mw.visitVarInsn(ALOAD, context.processValue());
  792. if (format != null) {
  793. mw.visitLdcInsn(format);
  794. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "writeWithFormat",
  795. "(Ljava/lang/Object;Ljava/lang/String;)V");
  796. } else {
  797. mw.visitVarInsn(ALOAD, context.fieldName());
  798. if (fieldInfo.getFieldType() instanceof Class<?> && ((Class<?>) fieldInfo.getFieldType()).isPrimitive()) {
  799. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "writeWithFieldName",
  800. "(Ljava/lang/Object;Ljava/lang/Object;)V");
  801. } else {
  802. // fieldInfo.getName() + "_asm_fieldType"
  803. mw.visitVarInsn(ALOAD, 0);
  804. mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_fieldType",
  805. "Ljava/lang/reflect/Type;");
  806. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "writeWithFieldName",
  807. "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;)V");
  808. }
  809. }
  810. _seperator(mw, context);
  811. }
  812. private void _apply(MethodVisitor mw, FieldInfo property, Context context) {
  813. Class<?> propertyClass = property.getFieldClass();
  814. mw.visitVarInsn(ALOAD, context.serializer());
  815. mw.visitVarInsn(ALOAD, context.obj());
  816. mw.visitVarInsn(ALOAD, context.fieldName());
  817. if (propertyClass == byte.class) {
  818. mw.visitVarInsn(ILOAD, context.var("byte"));
  819. mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "apply",
  820. "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;B)Z");
  821. } else if (propertyClass == short.class) {
  822. mw.visitVarInsn(ILOAD, context.var("short"));
  823. mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "apply",
  824. "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;S)Z");
  825. } else if (propertyClass == int.class) {
  826. mw.visitVarInsn(ILOAD, context.var("int"));
  827. mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "apply",
  828. "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;I)Z");
  829. } else if (propertyClass == char.class) {
  830. mw.visitVarInsn(ILOAD, context.var("char"));
  831. mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "apply",
  832. "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;C)Z");
  833. } else if (propertyClass == long.class) {
  834. mw.visitVarInsn(LLOAD, context.var("long", 2));
  835. mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "apply",
  836. "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;J)Z");
  837. } else if (propertyClass == float.class) {
  838. mw.visitVarInsn(FLOAD, context.var("float"));
  839. mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "apply",
  840. "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;F)Z");
  841. } else if (propertyClass == double.class) {
  842. mw.visitVarInsn(DLOAD, context.var("double", 2));
  843. mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "apply",
  844. "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;D)Z");
  845. } else if (propertyClass == boolean.class) {
  846. mw.visitVarInsn(ILOAD, context.var("boolean"));
  847. mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "apply",
  848. "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;B)Z");
  849. } else if (propertyClass == BigDecimal.class) {
  850. mw.visitVarInsn(ALOAD, context.var("decimal"));
  851. mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "apply",
  852. "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Z");
  853. } else if (propertyClass == String.class) {
  854. mw.visitVarInsn(ALOAD, context.var("string"));
  855. mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "apply",
  856. "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Z");
  857. } else if (propertyClass.isEnum()) {
  858. mw.visitVarInsn(ALOAD, context.var("enum"));
  859. mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "apply",
  860. "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Z");
  861. } else if (List.class.isAssignableFrom(propertyClass)) {
  862. mw.visitVarInsn(ALOAD, context.var("list"));
  863. mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "apply",
  864. "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Z");
  865. } else {
  866. mw.visitVarInsn(ALOAD, context.var("object"));
  867. mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "apply",
  868. "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Z");
  869. }
  870. }
  871. private void _processValue(MethodVisitor mw, FieldInfo property, Context context) {
  872. Class<?> propertyClass = property.getFieldClass();
  873. mw.visitVarInsn(ALOAD, context.serializer());
  874. mw.visitVarInsn(ALOAD, context.obj());
  875. mw.visitVarInsn(ALOAD, context.fieldName());
  876. if (propertyClass == byte.class) {
  877. mw.visitVarInsn(ILOAD, context.var("byte"));
  878. mw.visitMethodInsn(INVOKESTATIC, getType(Byte.class), "valueOf", "(B)Ljava/lang/Byte;");
  879. } else if (propertyClass == short.class) {
  880. mw.visitVarInsn(ILOAD, context.var("short"));
  881. mw.visitMethodInsn(INVOKESTATIC, getType(Short.class), "valueOf", "(S)Ljava/lang/Short;");
  882. } else if (propertyClass == int.class) {
  883. mw.visitVarInsn(ILOAD, context.var("int"));
  884. mw.visitMethodInsn(INVOKESTATIC, getType(Integer.class), "valueOf", "(I)Ljava/lang/Integer;");
  885. } else if (propertyClass == char.class) {
  886. mw.visitVarInsn(ILOAD, context.var("char"));
  887. mw.visitMethodInsn(INVOKESTATIC, getType(Character.class), "valueOf", "(C)Ljava/lang/Character;");
  888. } else if (propertyClass == long.class) {
  889. mw.visitVarInsn(LLOAD, context.var("long", 2));
  890. mw.visitMethodInsn(INVOKESTATIC, getType(Long.class), "valueOf", "(J)Ljava/lang/Long;");
  891. } else if (propertyClass == float.class) {
  892. mw.visitVarInsn(FLOAD, context.var("float"));
  893. mw.visitMethodInsn(INVOKESTATIC, getType(Float.class), "valueOf", "(F)Ljava/lang/Float;");
  894. } else if (propertyClass == double.class) {
  895. mw.visitVarInsn(DLOAD, context.var("double", 2));
  896. mw.visitMethodInsn(INVOKESTATIC, getType(Double.class), "valueOf", "(D)Ljava/lang/Double;");
  897. } else if (propertyClass == boolean.class) {
  898. mw.visitVarInsn(ILOAD, context.var("boolean"));
  899. mw.visitMethodInsn(INVOKESTATIC, getType(Boolean.class), "valueOf", "(Z)Ljava/lang/Boolean;");
  900. } else if (propertyClass == BigDecimal.class) {
  901. mw.visitVarInsn(ALOAD, context.var("decimal"));
  902. } else if (propertyClass == String.class) {
  903. mw.visitVarInsn(ALOAD, context.var("string"));
  904. } else if (propertyClass.isEnum()) {
  905. mw.visitVarInsn(ALOAD, context.var("enum"));
  906. } else if (List.class.isAssignableFrom(propertyClass)) {
  907. mw.visitVarInsn(ALOAD, context.var("list"));
  908. } else {
  909. mw.visitVarInsn(ALOAD, context.var("object"));
  910. }
  911. mw.visitVarInsn(ASTORE, context.original());
  912. mw.visitVarInsn(ALOAD, context.original());
  913. mw.visitMethodInsn(INVOKESTATIC,
  914. getType(FilterUtils.class),
  915. "processValue",
  916. "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;");
  917. mw.visitVarInsn(ASTORE, context.processValue());
  918. }
  919. private void _processKey(MethodVisitor mw, FieldInfo property, Context context) {