示例#1
0
        /// <summary>
        ///		Initializes a new instance of the <see cref="ContextBasedSerializerEmitter"/> class.
        /// </summary>
        /// <param name="targetType">Type of the target.</param>
        public ContextBasedSerializerEmitter(Type targetType)
        {
            Contract.Requires(targetType != null);

            this._targetType = targetType;
            this._traits     = targetType.GetCollectionTraits();
        }
        public ReflectionNonGenericDictionaryMessagePackSerializer(
            SerializationContext ownerContext,
            Type targetType,
            CollectionTraits collectionTraits,
            PolymorphismSchema itemsSchema,
            SerializationTarget targetInfo
            )
            : base(ownerContext, itemsSchema, targetInfo.GetCapabilitiesForCollection(collectionTraits))
        {
            if (targetInfo.CanDeserialize)
            {
                this._factory = ReflectionSerializerHelper.CreateCollectionInstanceFactory <TDictionary, object>(targetInfo.DeserializationConstructor);
            }
            else
            {
                this._factory = _ => { throw SerializationExceptions.NewCreateInstanceIsNotSupported(targetType); };
            }

            this._isPackable   = typeof(IPackable).IsAssignableFrom(targetType ?? typeof(TDictionary));
            this._isUnpackable = typeof(IUnpackable).IsAssignableFrom(targetType ?? typeof(TDictionary));
#if FEATURE_TAP
            this._isAsyncPackable   = typeof(IAsyncPackable).IsAssignableFrom(targetType ?? typeof(TDictionary));
            this._isAsyncUnpackable = typeof(IAsyncUnpackable).IsAssignableFrom(targetType ?? typeof(TDictionary));
#endif // FEATURE_TAP
        }
        private void BuildCollectionAddItem(TContext context, CollectionTraits traits)
        {
            var addItem = this.BaseClass.GetRuntimeMethod(MethodName.AddItem);

            context.BeginMethodOverride(MethodName.AddItem);
            context.EndMethodOverride(
                MethodName.AddItem,
                traits.CollectionType == CollectionKind.Map
                                ? this.EmitAppendDictionaryItem(
                    context,
                    traits,
                    context.CollectionToBeAdded,
                    addItem.GetParameters()[0].ParameterType,
                    context.KeyToAdd,
                    addItem.GetParameters()[1].ParameterType,
                    context.ValueToAdd,
                    false
                    )
                                : this.EmitAppendCollectionItem(
                    context,
                    null,
                    traits,
                    context.CollectionToBeAdded,
                    context.ItemToAdd
                    )
                );
        }
示例#4
0
        /// <summary>
        ///		Initializes a new instance of the <see cref="ContextBasedSerializerEmitter"/> class.
        /// </summary>
        /// <param name="specification">The specification of the serializer.</param>
        public ContextBasedSerializerEmitter(SerializerSpecification specification)
        {
            Contract.Requires(specification != null);

            this._targetType = specification.TargetType;
            this._traits     = specification.TargetCollectionTraits;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="FieldBasedSerializerEmitter"/> class.
        /// </summary>
        /// <param name="host">The host <see cref="ModuleBuilder"/>.</param>
        /// <param name="specification">The specification of the serializer.</param>
        /// <param name="baseClass">Type of the base class of the serializer.</param>
        /// <param name="isDebuggable">Set to <c>true</c> when <paramref name="host"/> is debuggable.</param>
        public FieldBasedSerializerEmitter(ModuleBuilder host, SerializerSpecification specification, Type baseClass, bool isDebuggable)
        {
            Contract.Requires(host != null);
            Contract.Requires(specification != null);
            Contract.Requires(baseClass != null);

            Tracer.Emit.TraceEvent(Tracer.EventType.DefineType, Tracer.EventId.DefineType, "Create {0}", specification.SerializerTypeFullName);
            this._typeBuilder =
                host.DefineType(
                    specification.SerializerTypeFullName,
                    TypeAttributes.Sealed | TypeAttributes.Public | TypeAttributes.UnicodeClass | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit,
                    baseClass
                    );

            this._defaultConstructorBuilder = this._typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes);
            this._contextConstructorBuilder = this._typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, ConstructorParameterTypes);

            this._traits = specification.TargetCollectionTraits;
            var baseType = this._typeBuilder.BaseType;

#if DEBUG
            Contract.Assert(baseType != null, "baseType != null");
#endif
            this._serializers  = new Dictionary <SerializerFieldKey, SerializerFieldInfo>();
            this._fieldInfos   = new Dictionary <RuntimeFieldHandle, FieldBuilder>();
            this._methodBases  = new Dictionary <RuntimeMethodHandle, FieldBuilder>();
            this._isDebuggable = isDebuggable;

#if !SILVERLIGHT && !NETFX_35
            if (isDebuggable && SerializerDebugging.DumpEnabled)
            {
                SerializerDebugging.PrepareDump(host.Assembly as AssemblyBuilder);
            }
#endif
        }
示例#6
0
        public static MessagePackSerializer <T> CreateMapSerializer <T>(
            SerializationContext context,
            Type targetType,
            CollectionTraits traits)
        {
            if (traits.DetailedCollectionType == CollectionDetailedKind.GenericDictionary)
            {
                return
                    (new ReflectionCollectionSerializer <T>(
                         context,
                         Activator.CreateInstance(
                             typeof(DictionarySerializer <,>).MakeGenericType(traits.ElementType.GetGenericArguments()),
                             context,
                             targetType
                             ) as IMessagePackSerializer
                         ));
            }
            else
            {
#if DEBUG && !UNITY
                Contract.Assert(traits.DetailedCollectionType == CollectionDetailedKind.NonGenericDictionary);
#endif // DEBUG && !UNITY
                return
                    (new ReflectionCollectionSerializer <T>(
                         context,
                         new NonGenericDictionarySerializer(context, targetType)
                         ));
            }
        }
        /// <summary>
        ///		Create new <see cref="AssemblyBuilderEmittingContext"/> for specified <see cref="Type"/>.
        /// </summary>
        /// <param name="targetType">The target type of the serializer.</param>
        /// <param name="targetTypeCollectionTraits">The collection traits of <paramref name="targetType"/>.</param>
        /// <param name="serializerBaseClass">The base class of the serializer.</param>
        /// <returns><see cref="AssemblyBuilderEmittingContext"/>.</returns>
        public AssemblyBuilderEmittingContext CreateEmittingContext(Type targetType, CollectionTraits targetTypeCollectionTraits, Type serializerBaseClass)
        {
            string serializerTypeName, serializerTypeNamespace;

            DefaultSerializerNameResolver.ResolveTypeName(
                this._assemblyBuilder == null,
                targetType,
                this._namespace,
                out serializerTypeName,
                out serializerTypeNamespace
                );
            var spec =
                new SerializerSpecification(
                    targetType,
                    targetTypeCollectionTraits,
                    serializerTypeName,
                    serializerTypeNamespace
                    );

            this._generatedSerializers.Add(spec);

            return
                (new AssemblyBuilderEmittingContext(
                     this._context,
                     targetType,
                     targetType.GetIsEnum()
                                                ? new Func <SerializerEmitter>(() => this._generatorManager.CreateEnumEmitter(this._context, spec))
                                                : () => this._generatorManager.CreateObjectEmitter(spec, serializerBaseClass)
                     ));
        }
		/// <summary>
		///		Create new <see cref="AssemblyBuilderEmittingContext"/> for specified <see cref="Type"/>.
		/// </summary>
		/// <param name="targetType">The target type of the serializer.</param>
		/// <param name="targetTypeCollectionTraits">The collection traits of <paramref name="targetType"/>.</param>
		/// <param name="serializerBaseClass">The base class of the serializer.</param>
		/// <returns><see cref="AssemblyBuilderEmittingContext"/>.</returns>
		public AssemblyBuilderEmittingContext CreateEmittingContext( Type targetType, CollectionTraits targetTypeCollectionTraits, Type serializerBaseClass )
		{
			string serializerTypeName, serializerTypeNamespace;
			DefaultSerializerNameResolver.ResolveTypeName(
				this._assemblyBuilder == null,
				targetType,
				typeof( AssemblyBuilderCodeGenerationContext ).Namespace,
				out serializerTypeName,
				out serializerTypeNamespace 
			);
			var spec =
				new SerializerSpecification(
					targetType,
					targetTypeCollectionTraits,
					serializerTypeName,
					serializerTypeNamespace
				);

			this._generatedSerializers.Add( spec );

			return
				new AssemblyBuilderEmittingContext(
					this._context,
					targetType,
					() => this._generatorManager.CreateEmitter( spec, serializerBaseClass, EmitterFlavor.FieldBased ),
					() => this._generatorManager.CreateEnumEmitter( this._context, spec, EmitterFlavor.FieldBased ) 
				);
		}
        public static Action <object, object> GetAddItem(Type targetType, CollectionTraits collectionTraits)
