private void EmitDefaultEnumConstructor(ConstructorBuilder methodConstructor, TracingILGenerator il)
        {
            /*
             *	.ctor( SerializationContext c )
             *	  : this( c, DEFAULT_METHOD )
             *	{
             *	}
             */
            // : this( c, DEFAULT_METHOD )
            il.EmitLdarg_0();
            il.EmitLdarg_1();
            il.EmitAnyLdc_I4(( int )this._defaultEnumSerializationMethod);

            il.EmitCallConstructor(methodConstructor);

            il.EmitRet();
        }
Ejemplo n.º 2
0
        public override Func <SerializationContext, EnumSerializationMethod, MessagePackSerializer <T> > CreateConstructor <T>()
        {
            if (!this._typeBuilder.IsCreated())
            {
                /*
                 *	.ctor( PackerCompatibilityOptions c, EnumSerializerMethod method )
                 *	  : base( c, method )
                 *	{
                 *	}
                 */
                var il = new TracingILGenerator(this._contextConstructorBuilder, TextWriter.Null, this._isDebuggable);
                // : base( c, method )
                il.EmitLdarg_0();
                il.EmitLdarg_1();
                il.EmitLdarg_2();

                Contract.Assert(this._typeBuilder.BaseType != null);

                il.EmitCallConstructor(
                    this._typeBuilder.BaseType.GetConstructor(
                        BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, this._constructorParameterTypes, null
                        )
                    );

                il.EmitRet();
            }

            var ctor             = this._typeBuilder.CreateType().GetConstructor(this._constructorParameterTypes);
            var contextParameter = Expression.Parameter(typeof(SerializationContext), "context");
            var methodParameter  = Expression.Parameter(typeof(EnumSerializationMethod), "method");

#if DEBUG
            Contract.Assert(ctor != null, "ctor != null");
#endif
            return
                (Expression.Lambda <Func <SerializationContext, EnumSerializationMethod, MessagePackSerializer <T> > >(
                     Expression.New(
                         ctor,
                         contextParameter,
                         methodParameter
                         ),
                     contextParameter,
                     methodParameter
                     ).Compile());
        }
        private void EmitMethodEnumConstructor(Type baseType, TracingILGenerator il)
        {
            /*
             *	.ctor( SerializationContext c, EnumSerializerMethod method )
             *	  : base( c, method )
             *	{
             *	}
             */
            // : base( c, method )
            il.EmitLdarg_0();
            il.EmitLdarg_1();
            il.EmitLdarg_2();

            il.EmitCallConstructor(
                baseType.GetRuntimeConstructor(ContextAndEnumSerializationMethodConstructorParameterTypes)
                );

            il.EmitRet();
        }
        public override Func <SerializationContext, PolymorphismSchema, MessagePackSerializer <T> > CreateConstructor <T>()
        {
            if (!this._typeBuilder.IsCreated())
            {
                /*
                 *	.ctor() : this(null)
                 *	{}
                 */
                /*
                 *	.ctor( SerializationContext context )
                 *	  : base( ( context ?? SerializationContext.Default ).CompabilityOptions.PackerCompatibilityOptions )
                 *	{
                 *		this._serializer0 = context.GetSerializer<T0>();
                 *		this._serializer1 = context.GetSerializer<T1>();
                 *		this._serializer2 = context.GetSerializer<T2>();
                 *			:
                 *	}
                 */
                // default
                {
                    var il = this._defaultConstructorBuilder.GetILGenerator();
                    // : this(null)
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldnull);
                    il.Emit(OpCodes.Call, this._contextConstructorBuilder);
                    il.Emit(OpCodes.Ret);
                }

                // context
                {
                    var il = new TracingILGenerator(this._contextConstructorBuilder, TextWriter.Null, this._isDebuggable);
                    // : base()
                    il.EmitLdarg_0();
                    il.EmitLdarg_1();
#if DEBUG
                    Contract.Assert(this._typeBuilder.BaseType != null, "this._typeBuilder.BaseType != null");
#endif
                    if (this._traits.CollectionType == CollectionKind.NotCollection)
                    {
                        il.EmitCallConstructor(
                            this._typeBuilder.BaseType.GetConstructor(
                                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, ConstructorParameterTypes, null
                                )
                            );
                    }
                    else
                    {
                        il.EmitCall(this._restoreSchemaMethodBuilder);
                        il.EmitCallConstructor(
                            this._typeBuilder.BaseType.GetConstructor(
                                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, CollectionConstructorParameterTypes, null
                                )
                            );
                    }

                    // this._serializerN = context.GetSerializer<T>();
                    foreach (var entry in this._serializers)
                    {
                        var        targetType = Type.GetTypeFromHandle(entry.Key.TypeHandle);
                        MethodInfo getMethod  = Metadata._SerializationContext.GetSerializer1_Parameter_Method.MakeGenericMethod(targetType);

                        il.EmitLdarg_0();
                        il.EmitLdarg_1();
                        if (targetType.GetIsEnum())
                        {
                            il.EmitLdarg_1();
                            il.EmitTypeOf(targetType);
                            il.EmitAnyLdc_I4(( int )entry.Key.EnumSerializationMethod);
                            il.EmitCall(Metadata._EnumMessagePackSerializerHelpers.DetermineEnumSerializationMethodMethod);
                            il.EmitBox(typeof(EnumSerializationMethod));
                        }
                        else if (DateTimeMessagePackSerializerHelpers.IsDateTime(targetType))
                        {
                            il.EmitLdarg_1();
                            il.EmitAnyLdc_I4(( int )entry.Key.DateTimeConversionMethod);
                            il.EmitCall(Metadata._DateTimeMessagePackSerializerHelpers.DetermineDateTimeConversionMethodMethod);
                            il.EmitBox(typeof(DateTimeConversionMethod));
                        }
                        else
                        {
                            if (entry.Key.PolymorphismSchema == null)
                            {
                                il.EmitLdnull();
                            }
                            else
                            {
                                entry.Value.SchemaProvider(il);
                            }
                        }

                        il.EmitCallvirt(getMethod);
                        il.EmitStfld(entry.Value.Field);
                    }

                    foreach (var entry in this._fieldInfos)
                    {
                        il.EmitLdarg_0();
                        il.EmitLdtoken(FieldInfo.GetFieldFromHandle(entry.Key));
                        il.EmitCall(Metadata._FieldInfo.GetFieldFromHandle);
                        il.EmitStfld(entry.Value);
                    }

                    foreach (var entry in this._methodBases)
                    {
                        il.EmitLdarg_0();
                        il.EmitLdtoken(MethodBase.GetMethodFromHandle(entry.Key));
                        il.EmitCall(Metadata._MethodBase.GetMethodFromHandle);
                        il.EmitStfld(entry.Value);
                    }

                    il.EmitRet();
                }
            }

            var ctor             = this._typeBuilder.CreateType().GetConstructor(ConstructorParameterTypes);
            var contextParameter = Expression.Parameter(typeof(SerializationContext), "context");
            var schemaParameter  = Expression.Parameter(typeof(PolymorphismSchema), "schema");
