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); }
internal IProtoSerializerWithWireType GetSerializer(RuntimeTypeModel model) => _serializer ?? (_serializer = BuildSerializer(model));
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; } } }