#endif // !UNITY
        {
            if (collectionTraits.AddMethod == null)
            {
                throw new SerializationException(
                          String.Format(
                              CultureInfo.CurrentCulture,
                              "Reflection based serializer only supports collection types which implement interface to add new item such as '{0}' and '{1}'",
                              typeof(ICollection <>).GetFullName(),
                              typeof(IList)
                              )
                          );
            }

            // CreateDelegate causes AOT error.
            // So use reflection in AOT environment.
#if !AOT || AOT_CHECK
            try
            {
                return(collectionTraits.AddMethod.CreateDelegate(typeof(Action <TCollection, TItem>)) as Action <TCollection, TItem>);
            }
            catch (ArgumentException)
            {
#endif // !AOT || AOT_CHECK
            return((collection, item) => collectionTraits.AddMethod.InvokePreservingExceptionType(collection, item));

#if !AOT || AOT_CHECK
        }
#endif // !AOT || AOT_CHECK
        }
示例#10
0
        protected override ExpressionConstruct EmitForEachLoop(
            ExpressionTreeContext context, CollectionTraits collectionTraits, ExpressionConstruct collection, Func <ExpressionConstruct, ExpressionConstruct> loopBodyEmitter
            )
        {
            var enumerator      = Expression.Variable(collectionTraits.GetEnumeratorMethod.ReturnType, "enumerator");
            var current         = Expression.Variable(collectionTraits.ElementType, "current");
            var moveNextMethod  = Metadata._IEnumerator.FindEnumeratorMoveNextMethod(enumerator.Type);
            var currentProperty = Metadata._IEnumerator.FindEnumeratorCurrentProperty(enumerator.Type, collectionTraits);

            var endForEach = Expression.Label("END_FOREACH");

            return
                (Expression.Block(
                     new[] { enumerator, current },
                     Expression.Assign(enumerator, Expression.Call(collection, collectionTraits.GetEnumeratorMethod)),
                     Expression.Loop(
                         Expression.IfThenElse(
                             Expression.Call(enumerator, moveNextMethod),
                             Expression.Block(
                                 Expression.Assign(current, Expression.Property(enumerator, currentProperty)),
                                 loopBodyEmitter(current)
                                 ),
                             Expression.Break(endForEach)
                             ),
                         endForEach
                         )
                     ));
        }
示例#11
0
		public static PropertyInfo FindEnumeratorCurrentProperty( Type enumeratorType, CollectionTraits traits )
		{
#if DEBUG
			Contract.Assert( traits.GetEnumeratorMethod != null );
#endif // DEBUG
			PropertyInfo currentProperty = traits.GetEnumeratorMethod.ReturnType.GetProperty( "Current" );

			if ( currentProperty == null )
			{
				if ( enumeratorType == typeof( IDictionaryEnumerator ) )
				{
					currentProperty = Metadata._IDictionaryEnumerator.Entry;
				}
				else if ( enumeratorType.GetIsInterface() )
				{
					if ( enumeratorType.GetIsGenericType() && enumeratorType.GetGenericTypeDefinition() == typeof( IEnumerator<> ) )
					{
						currentProperty = typeof( IEnumerator<> ).MakeGenericType( traits.ElementType ).GetProperty( "Current" );
					}
					else
					{
						currentProperty = Metadata._IEnumerator.Current;
					}
				}
			}
			return currentProperty;
		}
		/// <summary>
		///		Create new <see cref="AssemblyBuilderEmittingContext"/> for specified <see cref="Type"/>.
		/// </summary>
		/// <param name="targetType">The target type of the serializer.</param>
		/// <param name="targetTypeCollectionTraits">The collection traits of <paramref name="targetType"/>.</param>
		/// <param name="serializerBaseClass">The base class of the serializer.</param>
		/// <returns><see cref="AssemblyBuilderEmittingContext"/>.</returns>
		public AssemblyBuilderEmittingContext CreateEmittingContext( Type targetType, CollectionTraits targetTypeCollectionTraits, Type serializerBaseClass )
		{
			string serializerTypeName, serializerTypeNamespace;
			DefaultSerializerNameResolver.ResolveTypeName(
				this._assemblyBuilder == null,
				targetType,
				this._namespace,
				out serializerTypeName,
				out serializerTypeNamespace
			);
			var spec =
				new SerializerSpecification(
					targetType,
					targetTypeCollectionTraits,
					serializerTypeName,
					serializerTypeNamespace
				);

			this._generatedSerializers.Add( spec );

			return
				new AssemblyBuilderEmittingContext(
					this._context,
					targetType,
					targetType.GetIsEnum()
						? new Func<SerializerEmitter>( () => this._generatorManager.CreateEnumEmitter( this._context, spec ) )
						: () => this._generatorManager.CreateObjectEmitter( spec, serializerBaseClass )
				);
		}
        private void BuildCollectionAddItem(TContext context, Type declaringType, CollectionTraits traits)
        {
            var addItem = GetCollectionSerializerMethod("AddItem", declaringType);

            this.EmitMethodPrologue(context, CollectionSerializerMethod.AddItem, addItem);
            TConstruct construct = null;

            try
            {
                construct =
                    traits.CollectionType == CollectionKind.Map
                                        ? this.EmitAppendDictionaryItem(
                        context,
                        traits,
                        context.CollectionToBeAdded,
                        addItem.GetParameters()[0].ParameterType,
                        context.KeyToAdd,
                        addItem.GetParameters()[1].ParameterType,
                        context.ValueToAdd,
                        false
                        )
                                        : this.EmitAppendCollectionItem(
                        context,
                        null,
                        traits,
                        context.CollectionToBeAdded,
                        context.ItemToAdd
                        );
            }
            finally
            {
                this.EmitMethodEpilogue(context, CollectionSerializerMethod.AddItem, construct);
            }
        }
