Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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]);
                    }
                }
            }
        }
Exemplo n.º 4
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);
     }
 }
Exemplo n.º 6
0
        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();
        }
Exemplo n.º 8
0
        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);
            }
        }