private static MethodContext EmitBoxedSerializer(TypeBuilder type, int i, Type valueType, SerializerPair[] methodPairs, RuntimeTypeModel model, Compiler.CompilerContext.ILVersion ilVersion, string assemblyName)
        {
            MethodInfo dedicated = methodPairs[i].Deserialize;
            string     name      = "_" + i.ToString();

            MethodContext methodContext;

            model.EmitDefineMethod(
                type,
                name,
                MethodAttributes.Static,
                CallingConventions.Standard,
                model.MapType(typeof(object)),
                new[]
            {
                new MethodContext.ParameterGenInfo(model.MapType(typeof(object)), "obj", 1),
                new MethodContext.ParameterGenInfo(model.MapType(typeof(ProtoReader)), "source", 2),
            },
                false,
                out methodContext);

            Compiler.CompilerContext ctx = new Compiler.CompilerContext(methodContext, true, false, methodPairs, model, ilVersion, assemblyName, model.MapType(typeof(object)));
            ctx.LoadValue(ctx.InputValue);
            Compiler.CodeLabel @null = ctx.DefineLabel();
            ctx.BranchIfFalse(@null, true);

            Type mappedValueType = valueType;

            ctx.LoadValue(ctx.InputValue);
            ctx.CastFromObject(mappedValueType);
            ctx.LoadReaderWriter();
            ctx.EmitCall(dedicated);
            ctx.CastToObject(mappedValueType);
            ctx.Return();

            ctx.MarkLabel(@null);
            using (Compiler.Local typedVal = new Compiler.Local(ctx, mappedValueType))
            {
                // create a new valueType
                ctx.LoadAddress(typedVal, mappedValueType);
                ctx.EmitCtor(mappedValueType);
                ctx.LoadValue(typedVal);
                ctx.LoadReaderWriter();
                ctx.EmitCall(dedicated);
                ctx.CastToObject(mappedValueType);
                ctx.Return();
            }
            return(methodContext);
        }
示例#2
0
 internal IProtoSerializerWithWireType GetSerializer(RuntimeTypeModel model) => _serializer ?? (_serializer = BuildSerializer(model));
示例#3
0
 private IProtoSerializerWithWireType BuildSerializer(RuntimeTypeModel model)
 {
     // note the caller here is MetaType.BuildSerializer, which already has the sync-lock
     return(new ModelTypeSerializer(DerivedType.Type, DerivedType.GetKey(false, false), DerivedType, model));
 }
        internal static void ResolveListTypes(RuntimeTypeModel model, Type type, ref Type itemType, ref Type defaultType)
        {
            if (type == null)
            {
                return;
            }
            if (Helpers.GetTypeCode(type) != ProtoTypeCode.Unknown)
            {
                return;                                                     // don't try this[type] for inbuilts
            }
            // handle arrays
            if (type.IsArray)
            {
                itemType = type.GetElementType();
                if (itemType == model.MapType(typeof(byte)))
                {
                    defaultType = itemType = null;
                }
                else
                {
                    defaultType = type;
                }
            }
            // handle lists
            if (itemType == null)
            {
                itemType = TypeModel.GetListItemType(model, type);
            }

            if (itemType != null && defaultType == null)
            {
#if WINRT
                TypeInfo typeInfo = type.GetTypeInfo();
                if (typeInfo.IsClass && !typeInfo.IsAbstract && Helpers.GetConstructor(typeInfo, Helpers.EmptyTypes, true) != null)
#else
                if (type.IsClass && !type.IsAbstract && Helpers.GetConstructor(type, Helpers.EmptyTypes, true) != null)
#endif
                {
                    defaultType = type;
                }
                if (defaultType == null)
                {
#if WINRT
                    if (typeInfo.IsInterface)
#else
                    if (type.IsInterface)
#endif
                    {
#if NO_GENERICS
                        defaultType = typeof(ArrayList);
#else
                        Type[] genArgs;
#if WINRT
                        if (typeInfo.IsGenericType && type.GetGenericTypeDefinition() == typeof(System.Collections.Generic.IDictionary <,>) &&
                            itemType == typeof(System.Collections.Generic.KeyValuePair <,>).MakeGenericType(genArgs = typeInfo.GenericTypeArguments))
#else
                        if (type.IsGenericType && type.GetGenericTypeDefinition() == model.MapType(typeof(System.Collections.Generic.IDictionary <,>)) &&
                            itemType == model.MapType(typeof(System.Collections.Generic.KeyValuePair <,>)).MakeGenericType(genArgs = type.GetGenericArguments()))
#endif
                        {
                            defaultType = model.MapType(typeof(System.Collections.Generic.Dictionary <,>)).MakeGenericType(genArgs);
                        }
                        else
                        {
                            defaultType = model.MapType(typeof(System.Collections.Generic.List <>)).MakeGenericType(itemType);
                        }
#endif
                    }
                }
                // verify that the default type is appropriate
                if (defaultType != null && !Helpers.IsAssignableFrom(type, defaultType))
                {
                    defaultType = null;
                }
            }
        }