示例#14
0
        /// <summary>
        ///		Create new <see cref="AssemblyBuilderEmittingContext"/> for specified <see cref="Type"/>.
        /// </summary>
        /// <param name="targetType">The target type of the serializer.</param>
        /// <param name="targetTypeCollectionTraits">The collection traits of <paramref name="targetType"/>.</param>
        /// <param name="serializerBaseClass">The base class of the serializer.</param>
        /// <returns><see cref="AssemblyBuilderEmittingContext"/>.</returns>
        public AssemblyBuilderEmittingContext CreateEmittingContext(Type targetType, CollectionTraits targetTypeCollectionTraits, Type serializerBaseClass)
        {
            string serializerTypeName, serializerTypeNamespace;

            DefaultSerializerNameResolver.ResolveTypeName(
                this._assemblyBuilder == null,
                targetType,
                typeof(AssemblyBuilderCodeGenerationContext).Namespace,
                out serializerTypeName,
                out serializerTypeNamespace
                );
            var spec =
                new SerializerSpecification(
                    targetType,
                    targetTypeCollectionTraits,
                    serializerTypeName,
                    serializerTypeNamespace
                    );

            this._generatedSerializers.Add(spec);

            return
                (new AssemblyBuilderEmittingContext(
                     this._context,
                     targetType,
                     () => this._generatorManager.CreateEmitter(spec, serializerBaseClass, EmitterFlavor.FieldBased),
                     () => this._generatorManager.CreateEnumEmitter(this._context, spec, EmitterFlavor.FieldBased)
                     ));
        }
        private TConstruct EmitUnpackToSpecifiedCollection(
            TContext context,
            CollectionTraits traitsOfTheCollection,
            TConstruct unpacker,
            TConstruct collection
            )
        {
            var count =
                this.DeclareLocal(
                    context,
                    typeof(int),
                    "count"
                    );

            return
                (this.EmitSequentialStatements(
                     context,
                     typeof(void),
                     this.EmitCheckIsArrayHeaderExpression(context, context.Unpacker),
                     count,
                     this.EmitStoreVariableStatement(
                         context,
                         count,
                         this.EmitGetItemsCountExpression(context, context.Unpacker)
                         ),
                     this.EmitForLoop(
                         context,
                         count,
                         flc => this.EmitUnpackToCollectionLoopBody(context, flc, traitsOfTheCollection, unpacker, collection)
                         )
                     ));
        }
 protected override TConstruct EmitForEachLoop(TContext context, CollectionTraits collectionTraits, TConstruct collection, Func <TConstruct, TConstruct> loopBodyEmitter)
 {
     Contract.Requires(context != null);
     Contract.Requires(collection != null);
     Contract.Requires(loopBodyEmitter != null);
     Contract.Ensures(Contract.Result <TConstruct>() != null);
     Contract.Ensures(Contract.Result <TConstruct>().ContextType == typeof(void));
     return(default(TConstruct));
 }
示例#17
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();
                    }
                }
            }
        }
		/// <summary>
		///		Determines that whether built-in serializer for specified type exists or not.
		/// </summary>
		/// <param name="type">The type for check.</param>
		/// <param name="traits">The known <see cref="CollectionTraits"/> of the <paramref name="type"/>.</param>
		/// <returns>
		///   <c>true</c> if built-in serializer for specified type exists; <c>false</c>, otherwise.
		/// </returns>
		/// <exception cref="System.NotImplementedException"></exception>
		public bool BuiltInSerializerExists( Type type, CollectionTraits traits )
		{
			if ( type == null )
			{
				throw new ArgumentNullException( "type" );
			}

			return GenericSerializer.IsSupported( type, traits, this._preferReflectionBasedSerializer  ) || SerializerRepository.InternalDefault.Contains( type );
		}
 private void BuildArraySerializer(TContext context, CollectionTraits traits)
 {
     this.BuildCollectionPackTo(context, traits);
     this.BuildCollectionUnpackFrom(context, traits);
     if (traits.AddMethod != null)
     {
         this.BuildCollectionUnpackTo(context, traits);
     }
 }
示例#20
0
        public static Type GetSerializerClass(Type targetType, CollectionTraits traits)
        {
            switch (traits.DetailedCollectionType)
            {
            case CollectionDetailedKind.GenericEnumerable:
            {
                return(typeof(ExpressionCallbackEnumerableMessagePackSerializer <,>).MakeGenericType(targetType, traits.ElementType));
            }

            case CollectionDetailedKind.GenericCollection:
            case CollectionDetailedKind.GenericSet:
            case CollectionDetailedKind.GenericList:
            {
                return(typeof(ExpressionCallbackCollectionMessagePackSerializer <,>).MakeGenericType(targetType, traits.ElementType));
            }

            case CollectionDetailedKind.GenericDictionary:
            {
                var keyValuePairGenericArguments = traits.ElementType.GetGenericArguments();
                return
                    (typeof(ExpressionCallbackDictionaryMessagePackSerializer <, ,>).MakeGenericType(
                         targetType,
                         keyValuePairGenericArguments[0],
                         keyValuePairGenericArguments[1]
                         ));
            }

            case CollectionDetailedKind.NonGenericEnumerable:
            {
                return(typeof(ExpressionCallbackNonGenericEnumerableMessagePackSerializer <>).MakeGenericType(targetType));
            }

            case CollectionDetailedKind.NonGenericCollection:
            {
                return(typeof(ExpressionCallbackNonGenericCollectionMessagePackSerializer <>).MakeGenericType(targetType));
            }

            case CollectionDetailedKind.NonGenericList:
            {
                return(typeof(ExpressionCallbackNonGenericListMessagePackSerializer <>).MakeGenericType(targetType));
            }

            case CollectionDetailedKind.NonGenericDictionary:
            {
                return(typeof(ExpressionCallbackNonGenericDictionaryMessagePackSerializer <>).MakeGenericType(targetType));
            }

            default:
            {
                return
                    (targetType.GetIsEnum()
                                                ? typeof(ExpressionCallbackEnumMessagePackSerializer <>).MakeGenericType(targetType)
                                                : typeof(ExpressionCallbackMessagePackSerializer <>).MakeGenericType(targetType));
            }
            }
        }
 protected UnityEnumerableMessagePackSerializer(
     SerializationContext ownerContext,
     Type targetType,
     CollectionTraits traits,
     PolymorphismSchema schema
     )
     : base(ownerContext, targetType, traits.ElementType, schema)
 {
     this._getCount = traits.CountPropertyGetter;
 }
示例#22
0
 public ReflectionCollectionMessagePackSerializer(
     SerializationContext ownerContext,
     Type abstractType,
     Type concreteType,
     CollectionTraits traits,
     PolymorphismSchema itemsSchema)
     : base(ownerContext, abstractType, traits, itemsSchema)
 {
     this._factory = ReflectionSerializerHelper.CreateCollectionInstanceFactory(abstractType, concreteType, traits.ElementType);
 }
        public static SerializerEmitter CreateArraySerializerCore(Type targetType, EmitterFlavor emitterFlavor)
        {
            Contract.Requires(targetType != null);
            SerializerEmitter emitter          = SerializationMethodGeneratorManager.Get().CreateEmitter(targetType, emitterFlavor);
            CollectionTraits  collectionTraits = targetType.GetCollectionTraits();

            CreatePackArrayProceduresCore(targetType, emitter, collectionTraits);
            CreateUnpackArrayProceduresCore(targetType, emitter, collectionTraits);
            return(emitter);
        }
