コード例 #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);
        }
コード例 #2
0
 private static void CreateDefaultObjectConstructor(ConstructorBuilder contextfulConstructorBuilder, TracingILGenerator il)
 {
     /*
      *	.ctor() : this(null)
      *	{}
      */
     // : this(null)
     il.EmitAnyLdarg(0);
     il.EmitLdnull();
     il.EmitCallConstructor(contextfulConstructorBuilder);
     il.EmitRet();
 }
コード例 #3
0
        private void Invoke(TracingILGenerator il)
        {
            ConstructorInfo asConsctructor;

            if ((asConsctructor = this._method as ConstructorInfo) != null)
            {
                if (asConsctructor.DeclaringType.GetIsValueType())
                {
                    this._target.LoadValue(il, true);
                    foreach (var argument in this._arguments)
                    {
                        argument.LoadValue(il, false);
                    }

                    il.EmitCallConstructor(asConsctructor);

                    // For compatibility to ref type.
                    this._target.LoadValue(il, false);
                }
                else
                {
                    foreach (var argument in this._arguments)
                    {
                        argument.LoadValue(il, false);
                    }

                    il.EmitNewobj(asConsctructor);
                }
            }
            else
            {
                // method
                if (!this._method.IsStatic)
                {
                    this._target.LoadValue(il, this._target.ContextType.GetIsValueType());
                }

                foreach (var argument in this._arguments)
                {
                    argument.LoadValue(il, false);
                }

                if (this._method.IsStatic || this._target.ContextType.GetIsValueType())
                {
                    il.EmitCall(this._method as MethodInfo);
                }
                else
                {
                    il.EmitCallvirt(this._method as MethodInfo);
                }
            }
        }
コード例 #4
0
        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();
        }
コード例 #5
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());
        }
コード例 #6
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);
         }
     }
 }
コード例 #7
0
        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();
        }
コード例 #8
0
        private void Invoke(TracingILGenerator il)
        {
            ConstructorInfo asConsctructor;

            if ((asConsctructor = this._method as ConstructorInfo) != null)
            {
                if (asConsctructor.DeclaringType.GetIsValueType())
                {
                    this._target.LoadValue(il, true);
                    foreach (var argument in this._arguments)
                    {
                        argument.LoadValue(il, false);
                    }

                    il.EmitCallConstructor(asConsctructor);

                    // For compatibility to ref type.
                    this._target.LoadValue(il, false);
                }
                else
                {
                    foreach (var argument in this._arguments)
                    {
                        argument.LoadValue(il, false);
                    }

                    il.EmitNewobj(asConsctructor);
                }
            }
            else
            {
                // method
                if (!this._method.IsStatic)
                {
                    this._target.LoadValue(il, this._target.ContextType.ResolveRuntimeType().GetIsValueType());
                }

                foreach (var argument in this._arguments)
                {
                    argument.LoadValue(il, false);
                }

                if (this._method.IsStatic || this._target.ContextType.ResolveRuntimeType().GetIsValueType())
                {
                    il.EmitCall(this._method as MethodInfo);
                }
                else if (this._interface != null)
                {
                    // Explicit interface impl
                    il.EmitCallvirt(
                        this._interface.GetRuntimeMethod(
                            this._method.Name.Substring(this._method.Name.LastIndexOf('.') + 1),
                            this._method.GetParameters().Select(p => p.ParameterType).ToArray()
                            )
                        );
                }
                else
                {
                    il.EmitCallvirt(this._method as MethodInfo);
                }
            }
        }
コード例 #9
0
        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());
        }
コード例 #10
0
        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();
        }