Skip to content

Commit

Permalink
refactor ASMDeserializerFactory
Browse files Browse the repository at this point in the history
  • Loading branch information
wenshao committed Apr 18, 2016
1 parent 080d068 commit 7f16b57
Show file tree
Hide file tree
Showing 9 changed files with 290 additions and 285 deletions.
12 changes: 6 additions & 6 deletions src/main/java/com/alibaba/fastjson/JSON.java
Expand Up @@ -61,13 +61,13 @@
* @author wenshao[szujobs@hotmail.com] * @author wenshao[szujobs@hotmail.com]
*/ */
public abstract class JSON implements JSONStreamAware, JSONAware { public abstract class JSON implements JSONStreamAware, JSONAware {
public static TimeZone defaultTimeZone = TimeZone.getDefault(); public static TimeZone defaultTimeZone = TimeZone.getDefault();
public static Locale defaultLocale = Locale.getDefault(); public static Locale defaultLocale = Locale.getDefault();


public static String DEFAULT_TYPE_KEY = "@type"; public static String DEFAULT_TYPE_KEY = "@type";

public static int DEFAULT_PARSER_FEATURE;


public static int DEFAULT_PARSER_FEATURE;

static final SerializeFilter[] emptyFilters = new SerializeFilter[0]; static final SerializeFilter[] emptyFilters = new SerializeFilter[0];


// /** // /**
Expand Down
13 changes: 3 additions & 10 deletions src/main/java/com/alibaba/fastjson/parser/JSONLexerBase.java
Expand Up @@ -452,7 +452,7 @@ public final Number integerValue() throws NumberFormatException {
} else { } else {
limit = -Long.MAX_VALUE; limit = -Long.MAX_VALUE;
} }
multmin = negative ? MULTMIN_RADIX_TEN : N_MULTMAX_RADIX_TEN; multmin = MULTMIN_RADIX_TEN;
if (i < max) { if (i < max) {
digit = digits[charAt(i++)]; digit = digits[charAt(i++)];
result = -digit; result = -digit;
Expand Down Expand Up @@ -1016,7 +1016,6 @@ public final int intValue() {
boolean negative = false; boolean negative = false;
int i = np, max = np + sp; int i = np, max = np + sp;
int limit; int limit;
int multmin;
int digit; int digit;


if (charAt(np) == '-') { if (charAt(np) == '-') {
Expand All @@ -1026,7 +1025,7 @@ public final int intValue() {
} else { } else {
limit = -Integer.MAX_VALUE; limit = -Integer.MAX_VALUE;
} }
multmin = negative ? INT_MULTMIN_RADIX_TEN : INT_N_MULTMAX_RADIX_TEN; long multmin = INT_MULTMIN_RADIX_TEN;
if (i < max) { if (i < max) {
digit = digits[charAt(i++)]; digit = digits[charAt(i++)];
result = -digit; result = -digit;
Expand Down Expand Up @@ -2918,7 +2917,6 @@ public final long longValue() throws NumberFormatException {
long result = 0; long result = 0;
boolean negative = false; boolean negative = false;
long limit; long limit;
long multmin;
int digit; int digit;


if (np == -1) { if (np == -1) {
Expand All @@ -2934,7 +2932,7 @@ public final long longValue() throws NumberFormatException {
} else { } else {
limit = -Long.MAX_VALUE; limit = -Long.MAX_VALUE;
} }
multmin = negative ? MULTMIN_RADIX_TEN : N_MULTMAX_RADIX_TEN; long multmin = MULTMIN_RADIX_TEN;
if (i < max) { if (i < max) {
digit = digits[charAt(i++)]; digit = digits[charAt(i++)];
result = -digit; result = -digit;
Expand Down Expand Up @@ -2973,12 +2971,10 @@ public final Number decimalValue(boolean decimal) {
char chLocal = charAt(np + sp - 1); char chLocal = charAt(np + sp - 1);
if (chLocal == 'F') { if (chLocal == 'F') {
return Float.parseFloat(numberString()); return Float.parseFloat(numberString());
// return Float.parseFloat(new String(buf, np, sp - 1));
} }


if (chLocal == 'D') { if (chLocal == 'D') {
return Double.parseDouble(numberString()); return Double.parseDouble(numberString());
// return Double.parseDouble(new String(buf, np, sp - 1));
} }


if (decimal) { if (decimal) {
Expand All @@ -2998,10 +2994,7 @@ public static boolean isWhitespace(char ch) {
} }


protected static final long MULTMIN_RADIX_TEN = Long.MIN_VALUE / 10; protected static final long MULTMIN_RADIX_TEN = Long.MIN_VALUE / 10;
protected static final long N_MULTMAX_RADIX_TEN = -Long.MAX_VALUE / 10;

protected static final int INT_MULTMIN_RADIX_TEN = Integer.MIN_VALUE / 10; protected static final int INT_MULTMIN_RADIX_TEN = Integer.MIN_VALUE / 10;
protected static final int INT_N_MULTMAX_RADIX_TEN = -Integer.MAX_VALUE / 10;


protected final static int[] digits = new int[(int) 'f' + 1]; protected final static int[] digits = new int[(int) 'f' + 1];


Expand Down

Large diffs are not rendered by default.

@@ -1,7 +1,7 @@
package com.alibaba.fastjson.serializer; package com.alibaba.fastjson.serializer;


import static com.alibaba.fastjson.util.ASMUtils.getDesc; import static com.alibaba.fastjson.util.ASMUtils.desc;
import static com.alibaba.fastjson.util.ASMUtils.getType; import static com.alibaba.fastjson.util.ASMUtils.type;


import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
Expand Down Expand Up @@ -161,7 +161,7 @@ public ObjectSerializer createJavaBeanSerializer(Class<?> clazz, Map<String, Str


MethodVisitor mw = new MethodWriter(cw, ACC_PUBLIC, "<init>", "()V", null, null); MethodVisitor mw = new MethodWriter(cw, ACC_PUBLIC, "<init>", "()V", null, null);
mw.visitVarInsn(ALOAD, 0); mw.visitVarInsn(ALOAD, 0);
mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc(clazz))); mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc(clazz)));
mw.visitMethodInsn(INVOKESPECIAL, "com/alibaba/fastjson/serializer/ASMJavaBeanSerializer", "<init>", "(Ljava/lang/Class;)V"); mw.visitMethodInsn(INVOKESPECIAL, "com/alibaba/fastjson/serializer/ASMJavaBeanSerializer", "<init>", "(Ljava/lang/Class;)V");


// init _asm_fieldType // init _asm_fieldType
Expand All @@ -174,7 +174,7 @@ public ObjectSerializer createJavaBeanSerializer(Class<?> clazz, Map<String, Str


mw.visitVarInsn(ALOAD, 0); mw.visitVarInsn(ALOAD, 0);


mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc(fieldInfo.declaringClass))); mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc(fieldInfo.declaringClass)));


if (fieldInfo.method != null) { if (fieldInfo.method != null) {
mw.visitLdcInsn(fieldInfo.method.getName()); mw.visitLdcInsn(fieldInfo.method.getName());
Expand Down Expand Up @@ -269,7 +269,7 @@ public ObjectSerializer createJavaBeanSerializer(Class<?> clazz, Map<String, Str




mw.visitVarInsn(ALOAD, Context.obj); // obj mw.visitVarInsn(ALOAD, Context.obj); // obj
mw.visitTypeInsn(CHECKCAST, getType(clazz)); // serializer mw.visitTypeInsn(CHECKCAST, type(clazz)); // serializer
mw.visitVarInsn(ASTORE, context.var("entity")); // obj mw.visitVarInsn(ASTORE, context.var("entity")); // obj
generateWriteMethod(clazz, mw, getters, context); generateWriteMethod(clazz, mw, getters, context);
mw.visitInsn(RETURN); mw.visitInsn(RETURN);
Expand All @@ -292,7 +292,7 @@ public ObjectSerializer createJavaBeanSerializer(Class<?> clazz, Map<String, Str
mw.visitVarInsn(ASTORE, context.var("out")); mw.visitVarInsn(ASTORE, context.var("out"));


mw.visitVarInsn(ALOAD, Context.obj); // obj mw.visitVarInsn(ALOAD, Context.obj); // obj
mw.visitTypeInsn(CHECKCAST, getType(clazz)); // serializer mw.visitTypeInsn(CHECKCAST, type(clazz)); // serializer
mw.visitVarInsn(ASTORE, context.var("entity")); // obj mw.visitVarInsn(ASTORE, context.var("entity")); // obj


generateWriteMethod(clazz, mw, unsortedGetters, context); generateWriteMethod(clazz, mw, unsortedGetters, context);
Expand All @@ -317,7 +317,7 @@ public ObjectSerializer createJavaBeanSerializer(Class<?> clazz, Map<String, Str
mw.visitVarInsn(ASTORE, context.var("out")); mw.visitVarInsn(ASTORE, context.var("out"));


mw.visitVarInsn(ALOAD, Context.obj); // obj mw.visitVarInsn(ALOAD, Context.obj); // obj
mw.visitTypeInsn(CHECKCAST, getType(clazz)); // serializer mw.visitTypeInsn(CHECKCAST, type(clazz)); // serializer
mw.visitVarInsn(ASTORE, context.var("entity")); // obj mw.visitVarInsn(ASTORE, context.var("entity")); // obj
generateWriteAsArray(clazz, mw, getters, context); generateWriteAsArray(clazz, mw, getters, context);
mw.visitInsn(RETURN); mw.visitInsn(RETURN);
Expand Down Expand Up @@ -843,11 +843,11 @@ private void _get(MethodVisitor mw, Context context, FieldInfo property) {
Method method = property.method; Method method = property.method;
if (method != null) { if (method != null) {
mw.visitVarInsn(ALOAD, context.var("entity")); mw.visitVarInsn(ALOAD, context.var("entity"));
mw.visitMethodInsn(INVOKEVIRTUAL, getType(method.getDeclaringClass()), method.getName(), getDesc(method)); mw.visitMethodInsn(INVOKEVIRTUAL, type(method.getDeclaringClass()), method.getName(), desc(method));
} else { } else {
mw.visitVarInsn(ALOAD, context.var("entity")); mw.visitVarInsn(ALOAD, context.var("entity"));
mw.visitFieldInsn(GETFIELD, getType(property.declaringClass), property.field.getName(), mw.visitFieldInsn(GETFIELD, type(property.declaringClass), property.field.getName(),
getDesc(property.fieldClass)); desc(property.fieldClass));
} }
} }


Expand Down Expand Up @@ -1124,7 +1124,7 @@ private void _list(Class<?> clazz, MethodVisitor mw, FieldInfo property, Context
mw.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;"); mw.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;");


if (elementClass != null && Modifier.isPublic(elementClass.getModifiers())) { if (elementClass != null && Modifier.isPublic(elementClass.getModifiers())) {
mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc((Class<?>) elementType))); mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc((Class<?>) elementType)));
mw.visitLdcInsn(property.serialzeFeatures); mw.visitLdcInsn(property.serialzeFeatures);
mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JSONSerializer", "writeWithFieldName", mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JSONSerializer", "writeWithFieldName",
"(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V"); "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V");
Expand Down Expand Up @@ -1169,7 +1169,7 @@ private void _list(Class<?> clazz, MethodVisitor mw, FieldInfo property, Context
mw.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;"); mw.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;");


if (elementClass != null && Modifier.isPublic(elementClass.getModifiers())) { if (elementClass != null && Modifier.isPublic(elementClass.getModifiers())) {
mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc((Class<?>) elementType))); mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc((Class<?>) elementType)));
mw.visitLdcInsn(property.serialzeFeatures); mw.visitLdcInsn(property.serialzeFeatures);
mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JSONSerializer", "writeWithFieldName", mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JSONSerializer", "writeWithFieldName",
"(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V"); "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V");
Expand Down Expand Up @@ -1310,7 +1310,7 @@ private void _writeObject(MethodVisitor mw, FieldInfo fieldInfo, Context context
"(Ljava/lang/Object;Ljava/lang/Object;)V"); "(Ljava/lang/Object;Ljava/lang/Object;)V");
} else { } else {
if (fieldInfo.fieldClass == String.class) { if (fieldInfo.fieldClass == String.class) {
mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc(String.class))); mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc(String.class)));
} else { } else {
mw.visitVarInsn(ALOAD, 0); mw.visitVarInsn(ALOAD, 0);
mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_fieldType", mw.visitFieldInsn(GETFIELD, context.className, fieldInfo.name + "_asm_fieldType",
Expand Down
17 changes: 9 additions & 8 deletions src/main/java/com/alibaba/fastjson/util/ASMUtils.java
Expand Up @@ -28,31 +28,31 @@ public static boolean isAndroid(String vmName) {
; ;
} }