示例#24
0
        /// <summary>
        /// Initializes a new instance of the <see cref="FieldBasedSerializerEmitter"/> class.
        /// </summary>
        /// <param name="host">The host <see cref="ModuleBuilder"/>.</param>
        /// <param name="sequence">The sequence number to name new type.</param>
        /// <param name="targetType">Type of the serialization target.</param>
        /// <param name="baseClass">Type of the base class of the serializer.</param>
        /// <param name="isDebuggable">Set to <c>true</c> when <paramref name="host"/> is debuggable.</param>
        public FieldBasedSerializerEmitter(ModuleBuilder host, int?sequence, Type targetType, Type baseClass, bool isDebuggable)
        {
            Contract.Requires(host != null);
            Contract.Requires(targetType != null);
            Contract.Requires(baseClass != null);

            string typeName =
#if !NETFX_35
                String.Join(
                    Type.Delimiter.ToString(CultureInfo.InvariantCulture),
                    typeof(SerializerEmitter).Namespace,
                    "Generated",
                    IdentifierUtility.EscapeTypeName(targetType) + "Serializer" + sequence
                    );
#else
                String.Join(
                    Type.Delimiter.ToString(),
                    new string[]
            {
                typeof(SerializerEmitter).Namespace,
                "Generated",
                IdentifierUtility.EscapeTypeName(targetType) + "Serializer" + sequence
            }
                    );
#endif
            Tracer.Emit.TraceEvent(Tracer.EventType.DefineType, Tracer.EventId.DefineType, "Create {0}", typeName);
            this._typeBuilder =
                host.DefineType(
                    typeName,
                    TypeAttributes.Sealed | TypeAttributes.Public | TypeAttributes.UnicodeClass | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit,
                    baseClass
                    );

            this._defaultConstructorBuilder = this._typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes);
            this._contextConstructorBuilder = this._typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, ConstructorParameterTypes);

            this._targetType = targetType;
            this._traits     = targetType.GetCollectionTraits();
            var baseType = this._typeBuilder.BaseType;
#if DEBUG
            Contract.Assert(baseType != null, "baseType != null");
#endif
            this._serializers  = new Dictionary <SerializerFieldKey, SerializerFieldInfo>();
            this._fieldInfos   = new Dictionary <RuntimeFieldHandle, FieldBuilder>();
            this._methodBases  = new Dictionary <RuntimeMethodHandle, FieldBuilder>();
            this._isDebuggable = isDebuggable;

#if !SILVERLIGHT && !NETFX_35
            if (isDebuggable && SerializerDebugging.DumpEnabled)
            {
                SerializerDebugging.PrepareDump(host.Assembly as AssemblyBuilder);
            }
#endif
        }
        /// <summary>
        ///		Initializes a new instance of the <see cref="SerializerBuilder{TContext, TConstruct}"/> class.
        /// </summary>
        /// <param name="targetType">The type of serialization target.</param>
        /// <param name="collectionTraits">The collection traits of the serialization target.</param>
        protected SerializerBuilder(Type targetType, CollectionTraits collectionTraits)
        {
#if DEBUG
            Contract.Assert(targetType != null, "targetType != null");
#endif // DEBUG

            this.TargetType             = targetType;
            this.CollectionTraits       = collectionTraits;
            this.BaseClass              = DetermineBaseClass(targetType, collectionTraits);
            this._nilImplicationHandler = new SerializerBuilderNilImplicationHandler(targetType);
        }
示例#26
0
 protected UnityCollectionMessagePackSerializer(
     SerializationContext ownerContext,
     Type targetType,
     CollectionTraits traits,
     PolymorphismSchema schema,
     SerializerCapabilities capabilities
     )
     : base(ownerContext, targetType, traits.ElementType, schema, capabilities)
 {
     this._getCount = traits.CountPropertyGetter;
     this._add      = traits.AddMethod;
 }
        private void BuildCollectionPackTo(TContext context, CollectionTraits traits)
        {
#if DEBUG
            Contract.Assert(!typeof(TObject).IsArray);
#endif
            this.EmitMethodPrologue(context, SerializerMethod.PackToCore);
            TConstruct construct = null;
            try
            {
                if (traits.CountProperty == null)
                {
                    // IEnumerable but not ICollection
                    var arrayType = traits.ElementType.MakeArrayType();
                    construct =
                        this.EmitInvokeMethodExpression(
                            context,
                            this.EmitGetSerializerExpression(context, arrayType, null),
                            typeof(MessagePackSerializer <>).MakeGenericType(arrayType).GetMethod("PackTo"),
                            context.Packer,
                            this.EmitInvokeEnumerableToArrayExpression(context, context.PackToTarget, traits.ElementType)
                            );
                }
                else
                {
                    // ICollection
                    construct =
                        this.EmitSequentialStatements(
                            context,
                            typeof(void),
                            this.EmitPutArrayHeaderExpression(
                                context,
                                this.EmitGetCollectionCountExpression(context, context.PackToTarget, traits)
                                ),
                            this.EmitForEachLoop(
                                context,
                                traits,
                                context.PackToTarget,
                                item =>
                                this.EmitSequentialStatements(
                                    context,
                                    typeof(void),
                                    this.EmitPackItemStatements(context, context.Packer, traits.ElementType, NilImplication.Null, null, item, null)
                                    )
                                )
                            );
                }
            }
            finally
            {
                this.EmitMethodEpilogue(context, SerializerMethod.PackToCore, construct);
            }
        }
示例#28
0
 public ReflectionCollectionMessagePackSerializer(
     SerializationContext ownerContext,
     Type abstractType,
     Type concreteType,
     CollectionTraits traits,
     PolymorphismSchema itemsSchema
     )
     : base(ownerContext, abstractType, traits, itemsSchema)
 {
     this._factory      = ReflectionSerializerHelper.CreateCollectionInstanceFactory(abstractType, concreteType, traits.ElementType);
     this._isPackable   = typeof(IPackable).IsAssignableFrom(concreteType ?? abstractType);
     this._isUnpackable = typeof(IUnpackable).IsAssignableFrom(concreteType ?? abstractType);
 }
示例#29
0
 public ReflectionNonGenericEnumerableMessagePackSerializer(
     SerializationContext ownerContext,
     Type abstractType,
     Type concreteType,
     CollectionTraits concreteTypeCollectionTraits,
     PolymorphismSchema itemsSchema
     )
     : base(ownerContext, abstractType, itemsSchema)
 {
     this._factory      = ReflectionSerializerHelper.CreateCollectionInstanceFactory(abstractType, concreteType, typeof(object));
     this._addItem      = ReflectionSerializerHelper.GetAddItem(concreteType, concreteTypeCollectionTraits);
     this._isPackable   = typeof(IPackable).IsAssignableFrom(concreteType ?? abstractType);
     this._isUnpackable = typeof(IUnpackable).IsAssignableFrom(concreteType ?? abstractType);
 }
