Search in sources :

Example 6 with MethodVisitor

use of com.alibaba.fastjson.asm.MethodVisitor in project fastjson by alibaba.

the class ASMDeserializerFactory method _deserialzeArrayMapping.

private void _deserialzeArrayMapping(ClassWriter cw, Context context) {
    MethodVisitor mw = new MethodWriter(cw, ACC_PUBLIC, "deserialzeArrayMapping", "(L" + DefaultJSONParser + ";Ljava/lang/reflect/Type;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", null, null);
    defineVarLexer(context, mw);
    _createInstance(context, mw);
    FieldInfo[] sortedFieldInfoList = context.beanInfo.sortedFields;
    int fieldListSize = sortedFieldInfoList.length;
    for (int i = 0; i < fieldListSize; ++i) {
        final boolean last = (i == fieldListSize - 1);
        final char seperator = last ? ']' : ',';
        FieldInfo fieldInfo = sortedFieldInfoList[i];
        Class<?> fieldClass = fieldInfo.fieldClass;
        Type fieldType = fieldInfo.fieldType;
        if (//
        fieldClass == byte.class || //
        fieldClass == short.class || fieldClass == int.class) {
            mw.visitVarInsn(ALOAD, context.var("lexer"));
            mw.visitVarInsn(BIPUSH, seperator);
            mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanInt", "(C)I");
            mw.visitVarInsn(ISTORE, context.var(fieldInfo.name + "_asm"));
        } else if (fieldClass == long.class) {
            mw.visitVarInsn(ALOAD, context.var("lexer"));
            mw.visitVarInsn(BIPUSH, seperator);
            mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanLong", "(C)J");
            mw.visitVarInsn(LSTORE, context.var(fieldInfo.name + "_asm", 2));
        } else if (fieldClass == boolean.class) {
            mw.visitVarInsn(ALOAD, context.var("lexer"));
            mw.visitVarInsn(BIPUSH, seperator);
            mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanBoolean", "(C)Z");
            mw.visitVarInsn(ISTORE, context.var(fieldInfo.name + "_asm"));
        } else if (fieldClass == float.class) {
            mw.visitVarInsn(ALOAD, context.var("lexer"));
            mw.visitVarInsn(BIPUSH, seperator);
            mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanFloat", "(C)F");
            mw.visitVarInsn(FSTORE, context.var(fieldInfo.name + "_asm"));
        } else if (fieldClass == double.class) {
            mw.visitVarInsn(ALOAD, context.var("lexer"));
            mw.visitVarInsn(BIPUSH, seperator);
            mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanDouble", "(C)D");
            mw.visitVarInsn(DSTORE, context.var(fieldInfo.name + "_asm", 2));
        } else if (fieldClass == char.class) {
            mw.visitVarInsn(ALOAD, context.var("lexer"));
            mw.visitVarInsn(BIPUSH, seperator);
            mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanString", "(C)Ljava/lang/String;");
            mw.visitInsn(ICONST_0);
            mw.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "charAt", "(I)C");
            mw.visitVarInsn(ISTORE, context.var(fieldInfo.name + "_asm"));
        } else if (fieldClass == String.class) {
            mw.visitVarInsn(ALOAD, context.var("lexer"));
            mw.visitVarInsn(BIPUSH, seperator);
            mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanString", "(C)Ljava/lang/String;");
            mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm"));
        } else if (fieldClass.isEnum()) {
            Label enumNumIf_ = new Label();
            Label enumNumErr_ = new Label();
            Label enumStore_ = new Label();
            Label enumQuote_ = new Label();
            mw.visitVarInsn(ALOAD, context.var("lexer"));
            mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "getCurrent", "()C");
            mw.visitInsn(DUP);
            mw.visitVarInsn(ISTORE, context.var("ch"));
            mw.visitLdcInsn((int) 'n');
            mw.visitJumpInsn(IF_ICMPEQ, enumQuote_);
            mw.visitVarInsn(ILOAD, context.var("ch"));
            mw.visitLdcInsn((int) '\"');
            mw.visitJumpInsn(IF_ICMPNE, enumNumIf_);
            mw.visitLabel(enumQuote_);
            mw.visitVarInsn(ALOAD, context.var("lexer"));
            mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc(fieldClass)));
            mw.visitVarInsn(ALOAD, 1);
            mw.visitMethodInsn(INVOKEVIRTUAL, DefaultJSONParser, "getSymbolTable", "()" + desc(SymbolTable.class));
            mw.visitVarInsn(BIPUSH, seperator);
            mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanEnum", "(Ljava/lang/Class;" + desc(SymbolTable.class) + "C)Ljava/lang/Enum;");
            mw.visitJumpInsn(GOTO, enumStore_);
            // (ch >= '0' && ch <= '9') {
            mw.visitLabel(enumNumIf_);
            mw.visitVarInsn(ILOAD, context.var("ch"));
            mw.visitLdcInsn((int) '0');
            mw.visitJumpInsn(IF_ICMPLT, enumNumErr_);
            mw.visitVarInsn(ILOAD, context.var("ch"));
            mw.visitLdcInsn((int) '9');
            mw.visitJumpInsn(IF_ICMPGT, enumNumErr_);
            _getFieldDeser(context, mw, fieldInfo);
            // cast
            mw.visitTypeInsn(CHECKCAST, type(EnumDeserializer.class));
            mw.visitVarInsn(ALOAD, context.var("lexer"));
            mw.visitVarInsn(BIPUSH, seperator);
            mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanInt", "(C)I");
            mw.visitMethodInsn(INVOKEVIRTUAL, type(EnumDeserializer.class), "valueOf", "(I)Ljava/lang/Enum;");
            mw.visitJumpInsn(GOTO, enumStore_);
            mw.visitLabel(enumNumErr_);
            mw.visitVarInsn(ALOAD, 0);
            mw.visitVarInsn(ALOAD, context.var("lexer"));
            mw.visitVarInsn(BIPUSH, seperator);
            mw.visitMethodInsn(INVOKEVIRTUAL, type(JavaBeanDeserializer.class), "scanEnum", "(L" + JSONLexerBase + ";C)Ljava/lang/Enum;");
            mw.visitLabel(enumStore_);
            // cast
            mw.visitTypeInsn(CHECKCAST, type(fieldClass));
            mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm"));
        } else if (Collection.class.isAssignableFrom(fieldClass)) {
            Class<?> itemClass = TypeUtils.getCollectionItemClass(fieldType);
            if (itemClass == String.class) {
                if (fieldClass == List.class || fieldClass == Collections.class || fieldClass == ArrayList.class) {
                    mw.visitTypeInsn(NEW, type(ArrayList.class));
                    mw.visitInsn(DUP);
                    mw.visitMethodInsn(INVOKESPECIAL, type(ArrayList.class), "<init>", "()V");
                } else {
                    mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc(fieldClass)));
                    mw.visitMethodInsn(INVOKESTATIC, type(TypeUtils.class), "createCollection", "(Ljava/lang/Class;)Ljava/util/Collection;");
                }
                mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm"));
                mw.visitVarInsn(ALOAD, context.var("lexer"));
                mw.visitVarInsn(ALOAD, context.var(fieldInfo.name + "_asm"));
                mw.visitVarInsn(BIPUSH, seperator);
                mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanStringArray", "(Ljava/util/Collection;C)V");
                Label valueNullEnd_ = new Label();
                mw.visitVarInsn(ALOAD, context.var("lexer"));
                mw.visitFieldInsn(GETFIELD, JSONLexerBase, "matchStat", "I");
                mw.visitLdcInsn(com.alibaba.fastjson.parser.JSONLexerBase.VALUE_NULL);
                mw.visitJumpInsn(IF_ICMPNE, valueNullEnd_);
                mw.visitInsn(ACONST_NULL);
                mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm"));
                mw.visitLabel(valueNullEnd_);
            } else {
                Label notError_ = new Label();
                mw.visitVarInsn(ALOAD, context.var("lexer"));
                mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "token", "()I");
                mw.visitVarInsn(ISTORE, context.var("token"));
                mw.visitVarInsn(ILOAD, context.var("token"));
                int token = i == 0 ? JSONToken.LBRACKET : JSONToken.COMMA;
                mw.visitLdcInsn(token);
                mw.visitJumpInsn(IF_ICMPEQ, notError_);
                // DefaultJSONParser
                mw.visitVarInsn(ALOAD, 1);
                mw.visitVarInsn(ILOAD, context.var("token"));
                mw.visitMethodInsn(INVOKEVIRTUAL, DefaultJSONParser, "throwException", "(I)V");
                mw.visitLabel(notError_);
                Label quickElse_ = new Label(), quickEnd_ = new Label();
                mw.visitVarInsn(ALOAD, context.var("lexer"));
                mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "getCurrent", "()C");
                mw.visitVarInsn(BIPUSH, '[');
                mw.visitJumpInsn(IF_ICMPNE, quickElse_);
                mw.visitVarInsn(ALOAD, context.var("lexer"));
                mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "next", "()C");
                mw.visitInsn(POP);
                mw.visitVarInsn(ALOAD, context.var("lexer"));
                mw.visitLdcInsn(JSONToken.LBRACKET);
                mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "setToken", "(I)V");
                mw.visitJumpInsn(GOTO, quickEnd_);
                mw.visitLabel(quickElse_);
                mw.visitVarInsn(ALOAD, context.var("lexer"));
                mw.visitLdcInsn(JSONToken.LBRACKET);
                mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "nextToken", "(I)V");
                mw.visitLabel(quickEnd_);
                _newCollection(mw, fieldClass, i, false);
                mw.visitInsn(DUP);
                mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm"));
                _getCollectionFieldItemDeser(context, mw, fieldInfo, itemClass);
                mw.visitVarInsn(ALOAD, 1);
                mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(desc(itemClass)));
                mw.visitVarInsn(ALOAD, 3);
                mw.visitMethodInsn(INVOKESTATIC, type(JavaBeanDeserializer.class), "parseArray", //
                "(Ljava/util/Collection;" + //
                desc(ObjectDeserializer.class) + "L" + DefaultJSONParser + //
                ";" + "Ljava/lang/reflect/Type;Ljava/lang/Object;)V");
            }
        } else if (fieldClass.isArray()) {
            mw.visitVarInsn(ALOAD, context.var("lexer"));
            mw.visitLdcInsn(com.alibaba.fastjson.parser.JSONToken.LBRACKET);
            mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "nextToken", "(I)V");
            mw.visitVarInsn(ALOAD, Context.parser);
            mw.visitVarInsn(ALOAD, 0);
            mw.visitLdcInsn(i);
            mw.visitMethodInsn(INVOKEVIRTUAL, type(JavaBeanDeserializer.class), "getFieldType", "(I)Ljava/lang/reflect/Type;");
            mw.visitMethodInsn(INVOKEVIRTUAL, DefaultJSONParser, "parseObject", "(Ljava/lang/reflect/Type;)Ljava/lang/Object;");
            // cast
            mw.visitTypeInsn(CHECKCAST, type(fieldClass));
            mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm"));
        } else {
            Label objElseIf_ = new Label();
            Label objEndIf_ = new Label();
            if (fieldClass == java.util.Date.class) {
                mw.visitVarInsn(ALOAD, context.var("lexer"));
                mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "getCurrent", "()C");
                mw.visitLdcInsn((int) '1');
                mw.visitJumpInsn(IF_ICMPNE, objElseIf_);
                mw.visitTypeInsn(NEW, type(java.util.Date.class));
                mw.visitInsn(DUP);
                mw.visitVarInsn(ALOAD, context.var("lexer"));
                mw.visitVarInsn(BIPUSH, seperator);
                mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "scanLong", "(C)J");
                mw.visitMethodInsn(INVOKESPECIAL, type(java.util.Date.class), "<init>", "(J)V");
                mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm"));
                mw.visitJumpInsn(GOTO, objEndIf_);
            }
            mw.visitLabel(objElseIf_);
            _quickNextToken(context, mw, JSONToken.LBRACKET);
            _deserObject(context, mw, fieldInfo, fieldClass, i);
            mw.visitVarInsn(ALOAD, 0);
            mw.visitVarInsn(ALOAD, context.var("lexer"));
            if (!last) {
                mw.visitLdcInsn(JSONToken.COMMA);
            } else {
                mw.visitLdcInsn(JSONToken.RBRACKET);
            }
            //
            mw.visitMethodInsn(//
            INVOKESPECIAL, //
            type(JavaBeanDeserializer.class), "check", "(" + desc(JSONLexer.class) + "I)V");
            mw.visitLabel(objEndIf_);
            continue;
        }
    }
    _batchSet(context, mw, false);
    Label quickElse_ = new Label(), quickElseIf_ = new Label(), quickElseIfEOI_ = new Label(), quickEnd_ = new Label();
    mw.visitVarInsn(ALOAD, context.var("lexer"));
    mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "getCurrent", "()C");
    mw.visitInsn(DUP);
    mw.visitVarInsn(ISTORE, context.var("ch"));
    mw.visitVarInsn(BIPUSH, ',');
    mw.visitJumpInsn(IF_ICMPNE, quickElseIf_);
    mw.visitVarInsn(ALOAD, context.var("lexer"));
    mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "next", "()C");
    mw.visitInsn(POP);
    mw.visitVarInsn(ALOAD, context.var("lexer"));
    mw.visitLdcInsn(JSONToken.COMMA);
    mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "setToken", "(I)V");
    mw.visitJumpInsn(GOTO, quickEnd_);
    mw.visitLabel(quickElseIf_);
    mw.visitVarInsn(ILOAD, context.var("ch"));
    mw.visitVarInsn(BIPUSH, ']');
    mw.visitJumpInsn(IF_ICMPNE, quickElseIfEOI_);
    mw.visitVarInsn(ALOAD, context.var("lexer"));
    mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "next", "()C");
    mw.visitInsn(POP);
    mw.visitVarInsn(ALOAD, context.var("lexer"));
    mw.visitLdcInsn(JSONToken.RBRACKET);
    mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "setToken", "(I)V");
    mw.visitJumpInsn(GOTO, quickEnd_);
    mw.visitLabel(quickElseIfEOI_);
    mw.visitVarInsn(ILOAD, context.var("ch"));
    mw.visitVarInsn(BIPUSH, (char) JSONLexer.EOI);
    mw.visitJumpInsn(IF_ICMPNE, quickElse_);
    mw.visitVarInsn(ALOAD, context.var("lexer"));
    mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "next", "()C");
    mw.visitInsn(POP);
    mw.visitVarInsn(ALOAD, context.var("lexer"));
    mw.visitLdcInsn(JSONToken.EOF);
    mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "setToken", "(I)V");
    mw.visitJumpInsn(GOTO, quickEnd_);
    mw.visitLabel(quickElse_);
    mw.visitVarInsn(ALOAD, context.var("lexer"));
    mw.visitLdcInsn(JSONToken.COMMA);
    mw.visitMethodInsn(INVOKEVIRTUAL, JSONLexerBase, "nextToken", "(I)V");
    mw.visitLabel(quickEnd_);
    mw.visitVarInsn(ALOAD, context.var("instance"));
    mw.visitInsn(ARETURN);
    mw.visitMaxs(5, context.variantIndex);
    mw.visitEnd();
}
Also used : MethodWriter(com.alibaba.fastjson.asm.MethodWriter) Label(com.alibaba.fastjson.asm.Label) ArrayList(java.util.ArrayList) SymbolTable(com.alibaba.fastjson.parser.SymbolTable) TypeUtils(com.alibaba.fastjson.util.TypeUtils) MethodVisitor(com.alibaba.fastjson.asm.MethodVisitor) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) FieldInfo(com.alibaba.fastjson.util.FieldInfo)

