public static void EmitConstruction(TracingILGenerator il, LocalBuilder target, Action <TracingILGenerator> initialCountLoadingEmitter) { Contract.Requires(il != null); Contract.Requires(target != null); // TODO: For collection, supports .ctor(IEnumerable<> other) if (target.LocalType.IsAbstract || target.LocalType.IsInterface) { throw SerializationExceptions.NewNotSupportedBecauseCannotInstanciateAbstractType(target.LocalType); } if (target.LocalType.IsArray) { Contract.Assert(initialCountLoadingEmitter != null); initialCountLoadingEmitter(il); il.EmitNewarr(target.LocalType.GetElementType()); il.EmitAnyStloc(target); return; } ConstructorInfo ctor = target.LocalType.GetConstructor(_ctor_Int32_ParameterTypes); if (ctor != null && initialCountLoadingEmitter != null && typeof(IEnumerable).IsAssignableFrom(target.LocalType)) { if (target.LocalType.IsValueType) { // Same as general method call var capacity = il.DeclareLocal(typeof(int), "capacity"); initialCountLoadingEmitter(il); il.EmitAnyStloc(capacity); il.EmitAnyLdloca(target); il.EmitAnyLdloc(capacity); il.EmitCallConstructor(ctor); } else { initialCountLoadingEmitter(il); il.EmitNewobj(ctor); il.EmitAnyStloc(target); } return; } if (target.LocalType.IsValueType) { // ValueType instance has been initialized by the runtime. return; } ctor = target.LocalType.GetConstructor(Type.EmptyTypes); if (ctor == null) { throw SerializationExceptions.NewTargetDoesNotHavePublicDefaultConstructorNorInitialCapacity(target.LocalType); } il.EmitNewobj(ctor); il.EmitAnyStloc(target); }
public ListExpressionMessagePackSerializer(SerializationContext context, CollectionTraits traits) : base(context, traits) { Type type = typeof(T); if (type.GetIsAbstract()) { type = context.DefaultCollectionTypes.GetConcreteType(typeof(T)) ?? type; } if (type.IsArray) { var capacityParameter = Expression.Parameter(typeof(int), "length"); this._createInstanceWithCapacity = Expression.Lambda <Func <int, T> >( Expression.NewArrayBounds(type.GetElementType(), capacityParameter), capacityParameter ).Compile(); this._createInstance = null; } else if (type.GetIsAbstract()) { this._createInstance = () => { throw SerializationExceptions.NewNotSupportedBecauseCannotInstanciateAbstractType(type); }; this._createInstanceWithCapacity = null; } else { var constructor = ExpressionSerializerLogics.GetCollectionConstructor(context, type); if (constructor == null) { this._createInstance = () => { throw SerializationExceptions.NewTargetDoesNotHavePublicDefaultConstructorNorInitialCapacity(type); }; this._createInstanceWithCapacity = null; } else { if (constructor.GetParameters().Length == 1) { this._createInstance = null; var capacityParameter = Expression.Parameter(typeof(int), "parameter"); this._createInstanceWithCapacity = Expression.Lambda <Func <int, T> >( Expression.New(constructor, capacityParameter), capacityParameter ).Compile(); } else { this._createInstanceWithCapacity = null; this._createInstance = Expression.Lambda <Func <T> >( Expression.New(constructor) ).Compile(); } } } }
public ListReflectionMessagePackSerializer(Type type, SerializationContext context, CollectionTraits traits) : base(type, context, traits) { if (type.GetIsAbstract()) { type = context.DefaultCollectionTypes.GetConcreteType(type) ?? type; } if (type.IsArray) { var elementType = type.GetElementType(); this._createInstanceWithCapacity = length => { return(Array.CreateInstance(elementType, length)); }; this._createInstance = null; } else if (type.GetIsAbstract()) { this._createInstance = () => { throw SerializationExceptions.NewNotSupportedBecauseCannotInstanciateAbstractType(type); }; this._createInstanceWithCapacity = null; } else { var constructor = ReflectionSerializerLogics.GetCollectionConstructor(context, type); if (constructor == null) { this._createInstance = () => { throw SerializationExceptions.NewTargetDoesNotHavePublicDefaultConstructorNorInitialCapacity(type); }; this._createInstanceWithCapacity = null; } else { if (constructor.GetParameters().Length == 1) { this._createInstance = null; this._createInstanceWithCapacity = length => constructor.Invoke(new object[] { length }); } else { this._createInstanceWithCapacity = null; this._createInstance = () => constructor.Invoke(new object[0]); } } } }
public static void EmitConstruction(TracingILGenerator il, LocalBuilder target, Action <TracingILGenerator> initialCountLoadingEmitter) { Contract.Requires(il != null); Contract.Requires(target != null); if (target.LocalType.IsArray) { Contract.Assert(initialCountLoadingEmitter != null); initialCountLoadingEmitter(il); il.EmitNewarr(target.LocalType.GetElementType()); il.EmitAnyStloc(target); } else { ConstructorInfo constructor = target.LocalType.GetConstructor(_ctor_Int32_ParameterTypes); if (((constructor != null) && (initialCountLoadingEmitter != null)) && typeof(IEnumerable).IsAssignableFrom(target.LocalType)) { if (target.LocalType.IsValueType) { LocalBuilder local = il.DeclareLocal(typeof(int), "capacity"); initialCountLoadingEmitter(il); il.EmitAnyStloc(local); il.EmitAnyLdloca(target); il.EmitAnyLdloc(local); il.EmitCallConstructor(constructor); } else { initialCountLoadingEmitter(il); il.EmitNewobj(constructor); il.EmitAnyStloc(target); } } else if (!target.LocalType.IsValueType) { constructor = target.LocalType.GetConstructor(Type.EmptyTypes); if (constructor == null) { throw SerializationExceptions.NewTargetDoesNotHavePublicDefaultConstructorNorInitialCapacity(target.LocalType); } il.EmitNewobj(constructor); il.EmitAnyStloc(target); } } }
public NonGenericDictionarySerializer(SerializationContext ownerContext, Type targetType) : base(ownerContext) { if (ownerContext.EmitterFlavor == EmitterFlavor.ReflectionBased) { this._collectionConstructorWithCapacity = targetType.GetConstructor(UnpackHelpers.CollectionConstructorWithCapacityParameterTypes); if (this._collectionConstructorWithCapacity == null) { this._collectionConstructorWithoutCapacity = targetType.GetConstructor(ReflectionAbstractions.EmptyTypes); if (this._collectionConstructorWithoutCapacity == null) { throw SerializationExceptions.NewTargetDoesNotHavePublicDefaultConstructorNorInitialCapacity(targetType); } } } else { this._collectionDeserializer = ownerContext.GetSerializer(targetType); } }
protected EnumerableSerializerBase(SerializationContext ownerContext, Type targetType) : base(ownerContext) { this._itemSerializer = ownerContext.GetSerializer <TItem>(); if (ownerContext.EmitterFlavor == EmitterFlavor.ReflectionBased) { // First use abstract type instead of surrogate concrete type. var traits = typeof(T).GetCollectionTraits(); if (traits.AddMethod != null) { this._addItem = traits.AddMethod; } else { // Try use concrete type method... it might fail. traits = targetType.GetCollectionTraits(); if (traits.AddMethod != null) { this._addItem = traits.AddMethod; } } this._collectionConstructorWithCapacity = targetType.GetConstructor(UnpackHelpers.CollectionConstructorWithCapacityParameterTypes); if (this._collectionConstructorWithCapacity == null) { this._collectionConstructorWithoutCapacity = targetType.GetConstructor(ReflectionAbstractions.EmptyTypes); if (this._collectionConstructorWithoutCapacity == null) { throw SerializationExceptions.NewTargetDoesNotHavePublicDefaultConstructorNorInitialCapacity(targetType); } } } else { this._collectionDeserializer = ownerContext.GetSerializer(targetType); } }
public MapExpressionMessagePackSerializer(SerializationContext context, CollectionTraits traits) { Contract.Assert(typeof(IEnumerable).IsAssignableFrom(typeof(T)), typeof(T) + " is IEnumerable"); Contract.Assert(traits.ElementType == typeof(DictionaryEntry) || (traits.ElementType.GetIsGenericType() && traits.ElementType.GetGenericTypeDefinition() == typeof(KeyValuePair <,>)), "Element type " + traits.ElementType + " is not KeyValuePair<TKey,TValue>."); this._traits = traits; this._keySerializer = traits.ElementType.GetIsGenericType() ? context.GetSerializer(traits.ElementType.GetGenericArguments()[0]) : context.GetSerializer(typeof(MessagePackObject)); this._valueSerializer = traits.ElementType.GetIsGenericType() ? context.GetSerializer(traits.ElementType.GetGenericArguments()[1]) : context.GetSerializer(typeof(MessagePackObject)); this._getCount = ExpressionSerializerLogics.CreateGetCount <T>(traits); var constructor = ExpressionSerializerLogics.GetCollectionConstructor <T>(); if (constructor == null) { this._createInstance = () => { throw SerializationExceptions.NewTargetDoesNotHavePublicDefaultConstructorNorInitialCapacity(typeof(T)); }; this._createInstanceWithCapacity = null; } else if (constructor.GetParameters().Length == 1) { this._createInstance = null; var capacityParameter = Expression.Parameter(typeof(int), "parameter"); this._createInstanceWithCapacity = Expression.Lambda <Func <int, T> >( Expression.New(constructor, capacityParameter), capacityParameter ).Compile(); } else { this._createInstanceWithCapacity = null; this._createInstance = Expression.Lambda <Func <T> >( Expression.New(constructor) ).Compile(); } var packerParameter = Expression.Parameter(typeof(Packer), "packer"); var objectTreeParameter = Expression.Parameter(typeof(T), "objectTree"); var keySerializerParameter = Expression.Parameter(typeof(IMessagePackSerializer), "keySerializer"); var valueSerializerParameter = Expression.Parameter(typeof(IMessagePackSerializer), "valueSerializer"); var keyType = traits.ElementType.GetIsGenericType() ? traits.ElementType.GetGenericArguments()[0] : typeof(MessagePackObject); var valueType = traits.ElementType.GetIsGenericType() ? traits.ElementType.GetGenericArguments()[1] : typeof(MessagePackObject); var keySerializerType = typeof(MessagePackSerializer <>).MakeGenericType(keyType); var valueSerializerType = typeof(MessagePackSerializer <>).MakeGenericType(valueType); /* * packer.PackMapHeader( objectTree.Count() ); * foreach( var item in objectTree ) * { * elementSerializer.PackTo( packer, item.Key ); * elementSerializer.PackTo( packer, item.Value ); * } */ var packToCore = Expression.Lambda <Action <Packer, T, IMessagePackSerializer, IMessagePackSerializer> >( Expression.Block( Expression.Call( packerParameter, Metadata._Packer.PackMapHeader, ExpressionSerializerLogics.CreateGetCountExpression <T>(traits, objectTreeParameter) ), ExpressionSerializerLogics.ForEach( objectTreeParameter, traits, elementVariable => Expression.Block( Expression.Call( Expression.TypeAs(keySerializerParameter, keySerializerType), typeof(MessagePackSerializer <>).MakeGenericType(keyType).GetMethod("PackTo"), packerParameter, traits.ElementType.GetIsGenericType() ? Expression.Property(elementVariable, traits.ElementType.GetProperty("Key")) as Expression : Expression.Unbox(Expression.Property(elementVariable, traits.ElementType.GetProperty("Key")), typeof(MessagePackObject)) ), Expression.Call( Expression.TypeAs(valueSerializerParameter, valueSerializerType), typeof(MessagePackSerializer <>).MakeGenericType(valueType).GetMethod("PackTo"), packerParameter, traits.ElementType.GetIsGenericType() ? Expression.Property(elementVariable, traits.ElementType.GetProperty("Value")) as Expression : Expression.Unbox(Expression.Property(elementVariable, traits.ElementType.GetProperty("Value")), typeof(MessagePackObject)) ) ) ) ), packerParameter, objectTreeParameter, keySerializerParameter, valueSerializerParameter ); #if !SILVERLIGHT if (context.GeneratorOption == SerializationMethodGeneratorOption.CanDump) { this._packToCoreExpression = packToCore; } #endif this._packToCore = packToCore.Compile(); var unpackerParameter = Expression.Parameter(typeof(Unpacker), "unpacker"); var instanceParameter = Expression.Parameter(typeof(T), "instance"); var countParamter = Expression.Parameter(typeof(int), "count"); Expression <Action <Unpacker, T, IMessagePackSerializer, IMessagePackSerializer> > unpackToCore; if (traits.ElementType.GetIsGenericType()) { /* * UnpackHelpers.UnpackMapTo<TKey,TValue>( unpacker, keySerializer, valueSerializer, instance ); */ unpackToCore = Expression.Lambda <Action <Unpacker, T, IMessagePackSerializer, IMessagePackSerializer> >( Expression.Call( Metadata._UnpackHelpers.UnpackMapTo_2.MakeGenericMethod(keyType, valueType), unpackerParameter, Expression.TypeAs(keySerializerParameter, keySerializerType), Expression.TypeAs(valueSerializerParameter, valueSerializerType), Expression.TypeAs(instanceParameter, typeof(IDictionary <,>).MakeGenericType(keyType, valueType)) ), unpackerParameter, instanceParameter, keySerializerParameter, valueSerializerParameter ); } else { /* * UnpackHelpers.UnpackNonGenericMapTo( unpacker, instance ); */ unpackToCore = Expression.Lambda <Action <Unpacker, T, IMessagePackSerializer, IMessagePackSerializer> >( Expression.Call( Metadata._UnpackHelpers.UnpackNonGenericMapTo, unpackerParameter, Expression.TypeAs(instanceParameter, typeof(IDictionary)) ), unpackerParameter, instanceParameter, keySerializerParameter, valueSerializerParameter ); } #if !SILVERLIGHT if (context.GeneratorOption == SerializationMethodGeneratorOption.CanDump) { this._unpackToCoreExpression = unpackToCore; } #endif this._unpackToCore = unpackToCore.Compile(); }
public MapReflectionMessagePackSerializer(Type type, SerializationContext context, CollectionTraits traits) : base(type, (context ?? SerializationContext.Default).CompatibilityOptions.PackerCompatibilityOptions) { Contract.Assert(typeof(IEnumerable).IsAssignableFrom(type), type + " is IEnumerable"); Contract.Assert(traits.ElementType == typeof(DictionaryEntry) || (traits.ElementType.GetIsGenericType() && traits.ElementType.GetGenericTypeDefinition() == typeof(KeyValuePair <,>)), "Element type " + traits.ElementType + " is not KeyValuePair<TKey,TValue>."); this._traits = traits; this._keySerializer = traits.ElementType.GetIsGenericType() ? context.GetSerializer(traits.ElementType.GetGenericArguments()[0]) : context.GetSerializer(typeof(MessagePackObject)); this._valueSerializer = traits.ElementType.GetIsGenericType() ? context.GetSerializer(traits.ElementType.GetGenericArguments()[1]) : context.GetSerializer(typeof(MessagePackObject)); this._getCount = ReflectionSerializerLogics.CreateGetCount(type, traits); var constructor = ReflectionSerializerLogics.GetCollectionConstructor(context, type); if (constructor == null) { this._createInstance = () => { throw SerializationExceptions.NewTargetDoesNotHavePublicDefaultConstructorNorInitialCapacity(type); }; this._createInstanceWithCapacity = null; } else if (constructor.GetParameters().Length == 1) { this._createInstance = null; this._createInstanceWithCapacity = length => constructor.Invoke(new object[] { length }); } else { this._createInstanceWithCapacity = null; this._createInstance = () => constructor.Invoke(new object[0]); } var keyType = traits.ElementType.GetIsGenericType() ? traits.ElementType.GetGenericArguments()[0] : typeof(MessagePackObject); var valueType = traits.ElementType.GetIsGenericType() ? traits.ElementType.GetGenericArguments()[1] : typeof(MessagePackObject); var keyProperty = traits.ElementType.GetProperty("Key"); var valueProperty = traits.ElementType.GetProperty("Value"); this._packToCore = (Packer packer, object objectTree, IMessagePackSerializer keySerializer, IMessagePackSerializer valueSerializer) => { packer.PackMapHeader(this._getCount(objectTree)); foreach (var kvp in (IEnumerable)objectTree) { keySerializer.PackTo(packer, keyProperty.GetValue(kvp, new object[0])); valueSerializer.PackTo(packer, valueProperty.GetValue(kvp, new object[0])); } }; if (traits.ElementType.GetIsGenericType()) { /* * UnpackHelpers.UnpackMapTo<TKey,TValue>( unpacker, keySerializer, valueSerializer, instance ); */ var unpackMapToMethod = Metadata._UnpackHelpers.UnpackMapTo_2; //.MakeGenericMethod(keyType, valueType); this._unpackToCore = (Unpacker unpacker, object objectTree, IMessagePackSerializer keySerializer, IMessagePackSerializer valueSerializer) => { unpackMapToMethod.Invoke(null, new object[] { unpacker, keySerializer, valueSerializer, objectTree }); }; } else { /* * UnpackHelpers.UnpackNonGenericMapTo( unpacker, instance ); */ this._unpackToCore = (Unpacker unpacker, object objectTree, IMessagePackSerializer keySerializer, IMessagePackSerializer valueSerializer) => UnpackHelpers.UnpackMapTo(unpacker, (IDictionary)objectTree); } }