示例#30
0
        /// <summary>
        ///		Creates an <see cref="Expression"/> which represents foreach block.
        /// </summary>
        /// <param name="collection">The collection to be enumerated.</param>
        /// <param name="traits">The traits of the collection.</param>
        /// <param name="bodyCreator">The body creator. The argument is <c>Current</c> property of the enumerator.</param>
        /// <returns>An <see cref="Expression"/> which represents foreach block.</returns>
        public static Expression ForEach(Expression collection, CollectionTraits traits, Func <Expression, Expression> bodyCreator)
        {
            /*
             *	var enumerator = collection.GetEnumerator();
             *	try
             *	{
             *		while(true)
             *		{
             *			if ( enumerator.MoveNext() )
             *			{
             *				body( enumerator.Current );
             *			}
             *			else
             *			{
             *				break;
             *			}
             *		}
             *	}
             *	finally
             *	{
             *		var asDisposable = enumerator as IDisposable;
             *		if( asDisposable != null )
             *		{
             *			asDisposable.Dispose();
             *		}
             *	}
             */

            var enumeratorVariable = Expression.Variable(traits.GetEnumeratorMethod.ReturnType, "enumerator");
            var tryBlock           = CreateForEachTry(enumeratorVariable, traits, bodyCreator);
            var finallyBlock       = CreateForEachFinally(enumeratorVariable, traits);

            return
                (Expression.Block(
                     new[] { enumeratorVariable },
                     Expression.Assign(enumeratorVariable, Expression.Call(collection, traits.GetEnumeratorMethod)),
                     finallyBlock == null
                                        ? tryBlock
                                        : Expression.TryFinally(
                         tryBlock,
                         enumeratorVariable.Type.GetIsValueType()
                                                ? finallyBlock
                                                : Expression.IfThen(
                             Expression.ReferenceNotEqual(enumeratorVariable, Expression.Constant(null)),
                             finallyBlock
                             )
                         )
                     ));
        }
示例#31
0
        public AbstractEnumerableMessagePackSerializer(
            SerializationContext ownerContext,
#if !UNITY
            Type targetType,
#else
            Type abstractType,
            Type concreteType,
            CollectionTraits traits,
#endif // !UNITY
            PolymorphismSchema schema
            )
#if !UNITY
            : base(ownerContext, schema)
#else
            : base(ownerContext, abstractType, traits, schema, SerializerCapabilities.PackTo | SerializerCapabilities.UnpackFrom | SerializerCapabilities.UnpackTo)
示例#32
0
        public AbstractCollectionMessagePackSerializer(
            SerializationContext ownerContext,
#if !UNITY
            Type targetType,
#else
            Type abstractType,
            Type concreteType,
            CollectionTraits traits,
#endif // !UNITY
            PolymorphismSchema schema
            )
#if !UNITY
            : base(ownerContext, schema)
#else
            : base(ownerContext, abstractType, traits, schema)
        public SerializerSpecification(Type targetType, CollectionTraits targetCollectionTraits, string serializerTypeName, string serializerTypeNamespace)
        {
#if DEBUG
            Contract.Assert(targetType != null, "targetType != null");
            Contract.Assert(serializerTypeName != null, "serializerTypeName != null");
            Contract.Assert(serializerTypeNamespace != null, "serializerTypeNamespace != null");
#endif // DEBUG
            this.TargetType              = targetType;
            this.TargetCollectionTraits  = targetCollectionTraits;
            this.SerializerTypeName      = serializerTypeName;
            this.SerializerTypeNamespace = serializerTypeNamespace;
            this.SerializerTypeFullName  =
                String.IsNullOrEmpty(serializerTypeNamespace)
                                ? serializerTypeName
                                : serializerTypeNamespace + "." + serializerTypeName;
        }
        public ReflectionEnumerableMessagePackSerializer(
            SerializationContext ownerContext,
            Type targetType,
            CollectionTraits collectionTraits,
            PolymorphismSchema itemsSchema
            )
            : base(ownerContext, itemsSchema)
        {
            this._factory      = ReflectionSerializerHelper.CreateCollectionInstanceFactory <TCollection, TItem>(targetType);
            this._addItem      = ReflectionSerializerHelper.GetAddItem <TCollection, TItem>(targetType, collectionTraits);
            this._isPackable   = typeof(IPackable).IsAssignableFrom(targetType ?? typeof(TCollection));
            this._isUnpackable = typeof(IUnpackable).IsAssignableFrom(targetType ?? typeof(TCollection));
#if FEATURE_TAP
            this._isAsyncPackable   = typeof(IAsyncPackable).IsAssignableFrom(targetType ?? typeof(TCollection));
            this._isAsyncUnpackable = typeof(IAsyncUnpackable).IsAssignableFrom(targetType ?? typeof(TCollection));
#endif // FEATURE_TAP
        }
 public static Func<object, int> CreateGetCount(Type type, CollectionTraits traits)
 {
     if (type.IsArray)
     {
         var lengthAccessor = type.GetProperty("Length").GetGetMethod();
         return t => (int)lengthAccessor.Invoke(t, new object[0]);
     }
     else if (traits.CountProperty != null)
     {
         var countAccessor = traits.CountProperty.GetGetMethod();
         return t => (int)countAccessor.Invoke(t, new object[0]);
     }
     else
     {
         var countMethod = Metadata._Enumerable.Count1Method.MakeGenericMethod(traits.ElementType);
         return t => (int)countMethod.Invoke(null, new object[] {t});
     }
 }
 public ArrayRecflectionMessagePackSerializer(Type type, SerializationContext context, CollectionTraits traits) : base(type, context, traits) { }