Aggregations

MethodVisitor (com.alibaba.fastjson.asm.MethodVisitor)6 MethodWriter (com.alibaba.fastjson.asm.MethodWriter)6 FieldInfo (com.alibaba.fastjson.util.FieldInfo)4 Label (com.alibaba.fastjson.asm.Label)3 ClassWriter (com.alibaba.fastjson.asm.ClassWriter)2 FieldWriter (com.alibaba.fastjson.asm.FieldWriter)2 JavaBeanInfo (com.alibaba.fastjson.util.JavaBeanInfo)2 Method (java.lang.reflect.Method)2 ParameterizedType (java.lang.reflect.ParameterizedType)2 Type (java.lang.reflect.Type)2 JSONException (com.alibaba.fastjson.JSONException)1 JSONType (com.alibaba.fastjson.annotation.JSONType)1 ParseContext (com.alibaba.fastjson.parser.ParseContext)1 SymbolTable (com.alibaba.fastjson.parser.SymbolTable)1 JSONSerializer (com.alibaba.fastjson.serializer.JSONSerializer)1 SerializeWriter (com.alibaba.fastjson.serializer.SerializeWriter)1 ASMUtils (com.alibaba.fastjson.util.ASMUtils)1 TypeUtils (com.alibaba.fastjson.util.TypeUtils)1 FileOutputStream (java.io.FileOutputStream)1 ArrayList (java.util.ArrayList)1