public static String getDesc(Method method) { public static String desc(Method method) {
Class<?>[] types = method.getParameterTypes(); Class<?>[] types = method.getParameterTypes();
StringBuilder buf = new StringBuilder((types.length + 1) << 4); StringBuilder buf = new StringBuilder((types.length + 1) << 4);
buf.append('('); buf.append('(');
for (int i = 0; i < types.length; ++i) { for (int i = 0; i < types.length; ++i) {
buf.append(getDesc(types[i])); buf.append(desc(types[i]));
} }
buf.append(')'); buf.append(')');
buf.append(getDesc(method.getReturnType())); buf.append(desc(method.getReturnType()));
return buf.toString(); return buf.toString();
} }


public static String getDesc(Class<?> returnType) { public static String desc(Class<?> returnType) {
if (returnType.isPrimitive()) { if (returnType.isPrimitive()) {
return getPrimitiveLetter(returnType); return getPrimitiveLetter(returnType);
} else if (returnType.isArray()) { } else if (returnType.isArray()) {
return "[" + getDesc(returnType.getComponentType()); return "[" + desc(returnType.getComponentType());
} else { } else {
return "L" + getType(returnType) + ";"; return "L" + type(returnType) + ";";
} }
} }


public static String getType(Class<?> parameterType) { public static String type(Class<?> parameterType) {
if (parameterType.isArray()) { if (parameterType.isArray()) {
return "[" + getDesc(parameterType.getComponentType()); return "[" + desc(parameterType.getComponentType());
} else { } else {
if (!parameterType.isPrimitive()) { if (!parameterType.isPrimitive()) {
String clsName = parameterType.getName(); String clsName = parameterType.getName();
Expand All @@ -62,6 +62,7 @@ public static String getType(Class<?> parameterType) {
} }
} }
} }



public static String getPrimitiveLetter(Class<?> type) { public static String getPrimitiveLetter(Class<?> type) {
if (Integer.TYPE.equals(type)) { if (Integer.TYPE.equals(type)) {
Expand Down
2 changes: 1 addition & 1 deletion src/test/java/com/alibaba/json/bvt/asm/ASMUtilsTest.java
Expand Up @@ -17,7 +17,7 @@ public void test_isAnroid() throws Exception {
} }


public void test_getDescs() throws Exception { public void test_getDescs() throws Exception {
Assert.assertEquals("Lcom/alibaba/fastjson/parser/ParseContext;", ASMUtils.getDesc(ParseContext.class)); Assert.assertEquals("Lcom/alibaba/fastjson/parser/ParseContext;", ASMUtils.desc(ParseContext.class));
} }


public void test_getType_null() throws Exception { public void test_getType_null() throws Exception {
Expand Down
8 changes: 4 additions & 4 deletions src/test/java/com/alibaba/json/bvt/asm/JSONASMUtilTest.java
Expand Up @@ -8,10 +8,10 @@
public class JSONASMUtilTest extends TestCase { public class JSONASMUtilTest extends TestCase {


public void test_1() throws Exception { public void test_1() throws Exception {
Assert.assertEquals("V", ASMUtils.getDesc(Void.TYPE)); Assert.assertEquals("V", ASMUtils.desc(Void.TYPE));
Assert.assertEquals("J", ASMUtils.getDesc(Long.TYPE)); Assert.assertEquals("J", ASMUtils.desc(Long.TYPE));
Assert.assertEquals("[J", ASMUtils.getDesc(long[].class)); Assert.assertEquals("[J", ASMUtils.desc(long[].class));
Assert.assertEquals("[Ljava/lang/Long;", ASMUtils.getDesc(Long[].class)); Assert.assertEquals("[Ljava/lang/Long;", ASMUtils.desc(Long[].class));
} }


public void test_error_1() throws Exception { public void test_error_1() throws Exception {
Expand Down
24 changes: 12 additions & 12 deletions src/test/java/com/alibaba/json/bvt/asm/TestType.java
Expand Up @@ -9,27 +9,27 @@
public class TestType extends TestCase { public class TestType extends TestCase {


public void test_getType() throws Exception { public void test_getType() throws Exception {
Assert.assertEquals(Type.VOID_TYPE, Type.getType(ASMUtils.getDesc(void.class))); Assert.assertEquals(Type.VOID_TYPE, Type.getType(ASMUtils.desc(void.class)));


Assert.assertEquals(Type.BOOLEAN_TYPE, Type.getType(ASMUtils.getDesc(boolean.class))); Assert.assertEquals(Type.BOOLEAN_TYPE, Type.getType(ASMUtils.desc(boolean.class)));


Assert.assertEquals(Type.CHAR_TYPE, Type.getType(ASMUtils.getDesc(char.class))); Assert.assertEquals(Type.CHAR_TYPE, Type.getType(ASMUtils.desc(char.class)));


Assert.assertEquals(Type.BYTE_TYPE, Type.getType(ASMUtils.getDesc(byte.class))); Assert.assertEquals(Type.BYTE_TYPE, Type.getType(ASMUtils.desc(byte.class)));


Assert.assertEquals(Type.SHORT_TYPE, Type.getType(ASMUtils.getDesc(short.class))); Assert.assertEquals(Type.SHORT_TYPE, Type.getType(ASMUtils.desc(short.class)));


Assert.assertEquals(Type.INT_TYPE, Type.getType(ASMUtils.getDesc(int.class))); Assert.assertEquals(Type.INT_TYPE, Type.getType(ASMUtils.desc(int.class)));


Assert.assertEquals(Type.LONG_TYPE, Type.getType(ASMUtils.getDesc(long.class))); Assert.assertEquals(Type.LONG_TYPE, Type.getType(ASMUtils.desc(long.class)));


Assert.assertEquals(Type.FLOAT_TYPE, Type.getType(ASMUtils.getDesc(float.class))); Assert.assertEquals(Type.FLOAT_TYPE, Type.getType(ASMUtils.desc(float.class)));


Assert.assertEquals(Type.DOUBLE_TYPE, Type.getType(ASMUtils.getDesc(double.class))); Assert.assertEquals(Type.DOUBLE_TYPE, Type.getType(ASMUtils.desc(double.class)));


Assert.assertEquals("[D", Type.getType(ASMUtils.getDesc(double[].class)).getInternalName()); Assert.assertEquals("[D", Type.getType(ASMUtils.desc(double[].class)).getInternalName());
Assert.assertEquals("[[D", Type.getType(ASMUtils.getDesc(double[][].class)).getInternalName()); Assert.assertEquals("[[D", Type.getType(ASMUtils.desc(double[][].class)).getInternalName());
Assert.assertEquals("[Ljava/lang/Double;", Type.getType(ASMUtils.getDesc(Double[].class)).getInternalName()); Assert.assertEquals("[Ljava/lang/Double;", Type.getType(ASMUtils.desc(Double[].class)).getInternalName());
} }


} }
14 changes: 7 additions & 7 deletions src/test/java/com/alibaba/json/bvt/util/JSONASMUtilTest.java
Expand Up @@ -10,18 +10,18 @@
public class JSONASMUtilTest extends TestCase { public class JSONASMUtilTest extends TestCase {


public void test_0() throws Exception { public void test_0() throws Exception {
Assert.assertEquals("()I", ASMUtils.getDesc(HashMap.class.getMethod("size"))); Assert.assertEquals("()I", ASMUtils.desc(HashMap.class.getMethod("size")));
Assert.assertEquals("(Ljava/lang/Object;)Ljava/lang/Object;", ASMUtils.getDesc(HashMap.class.getMethod("get", Object.class))); Assert.assertEquals("(Ljava/lang/Object;)Ljava/lang/Object;", ASMUtils.desc(HashMap.class.getMethod("get", Object.class)));
Assert.assertEquals("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", ASMUtils.getDesc(HashMap.class.getMethod("put", Object.class, Object.class))); Assert.assertEquals("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", ASMUtils.desc(HashMap.class.getMethod("put", Object.class, Object.class)));
} }


public void test_1() throws Exception { public void test_1() throws Exception {
Assert.assertEquals("I", ASMUtils.getType(int.class)); Assert.assertEquals("I", ASMUtils.type(int.class));
Assert.assertEquals("java/lang/Integer", ASMUtils.getType(Integer.class)); Assert.assertEquals("java/lang/Integer", ASMUtils.type(Integer.class));
} }


public void test_2() throws Exception { public void test_2() throws Exception {
Assert.assertEquals("[I", ASMUtils.getType(int[].class)); Assert.assertEquals("[I", ASMUtils.type(int[].class));
Assert.assertEquals("[Ljava/lang/Integer;", ASMUtils.getType(Integer[].class)); Assert.assertEquals("[Ljava/lang/Integer;", ASMUtils.type(Integer[].class));
} }
} }

0 comments on commit 7f16b57

Please sign in to comment.