示例#37
0
		/// <summary>
		///		Emits 'foreach' statement on the IL stream.
		/// </summary>
		/// <param name="il">IL generator to be emitted to.</param>
		/// <param name="traits"><see cref="CollectionTraits"/> which contains traits of the iterating collection.</param>
		/// <param name="collection">'collection' argument index.</param>
		/// <param name="bodyEmitter">Delegate to emit body statement.</param>
		public static void EmitForEach( TracingILGenerator il, CollectionTraits traits, LocalBuilder collection, Action<TracingILGenerator, Action> bodyEmitter )
		{
			Contract.Requires( il != null );
			Contract.Requires( collection != null );
			Contract.Requires( bodyEmitter != null );

			var enumerator = il.DeclareLocal( traits.GetEnumeratorMethod.ReturnType, "enumerator" );

			// gets enumerator
			if ( collection.LocalType.IsValueType )
			{
				il.EmitAnyLdloca( collection );
			}
			else
			{
				il.EmitAnyLdloc( collection );
			}

			il.EmitAnyCall( traits.GetEnumeratorMethod );
			il.EmitAnyStloc( enumerator );

			if ( typeof( IDisposable ).IsAssignableFrom( traits.GetEnumeratorMethod.ReturnType ) )
			{
				il.BeginExceptionBlock();
			}

			var startLoop = il.DefineLabel( "START_LOOP" );
			il.MarkLabel( startLoop );
			var endLoop = il.DefineLabel( "END_LOOP" );
			var enumeratorType = traits.GetEnumeratorMethod.ReturnType;
			MethodInfo moveNextMethod = enumeratorType.GetMethod( "MoveNext", Type.EmptyTypes );
			PropertyInfo currentProperty = traits.GetEnumeratorMethod.ReturnType.GetProperty( "Current" );

			if ( moveNextMethod == null )
			{
				moveNextMethod = Metadata._IEnumerator.MoveNext;
			}

			if ( currentProperty == null )
			{
				if ( enumeratorType == typeof( IDictionaryEnumerator ) )
				{
					currentProperty = Metadata._IDictionaryEnumerator.Current;
				}
				else if ( enumeratorType.IsInterface )
				{
					if ( enumeratorType.IsGenericType && enumeratorType.GetGenericTypeDefinition() == typeof( IEnumerator<> ) )
					{
						currentProperty = typeof( IEnumerator<> ).MakeGenericType( traits.ElementType ).GetProperty( "Current" );
					}
					else
					{
						currentProperty = Metadata._IEnumerator.Current;
					}
				}
			}

			Contract.Assert( currentProperty != null, enumeratorType.ToString() );

			// iterates
			if ( traits.GetEnumeratorMethod.ReturnType.IsValueType )
			{
				il.EmitAnyLdloca( enumerator );
			}
			else
			{
				il.EmitAnyLdloc( enumerator );
			}

			il.EmitAnyCall( moveNextMethod );
			il.EmitBrfalse( endLoop );

			bodyEmitter(
				il,
				() =>
				{
					if ( traits.GetEnumeratorMethod.ReturnType.IsValueType )
					{
						il.EmitAnyLdloca( enumerator );
					}
					else
					{
						il.EmitAnyLdloc( enumerator );
					}
					il.EmitGetProperty( currentProperty );
				}
			);

			il.EmitBr( startLoop );
			il.MarkLabel( endLoop );

			// Dispose
			if ( typeof( IDisposable ).IsAssignableFrom( traits.GetEnumeratorMethod.ReturnType ) )
			{
				il.BeginFinallyBlock();

				if ( traits.GetEnumeratorMethod.ReturnType.IsValueType )
				{
					var disposeMethod = traits.GetEnumeratorMethod.ReturnType.GetMethod( "Dispose" );
					if ( disposeMethod != null && disposeMethod.GetParameters().Length == 0 && disposeMethod.ReturnType == typeof( void ) )
					{
						il.EmitAnyLdloca( enumerator );
						il.EmitAnyCall( disposeMethod );
					}
					else
					{
						il.EmitAnyLdloc( enumerator );
						il.EmitBox( traits.GetEnumeratorMethod.ReturnType );
						il.EmitAnyCall( Metadata._IDisposable.Dispose );
					}
				}
				else
				{
					il.EmitAnyLdloc( enumerator );
					il.EmitAnyCall( Metadata._IDisposable.Dispose );
				}

				il.EndExceptionBlock();
			}
		}
		private static void CreateMapUnpack( Type targetType, SerializerEmitter emitter, CollectionTraits traits )
		{
			CreateMapUnpackFrom( targetType, emitter, traits );
			CreateMapUnpackTo( targetType, emitter, traits );
		}
		private static void CreateMapUnpackTo( Type targetType, SerializerEmitter emitter, CollectionTraits traits )
		{
			var il = emitter.GetUnpackToMethodILGenerator();
			try
			{
				EmitInvokeMapUnpackToHelper( targetType, emitter, traits, il, 1, il0 => il0.EmitAnyLdarg( 2 ) );

				il.EmitRet();
			}
			finally
			{
				il.FlushTrace();
			}
		}
        protected SequenceReflectionMessagePackSerializer(Type type, SerializationContext context, CollectionTraits traits)
            : base(type, (context ?? SerializationContext.Default).CompatibilityOptions.PackerCompatibilityOptions)
        {
            Contract.Assert(type.IsArray || typeof(IEnumerable).IsAssignableFrom(type), type + " is not array nor IEnumerable");
            this._traits = traits;
            this._elementSerializer = context.GetSerializer(traits.ElementType);
            this._getCount = ReflectionSerializerLogics.CreateGetCount(type, traits);

            //var packerParameter = Expression.Parameter(typeof(Packer), "packer");
            //var objectTreeParameter = Expression.Parameter(typeof(T), "objectTree");
            //var elementSerializerParameter = Expression.Parameter(typeof(IMessagePackSerializer), "elementSerializer");

            this._packToCore = (Packer packer, object objectTree, IMessagePackSerializer elementSerializer) =>
                {
                    var length = this._getCount(objectTree);
                    packer.PackArrayHeader(length);
                    foreach (var item in (IEnumerable)objectTree)
                    {
                        elementSerializer.PackTo(packer, item);
                    }
                };


            /*
             *	for ( int i = 0; i < count; i++ )
             *	{
             *		if ( !unpacker.Read() )
             *		{
             *			throw SerializationExceptions.NewMissingItem( i );
             *		}
             *	
             *		T item;
             *		if ( !unpacker.IsArrayHeader && !unpacker.IsMapHeader )
             *		{
             *			item = this.ElementSerializer.UnpackFrom( unpacker );
             *		}
             *		else
             *		{
             *			using ( Unpacker subtreeUnpacker = unpacker.ReadSubtree() )
             *			{
             *				item = this.ElementSerializer.UnpackFrom( subtreeUnpacker );
             *			}
             *		}
             *
             *		instance[ i ] = item; -- OR -- instance.Add( item );
             *	}
             */

            // FIXME: use UnpackHelper

            if (type.IsArray)
            {
                var arrayUnpackerMethod = _UnpackHelpers.UnpackArrayTo_1.MakeGenericMethod(traits.ElementType);
                this._unpackToCore = (Unpacker unpacker, object instance, IMessagePackSerializer elementSerializer) =>
                {
                    arrayUnpackerMethod.Invoke(null, new object[] { unpacker, elementSerializer, instance });
                };
            }
            else
            {
                this._unpackToCore = (Unpacker unpacker, object instance, IMessagePackSerializer elementSerializer) =>
                {
                    var count = UnpackHelpers.GetItemsCount(unpacker);
                    for (int i = 0; i < count; i++)
                    {
                        if (!unpacker.Read())
                        {
                            throw SerializationExceptions.NewMissingItem(i);
                        }
                        object item;
                        if (!unpacker.IsArrayHeader && !unpacker.IsMapHeader)
                        {
                            item = elementSerializer.UnpackFrom(unpacker);
                        }
                        else
                        {
                            using (Unpacker subtreeUnpacker = unpacker.ReadSubtree())
                            {
                                item = elementSerializer.UnpackFrom(subtreeUnpacker);
                            }
                        }
                        traits.AddMethod.Invoke(instance, new object[] { item });
                    }
                };
            }
        }
		private static void CreateUnpackArrayProceduresCore( Type targetType, SerializerEmitter emitter, CollectionTraits traits )
		{
			CreateArrayUnpackFrom( targetType, emitter, traits );
			CreateArrayUnpackTo( targetType, emitter, traits );
		}
		private static void EmitInvokeArrayUnpackToHelper( Type targetType, SerializerEmitter emitter, CollectionTraits traits, TracingILGenerator il, int unpackerArgumentIndex, Action<TracingILGenerator> loadCollectionEmitting )
		{
			il.EmitAnyLdarg( unpackerArgumentIndex );
			var serializerGetting = emitter.RegisterSerializer( traits.ElementType );

			if ( targetType.IsArray )
			{
				// Array
				/*
				 * UnpackHelpers.UnpackArrayTo( unpacker, GET_SERIALIZER, collection );
				 */
				serializerGetting( il, 0 );
				loadCollectionEmitting( il );
				il.EmitAnyCall( Metadata._UnpackHelpers.UnpackArrayTo_1.MakeGenericMethod( traits.ElementType ) );
			}
			else if ( targetType.IsGenericType )
			{
				serializerGetting( il, 0 );
				loadCollectionEmitting( il );
				if ( targetType.IsValueType )
				{
					il.EmitBox( targetType );
				}

				if ( traits.AddMethod.ReturnType == null || traits.AddMethod.ReturnType == typeof( void ) )
				{
					// with void Add( T item )
					/*
					 * Action<T> addition = TCollection.Add
					 * UnpackHelpers.UnpackCollectionTo( unpacker, GET_SERIALIZER, collection, addition );
					 */
					var itemType = traits.AddMethod.GetParameters()[ 0 ].ParameterType;
					EmitNewDelegate( il, targetType, traits.AddMethod, loadCollectionEmitting, typeof( Action<> ).MakeGenericType( itemType ) );
					il.EmitAnyCall( Metadata._UnpackHelpers.UnpackCollectionTo_1.MakeGenericMethod( itemType ) );
				}
				else
				{
					// with TDiscarded Add( T item )
					/*
					 * Func<T, TDiscarded> addition = TCollection.Add
					 * UnpackHelpers.UnpackCollectionTo( unpacker, GET_SERIALIZER, collection, addition );
					 */
					var itemType = traits.AddMethod.GetParameters()[ 0 ].ParameterType;
					var discardingType = traits.AddMethod.ReturnType;
					EmitNewDelegate( il, targetType, traits.AddMethod, loadCollectionEmitting, typeof( Func<,> ).MakeGenericType( itemType, discardingType ) );
					il.EmitAnyCall( Metadata._UnpackHelpers.UnpackCollectionTo_2.MakeGenericMethod( itemType, discardingType ) );
				}
			}
			else
			{
				loadCollectionEmitting( il );
				if ( targetType.IsValueType )
				{
					il.EmitBox( targetType );
				}

				if ( traits.AddMethod.ReturnType == null || traits.AddMethod.ReturnType == typeof( void ) )
				{
					// with void Add( object item )
					/*
					 * Action<object> addition = TCollection.Add
					 * UnpackHelpers.UnpackCollectionTo( unpacker, collection, addition );
					 */
					EmitNewDelegate( il, targetType, traits.AddMethod, loadCollectionEmitting, typeof( Action<object> ) );
					il.EmitAnyCall( Metadata._UnpackHelpers.UnpackNonGenericCollectionTo );
				}
				else
				{
					// with TDiscarded Add( object item )
					/*
					 * Func<TDiscarded> addition = TCollection.Add
					 * UnpackHelpers.UnpackCollectionTo( unpacker, collection, addition );
					 */
					var discardingType = traits.AddMethod.ReturnType;
					EmitNewDelegate( il, targetType, traits.AddMethod, loadCollectionEmitting, typeof( Func<,> ).MakeGenericType( typeof( object ), discardingType ) );
					il.EmitAnyCall( Metadata._UnpackHelpers.UnpackNonGenericCollectionTo_1.MakeGenericMethod( discardingType ) );
				}
			}
		}
		private static void CreateMapPack( Type targetType, SerializerEmitter emiter, CollectionTraits traits )
		{
			var il = emiter.GetPackToMethodILGenerator();
			try
			{

				/*
				 * 	int count = ((ICollection<KeyValuePair<string, DateTime>>)dictionary).Count;
				 * 	packer.PackMapHeader(count);
				 * 	foreach (KeyValuePair<string, DateTime> current in dictionary)
				 * 	{
				 * 		this._serializer0.PackTo(packer, current.Key);
				 * 		this._serializer1.PackTo(packer, current.Value);
				 * 	}
				 */

				var collection = il.DeclareLocal( targetType, "collection" );
				var item = il.DeclareLocal( traits.ElementType, "item" );
				var keyProperty = traits.ElementType.GetProperty( "Key" );
				var valueProperty = traits.ElementType.GetProperty( "Value" );
				// This instruction is always ldarg, not to be ldarga.
				il.EmitAnyLdarg( 2 );
				il.EmitAnyStloc( collection );
				var count = il.DeclareLocal( typeof( int ), "count" );
				EmitLoadTarget( targetType, il, collection );
				il.EmitGetProperty( traits.CountProperty );
				il.EmitAnyStloc( count );
				il.EmitAnyLdarg( 1 );
				il.EmitAnyLdloc( count );
				il.EmitAnyCall( Metadata._Packer.PackMapHeader );
				il.EmitPop();

				Emittion.EmitForEach(
					il,
					traits,
					collection,
					( il0, getCurrentEmitter ) =>
					{
						if ( traits.ElementType.IsGenericType )
						{
							Contract.Assert( traits.ElementType.GetGenericTypeDefinition() == typeof( KeyValuePair<,> ) );
							getCurrentEmitter();
							il0.EmitAnyStloc( item );
							Emittion.EmitSerializeValue(
								emiter,
								il0,
								1,
								traits.ElementType.GetGenericArguments()[ 0 ],
								null,
								NilImplication.MemberDefault,
								il1 =>
								{
									il1.EmitAnyLdloca( item );
									il1.EmitGetProperty( keyProperty );
								}
							);

							Emittion.EmitSerializeValue(
								emiter,
								il0,
								1,
								traits.ElementType.GetGenericArguments()[ 1 ],
								null,
								NilImplication.MemberDefault,
								il1 =>
								{
									il1.EmitAnyLdloca( item );
									il1.EmitGetProperty( valueProperty );
								}
							);
						}
						else
						{
							Contract.Assert( traits.ElementType == typeof( DictionaryEntry ) );
							getCurrentEmitter();
							il0.EmitAnyStloc( item );
							Emittion.EmitSerializeValue(
								emiter,
								il0,
								1,
								typeof( MessagePackObject ),
								null,
								NilImplication.MemberDefault,
								il1 =>
								{
									il0.EmitAnyLdloca( item );
									il0.EmitGetProperty( Metadata._DictionaryEntry.Key );
									il0.EmitUnbox_Any( typeof( MessagePackObject ) );
								}
							);

							Emittion.EmitSerializeValue(
								emiter,
								il0,
								1,
								typeof( MessagePackObject ),
								null,
								NilImplication.MemberDefault,
								il1 =>
								{
									il0.EmitAnyLdloca( item );
									il0.EmitGetProperty( Metadata._DictionaryEntry.Value );
									il0.EmitUnbox_Any( typeof( MessagePackObject ) );
								}
							);
						}
					}
				);
				il.EmitRet();
			}
			finally
			{
				il.FlushTrace();
			}
		}
		private static void CreatePackArrayProceduresCore( Type targetType, SerializerEmitter emitter, CollectionTraits traits )
		{
			var il = emitter.GetPackToMethodILGenerator();
			try
			{
				// Array
				if ( targetType.IsArray )
				{
					/*
					 * // array
					 *  packer.PackArrayHeader( length );
					 * for( int i = 0; i < length; i++ )
					 * {
					 * 		this._serializer.PackTo( packer, collection[ i ] );
					 * }
					 */
					var length = il.DeclareLocal( typeof( int ), "length" );
					il.EmitAnyLdarg( 2 );
					il.EmitLdlen();
					il.EmitAnyStloc( length );
					il.EmitAnyLdarg( 1 );
					il.EmitAnyLdloc( length );
					il.EmitAnyCall( Metadata._Packer.PackArrayHeader );
					il.EmitPop();
					Emittion.EmitFor(
						il,
						length,
						( il0, i ) =>
						{
							Emittion.EmitSerializeValue(
								emitter,
								il0,
								1,
								traits.ElementType,
								null,
								NilImplication.MemberDefault,
								il1 =>
								{
									il1.EmitAnyLdarg( 2 );
									il1.EmitAnyLdloc( i );
									il1.EmitLdelem( traits.ElementType );
								}
							);
						}
					);
				}
				else if ( traits.CountProperty == null )
				{
					/*
					 *  array = collection.ToArray();
					 *  packer.PackArrayHeader( length );
					 * for( int i = 0; i < length; i++ )
					 * {
					 * 		this._serializer.PackTo( packer, array[ i ] );
					 * }
					 */
					var array = il.DeclareLocal( traits.ElementType.MakeArrayType(), "array" );
					EmitLoadTarget( targetType, il, 2 );
					il.EmitAnyCall( Metadata._Enumerable.ToArray1Method.MakeGenericMethod( traits.ElementType ) );
					il.EmitAnyStloc( array );
					var length = il.DeclareLocal( typeof( int ), "length" );
					il.EmitAnyLdloc( array );
					il.EmitLdlen();
					il.EmitAnyStloc( length );
					il.EmitAnyLdarg( 1 );
					il.EmitAnyLdloc( length );
					il.EmitAnyCall( Metadata._Packer.PackArrayHeader );
					il.EmitPop();
					Emittion.EmitFor(
						il,
						length,
						( il0, i ) =>
						{
							Emittion.EmitSerializeValue(
								emitter,
								il0,
								1,
								traits.ElementType,
								null,
								NilImplication.MemberDefault,
								il1 =>
								{
									il1.EmitAnyLdloc( array );
									il1.EmitAnyLdloc( i );
									il1.EmitLdelem( traits.ElementType );
								}
							);
						}
					);
				}
				else
				{
					/*
					 * // Enumerable
					 *  packer.PackArrayHeader( collection.Count );
					 * foreach( var item in list )
					 * {
					 * 		this._serializer.PackTo( packer, array[ i ] );
					 * }
					 */
					var collection = il.DeclareLocal( targetType, "collection" );
					// This instruction always ldarg, not to be ldarga
					il.EmitAnyLdarg( 2 );
					il.EmitAnyStloc( collection );
					var count = il.DeclareLocal( typeof( int ), "count" );
					EmitLoadTarget( targetType, il, 2 );
					il.EmitGetProperty( traits.CountProperty );
					il.EmitAnyStloc( count );
					il.EmitAnyLdarg( 1 );
					il.EmitAnyLdloc( count );
					il.EmitAnyCall( Metadata._Packer.PackArrayHeader );
					il.EmitPop();
					Emittion.EmitForEach(
						il,
						traits,
						collection,
						( il0, getCurrentEmitter ) =>
						{
							Emittion.EmitSerializeValue(
								emitter,
								il0,
								1,
								traits.ElementType,
								null,
								NilImplication.MemberDefault,
								_ => getCurrentEmitter()
							);
						}
					);
				}
				il.EmitRet();
			}
			finally
			{
				il.FlushTrace();
			}
		}
		private static void CreateArrayUnpackFrom( SerializationContext context, Type targetType, SerializerEmitter emitter, CollectionTraits traits )
		{
			var il = emitter.GetUnpackFromMethodILGenerator();
			var localHolder = new LocalVariableHolder( il );
			var instanceType = targetType;

			try
			{
				if ( targetType.IsInterface || targetType.IsAbstract )
				{
					instanceType = context.DefaultCollectionTypes.GetConcreteType( targetType );
					if ( instanceType == null )
					{
						il.EmitTypeOf( targetType );
						il.EmitAnyCall( SerializationExceptions.NewNotSupportedBecauseCannotInstanciateAbstractTypeMethod );
						il.EmitThrow();
						return;
					}
				}

				/*
				 *	if (!unpacker.IsArrayHeader)
				 *	{
				 *		throw SerializationExceptions.NewIsNotArrayHeader();
				 *	}
				 *	
				 *	TCollection collection = new ...;
				 *	this.UnpackToCore(unpacker, array);
				 *	return collection;
				 */

				il.EmitAnyLdarg( 1 );
				il.EmitGetProperty( Metadata._Unpacker.IsArrayHeader );
				var endIf = il.DefineLabel( "END_IF" );
				il.EmitBrtrue_S( endIf );
				il.EmitAnyCall( SerializationExceptions.NewIsNotArrayHeaderMethod );
				il.EmitThrow();
				il.MarkLabel( endIf );
				var collection = localHolder.GetDeserializingCollection( instanceType );
				// Emit newobj, newarr, or call ValueType..ctor()
				Emittion.EmitConstruction(
					il,
					collection,
					il0 => Emittion.EmitGetUnpackerItemsCountAsInt32( il0, 1, localHolder )
				);

				EmitInvokeArrayUnpackToHelper( targetType, emitter, traits, il, 1, il0 => il0.EmitAnyLdloc( collection ) );

				il.EmitAnyLdloc( collection );
				il.EmitRet();
			}
			finally
			{
				il.FlushTrace();
			}
		}
        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);
            }
        }
		private static void EmitInvokeMapUnpackToHelper( Type targetType, SerializerEmitter emitter, CollectionTraits traits, TracingILGenerator il, int unpackerArgumentIndex, Action<TracingILGenerator> loadCollectionEmitting )
		{
			il.EmitAnyLdarg( unpackerArgumentIndex );
			if ( traits.ElementType.IsGenericType )
			{
				var keyType = traits.ElementType.GetGenericArguments()[ 0 ];
				var valueType = traits.ElementType.GetGenericArguments()[ 1 ];
				var keySerializerGetting = emitter.RegisterSerializer( keyType );
				var valueSerializerGetting = emitter.RegisterSerializer( valueType );
				keySerializerGetting( il, 0 );
				valueSerializerGetting( il, 0 );
				loadCollectionEmitting( il );

				if ( targetType.IsValueType )
				{
					il.EmitBox( targetType );
				}

				il.EmitAnyCall( Metadata._UnpackHelpers.UnpackMapTo_2.MakeGenericMethod( keyType, valueType ) );
			}
			else
			{
				loadCollectionEmitting( il );

				if ( targetType.IsValueType )
				{
					il.EmitBox( targetType );
				}

				il.EmitAnyCall( Metadata._UnpackHelpers.UnpackNonGenericMapTo );
			}
		}
		private static void CreateMapUnpackFrom( Type targetType, SerializerEmitter emitter, CollectionTraits traits )
		{
			var il = emitter.GetUnpackFromMethodILGenerator();
			try
			{
				/*
				 *	if (!unpacker.IsMapHeader)
				 *	{
				 *		throw SerializationExceptions.NewIsNotMapHeader();
				 *	}
				 *	
				 *	TDictionary<TKey, TValue> dictionary = new ...;
				 *	this.UnpackToCore(unpacker, dictionary);
				 *	return dictionary;
				 */

				if ( targetType.IsInterface || targetType.IsAbstract )
				{
					il.EmitTypeOf( targetType );
					il.EmitAnyCall( SerializationExceptions.NewNotSupportedBecauseCannotInstanciateAbstractTypeMethod );
					il.EmitThrow();
					return;
				}

				il.EmitAnyLdarg( 1 );
				il.EmitGetProperty( Metadata._Unpacker.IsMapHeader );
				var endIf = il.DefineLabel( "END_IF" );
				il.EmitBrtrue_S( endIf );
				il.EmitAnyCall( SerializationExceptions.NewIsNotMapHeaderMethod );
				il.EmitThrow();
				il.MarkLabel( endIf );

				var collection = il.DeclareLocal( targetType, "collection" );
				Emittion.EmitConstruction(
					il,
					collection,
					il0 => Emittion.EmitGetUnpackerItemsCountAsInt32( il0, 1 )
				);

				EmitInvokeMapUnpackToHelper( targetType, emitter, traits, il, 1, il0 => il0.EmitAnyLdloc( collection ) );

				il.EmitAnyLdloc( collection );
				il.EmitRet();
			}
			finally
			{
				il.FlushTrace();
			}
		}