PageRenderTime 38ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/src/main/java/com/alibaba/fastjson/parser/deserializer/ASMDeserializerFactory.java

https://bitbucket.org/xiejuntao/xdesktop
Java | 1021 lines | 797 code | 181 blank | 43 comment | 181 complexity | 682ff3047e30f39596242b1796974432 MD5 | raw file
  1. package com.alibaba.fastjson.parser.deserializer;
  2. import static com.alibaba.fastjson.util.ASMUtils.getDesc;
  3. import static com.alibaba.fastjson.util.ASMUtils.getType;
  4. import java.lang.reflect.Constructor;
  5. import java.lang.reflect.Method;
  6. import java.lang.reflect.Modifier;
  7. import java.lang.reflect.ParameterizedType;
  8. import java.lang.reflect.Type;
  9. import java.util.ArrayList;
  10. import java.util.Collection;
  11. import java.util.Collections;
  12. import java.util.HashMap;
  13. import java.util.HashSet;
  14. import java.util.LinkedList;
  15. import java.util.List;
  16. import java.util.Map;
  17. import java.util.TreeSet;
  18. import java.util.concurrent.atomic.AtomicLong;
  19. import com.alibaba.fastjson.JSONException;
  20. import com.alibaba.fastjson.asm.ASMException;
  21. import com.alibaba.fastjson.asm.ClassWriter;
  22. import com.alibaba.fastjson.asm.FieldVisitor;
  23. import com.alibaba.fastjson.asm.Label;
  24. import com.alibaba.fastjson.asm.MethodVisitor;
  25. import com.alibaba.fastjson.asm.Opcodes;
  26. import com.alibaba.fastjson.parser.DefaultJSONParser;
  27. import com.alibaba.fastjson.parser.DefaultJSONParser.ResolveTask;
  28. import com.alibaba.fastjson.parser.Feature;
  29. import com.alibaba.fastjson.parser.JSONLexer;
  30. import com.alibaba.fastjson.parser.JSONScanner;
  31. import com.alibaba.fastjson.parser.JSONToken;
  32. import com.alibaba.fastjson.parser.ParseContext;
  33. import com.alibaba.fastjson.parser.ParserConfig;
  34. import com.alibaba.fastjson.parser.SymbolTable;
  35. import com.alibaba.fastjson.parser.deserializer.ASMJavaBeanDeserializer.InnerJavaBeanDeserializer;
  36. import com.alibaba.fastjson.util.ASMClassLoader;
  37. import com.alibaba.fastjson.util.ASMUtils;
  38. import com.alibaba.fastjson.util.DeserializeBeanInfo;
  39. import com.alibaba.fastjson.util.FieldInfo;
  40. public class ASMDeserializerFactory implements Opcodes {
  41. private static final ASMDeserializerFactory instance = new ASMDeserializerFactory();
  42. private ASMClassLoader classLoader = new ASMClassLoader();
  43. private final AtomicLong seed = new AtomicLong();
  44. public String getGenClassName(Class<?> clazz) {
  45. return "Fastjson_ASM_" + clazz.getSimpleName() + "_" + seed.incrementAndGet();
  46. }
  47. public String getGenFieldDeserializer(Class<?> clazz, FieldInfo fieldInfo) {
  48. String name = "Fastjson_ASM__Field_" + clazz.getSimpleName();
  49. name += "_" + fieldInfo.getName() + "_" + seed.incrementAndGet();
  50. return name;
  51. }
  52. public ASMDeserializerFactory(){
  53. }
  54. public final static ASMDeserializerFactory getInstance() {
  55. return instance;
  56. }
  57. public boolean isExternalClass(Class<?> clazz) {
  58. return classLoader.isExternalClass(clazz);
  59. }
  60. public ObjectDeserializer createJavaBeanDeserializer(ParserConfig config, Class<?> clazz, Type type)
  61. throws Exception {
  62. if (clazz.isPrimitive()) {
  63. throw new IllegalArgumentException("not support type :" + clazz.getName());
  64. }
  65. String className = getGenClassName(clazz);
  66. ClassWriter cw = new ClassWriter();
  67. cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, className, getType(ASMJavaBeanDeserializer.class), null);
  68. DeserializeBeanInfo beanInfo = DeserializeBeanInfo.computeSetters(clazz, type);
  69. _init(cw, new Context(className, config, beanInfo, 3));
  70. _createInstance(cw, new Context(className, config, beanInfo, 3));
  71. _deserialze(cw, new Context(className, config, beanInfo, 4));
  72. byte[] code = cw.toByteArray();
  73. // org.apache.commons.io.IOUtils.write(code, new java.io.FileOutputStream(
  74. // "/usr/alibaba/workspace-3.7/fastjson-asm/target/classes/"
  75. // + className + ".class"));
  76. Class<?> exampleClass = classLoader.defineClassPublic(className, code, 0, code.length);
  77. Constructor<?> constructor = exampleClass.getConstructor(ParserConfig.class, Class.class);
  78. Object instance = constructor.newInstance(config, clazz);
  79. return (ObjectDeserializer) instance;
  80. }
  81. void _setFlag(MethodVisitor mw, Context context, int i) {
  82. String varName = "_asm_flag_" + (i / 32);
  83. mw.visitVarInsn(ILOAD, context.var(varName));
  84. mw.visitLdcInsn(1 << i);
  85. mw.visitInsn(IOR);
  86. mw.visitVarInsn(ISTORE, context.var(varName));
  87. }
  88. void _isFlag(MethodVisitor mw, Context context, int i, Label label) {
  89. mw.visitVarInsn(ILOAD, context.var("_asm_flag_" + (i / 32)));
  90. mw.visitLdcInsn(1 << i);
  91. mw.visitInsn(IAND);
  92. mw.visitJumpInsn(IFEQ, label);
  93. }
  94. void _deserialze(ClassWriter cw, Context context) {
  95. if (context.getFieldInfoList().size() == 0) {
  96. return;
  97. }
  98. for (FieldInfo fieldInfo : context.getFieldInfoList()) {
  99. Class<?> fieldClass = fieldInfo.getFieldClass();
  100. Type fieldType = fieldInfo.getFieldType();
  101. if (fieldClass == char.class) {
  102. return;
  103. }
  104. if (Collection.class.isAssignableFrom(fieldClass)) {
  105. if (fieldType instanceof ParameterizedType) {
  106. Type itemType = ((ParameterizedType) fieldType).getActualTypeArguments()[0];
  107. if (itemType instanceof Class) {
  108. continue;
  109. } else {
  110. return;
  111. }
  112. } else {
  113. return;
  114. }
  115. }
  116. }
  117. Collections.sort(context.getFieldInfoList());
  118. MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "deserialze", "(" + getDesc(DefaultJSONParser.class)
  119. + getDesc(Type.class)
  120. + "Ljava/lang/Object;)Ljava/lang/Object;", null,
  121. null);
  122. Label reset_ = new Label();
  123. Label super_ = new Label();
  124. Label return_ = new Label();
  125. Label end_ = new Label();
  126. mw.visitVarInsn(ALOAD, 1);
  127. mw.visitMethodInsn(INVOKEVIRTUAL, getType(DefaultJSONParser.class), "getLexer", "()" + getDesc(JSONLexer.class));
  128. mw.visitTypeInsn(CHECKCAST, getType(JSONScanner.class)); // cast
  129. mw.visitVarInsn(ASTORE, context.var("lexer"));
  130. mw.visitVarInsn(ALOAD, context.var("lexer"));
  131. mw.visitFieldInsn(GETSTATIC, getType(Feature.class), "SortFeidFastMatch", "L" + getType(Feature.class) + ";");
  132. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "isEnabled", "(" + "L" + getType(Feature.class)
  133. + ";" + ")Z");
  134. mw.visitJumpInsn(IFEQ, super_);
  135. mw.visitVarInsn(ALOAD, context.var("lexer"));
  136. mw.visitFieldInsn(GETFIELD, getType(JSONScanner.class), "resetCount", "I");
  137. mw.visitJumpInsn(IFGT, super_);
  138. mw.visitVarInsn(ALOAD, context.var("lexer"));
  139. mw.visitLdcInsn(context.getClazz().getName());
  140. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "scanType", "(Ljava/lang/String;)I");
  141. mw.visitFieldInsn(GETSTATIC, getType(JSONScanner.class), "NOT_MATCH", "I");
  142. mw.visitJumpInsn(IF_ICMPEQ, super_);
  143. // matchType
  144. mw.visitVarInsn(ALOAD, context.var("lexer"));
  145. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "getBufferPosition", "()I");
  146. mw.visitVarInsn(ISTORE, context.var("mark"));
  147. mw.visitVarInsn(ALOAD, context.var("lexer"));
  148. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "getCurrent", "()C");
  149. mw.visitVarInsn(ISTORE, context.var("mark_ch"));
  150. mw.visitVarInsn(ALOAD, context.var("lexer"));
  151. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "token", "()I");
  152. mw.visitVarInsn(ISTORE, context.var("mark_token"));
  153. mw.visitVarInsn(ALOAD, 1); // parser
  154. mw.visitMethodInsn(INVOKEVIRTUAL, getType(DefaultJSONParser.class), "getContextLength", "()I");
  155. mw.visitVarInsn(ISTORE, context.var("contextLength"));
  156. mw.visitVarInsn(ALOAD, 1); // parser
  157. mw.visitMethodInsn(INVOKEVIRTUAL, getType(DefaultJSONParser.class), "getContext", "()Lcom/alibaba/fastjson/parser/ParseContext;");
  158. mw.visitVarInsn(ASTORE, context.var("mark_context"));
  159. // ParseContext context = parser.getContext();
  160. mw.visitInsn(ICONST_0);
  161. mw.visitVarInsn(ISTORE, context.var("matchedCount"));
  162. Constructor<?> defaultConstructor = context.getBeanInfo().getDefaultConstructor();
  163. // create instance
  164. if (context.getClazz().isInterface()) {
  165. mw.visitVarInsn(ALOAD, 0);
  166. mw.visitVarInsn(ALOAD, 1);
  167. mw.visitMethodInsn(INVOKESPECIAL, getType(ASMJavaBeanDeserializer.class), "createInstance",
  168. "(" + getDesc(DefaultJSONParser.class) + ")Ljava/lang/Object;");
  169. mw.visitTypeInsn(CHECKCAST, getType(context.getClazz())); // cast
  170. mw.visitVarInsn(ASTORE, context.var("instance"));
  171. } else {
  172. if (defaultConstructor != null) {
  173. if (Modifier.isPublic(defaultConstructor.getModifiers())) {
  174. mw.visitTypeInsn(NEW, getType(context.getClazz()));
  175. mw.visitInsn(DUP);
  176. mw.visitMethodInsn(INVOKESPECIAL, getType(context.getClazz()), "<init>", "()V");
  177. mw.visitVarInsn(ASTORE, context.var("instance"));
  178. } else {
  179. mw.visitVarInsn(ALOAD, 0);
  180. mw.visitVarInsn(ALOAD, 1);
  181. mw.visitMethodInsn(INVOKESPECIAL, getType(ASMJavaBeanDeserializer.class), "createInstance",
  182. "(" + getDesc(DefaultJSONParser.class) + ")Ljava/lang/Object;");
  183. mw.visitTypeInsn(CHECKCAST, getType(context.getClazz())); // cast
  184. mw.visitVarInsn(ASTORE, context.var("instance"));
  185. }
  186. } else {
  187. mw.visitInsn(ACONST_NULL);
  188. mw.visitTypeInsn(CHECKCAST, getType(context.getClazz())); // cast
  189. mw.visitVarInsn(ASTORE, context.var("instance"));
  190. }
  191. }
  192. {
  193. mw.visitVarInsn(ALOAD, 1); // parser
  194. mw.visitMethodInsn(INVOKEVIRTUAL, getType(DefaultJSONParser.class), "getContext",
  195. "()" + ASMUtils.getDesc(ParseContext.class));
  196. mw.visitVarInsn(ASTORE, context.var("context"));
  197. mw.visitVarInsn(ALOAD, 1); // parser
  198. mw.visitVarInsn(ALOAD, context.var("context"));
  199. mw.visitVarInsn(ALOAD, context.var("instance"));
  200. mw.visitVarInsn(ALOAD, 3); // fieldName
  201. mw.visitMethodInsn(INVOKEVIRTUAL, getType(DefaultJSONParser.class), "setContext",
  202. "(" + ASMUtils.getDesc(ParseContext.class) + "Ljava/lang/Object;Ljava/lang/Object;)"
  203. + ASMUtils.getDesc(ParseContext.class));
  204. mw.visitVarInsn(ASTORE, context.var("childContext"));
  205. }
  206. mw.visitVarInsn(ALOAD, context.var("lexer"));
  207. mw.visitFieldInsn(GETFIELD, getType(JSONScanner.class), "matchStat", "I");
  208. mw.visitFieldInsn(GETSTATIC, getType(JSONScanner.class), "END", "I");
  209. mw.visitJumpInsn(IF_ICMPEQ, return_);
  210. mw.visitInsn(ICONST_0); // UNKOWN
  211. mw.visitIntInsn(ISTORE, context.var("matchStat"));
  212. for (int i = 0, size = context.getFieldInfoList().size(); i < size; i+=32) {
  213. mw.visitInsn(ICONST_0);
  214. mw.visitVarInsn(ISTORE, context.var("_asm_flag_" + (i / 32)));
  215. }
  216. for (int i = 0, size = context.getFieldInfoList().size(); i < size; ++i) {
  217. FieldInfo fieldInfo = context.getFieldInfoList().get(i);
  218. Class<?> fieldClass = fieldInfo.getFieldClass();
  219. Type fieldType = fieldInfo.getFieldType();
  220. Label notMatch_ = new Label();
  221. if (fieldClass == boolean.class) {
  222. mw.visitVarInsn(ALOAD, context.var("lexer"));
  223. mw.visitVarInsn(ALOAD, 0);
  224. mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_prefix__", "[C");
  225. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "scanFieldBoolean", "([C)Z");
  226. mw.visitVarInsn(ISTORE, context.var(fieldInfo.getName() + "_asm"));
  227. } else if (fieldClass == byte.class) {
  228. mw.visitVarInsn(ALOAD, context.var("lexer"));
  229. mw.visitVarInsn(ALOAD, 0);
  230. mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_prefix__", "[C");
  231. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "scanFieldInt", "([C)I");
  232. mw.visitVarInsn(ISTORE, context.var(fieldInfo.getName() + "_asm"));
  233. } else if (fieldClass == short.class) {
  234. mw.visitVarInsn(ALOAD, context.var("lexer"));
  235. mw.visitVarInsn(ALOAD, 0);
  236. mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_prefix__", "[C");
  237. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "scanFieldInt", "([C)I");
  238. mw.visitVarInsn(ISTORE, context.var(fieldInfo.getName() + "_asm"));
  239. } else if (fieldClass == int.class) {
  240. mw.visitVarInsn(ALOAD, context.var("lexer"));
  241. mw.visitVarInsn(ALOAD, 0);
  242. mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_prefix__", "[C");
  243. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "scanFieldInt", "([C)I");
  244. mw.visitVarInsn(ISTORE, context.var(fieldInfo.getName() + "_asm"));
  245. } else if (fieldClass == long.class) {
  246. mw.visitVarInsn(ALOAD, context.var("lexer"));
  247. mw.visitVarInsn(ALOAD, 0);
  248. mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_prefix__", "[C");
  249. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "scanFieldLong", "([C)J");
  250. mw.visitVarInsn(LSTORE, context.var(fieldInfo.getName() + "_asm", 2));
  251. } else if (fieldClass == float.class) {
  252. mw.visitVarInsn(ALOAD, context.var("lexer"));
  253. mw.visitVarInsn(ALOAD, 0);
  254. mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_prefix__", "[C");
  255. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "scanFieldFloat", "([C)F");
  256. mw.visitVarInsn(FSTORE, context.var(fieldInfo.getName() + "_asm"));
  257. } else if (fieldClass == double.class) {
  258. mw.visitVarInsn(ALOAD, context.var("lexer"));
  259. mw.visitVarInsn(ALOAD, 0);
  260. mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_prefix__", "[C");
  261. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "scanFieldDouble", "([C)D");
  262. mw.visitVarInsn(DSTORE, context.var(fieldInfo.getName() + "_asm", 2));
  263. } else if (fieldClass == String.class) {
  264. Label notEnd_ = new Label();
  265. mw.visitIntInsn(ILOAD, context.var("matchStat"));
  266. mw.visitInsn(ICONST_4); // END
  267. mw.visitJumpInsn(IF_ICMPNE, notEnd_);
  268. mw.visitVarInsn(ALOAD, context.var("lexer"));
  269. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "stringDefaultValue",
  270. "()Ljava/lang/String;");
  271. mw.visitVarInsn(ASTORE, context.var(fieldInfo.getName() + "_asm"));
  272. mw.visitJumpInsn(GOTO, notMatch_);
  273. mw.visitLabel(notEnd_);
  274. mw.visitVarInsn(ALOAD, context.var("lexer"));
  275. mw.visitVarInsn(ALOAD, 0);
  276. mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_prefix__", "[C");
  277. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "scanFieldString",
  278. "([C)Ljava/lang/String;");
  279. mw.visitVarInsn(ASTORE, context.var(fieldInfo.getName() + "_asm"));
  280. } else if (fieldClass.isEnum()) {
  281. mw.visitVarInsn(ALOAD, context.var("lexer"));
  282. mw.visitVarInsn(ALOAD, 0);
  283. mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_prefix__", "[C");
  284. Label enumNull_ = new Label();
  285. mw.visitInsn(ACONST_NULL);
  286. mw.visitTypeInsn(CHECKCAST, getType(fieldClass)); // cast
  287. mw.visitVarInsn(ASTORE, context.var(fieldInfo.getName() + "_asm"));
  288. mw.visitVarInsn(ALOAD, 1);
  289. mw.visitMethodInsn(INVOKEVIRTUAL, getType(DefaultJSONParser.class), "getSymbolTable",
  290. "()" + getDesc(SymbolTable.class));
  291. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "scanFieldSymbol",
  292. "([C" + getDesc(SymbolTable.class) + ")Ljava/lang/String;");
  293. mw.visitInsn(DUP);
  294. mw.visitVarInsn(ASTORE, context.var(fieldInfo.getName() + "_asm_enumName"));
  295. mw.visitJumpInsn(IFNULL, enumNull_);
  296. mw.visitVarInsn(ALOAD, context.var(fieldInfo.getName() + "_asm_enumName"));
  297. mw.visitMethodInsn(INVOKESTATIC, getType(fieldClass), "valueOf", "(Ljava/lang/String;)"
  298. + getDesc(fieldClass));
  299. mw.visitVarInsn(ASTORE, context.var(fieldInfo.getName() + "_asm"));
  300. mw.visitLabel(enumNull_);
  301. } else if (Collection.class.isAssignableFrom(fieldClass)) {
  302. mw.visitVarInsn(ALOAD, context.var("lexer"));
  303. mw.visitVarInsn(ALOAD, 0);
  304. mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_prefix__", "[C");
  305. Type actualTypeArgument = ((ParameterizedType) fieldType).getActualTypeArguments()[0];
  306. if (actualTypeArgument instanceof Class) {
  307. Class<?> itemClass = (Class<?>) actualTypeArgument;
  308. if (!Modifier.isPublic(itemClass.getModifiers())) {
  309. throw new ASMException("can not create ASMParser");
  310. }
  311. if (itemClass == String.class) {
  312. mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc(fieldClass))); // cast
  313. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "scanFieldStringArray",
  314. "([CLjava/lang/Class;)" + getDesc(Collection.class));
  315. mw.visitVarInsn(ASTORE, context.var(fieldInfo.getName() + "_asm"));
  316. _setFlag(mw, context, i);
  317. } else {
  318. _deserialze_list_obj(context, mw, reset_, fieldInfo, fieldClass, itemClass, i);
  319. if (i == size - 1) {
  320. _deserialize_endCheck(context, mw, reset_);
  321. }
  322. continue;
  323. }
  324. } else {
  325. throw new ASMException("can not create ASMParser");
  326. }
  327. } else {
  328. _deserialze_obj(context, mw, reset_, fieldInfo, fieldClass, i);
  329. if (i == size - 1) {
  330. _deserialize_endCheck(context, mw, reset_);
  331. }
  332. continue;
  333. }
  334. mw.visitVarInsn(ALOAD, context.var("lexer"));
  335. mw.visitFieldInsn(GETFIELD, getType(JSONScanner.class), "matchStat", "I");
  336. mw.visitInsn(DUP);
  337. mw.visitVarInsn(ISTORE, context.var("matchStat"));
  338. mw.visitFieldInsn(GETSTATIC, getType(JSONScanner.class), "NOT_MATCH", "I");
  339. mw.visitJumpInsn(IF_ICMPEQ, reset_);
  340. // mw.visitFieldInsn(GETSTATIC, getType(System.class), "out", "Ljava/io/PrintStream;");
  341. // mw.visitVarInsn(ALOAD, context.var("lexer"));
  342. // mw.visitFieldInsn(GETFIELD, getType(JSONScanner.class), "matchStat", "I");
  343. // mw.visitMethodInsn(INVOKEVIRTUAL, getType(java.io.PrintStream.class), "println", "(I)V");
  344. mw.visitVarInsn(ALOAD, context.var("lexer"));
  345. mw.visitFieldInsn(GETFIELD, getType(JSONScanner.class), "matchStat", "I");
  346. mw.visitJumpInsn(IFLE, notMatch_);
  347. // increment matchedCount
  348. mw.visitVarInsn(ILOAD, context.var("matchedCount"));
  349. mw.visitInsn(ICONST_1);
  350. mw.visitInsn(IADD);
  351. mw.visitVarInsn(ISTORE, context.var("matchedCount"));
  352. // mw.visitFieldInsn(GETSTATIC, getType(System.class), "out", "Ljava/io/PrintStream;");
  353. // mw.visitVarInsn(ILOAD, context.var("matchedCount"));
  354. // mw.visitMethodInsn(INVOKEVIRTUAL, getType(java.io.PrintStream.class), "println", "(I)V");
  355. mw.visitLabel(notMatch_);
  356. if (i == size - 1) {
  357. mw.visitVarInsn(ALOAD, context.var("lexer"));
  358. mw.visitFieldInsn(GETFIELD, getType(JSONScanner.class), "matchStat", "I");
  359. mw.visitFieldInsn(GETSTATIC, getType(JSONScanner.class), "END", "I");
  360. mw.visitJumpInsn(IF_ICMPNE, reset_);
  361. }
  362. }
  363. mw.visitLabel(end_);
  364. if (!context.getClazz().isInterface() && !Modifier.isAbstract(context.getClazz().getModifiers())) {
  365. if (defaultConstructor != null) {
  366. _batchSet(context, mw);
  367. } else {
  368. Constructor<?> creatorConstructor = context.getBeanInfo().getCreatorConstructor();
  369. if (creatorConstructor != null) {
  370. mw.visitTypeInsn(NEW, getType(context.getClazz()));
  371. mw.visitInsn(DUP);
  372. _loadCreatorParameters(context, mw);
  373. mw.visitMethodInsn(INVOKESPECIAL, getType(context.getClazz()), "<init>",
  374. getDesc(creatorConstructor));
  375. mw.visitVarInsn(ASTORE, context.var("instance"));
  376. } else {
  377. Method factoryMethod = context.getBeanInfo().getFactoryMethod();
  378. if (factoryMethod != null) {
  379. _loadCreatorParameters(context, mw);
  380. mw.visitMethodInsn(INVOKESTATIC, getType(factoryMethod.getDeclaringClass()),
  381. factoryMethod.getName(), getDesc(factoryMethod));
  382. mw.visitVarInsn(ASTORE, context.var("instance"));
  383. } else {
  384. throw new JSONException("TODO");
  385. }
  386. }
  387. }
  388. }
  389. mw.visitLabel(return_);
  390. _setContext(context, mw);
  391. mw.visitVarInsn(ALOAD, context.var("instance"));
  392. mw.visitInsn(ARETURN);
  393. mw.visitLabel(reset_);
  394. // void reset(int mark, char mark_ch)
  395. mw.visitVarInsn(ALOAD, context.var("lexer"));
  396. mw.visitVarInsn(ILOAD, context.var("mark"));
  397. mw.visitVarInsn(ILOAD, context.var("mark_ch"));
  398. mw.visitVarInsn(ILOAD, context.var("mark_token"));
  399. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "reset", "(ICI)V");
  400. mw.visitVarInsn(ALOAD, 1); // parser
  401. mw.visitVarInsn(ALOAD, context.var("mark_context"));
  402. mw.visitVarInsn(ILOAD, context.var("contextLength"));
  403. mw.visitMethodInsn(INVOKEVIRTUAL, getType(DefaultJSONParser.class), "clearContext", "(Lcom/alibaba/fastjson/parser/ParseContext;I)V");
  404. // _setContext(context, mw, false);
  405. mw.visitLabel(super_);
  406. mw.visitVarInsn(ALOAD, 0);
  407. mw.visitVarInsn(ALOAD, 1);
  408. mw.visitVarInsn(ALOAD, 2);
  409. mw.visitVarInsn(ALOAD, 3);
  410. mw.visitMethodInsn(INVOKESPECIAL, getType(ASMJavaBeanDeserializer.class), "deserialze",
  411. "(" + getDesc(DefaultJSONParser.class) + getDesc(Type.class)
  412. + "Ljava/lang/Object;)Ljava/lang/Object;");
  413. mw.visitInsn(ARETURN);
  414. int maxStack = 4;
  415. Constructor<?> creatorConstructor = context.getBeanInfo().getCreatorConstructor();
  416. if (creatorConstructor != null) {
  417. int constructorTypeStack = 2;
  418. for (Class<?> type : creatorConstructor.getParameterTypes()) {
  419. if (type == long.class || type == double.class) {
  420. constructorTypeStack += 2;
  421. } else {
  422. constructorTypeStack++;
  423. }
  424. }
  425. if (maxStack < constructorTypeStack) {
  426. maxStack = constructorTypeStack;
  427. }
  428. } else {
  429. Method factoryMethod = context.getBeanInfo().getFactoryMethod();
  430. if (factoryMethod != null) {
  431. int paramStacks = 2;
  432. for (Class<?> type : factoryMethod.getParameterTypes()) {
  433. if (type == long.class || type == double.class) {
  434. paramStacks += 2;
  435. } else {
  436. paramStacks++;
  437. }
  438. }
  439. if (maxStack < paramStacks) {
  440. maxStack = paramStacks;
  441. }
  442. }
  443. }
  444. mw.visitMaxs(maxStack, context.getVariantCount());
  445. mw.visitEnd();
  446. }
  447. private void _loadCreatorParameters(Context context, MethodVisitor mw) {
  448. List<FieldInfo> fieldInfoList = context.getBeanInfo().getFieldList();
  449. for (int i = 0, size = fieldInfoList.size(); i < size; ++i) {
  450. FieldInfo fieldInfo = fieldInfoList.get(i);
  451. Class<?> fieldClass = fieldInfo.getFieldClass();
  452. Type fieldType = fieldInfo.getFieldType();
  453. if (fieldClass == boolean.class) {
  454. mw.visitVarInsn(ILOAD, context.var(fieldInfo.getName() + "_asm"));
  455. } else if (fieldClass == byte.class) {
  456. mw.visitVarInsn(ILOAD, context.var(fieldInfo.getName() + "_asm"));
  457. } else if (fieldClass == short.class) {
  458. mw.visitVarInsn(ILOAD, context.var(fieldInfo.getName() + "_asm"));
  459. } else if (fieldClass == int.class) {
  460. mw.visitVarInsn(ILOAD, context.var(fieldInfo.getName() + "_asm"));
  461. } else if (fieldClass == long.class) {
  462. mw.visitVarInsn(LLOAD, context.var(fieldInfo.getName() + "_asm", 2));
  463. } else if (fieldClass == float.class) {
  464. mw.visitVarInsn(FLOAD, context.var(fieldInfo.getName() + "_asm"));
  465. } else if (fieldClass == double.class) {
  466. mw.visitVarInsn(DLOAD, context.var(fieldInfo.getName() + "_asm", 2));
  467. } else if (fieldClass == String.class) {
  468. mw.visitVarInsn(ALOAD, context.var(fieldInfo.getName() + "_asm"));
  469. } else if (fieldClass.isEnum()) {
  470. mw.visitVarInsn(ALOAD, context.var(fieldInfo.getName() + "_asm"));
  471. } else if (Collection.class.isAssignableFrom(fieldClass)) {
  472. Type itemType = ((ParameterizedType) fieldType).getActualTypeArguments()[0];
  473. if (itemType == String.class) {
  474. mw.visitVarInsn(ALOAD, context.var(fieldInfo.getName() + "_asm"));
  475. mw.visitTypeInsn(CHECKCAST, getType(fieldClass)); // cast
  476. } else {
  477. mw.visitVarInsn(ALOAD, context.var(fieldInfo.getName() + "_asm"));
  478. }
  479. } else {
  480. mw.visitVarInsn(ALOAD, context.var(fieldInfo.getName() + "_asm"));
  481. }
  482. }
  483. }
  484. private void _batchSet(Context context, MethodVisitor mw) {
  485. for (int i = 0, size = context.getFieldInfoList().size(); i < size; ++i) {
  486. FieldInfo fieldInfo = context.getFieldInfoList().get(i);
  487. Class<?> fieldClass = fieldInfo.getFieldClass();
  488. Type fieldType = fieldInfo.getFieldType();
  489. if (fieldClass == boolean.class) {
  490. mw.visitVarInsn(ALOAD, context.var("instance"));
  491. mw.visitVarInsn(ILOAD, context.var(fieldInfo.getName() + "_asm"));
  492. _batchSetInvoke(context, mw, fieldInfo);
  493. } else if (fieldClass == byte.class) {
  494. mw.visitVarInsn(ALOAD, context.var("instance"));
  495. mw.visitVarInsn(ILOAD, context.var(fieldInfo.getName() + "_asm"));
  496. _batchSetInvoke(context, mw, fieldInfo);
  497. } else if (fieldClass == short.class) {
  498. mw.visitVarInsn(ALOAD, context.var("instance"));
  499. mw.visitVarInsn(ILOAD, context.var(fieldInfo.getName() + "_asm"));
  500. _batchSetInvoke(context, mw, fieldInfo);
  501. } else if (fieldClass == int.class) {
  502. mw.visitVarInsn(ALOAD, context.var("instance"));
  503. mw.visitVarInsn(ILOAD, context.var(fieldInfo.getName() + "_asm"));
  504. _batchSetInvoke(context, mw, fieldInfo);
  505. } else if (fieldClass == long.class) {
  506. mw.visitVarInsn(ALOAD, context.var("instance"));
  507. mw.visitVarInsn(LLOAD, context.var(fieldInfo.getName() + "_asm", 2));
  508. if (fieldInfo.getMethod() != null) {
  509. mw.visitMethodInsn(INVOKEVIRTUAL, getType(context.getClazz()), fieldInfo.getMethod().getName(),
  510. "(J)V");
  511. } else {
  512. mw.visitFieldInsn(PUTFIELD, getType(fieldInfo.getDeclaringClass()), fieldInfo.getField().getName(),
  513. getDesc(fieldInfo.getFieldClass()));
  514. }
  515. continue;
  516. } else if (fieldClass == float.class) {
  517. mw.visitVarInsn(ALOAD, context.var("instance"));
  518. mw.visitVarInsn(FLOAD, context.var(fieldInfo.getName() + "_asm"));
  519. _batchSetInvoke(context, mw, fieldInfo);
  520. } else if (fieldClass == double.class) {
  521. mw.visitVarInsn(ALOAD, context.var("instance"));
  522. mw.visitVarInsn(DLOAD, context.var(fieldInfo.getName() + "_asm", 2));
  523. _batchSetInvoke(context, mw, fieldInfo);
  524. } else if (fieldClass == String.class) {
  525. mw.visitVarInsn(ALOAD, context.var("instance"));
  526. mw.visitVarInsn(ALOAD, context.var(fieldInfo.getName() + "_asm"));
  527. _batchSetInvoke(context, mw, fieldInfo);
  528. } else if (fieldClass.isEnum()) {
  529. mw.visitVarInsn(ALOAD, context.var("instance"));
  530. mw.visitVarInsn(ALOAD, context.var(fieldInfo.getName() + "_asm"));
  531. _batchSetInvoke(context, mw, fieldInfo);
  532. } else if (Collection.class.isAssignableFrom(fieldClass)) {
  533. Label notSet_ = new Label();
  534. _isFlag(mw, context, i, notSet_);
  535. mw.visitVarInsn(ALOAD, context.var("instance"));
  536. Type itemType = ((ParameterizedType) fieldType).getActualTypeArguments()[0];
  537. if (itemType == String.class) {
  538. mw.visitVarInsn(ALOAD, context.var(fieldInfo.getName() + "_asm"));
  539. mw.visitTypeInsn(CHECKCAST, getType(fieldClass)); // cast
  540. } else {
  541. mw.visitVarInsn(ALOAD, context.var(fieldInfo.getName() + "_asm"));
  542. }
  543. _batchSetInvoke(context, mw, fieldInfo);
  544. mw.visitLabel(notSet_);
  545. } else {
  546. // mw.visitFieldInsn(GETSTATIC, getType(System.class), "out", "Ljava/io/PrintStream;");
  547. // mw.visitIntInsn(ILOAD, context.var(fieldInfo.getName() + "_asm_flag"));
  548. // mw.visitMethodInsn(INVOKEVIRTUAL, getType(java.io.PrintStream.class), "println", "(I)V");
  549. Label notSet_ = new Label();
  550. _isFlag(mw, context, i, notSet_);
  551. mw.visitVarInsn(ALOAD, context.var("instance"));
  552. mw.visitVarInsn(ALOAD, context.var(fieldInfo.getName() + "_asm"));
  553. _batchSetInvoke(context, mw, fieldInfo);
  554. mw.visitLabel(notSet_);
  555. }
  556. }
  557. }
  558. private void _batchSetInvoke(Context context, MethodVisitor mw, FieldInfo fieldInfo) {
  559. int INVAKE_TYPE;
  560. if (context.getClazz().isInterface()) {
  561. INVAKE_TYPE = INVOKEINTERFACE;
  562. } else {
  563. INVAKE_TYPE = INVOKEVIRTUAL;
  564. }
  565. if (fieldInfo.getMethod() != null) {
  566. mw.visitMethodInsn(INVAKE_TYPE, getType(fieldInfo.getDeclaringClass()), fieldInfo.getMethod().getName(),
  567. getDesc(fieldInfo.getMethod()));
  568. if (!fieldInfo.getMethod().getReturnType().equals(Void.TYPE)) {
  569. mw.visitInsn(POP);
  570. }
  571. } else {
  572. mw.visitFieldInsn(PUTFIELD, getType(fieldInfo.getDeclaringClass()), fieldInfo.getField().getName(),
  573. getDesc(fieldInfo.getFieldClass()));
  574. }
  575. }
  576. private void _setContext(Context context, MethodVisitor mw) {
  577. mw.visitVarInsn(ALOAD, 1); // parser
  578. mw.visitVarInsn(ALOAD, context.var("context"));
  579. mw.visitMethodInsn(INVOKEVIRTUAL, getType(DefaultJSONParser.class), "setContext",
  580. "(" + ASMUtils.getDesc(ParseContext.class) + ")V");
  581. Label endIf_ = new Label();
  582. mw.visitVarInsn(ALOAD, context.var("childContext"));
  583. mw.visitJumpInsn(IFNULL, endIf_);
  584. mw.visitVarInsn(ALOAD, context.var("childContext"));
  585. mw.visitVarInsn(ALOAD, context.var("instance"));
  586. mw.visitMethodInsn(INVOKEVIRTUAL, getType(ParseContext.class), "setObject", "(Ljava/lang/Object;)V");
  587. mw.visitLabel(endIf_);
  588. }
  589. private void _deserialize_endCheck(Context context, MethodVisitor mw, Label reset_) {
  590. Label _end_if = new Label();
  591. // Label nextToken_ = new Label();
  592. // mw.visitFieldInsn(GETSTATIC, getType(System.class), "out", "Ljava/io/PrintStream;");
  593. // mw.visitIntInsn(ILOAD, context.var("matchedCount"));
  594. // mw.visitMethodInsn(INVOKEVIRTUAL, getType(java.io.PrintStream.class), "println", "(I)V");
  595. mw.visitIntInsn(ILOAD, context.var("matchedCount"));
  596. mw.visitJumpInsn(IFLE, reset_);
  597. // mw.visitFieldInsn(GETSTATIC, getType(System.class), "out", "Ljava/io/PrintStream;");
  598. // mw.visitVarInsn(ALOAD, context.var("lexer"));
  599. // mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "token", "()I");
  600. // mw.visitMethodInsn(INVOKEVIRTUAL, getType(java.io.PrintStream.class), "println", "(I)V");
  601. mw.visitVarInsn(ALOAD, context.var("lexer"));
  602. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "token", "()I");
  603. mw.visitFieldInsn(GETSTATIC, getType(JSONToken.class), "RBRACE", "I");
  604. mw.visitJumpInsn(IF_ICMPNE, reset_);
  605. // mw.visitLabel(nextToken_);
  606. mw.visitVarInsn(ALOAD, context.var("lexer"));
  607. mw.visitFieldInsn(GETSTATIC, getType(JSONToken.class), "COMMA", "I");
  608. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "nextToken", "(I)V");
  609. mw.visitLabel(_end_if);
  610. }
  611. private void _deserialze_list_obj(Context context, MethodVisitor mw, Label reset_, FieldInfo fieldInfo,
  612. Class<?> fieldClass, Class<?> itemType, int i) {
  613. Label matched_ = new Label();
  614. Label _end_if = new Label();
  615. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "matchField", "([C)Z");
  616. mw.visitJumpInsn(IFNE, matched_);
  617. mw.visitInsn(ACONST_NULL);
  618. mw.visitVarInsn(ASTORE, context.var(fieldInfo.getName() + "_asm"));
  619. mw.visitJumpInsn(GOTO, _end_if);
  620. mw.visitLabel(matched_);
  621. _setFlag(mw, context, i);
  622. Label notNull_ = new Label();
  623. mw.visitVarInsn(ALOAD, 0);
  624. mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_list_item_deser__",
  625. getDesc(ObjectDeserializer.class));
  626. mw.visitJumpInsn(IFNONNULL, notNull_);
  627. mw.visitVarInsn(ALOAD, 0);
  628. mw.visitVarInsn(ALOAD, 1);
  629. mw.visitMethodInsn(INVOKEVIRTUAL, getType(DefaultJSONParser.class), "getConfig", "()"
  630. + getDesc(ParserConfig.class));
  631. mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc(itemType)));
  632. mw.visitMethodInsn(INVOKEVIRTUAL, getType(ParserConfig.class), "getDeserializer",
  633. "(" + getDesc(Type.class) + ")" + getDesc(ObjectDeserializer.class));
  634. mw.visitFieldInsn(PUTFIELD, context.getClassName(), fieldInfo.getName() + "_asm_list_item_deser__",
  635. getDesc(ObjectDeserializer.class));
  636. mw.visitLabel(notNull_);
  637. // if (lexer.token() != JSONToken.LBRACKET) reset
  638. mw.visitVarInsn(ALOAD, context.var("lexer"));
  639. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "token", "()I");
  640. mw.visitFieldInsn(GETSTATIC, getType(JSONToken.class), "LBRACKET", "I");
  641. mw.visitJumpInsn(IF_ICMPNE, reset_);
  642. mw.visitVarInsn(ALOAD, 0);
  643. mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_list_item_deser__",
  644. getDesc(ObjectDeserializer.class));
  645. mw.visitMethodInsn(INVOKEINTERFACE, getType(ObjectDeserializer.class), "getFastMatchToken", "()I");
  646. mw.visitVarInsn(ISTORE, context.var("fastMatchToken"));
  647. mw.visitVarInsn(ALOAD, context.var("lexer"));
  648. mw.visitVarInsn(ILOAD, context.var("fastMatchToken"));
  649. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "nextToken", "(I)V");
  650. if (fieldClass.isAssignableFrom(ArrayList.class)) {
  651. mw.visitTypeInsn(NEW, getType(ArrayList.class));
  652. mw.visitInsn(DUP);
  653. mw.visitMethodInsn(INVOKESPECIAL, getType(ArrayList.class), "<init>", "()V");
  654. } else if (fieldClass.isAssignableFrom(LinkedList.class)) {
  655. mw.visitTypeInsn(NEW, getType(LinkedList.class));
  656. mw.visitInsn(DUP);
  657. mw.visitMethodInsn(INVOKESPECIAL, getType(LinkedList.class), "<init>", "()V");
  658. } else if (fieldClass.isAssignableFrom(HashSet.class)) {
  659. mw.visitTypeInsn(NEW, getType(HashSet.class));
  660. mw.visitInsn(DUP);
  661. mw.visitMethodInsn(INVOKESPECIAL, getType(HashSet.class), "<init>", "()V");
  662. } else if (fieldClass.isAssignableFrom(TreeSet.class)) {
  663. mw.visitTypeInsn(NEW, getType(TreeSet.class));
  664. mw.visitInsn(DUP);
  665. mw.visitMethodInsn(INVOKESPECIAL, getType(TreeSet.class), "<init>", "()V");
  666. } else {
  667. mw.visitTypeInsn(NEW, getType(fieldClass));
  668. mw.visitInsn(DUP);
  669. mw.visitMethodInsn(INVOKESPECIAL, getType(fieldClass), "<init>", "()V");
  670. }
  671. mw.visitTypeInsn(CHECKCAST, getType(fieldClass)); // cast
  672. mw.visitVarInsn(ASTORE, context.var(fieldInfo.getName() + "_asm"));
  673. { // setContext
  674. mw.visitVarInsn(ALOAD, 1);
  675. mw.visitMethodInsn(INVOKEVIRTUAL, getType(DefaultJSONParser.class), "getContext",
  676. "()" + ASMUtils.getDesc(ParseContext.class));
  677. mw.visitVarInsn(ASTORE, context.var("listContext"));
  678. mw.visitVarInsn(ALOAD, 1); // parser
  679. mw.visitVarInsn(ALOAD, context.var(fieldInfo.getName() + "_asm"));
  680. mw.visitLdcInsn(fieldInfo.getName());
  681. mw.visitMethodInsn(INVOKEVIRTUAL, getType(DefaultJSONParser.class), "setContext",
  682. "(Ljava/lang/Object;Ljava/lang/Object;)" + ASMUtils.getDesc(ParseContext.class));
  683. mw.visitInsn(POP);
  684. }
  685. Label loop_ = new Label();
  686. Label loop_end_ = new Label();
  687. // for (;;) {
  688. mw.visitInsn(ICONST_0);
  689. mw.visitVarInsn(ISTORE, context.var("i"));
  690. mw.visitLabel(loop_);
  691. mw.visitVarInsn(ALOAD, context.var("lexer"));
  692. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "token", "()I");
  693. mw.visitFieldInsn(GETSTATIC, getType(JSONToken.class), "RBRACKET", "I");
  694. mw.visitJumpInsn(IF_ICMPEQ, loop_end_);
  695. // Object value = itemDeserializer.deserialze(parser, null);
  696. // array.add(value);
  697. mw.visitVarInsn(ALOAD, 0);
  698. mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_list_item_deser__",
  699. getDesc(ObjectDeserializer.class));
  700. mw.visitVarInsn(ALOAD, 1);
  701. mw.visitInsn(ACONST_NULL);
  702. mw.visitVarInsn(ILOAD, context.var("i"));
  703. mw.visitMethodInsn(INVOKESTATIC, getType(Integer.class), "valueOf", "(I)Ljava/lang/Integer;");
  704. mw.visitMethodInsn(INVOKEINTERFACE, getType(ObjectDeserializer.class), "deserialze",
  705. "(" + ASMUtils.getDesc(DefaultJSONParser.class)
  706. + "Ljava/lang/reflect/Type;Ljava/lang/Object;)Ljava/lang/Object;");
  707. mw.visitVarInsn(ASTORE, context.var("list_item_value"));
  708. mw.visitIincInsn(context.var("i"), 1);
  709. mw.visitVarInsn(ALOAD, context.var(fieldInfo.getName() + "_asm"));
  710. mw.visitVarInsn(ALOAD, context.var("list_item_value"));
  711. if (fieldClass.isInterface()) {
  712. mw.visitMethodInsn(INVOKEINTERFACE, getType(fieldClass), "add", "(Ljava/lang/Object;)Z");
  713. } else {
  714. mw.visitMethodInsn(INVOKEVIRTUAL, getType(fieldClass), "add", "(Ljava/lang/Object;)Z");
  715. }
  716. mw.visitInsn(POP);
  717. mw.visitVarInsn(ALOAD, 1);
  718. mw.visitVarInsn(ALOAD, context.var(fieldInfo.getName() + "_asm"));
  719. mw.visitMethodInsn(INVOKEVIRTUAL, getType(DefaultJSONParser.class), "checkListResolve",
  720. "(Ljava/util/Collection;)V");
  721. // if (lexer.token() == JSONToken.COMMA) {
  722. // lexer.nextToken(itemDeserializer.getFastMatchToken());
  723. // continue;
  724. // }
  725. mw.visitVarInsn(ALOAD, context.var("lexer"));
  726. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "token", "()I");
  727. mw.visitFieldInsn(GETSTATIC, getType(JSONToken.class), "COMMA", "I");
  728. mw.visitJumpInsn(IF_ICMPNE, loop_);
  729. mw.visitVarInsn(ALOAD, context.var("lexer"));
  730. mw.visitVarInsn(ILOAD, context.var("fastMatchToken"));
  731. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "nextToken", "(I)V");
  732. mw.visitJumpInsn(GOTO, loop_);
  733. mw.visitLabel(loop_end_);
  734. // mw.visitVarInsn(ASTORE, context.var("context"));
  735. // parser.setContext(context);
  736. { // setContext
  737. mw.visitVarInsn(ALOAD, 1); // parser
  738. mw.visitVarInsn(ALOAD, context.var("listContext"));
  739. mw.visitMethodInsn(INVOKEVIRTUAL, getType(DefaultJSONParser.class), "setContext",
  740. "(" + ASMUtils.getDesc(ParseContext.class) + ")V");
  741. }
  742. mw.visitVarInsn(ALOAD, context.var("lexer"));
  743. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "token", "()I");
  744. mw.visitFieldInsn(GETSTATIC, getType(JSONToken.class), "RBRACKET", "I");
  745. mw.visitJumpInsn(IF_ICMPNE, reset_);
  746. mw.visitVarInsn(ALOAD, context.var("lexer"));
  747. mw.visitFieldInsn(GETSTATIC, getType(JSONToken.class), "COMMA", "I");
  748. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "nextToken", "(I)V");
  749. // lexer.nextToken(JSONToken.COMMA);
  750. mw.visitLabel(_end_if);
  751. }
  752. private void _deserialze_obj(Context context, MethodVisitor mw, Label reset_, FieldInfo fieldInfo,
  753. Class<?> fieldClass, int i) {
  754. Label matched_ = new Label();
  755. Label _end_if = new Label();
  756. mw.visitVarInsn(ALOAD, context.var("lexer"));
  757. mw.visitVarInsn(ALOAD, 0);
  758. mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_prefix__", "[C");
  759. mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "matchField", "([C)Z");
  760. mw.visitJumpInsn(IFNE, matched_);
  761. mw.visitInsn(ACONST_NULL);
  762. mw.visitVarInsn(ASTORE, context.var(fieldInfo.getName() + "_asm"));
  763. mw.visitJumpInsn(GOTO, _end_if);
  764. mw.visitLabel(matched_);
  765. _setFlag(mw, context, i);
  766. // increment matchedCount
  767. mw.visitVarInsn(ILOAD, context.var("matchedCount"));
  768. mw.visitInsn(ICONST_1);
  769. mw.visitInsn(IADD);
  770. mw.visitVarInsn(ISTORE, context.var("matchedCount"));
  771. Label notNull_ = new Label();
  772. mw.visitVarInsn(ALOAD, 0);
  773. mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_deser__",
  774. getDesc(ObjectDeserializer.class));
  775. mw.visitJumpInsn(IFNONNULL, notNull_);
  776. mw.visitVarInsn(ALOAD, 0);
  777. mw.visitVarInsn(ALOAD, 1);
  778. mw.visitMethodInsn(INVOKEVIRTUAL, getType(DefaultJSONParser.class), "getConfig", "()"
  779. + getDesc(ParserConfig.class));
  780. mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc(fieldInfo.getFieldClass())));
  781. mw.visitMethodInsn(INVOKEVIRTUAL, getType(ParserConfig.class), "getDeserializer",
  782. "(" + getDesc(Type.class) + ")" + getDesc(ObjectDeserializer.class));
  783. mw.visitFieldInsn(PUTFIELD, context.getClassName(), fieldInfo.getName() + "_asm_deser__",
  784. getDesc(ObjectDeserializer.class));
  785. mw.visitLabel(notNull_);
  786. mw.visitVarInsn(ALOAD, 0);
  787. mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_deser__",
  788. getDesc(ObjectDeserializer.class));
  789. mw.visitVarInsn(ALOAD, 1);
  790. if (fieldInfo.getFieldType() instanceof Class) {
  791. mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc(fieldInfo.getFieldClass())));
  792. } else {
  793. mw.visitVarInsn(ALOAD, 0);
  794. mw.visitLdcInsn(fieldInfo.getName());
  795. mw.visitMethodInsn(INVOKEVIRTUAL, getType(ASMJavaBeanDeserializer.class), "getFieldType",
  796. "(Ljava/lang/String;)Ljava/lang/reflect/Type;");
  797. }
  798. mw.visitLdcInsn(fieldInfo.getName());
  799. mw.visitMethodInsn(INVOKEINTERFACE, getType(ObjectDeserializer.class), "deserialze",
  800. "(" + getDesc(DefaultJSONParser.class) + getDesc(Type.class)
  801. + "Ljava/lang/Object;)Ljava/lang/Object;");
  802. mw.visitTypeInsn(CHECKCAST, getType(fieldClass)); // cast
  803. mw.visitVarInsn(ASTORE, context.var(fieldInfo.getName() + "_asm"));
  804. mw.visitVarInsn(ALOAD, 1);
  805. mw.visitMethodInsn(INVOKEVIRTUAL, getType(DefaultJSONParser.class), "getResolveStatus", "()I");
  806. mw.visitFieldInsn(GETSTATIC, getType(DefaultJSONParser.class), "NeedToResolve", "I");
  807. mw.visitJumpInsn(IF_ICMPNE, _end_if);
  808. // ResolveTask task = parser.getLastResolveTask();
  809. // task.setFieldDeserializer(this);
  810. // task.setOwnerContext(parser.getContext());
  811. mw.visitVarInsn(ALOAD, 1);
  812. mw.visitMethodInsn(INVOKEVIRTUAL, getType(DefaultJSONParser.class), "getLastResolveTask",
  813. "()" + getDesc(ResolveTask.class));
  814. mw.visitVarInsn(ASTORE, context.var("resolveTask"));
  815. mw.visitVarInsn(ALOAD, context.var("resolveTask"));
  816. mw.visitVarInsn(ALOAD, 1);
  817. mw.visitMethodInsn(INVOKEVIRTUAL, getType(DefaultJSONParser.class), "getContext", "()"
  818. + getDesc(ParseContext.class));
  819. mw.visitMethodInsn(INVOKEVIRTUAL, getType(ResolveTask.class), "setOwnerContext", "("
  820. + getDesc(ParseContext.class)
  821. + ")V");
  822. mw.visitVarInsn(ALOAD, context.var("resolveTask"));
  823. mw.visitVarInsn(ALOAD, 0);
  824. mw.visitLdcInsn(fieldInfo.getName());
  825. mw.visitMethodInsn(INVOKEVIRTUAL, getType(ASMJavaBeanDeserializer.class), "getFieldDeserializer",
  826. "(Ljava/lang/String;)" + getDesc(FieldDeserializer.class));
  827. mw.visitMethodInsn(INVOKEVIRTUAL, getType(ResolveTask.class), "setFieldDeserializer",
  828. "(" + getDesc(FieldDeserializer.class) + ")V");
  829. mw.visitVarInsn(ALOAD, 1);
  830. mw.visitFieldInsn(GETSTATIC, getType(DefaultJSONParser.class), "NONE", "I");
  831. mw.visitMethodInsn(INVOKEVIRTUAL, getType(DefaultJSONParser.class), "setResolveStatus", "(I)V");
  832. mw.visitLabel(_end_if);
  833. }
  834. public FieldDeserializer createFieldDeserializer(ParserConfig mapping, Class<?> clazz, FieldInfo fieldInfo)
  835. throws Exception {
  836. Class<?> fieldClass = fieldInfo.getFieldClass();
  837. if (fieldClass == int.class || fieldClass == long.class || fieldClass == String.class) {
  838. return createStringFieldDeserializer(mapping, clazz, fieldInfo);
  839. }
  840. FieldDeserializer fieldDeserializer = mapping.createFieldDeserializ