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);
                }
            }
        }
        private static void EmitUnpackMembersFromMap(SerializerEmitter emitter, TracingILGenerator unpackerIL, SerializingMember[] entries, LocalBuilder result, LocalVariableHolder localHolder)
        {
            Label label  = unpackerIL.DefineLabel("BEGIN_LOOP");
            Label target = unpackerIL.DefineLabel("END_LOOP");

            unpackerIL.MarkLabel(label);
            LocalBuilder memberName = localHolder.MemberName;

            unpackerIL.EmitAnyLdarg(1);
            unpackerIL.EmitAnyLdloca(memberName);
            unpackerIL.EmitAnyCall(_Unpacker.ReadString);
            unpackerIL.EmitBrfalse(target);
            LocalBuilder unpackedData      = localHolder.UnpackedData;
            LocalBuilder unpackedDataValue = localHolder.UnpackedDataValue;

            for (int i = 0; i < entries.Length; i++)
            {
                if (entries[i].Contract.Name != null)
                {
                    unpackerIL.EmitAnyLdloc(memberName);
                    unpackerIL.EmitLdstr(entries[i].Contract.Name);
                    unpackerIL.EmitAnyCall(_String.op_Equality);
                    Label label3 = unpackerIL.DefineLabel("END_IF_MEMBER_" + i);
                    unpackerIL.EmitBrfalse(label3);
                    if (entries[i].Member == null)
                    {
                        Emittion.EmitGeneralRead(unpackerIL, 1);
                    }
                    else if (UnpackHelpers.IsReadOnlyAppendableCollectionMember(entries[i].Member))
                    {
                        Emittion.EmitDeserializeCollectionValue(emitter, unpackerIL, 1, result, entries[i].Member, entries[i].Member.GetMemberValueType(), entries[i].Contract.NilImplication, localHolder);
                    }
                    else
                    {
                        Emittion.EmitDeserializeValue(emitter, unpackerIL, 1, result, entries[i], localHolder);
                    }
                    unpackerIL.EmitBr(label);
                    unpackerIL.MarkLabel(label3);
                }
            }
            unpackerIL.EmitAnyLdarg(1);
            unpackerIL.EmitCallvirt(_Unpacker.Read);
            unpackerIL.EmitPop();
            unpackerIL.EmitBr(label);
            unpackerIL.MarkLabel(target);
        }
Example #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.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);
                }
            }
        }
Example #4
0
        private static void EmitUnpackMembersFromMap(SerializerEmitter emitter, TracingILGenerator unpackerIL, SerializingMember[] entries, LocalBuilder result, LocalVariableHolder localHolder)
        {
            /*
             *		var memberName = unpacker.Data.AsString();
             *		if( memberName == "A" )
             *		{
             *			if( !unpacker.Read() )
             *			{
             *				throw SerializationExceptions.NewUnexpectedStreamEndsException();
             *			}
             *
             *			isAFound = true;
             *		}
             *		:
             */

            var beginLoop = unpackerIL.DefineLabel("BEGIN_LOOP");
            var endLoop   = unpackerIL.DefineLabel("END_LOOP");

            unpackerIL.MarkLabel(beginLoop);
            var memberName = localHolder.MemberName;

            unpackerIL.EmitAnyLdarg(1);
            unpackerIL.EmitAnyLdloca(memberName);
            unpackerIL.EmitAnyCall(Metadata._Unpacker.ReadString);
            unpackerIL.EmitBrfalse(endLoop);

            for (int i = 0; i < entries.Length; i++)
            {
                if (entries[i].Contract.Name == null)
                {
                    // skip undefined member
                    continue;
                }

                // TODO: binary comparison

                // Is it current member?
                unpackerIL.EmitAnyLdloc(memberName);
                unpackerIL.EmitLdstr(entries[i].Contract.Name);
                unpackerIL.EmitAnyCall(Metadata._String.op_Equality);
                var endIfCurrentMember = unpackerIL.DefineLabel("END_IF_MEMBER_" + i);
                unpackerIL.EmitBrfalse(endIfCurrentMember);

                // Deserialize value
                if (entries[i].Member == null)
                {
                    Emittion.EmitGeneralRead(unpackerIL, 1);
                    // Ignore undefined member -- Nop.
                }
                else if (UnpackHelpers.IsReadOnlyAppendableCollectionMember(entries[i].Member))
                {
                    Emittion.EmitDeserializeCollectionValue(
                        emitter,
                        unpackerIL,
                        1,
                        result,
                        entries[i].Member,
                        entries[i].Member.GetMemberValueType(),
                        entries[i].Contract.NilImplication,
                        localHolder
                        );
                }
                else
                {
                    Emittion.EmitDeserializeValue(
                        emitter,
                        unpackerIL,
                        1,
                        result,
                        entries[i],
                        localHolder
                        );
                }

                // TOOD: Record for missing check

                unpackerIL.EmitBr(beginLoop);
                unpackerIL.MarkLabel(endIfCurrentMember);
            }

            // Drain next value with unpacker.Read()
            unpackerIL.EmitAnyLdarg(1);
            unpackerIL.EmitCallvirt(Metadata._Unpacker.Read);
            unpackerIL.EmitPop();
            unpackerIL.EmitBr(beginLoop);
            unpackerIL.MarkLabel(endLoop);
        }
        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();
        }