#if DEBUG
            Contract.Assert(ctor != null, "ctor != null");
#endif
            return
                (Expression.Lambda <Func <SerializationContext, PolymorphismSchema, MessagePackSerializer <T> > >(
                     Expression.New(
                         ctor,
                         contextParameter
                         ),
                     contextParameter,
                     schemaParameter
                     ).Compile());
        }
        private void CreateContextfulObjectConstructor(
            AssemblyBuilderEmittingContext context,
            Type baseType,
            TracingILGenerator il,
            Func <ILConstruct> packActionListInitializerProvider,
            Func <ILConstruct> packActionTableInitializerProvider,
            Func <ILConstruct> unpackActionListInitializerProvider,
            Func <ILConstruct> unpackActionTableInitializerProvider,
#if FEATURE_TAP
            Func <ILConstruct> packAsyncActionListInitializerProvider,
            Func <ILConstruct> packAsyncActionTableInitializerProvider,
            Func <ILConstruct> unpackAsyncActionListInitializerProvider,
            Func <ILConstruct> unpackAsyncActionTableInitializerProvider,
#endif // FEATURE_TAP
            Func <ILConstruct> memberNamesInitializerProvider,
            Func <ILConstruct> unpackToInitializerProvider
            )
        {
            /*
             *	.ctor( SerializationContext context )
             *	  : base( ( context ?? SerializationContext.Default ).CompabilityOptions.PackerCompatibilityOptions )
             *	{
             *		this._serializer0 = context.GetSerializer<T0>();
             *		this._serializer1 = context.GetSerializer<T1>();
             *		this._serializer2 = context.GetSerializer<T2>();
             *			:
             *	}
             */
            // : base()
            il.EmitLdarg_0();
            il.EmitLdarg_1();
            if (this._specification.TargetCollectionTraits.CollectionType == CollectionKind.NotCollection)
            {
                il.EmitCallConstructor(
                    baseType.GetRuntimeConstructor(ConstructorParameterTypes)
                    );
            }
            else
            {
                il.EmitCall(this._methodTable[MethodName.RestoreSchema]);
                il.EmitCallConstructor(
                    baseType.GetRuntimeConstructor(CollectionConstructorParameterTypes)
                    );
            }

            // this._serializerN = context.GetSerializer<T>();
            foreach (var entry in this._serializers)
            {
                var        targetType = Type.GetTypeFromHandle(entry.Key.TypeHandle);
                MethodInfo getMethod  = Metadata._SerializationContext.GetSerializer1_Parameter_Method.MakeGenericMethod(targetType);

                il.EmitLdarg_0();
                il.EmitLdarg_1();
                if (targetType.GetIsEnum())
                {
                    il.EmitLdarg_1();
                    il.EmitTypeOf(targetType);
                    il.EmitAnyLdc_I4(( int )entry.Key.EnumSerializationMethod);
                    il.EmitCall(Metadata._EnumMessagePackSerializerHelpers.DetermineEnumSerializationMethodMethod);
                    il.EmitBox(typeof(EnumSerializationMethod));
                }
                else if (DateTimeMessagePackSerializerHelpers.IsDateTime(targetType))
                {
                    il.EmitLdarg_1();
                    il.EmitAnyLdc_I4(( int )entry.Key.DateTimeConversionMethod);
                    il.EmitCall(Metadata._DateTimeMessagePackSerializerHelpers.DetermineDateTimeConversionMethodMethod);
                    il.EmitBox(typeof(DateTimeConversionMethod));
                }
                else
                {
                    if (entry.Key.PolymorphismSchema == null)
                    {
                        il.EmitLdnull();
                    }
                    else
                    {
                        entry.Value.SchemaProvider(il);
                    }
                }

                il.EmitCallvirt(getMethod);
                il.EmitStfld(entry.Value.Field);
            }

            foreach (var entry in this._cachedFieldInfos)
            {
                il.EmitLdarg_0();
                il.EmitLdtoken(entry.Value.Target);
                il.EmitLdtoken(entry.Value.Target.DeclaringType);
                il.EmitCall(Metadata._FieldInfo.GetFieldFromHandle);
                il.EmitStfld(entry.Value.StorageFieldBuilder);
            }

            foreach (var entry in this._cachedMethodBases)
            {
                il.EmitLdarg_0();
                il.EmitLdtoken(entry.Value.Target);
                il.EmitLdtoken(entry.Value.Target.DeclaringType);
                il.EmitCall(Metadata._MethodBase.GetMethodFromHandle);
                il.EmitStfld(entry.Value.StorageFieldBuilder);
            }

            if (packActionListInitializerProvider != null)
            {
                packActionListInitializerProvider().Evaluate(il);
            }

#if FEATURE_TAP
            if (packAsyncActionListInitializerProvider != null)
            {
                packAsyncActionListInitializerProvider().Evaluate(il);
            }
#endif // FEATURE_TAP

            if (packActionTableInitializerProvider != null)
            {
                packActionTableInitializerProvider().Evaluate(il);
            }

#if FEATURE_TAP
            if (packAsyncActionTableInitializerProvider != null)
            {
                packAsyncActionTableInitializerProvider().Evaluate(il);
            }
#endif // FEATURE_TAP

            if (unpackActionListInitializerProvider != null)
            {
                unpackActionListInitializerProvider().Evaluate(il);
            }

#if FEATURE_TAP
            if (unpackAsyncActionListInitializerProvider != null)
            {
                unpackAsyncActionListInitializerProvider().Evaluate(il);
            }
#endif // FEATURE_TAP

            if (unpackActionTableInitializerProvider != null)
            {
                unpackActionTableInitializerProvider().Evaluate(il);
            }

#if FEATURE_TAP
            if (unpackAsyncActionTableInitializerProvider != null)
            {
                unpackAsyncActionTableInitializerProvider().Evaluate(il);
            }
#endif // FEATURE_TAP

            if (memberNamesInitializerProvider != null)
            {
                memberNamesInitializerProvider().Evaluate(il);
            }

            if (unpackToInitializerProvider != null)
            {
                unpackToInitializerProvider().Evaluate(il);
            }

            foreach (var cachedDelegateInfo in context.GetCachedDelegateInfos())
            {
                // this for stfld
                il.EmitLdargThis();

                var delegateType = cachedDelegateInfo.BackingField.FieldType.ResolveRuntimeType();

                // Declare backing field now.
                var field = context.GetDeclaredField(cachedDelegateInfo.BackingField.FieldName).ResolveRuntimeField();

                if (cachedDelegateInfo.IsThisInstance)
                {
                    il.EmitLdargThis();
                }
                else
                {
                    il.EmitLdnull();
                }

                // OK this should not be ldvirtftn because target is private or static.
                il.EmitLdftn(cachedDelegateInfo.TargetMethod.ResolveRuntimeMethod());
                // call extern .ctor(Object, void*)
                il.EmitNewobj(delegateType.GetConstructors().Single());

                il.EmitStfld(field);
            }

            il.EmitRet();
        }