Exemplo n.º 1
0
        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);
            }
        }
        protected sealed override void ResetCore(Type targetType, Type baseClass)
        {
            // Note: baseClass is always null this class hiearchy.
            var targetTypeDefinition = TypeDefinition.Object(targetType);

            this.Packer          = ILConstruct.Argument(1, TypeDefinition.PackerType, "packer");
            this.PackToTarget    = ILConstruct.Argument(2, targetTypeDefinition, "objectTree");
            this.NullCheckTarget = ILConstruct.Argument(1, targetTypeDefinition, "objectTree");
            this.Unpacker        = ILConstruct.Argument(1, TypeDefinition.UnpackerType, "unpacker");
            this.IndexOfItem     = ILConstruct.Argument(3, TypeDefinition.Int32Type, "indexOfItem");
            this.ItemsCount      = ILConstruct.Argument(4, TypeDefinition.Int32Type, "itemsCount");
            this.UnpackToTarget  = ILConstruct.Argument(2, targetTypeDefinition, "collection");
            var traits = targetType.GetCollectionTraits(CollectionTraitOptions.Full, this.SerializationContext.CompatibilityOptions.AllowNonCollectionEnumerableTypes);

            if (traits.ElementType != null)
            {
                this.CollectionToBeAdded = ILConstruct.Argument(1, targetTypeDefinition, "collection");
                this.ItemToAdd           = ILConstruct.Argument(2, traits.ElementType, "item");
                if (traits.DetailedCollectionType == CollectionDetailedKind.GenericDictionary
#if !NETFX_35 && !UNITY && !NETFX_40 && !SILVERLIGHT
                    || traits.DetailedCollectionType == CollectionDetailedKind.GenericReadOnlyDictionary
#endif // !NETFX_35 && !UNITY && !NETFX_40 && !SILVERLIGHT
                    )
                {
                    this.KeyToAdd   = ILConstruct.Argument(2, traits.ElementType.GetGenericArguments()[0], "key");
                    this.ValueToAdd = ILConstruct.Argument(3, traits.ElementType.GetGenericArguments()[1], "value");
                }
                this.InitialCapacity = ILConstruct.Argument(1, TypeDefinition.Int32Type, "initialCapacity");
            }

            this._emitter = null;
            this._ilGeneratorStack.Clear();
        }
Exemplo n.º 3
0
        private static void EmitUnpackMembers(SerializerEmitter emitter, TracingILGenerator unpackerIL, SerializingMember[] entries, LocalBuilder result)
        {
            /*
             * #if T is IUnpackable
             *  result.UnpackFromMessage( unpacker );
             * #else
             *	if( unpacker.IsArrayHeader )
             *	{
             *		...
             *	}
             *	else
             *	{
             *		...
             *	}
             * #endif
             */

            var localHolder = new LocalVariableHolder(unpackerIL);

            unpackerIL.EmitAnyLdarg(1);
            unpackerIL.EmitGetProperty(Metadata._Unpacker.IsArrayHeader);
            var @else = unpackerIL.DefineLabel("ELSE");
            var endif = unpackerIL.DefineLabel("END_IF");

            unpackerIL.EmitBrfalse(@else);
            EmitUnpackMembersFromArray(emitter, unpackerIL, entries, result, localHolder, endif);
            unpackerIL.EmitBr(endif);
            unpackerIL.MarkLabel(@else);
            EmitUnpackMembersFromMap(emitter, unpackerIL, entries, result, localHolder);
            unpackerIL.MarkLabel(endif);
        }
Exemplo n.º 4
0
 public static void EmitUnpackFrom(SerializerEmitter emitter, TracingILGenerator il, LocalBuilder result, LocalBuilder unpacker)
 {
     emitter.RegisterSerializer(result.LocalType)(il, 0);
     il.EmitAnyLdloc(unpacker);
     il.EmitAnyCall(_UnpackHelpers.InvokeUnpackFrom_1Method.MakeGenericMethod(new Type[] { result.LocalType }));
     il.EmitAnyStloc(result);
 }
Exemplo n.º 5
0
        /// <summary>
        ///		Emits deserializing value instructions.
        /// </summary>
        /// <param name="emitter">The emitter.</param>
        /// <param name="il">The il generator.</param>
        /// <param name="unpackerArgumentIndex">Index of the unpacker argument.</param>
        /// <param name="value">The value local variable which stores unpacked value.</param>
        /// <param name="targetType">The type of deserialzing type.</param>
        /// <param name="memberName">The name of the member.</param>
        /// <param name="localHolder">The <see cref="LocalVariableHolder"/> which holds shared local variable information.</param>
        public static void EmitDeserializeValueWithoutNilImplication(SerializerEmitter emitter, TracingILGenerator il, int unpackerArgumentIndex, LocalBuilder value, Type targetType, string memberName, LocalVariableHolder localHolder)
        {
            Contract.Requires(emitter != null);
            Contract.Requires(il != null);
            Contract.Requires(unpackerArgumentIndex >= 0);
            Contract.Requires(value != null);

            var endOfDeserialization = il.DefineLabel("END_OF_DESERIALIZATION");

            /*
             *
             * if( !unpacker.IsArrayHeader && !unpacker.IsMapHeader )
             * {
             *		valueN = GET_SERIALIZER.UnpackFrom( unpacker );
             * }
             * else
             * {
             *		using( var subtreeUnpacker = unpacker.ReadSubtree )
             *		{
             *			valueN = GET_SERIALIZER.UnpackFrom( unpacker );
             *		}
             * }
             *
             * isValueNUnpacked = true;
             * END_OF_DESERIALIZATION:
             */

            // Nil implication is not needed.
            EmitDeserializeValueCore(emitter, il, unpackerArgumentIndex, value, targetType, null, memberName, endOfDeserialization, localHolder);

            il.MarkLabel(endOfDeserialization);
        }
        protected sealed override void ResetCore(Type targetType, Type baseClass)
        {
            // Note: baseClass is always null this class hiearchy.
            this.Packer         = ILConstruct.Argument(1, typeof(Packer), "packer");
            this.PackToTarget   = ILConstruct.Argument(2, targetType, "objectTree");
            this.Unpacker       = ILConstruct.Argument(1, typeof(Unpacker), "unpacker");
            this.IndexOfItem    = ILConstruct.Argument(3, typeof(int), "indexOfItem");
            this.ItemsCount     = ILConstruct.Argument(4, typeof(int), "itemsCount");
            this.UnpackToTarget = ILConstruct.Argument(2, targetType, "collection");
            var traits = targetType.GetCollectionTraits(CollectionTraitOptions.Full);

            if (traits.ElementType != null)
            {
                this.CollectionToBeAdded = ILConstruct.Argument(1, targetType, "collection");
                this.ItemToAdd           = ILConstruct.Argument(2, traits.ElementType, "item");
                if (traits.DetailedCollectionType == CollectionDetailedKind.GenericDictionary
#if !NETFX_35 && !UNITY && !NETFX_40 && !SILVERLIGHT
                    || traits.DetailedCollectionType == CollectionDetailedKind.GenericReadOnlyDictionary
#endif // !NETFX_35 && !UNITY && !NETFX_40 && !SILVERLIGHT
                    )
                {
                    this.KeyToAdd   = ILConstruct.Argument(2, traits.ElementType.GetGenericArguments()[0], "key");
                    this.ValueToAdd = ILConstruct.Argument(3, traits.ElementType.GetGenericArguments()[1], "value");
                }
                this.InitialCapacity = ILConstruct.Argument(1, typeof(int), "initialCapacity");
            }

            this._emitter = null;
            this._ilGeneratorStack.Clear();
        }
Exemplo n.º 7
0
        private static void EmitDeserializeValueCore(SerializerEmitter emitter, TracingILGenerator il, int unpackerArgumentIndex, LocalBuilder value, Type targetType, SerializingMember?member, string memberName, Label endOfDeserialization, LocalVariableHolder localHolder)
        {
            MethodInfo directReadMethod = _Unpacker.GetDirectReadMethod(value.LocalType);

            if ((directReadMethod != null) && (!member.HasValue || !UnpackHelpers.IsReadOnlyAppendableCollectionMember(member.Value.Member)))
            {
                LocalBuilder isDeserializationSucceeded = localHolder.IsDeserializationSucceeded;
                il.EmitLdc_I4_0();
                il.EmitAnyStloc(isDeserializationSucceeded);
                il.BeginExceptionBlock();
                il.EmitAnyLdarg(unpackerArgumentIndex);
                il.EmitAnyLdloca(value);
                il.EmitAnyCall(directReadMethod);
                il.EmitAnyStloc(isDeserializationSucceeded);
                il.BeginCatchBlock(typeof(MessageTypeException));
                LocalBuilder catchedException = localHolder.GetCatchedException(typeof(MessageTypeException));
                il.EmitAnyStloc(catchedException);
                il.EmitTypeOf(targetType);
                il.EmitLdstr(memberName);
                il.EmitAnyLdloc(catchedException);
                il.EmitAnyCall(SerializationExceptions.NewFailedToDeserializeMemberMethod);
                il.EmitThrow();
                il.EndExceptionBlock();
                Label target = il.DefineLabel("END_IF");
                il.EmitAnyLdloc(isDeserializationSucceeded);
                il.EmitBrtrue_S(target);
                il.EmitAnyCall(SerializationExceptions.NewUnexpectedEndOfStreamMethod);
                il.EmitThrow();
                il.MarkLabel(target);
                if (member.HasValue)
                {
                    EmitNilImplicationForPrimitive(il, member.Value, value, endOfDeserialization);
                }
            }
            else
            {
                EmitGeneralRead(il, unpackerArgumentIndex);
                if (member.HasValue)
                {
                    EmitNilImplication(il, unpackerArgumentIndex, member.Value.Contract.Name, member.Value.Contract.NilImplication, endOfDeserialization, localHolder);
                }
                Label label2 = il.DefineLabel("THEN_IF_COLLECTION");
                Label label3 = il.DefineLabel("END_IF_COLLECTION");
                il.EmitAnyLdarg(unpackerArgumentIndex);
                il.EmitGetProperty(_Unpacker.IsArrayHeader);
                il.EmitAnyLdarg(unpackerArgumentIndex);
                il.EmitGetProperty(_Unpacker.IsMapHeader);
                il.EmitOr();
                il.EmitBrtrue_S(label2);
                EmitUnpackFrom(emitter, il, value, unpackerArgumentIndex);
                il.EmitBr_S(label3);
                LocalBuilder subtreeUnpacker = localHolder.SubtreeUnpacker;
                il.MarkLabel(label2);
                EmitUnpackerBeginReadSubtree(il, unpackerArgumentIndex, subtreeUnpacker);
                EmitUnpackFrom(emitter, il, value, subtreeUnpacker);
                EmitUnpackerEndReadSubtree(il, subtreeUnpacker);
                il.MarkLabel(label3);
            }
        }
Exemplo n.º 8
0
        /// <summary>
        ///		Emits unpacking method with flavor specific getter.
        /// </summary>
        /// <param name="emitter">SerializerEmitter which knows the emittion flavor.</param>
        /// <param name="il">The il generator.</param>
        /// <param name="result">A variable wich stores unpacked result.</param>
        /// <param name="unpacker">The local variable which stores current Unpacker.</param>
        public static void EmitUnpackFrom(SerializerEmitter emitter, TracingILGenerator il, LocalBuilder result, LocalBuilder unpacker)
        {
            var serializerGetter = emitter.RegisterSerializer(result.LocalType);

            serializerGetter(il, 0);
            il.EmitAnyLdloc(unpacker);
            il.EmitAnyCall(Metadata._UnpackHelpers.InvokeUnpackFrom_1Method.MakeGenericMethod(result.LocalType));
            il.EmitAnyStloc(result);
        }
Exemplo n.º 9
0
        /// <summary>
        ///		Emits the serializing value instructions.
        /// </summary>
        /// <param name="emitter">The emitter.</param>
        /// <param name="il">The il generator.</param>
        /// <param name="packerArgumentIndex">Index of the packer argument.</param>
        /// <param name="valueType">Type of the current member value.</param>
        /// <param name="memberName">Name of the current member.</param>
        /// <param name="nilImplication">The nil implication of the current member.</param>
        /// <param name="loadValueEmitter">The delegate which emits case specific value loading instructions.</param>
        /// <param name="localHolder">The <see cref="LocalVariableHolder"/> which holds shared local variable information.</param>
        public static void EmitSerializeValue(SerializerEmitter emitter, TracingILGenerator il, int packerArgumentIndex, Type valueType, string memberName, NilImplication nilImplication, Action <TracingILGenerator> loadValueEmitter, LocalVariableHolder localHolder)
        {
            Contract.Requires(emitter != null);
            Contract.Requires(il != null);
            Contract.Requires(packerArgumentIndex >= 0);
            Contract.Requires(valueType != null);
            Contract.Requires(loadValueEmitter != null);

            /*
             * var serializingValue = LOAD_VALUE;
             * NULL_PROHIBIT_HANDLING
             * GET_SERIALIZER.PackTo( packer, serializingValue );
             */
            var value = localHolder.GetSerializingValue(valueType);

            loadValueEmitter(il);
            il.EmitAnyStloc(value);

            if (memberName != null && nilImplication == NilImplication.Prohibit)
            {
                /*
                 *	if( serializingValue == null )(
                 *	{
                 *		throw SerializationExceptions.NewNullIsProhibited();
                 *	}
                 */

                if (!valueType.IsValueType)
                {
                    il.EmitAnyLdloc(value);
                    var endIf = il.DefineLabel("END_IF");
                    il.EmitBrtrue_S(endIf);
                    il.EmitLdstr(memberName);
                    il.EmitAnyCall(SerializationExceptions.NewNullIsProhibitedMethod);
                    il.EmitThrow();
                    il.MarkLabel(endIf);
                }
                else if (Nullable.GetUnderlyingType(valueType) != null)
                {
                    il.EmitAnyLdloca(value);
                    il.EmitGetProperty(typeof(Nullable <>).MakeGenericType(Nullable.GetUnderlyingType(valueType)).GetProperty("HasValue"));
                    var endIf = il.DefineLabel("END_IF");
                    il.EmitBrtrue_S(endIf);
                    il.EmitLdstr(memberName);
                    il.EmitAnyCall(SerializationExceptions.NewNullIsProhibitedMethod);
                    il.EmitThrow();
                    il.MarkLabel(endIf);
                }
            }

            var serializerGetter = emitter.RegisterSerializer(valueType);

            serializerGetter(il, 0);
            il.EmitAnyLdarg(packerArgumentIndex);
            il.EmitAnyLdloc(value);
            il.EmitAnyCall(typeof(MessagePackSerializer <>).MakeGenericType(valueType).GetMethod("PackTo"));
        }
Exemplo n.º 10
0
 /// <summary>
 ///		Resets internal states for specified target type.
 /// </summary>
 /// <param name="targetType">Type of the serialization target.</param>
 protected sealed override void ResetCore(Type targetType)
 {
     this.Packer         = ILConstruct.Argument(1, typeof(Packer), "packer");
     this.PackToTarget   = ILConstruct.Argument(2, targetType, "objectTree");
     this.Unpacker       = ILConstruct.Argument(1, typeof(Unpacker), "unpacker");
     this.UnpackToTarget = ILConstruct.Argument(2, targetType, "collection");
     this._emitter       = null;
     this._enumEmitter   = null;
 }
        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);
        }
Exemplo n.º 12
0
        public static void EmitDeserializeValueWithoutNilImplication(SerializerEmitter emitter, TracingILGenerator il, int unpackerArgumentIndex, LocalBuilder value, Type targetType, string memberName, LocalVariableHolder localHolder)
        {
            Contract.Requires(emitter != null);
            Contract.Requires(il != null);
            Contract.Requires(unpackerArgumentIndex >= 0);
            Contract.Requires(value != null);
            Label endOfDeserialization = il.DefineLabel("END_OF_DESERIALIZATION");

            EmitDeserializeValueCore(emitter, il, unpackerArgumentIndex, value, targetType, null, memberName, endOfDeserialization, localHolder);
            il.MarkLabel(endOfDeserialization);
        }
Exemplo n.º 13
0
        public static void EmitDeserializeValue(SerializerEmitter emitter, TracingILGenerator il, int unpackerArgumentIndex, LocalBuilder result, SerializingMember member, LocalVariableHolder localHolder)
        {
            LocalBuilder deserializedValue;

            Contract.Requires(emitter != null);
            Contract.Requires(il != null);
            Contract.Requires(unpackerArgumentIndex >= 0);
            Contract.Requires(result != null);
            Label endOfDeserialization = il.DefineLabel("END_OF_DESERIALIZATION");
            bool  flag = false;

            if (member.Member.GetMemberValueType().GetIsValueType() && (Nullable.GetUnderlyingType(member.Member.GetMemberValueType()) == null))
            {
                deserializedValue = localHolder.GetDeserializedValue(typeof(Nullable <>).MakeGenericType(new Type[] { member.Member.GetMemberValueType() }));
                flag = true;
            }
            else
            {
                deserializedValue = localHolder.GetDeserializedValue(member.Member.GetMemberValueType());
            }
            if (deserializedValue.LocalType.GetIsValueType())
            {
                il.EmitAnyLdloca(deserializedValue);
                il.EmitInitobj(deserializedValue.LocalType);
            }
            else
            {
                il.EmitLdnull();
                il.EmitAnyStloc(deserializedValue);
            }
            EmitDeserializeValueCore(emitter, il, unpackerArgumentIndex, deserializedValue, result.LocalType, new SerializingMember?(member), member.Contract.Name, endOfDeserialization, localHolder);
            if (result.LocalType.IsValueType)
            {
                il.EmitAnyLdloca(result);
            }
            else
            {
                il.EmitAnyLdloc(result);
            }
            if (flag)
            {
                il.EmitAnyLdloca(deserializedValue);
                il.EmitGetProperty(typeof(Nullable <>).MakeGenericType(new Type[] { member.Member.GetMemberValueType() }).GetProperty("Value"));
            }
            else
            {
                il.EmitAnyLdloc(deserializedValue);
            }
            EmitStoreValue(il, member.Member);
            il.MarkLabel(endOfDeserialization);
        }
Exemplo n.º 14
0
        private static void CreateMapUnpackFrom(Type targetType, SerializerEmitter emitter, CollectionTraits traits)
        {
            var il          = emitter.GetUnpackFromMethodILGenerator();
            var localHolder = new LocalVariableHolder(il);

            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 = localHolder.GetDeserializingCollection(targetType);
                Emittion.EmitConstruction(
                    il,
                    collection,
                    il0 => Emittion.EmitGetUnpackerItemsCountAsInt32(il0, 1, localHolder)
                    );

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

                il.EmitAnyLdloc(collection);
                il.EmitRet();
            }
            finally
            {
                il.FlushTrace();
            }
        }
Exemplo n.º 15
0
        private static void CreateArrayUnpackTo(Type targetType, SerializerEmitter emitter, CollectionTraits traits)
        {
            var il = emitter.GetUnpackToMethodILGenerator();

            try
            {
                EmitInvokeArrayUnpackToHelper(targetType, emitter, traits, il, 1, il0 => il0.EmitAnyLdarg(2));
                il.EmitRet();
            }
            finally
            {
                il.FlushTrace();
            }
        }
        protected sealed override void EmitPackMembers(SerializerEmitter emitter, TracingILGenerator packerIL, SerializingMember[] entries)
        {
            var localHolder = new LocalVariableHolder(packerIL);

            packerIL.EmitAnyLdarg(1);
            packerIL.EmitAnyLdc_I4(entries.Length);
            packerIL.EmitAnyCall(Metadata._Packer.PackMapHeader);
            packerIL.EmitPop();

            foreach (var entry in entries)
            {
                if (entry.Member == null)
                {
                    // skip undefined member.
                    continue;
                }

                packerIL.EmitAnyLdarg(1);
                packerIL.EmitLdstr(entry.Contract.Name);
                packerIL.EmitAnyCall(Metadata._Packer.PackString);
                packerIL.EmitPop();
                Emittion.EmitSerializeValue(
                    emitter,
                    packerIL,
                    1,
                    entry.Member.GetMemberValueType(),
                    entry.Contract.Name,
                    entry.Contract.NilImplication,
                    il0 =>
                {
                    if (typeof(TObject).IsValueType)
                    {
                        il0.EmitAnyLdarga(2);
                    }
                    else
                    {
                        il0.EmitAnyLdarg(2);
                    }

                    Emittion.EmitLoadValue(il0, entry.Member);
                },
                    localHolder
                    );
            }

            packerIL.EmitRet();
        }
Exemplo n.º 17
0
        protected override void EmitPackMembers(SerializerEmitter emitter, TracingILGenerator packerIL, SerializingMember[] entries)
        {
            var localHolder = new LocalVariableHolder(packerIL);

            packerIL.EmitAnyLdarg(1);
            packerIL.EmitAnyLdc_I4(entries.Length);
            packerIL.EmitAnyCall(Metadata._Packer.PackArrayHeader);
            packerIL.EmitPop();

            foreach (var member in entries)
            {
                if (member.Member == null)
                {
                    // missing member, always nil
                    packerIL.EmitAnyLdarg(1);
                    packerIL.EmitAnyCall(Metadata._Packer.PackNull);
                    packerIL.EmitPop();
                }
                else
                {
                    Emittion.EmitSerializeValue(
                        emitter,
                        packerIL,
                        1,
                        member.Member.GetMemberValueType(),
                        member.Member.Name,
                        member.Contract.NilImplication,
                        il =>
                    {
                        if (typeof(TObject).IsValueType)
                        {
                            il.EmitAnyLdarga(2);
                        }
                        else
                        {
                            il.EmitAnyLdarg(2);
                        }

                        Emittion.EmitLoadValue(il, member.Member);
                    },
                        localHolder
                        );
                }
            }

            packerIL.EmitRet();
        }
        public sealed override MessagePackSerializer <TObject> CreateMapSerializer()
        {
            MessagePackSerializer <TObject> serializer;

            using (SerializerEmitter emitter = EmittingSerializerBuilderLogics.CreateMapSerializerCore(typeof(TObject), this._emitterFlavor))
            {
                try
                {
                    serializer = emitter.CreateInstance <TObject>(base.Context);
                }
                finally
                {
                    emitter.FlushTrace();
                }
            }
            return(serializer);
        }
        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);
        }
        private static void EmitUnpackMembers(SerializerEmitter emitter, TracingILGenerator unpackerIL, SerializingMember[] entries, LocalBuilder result)
        {
            LocalVariableHolder localHolder = new LocalVariableHolder(unpackerIL);

            unpackerIL.EmitAnyLdarg(1);
            unpackerIL.EmitGetProperty(_Unpacker.IsArrayHeader);
            Label target = unpackerIL.DefineLabel("ELSE");
            Label label2 = unpackerIL.DefineLabel("END_IF");

            unpackerIL.EmitBrfalse(target);
            EmittingSerializerBuilder <TObject> .EmitUnpackMembersFromArray(emitter, unpackerIL, entries, result, localHolder);

            unpackerIL.EmitBr(label2);
            unpackerIL.MarkLabel(target);
            EmittingSerializerBuilder <TObject> .EmitUnpackMembersFromMap(emitter, unpackerIL, entries, result, localHolder);

            unpackerIL.MarkLabel(label2);
        }
Exemplo n.º 21
0
        protected sealed override void ResetCore(Type targetType, Type baseClass)
        {
            // Note: baseClass is always null this class hiearchy.
            this.Packer         = ILConstruct.Argument(1, typeof(Packer), "packer");
            this.PackToTarget   = ILConstruct.Argument(2, targetType, "objectTree");
            this.Unpacker       = ILConstruct.Argument(1, typeof(Unpacker), "unpacker");
            this.UnpackToTarget = ILConstruct.Argument(2, targetType, "collection");
            var traits = targetType.GetCollectionTraits();

            if (traits.ElementType != null)
            {
                this.CollectionToBeAdded = ILConstruct.Argument(1, targetType, "collection");
                this.ItemToAdd           = ILConstruct.Argument(2, traits.ElementType, "item");
                this.InitialCapacity     = ILConstruct.Argument(1, typeof(int), "initialCapacity");
            }
            this._emitter     = null;
            this._enumEmitter = null;
        }
Exemplo n.º 22
0
        public static void EmitSerializeValue(SerializerEmitter emitter, TracingILGenerator il, int packerArgumentIndex, Type valueType, string memberName, NilImplication nilImplication, Action <TracingILGenerator> loadValueEmitter, LocalVariableHolder localHolder)
        {
            Contract.Requires(emitter != null);
            Contract.Requires(il != null);
            Contract.Requires(packerArgumentIndex >= 0);
            Contract.Requires(valueType != null);
            Contract.Requires(loadValueEmitter != null);
            LocalBuilder serializingValue = localHolder.GetSerializingValue(valueType);

            loadValueEmitter(il);
            il.EmitAnyStloc(serializingValue);
            if ((memberName != null) && (nilImplication == NilImplication.Prohibit))
            {
                Label label;
                if (!valueType.IsValueType)
                {
                    il.EmitAnyLdloc(serializingValue);
                    label = il.DefineLabel("END_IF");
                    il.EmitBrtrue_S(label);
                    il.EmitLdstr(memberName);
                    il.EmitAnyCall(SerializationExceptions.NewNullIsProhibitedMethod);
                    il.EmitThrow();
                    il.MarkLabel(label);
                }
                else if (Nullable.GetUnderlyingType(valueType) != null)
                {
                    il.EmitAnyLdloca(serializingValue);
                    il.EmitGetProperty(typeof(Nullable <>).MakeGenericType(new Type[] { Nullable.GetUnderlyingType(valueType) }).GetProperty("HasValue"));
                    label = il.DefineLabel("END_IF");
                    il.EmitBrtrue_S(label);
                    il.EmitLdstr(memberName);
                    il.EmitAnyCall(SerializationExceptions.NewNullIsProhibitedMethod);
                    il.EmitThrow();
                    il.MarkLabel(label);
                }
            }
            emitter.RegisterSerializer(valueType)(il, 0);
            il.EmitAnyLdarg(packerArgumentIndex);
            il.EmitAnyLdloc(serializingValue);
            il.EmitAnyCall(typeof(MessagePackSerializer <>).MakeGenericType(new Type[] { valueType }).GetMethod("PackTo"));
        }
Exemplo n.º 23
0
        protected override void EmitPackMembers(SerializerEmitter emitter, TracingILGenerator packerIL, SerializingMember[] entries)
        {
            LocalVariableHolder localHolder = new LocalVariableHolder(packerIL);

            packerIL.EmitAnyLdarg(1);
            packerIL.EmitAnyLdc_I4(entries.Length);
            packerIL.EmitAnyCall(_Packer.PackArrayHeader);
            packerIL.EmitPop();
            SerializingMember[] memberArray = entries;
            for (int i = 0; i < memberArray.Length; i++)
            {
                Action <TracingILGenerator> loadValueEmitter = null;
                SerializingMember           member           = memberArray[i];
                if (member.Member == null)
                {
                    packerIL.EmitAnyLdarg(1);
                    packerIL.EmitAnyCall(_Packer.PackNull);
                    packerIL.EmitPop();
                }
                else
                {
                    if (loadValueEmitter == null)
                    {
                        loadValueEmitter = delegate(TracingILGenerator il) {
                            if (typeof(TObject).IsValueType)
                            {
                                il.EmitAnyLdarga(2);
                            }
                            else
                            {
                                il.EmitAnyLdarg(2);
                            }
                            Emittion.EmitLoadValue(il, member.Member);
                        };
                    }
                    Emittion.EmitSerializeValue(emitter, packerIL, 1, member.Member.GetMemberValueType(), member.Member.Name, member.Contract.NilImplication, loadValueEmitter, localHolder);
                }
            }
            packerIL.EmitRet();
        }
        private static void CreateArrayUnpackFrom(Type targetType, SerializerEmitter emitter, CollectionTraits traits)
        {
            Action <TracingILGenerator> initialCountLoadingEmitter  = null;
            TracingILGenerator          unpackFromMethodILGenerator = emitter.GetUnpackFromMethodILGenerator();
            LocalVariableHolder         localHolder = new LocalVariableHolder(unpackFromMethodILGenerator);

            try
            {
                LocalBuilder collection;
                if (targetType.IsInterface || targetType.IsAbstract)
                {
                    unpackFromMethodILGenerator.EmitTypeOf(targetType);
                    unpackFromMethodILGenerator.EmitAnyCall(SerializationExceptions.NewNotSupportedBecauseCannotInstanciateAbstractTypeMethod);
                    unpackFromMethodILGenerator.EmitThrow();
                }
                else
                {
                    unpackFromMethodILGenerator.EmitAnyLdarg(1);
                    unpackFromMethodILGenerator.EmitGetProperty(_Unpacker.IsArrayHeader);
                    Label target = unpackFromMethodILGenerator.DefineLabel("END_IF");
                    unpackFromMethodILGenerator.EmitBrtrue_S(target);
                    unpackFromMethodILGenerator.EmitAnyCall(SerializationExceptions.NewIsNotArrayHeaderMethod);
                    unpackFromMethodILGenerator.EmitThrow();
                    unpackFromMethodILGenerator.MarkLabel(target);
                    collection = localHolder.GetDeserializingCollection(targetType);
                    if (initialCountLoadingEmitter == null)
                    {
                        initialCountLoadingEmitter = il0 => Emittion.EmitGetUnpackerItemsCountAsInt32(il0, 1, localHolder);
                    }
                    Emittion.EmitConstruction(unpackFromMethodILGenerator, collection, initialCountLoadingEmitter);
                    EmitInvokeArrayUnpackToHelper(targetType, emitter, traits, unpackFromMethodILGenerator, 1, il0 => il0.EmitAnyLdloc(collection));
                    unpackFromMethodILGenerator.EmitAnyLdloc(collection);
                    unpackFromMethodILGenerator.EmitRet();
                }
            }
            finally
            {
                unpackFromMethodILGenerator.FlushTrace();
            }
        }
        private static void EmitUnpackMembersFromArray(SerializerEmitter emitter, TracingILGenerator unpackerIL, SerializingMember[] entries, LocalBuilder result, LocalVariableHolder localHolder)
        {
            LocalBuilder itemsCount = localHolder.ItemsCount;
            LocalBuilder local      = unpackerIL.DeclareLocal(typeof(int), "unpacked");

            Emittion.EmitGetUnpackerItemsCountAsInt32(unpackerIL, 1, localHolder);
            unpackerIL.EmitAnyStloc(itemsCount);
            for (int i = 0; i < entries.Length; i++)
            {
                Label endOfDeserialization = unpackerIL.DefineLabel("END_IF");
                Label target = unpackerIL.DefineLabel("ELSE");
                unpackerIL.EmitAnyLdloc(local);
                unpackerIL.EmitAnyLdloc(itemsCount);
                unpackerIL.EmitBlt(target);
                if (entries[i].Member != null)
                {
                    Emittion.EmitNilImplication(unpackerIL, 1, entries[i].Contract.Name, entries[i].Contract.NilImplication, endOfDeserialization, localHolder);
                }
                unpackerIL.EmitBr(endOfDeserialization);
                unpackerIL.MarkLabel(target);
                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.EmitAnyLdloc(local);
                unpackerIL.EmitLdc_I4_1();
                unpackerIL.EmitAdd();
                unpackerIL.EmitAnyStloc(local);
                unpackerIL.MarkLabel(endOfDeserialization);
            }
        }
		private static void CreateTupleUnpack( SerializerEmitter emitter, IList<Type> itemTypes )
		{
			CreateTupleUnpackFrom( emitter, itemTypes );
		}
		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 CreateMapUnpack( Type targetType, SerializerEmitter emitter, CollectionTraits traits )
		{
			CreateMapUnpackFrom( targetType, emitter, traits );
			CreateMapUnpackTo( targetType, emitter, traits );
		}
		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();
			}
		}
Exemplo n.º 30
0
        /// <summary>
        /// Emits the deserialize collection value.
        /// </summary>
        /// <param name="emitter">The emitter.</param>
        /// <param name="il">The il generator.</param>
        /// <param name="unpackerArgumentIndex">Index of the unpacker argument.</param>
        /// <param name="target">The target collection variable.</param>
        /// <param name="member">The deserializing member metadata which holds the collection.</param>
        /// <param name="memberType">Type of the deserializing member.</param>
        /// <param name="nilImplication">The nil implication.</param>
        /// <param name="localHolder">The <see cref="LocalVariableHolder"/> which holds shared local variable information.</param>
        public static void EmitDeserializeCollectionValue(SerializerEmitter emitter, TracingILGenerator il, int unpackerArgumentIndex, LocalBuilder target, MemberInfo member, Type memberType, NilImplication nilImplication, LocalVariableHolder localHolder)
        {
            Contract.Requires(emitter != null);
            Contract.Requires(il != null);
            Contract.Requires(unpackerArgumentIndex >= 0);
            Contract.Requires(target != null);
            Contract.Requires(member != null);
            Contract.Requires(memberType != null);
            Contract.Requires(localHolder != null);

            var endOfDeserialization = il.DefineLabel("END_OF_DESERIALIZATION");

            EmitGeneralRead(il, unpackerArgumentIndex);

            switch (nilImplication)
            {
            case NilImplication.MemberDefault:
            {
                /*
                 * if( unpacker.Data.Value.IsNil )
                 * {
                 *		// Skip current.
                 *		goto END_OF_DESERIALIZATION;
                 * }
                 */
                il.EmitAnyLdarg(unpackerArgumentIndex);
                il.EmitGetProperty(Metadata._Unpacker.Data);
                var data = localHolder.UnpackedData;
                il.EmitAnyStloc(data);
                il.EmitAnyLdloca(data);
                il.EmitGetProperty(Metadata._Nullable <MessagePackObject> .Value);
                var dataValue = localHolder.UnpackedDataValue;
                il.EmitAnyStloc(dataValue);
                il.EmitAnyLdloca(dataValue);
                il.EmitGetProperty(Metadata._MessagePackObject.IsNil);
                il.EmitBrtrue(endOfDeserialization);

                break;
            }

            case NilImplication.Null:
            case NilImplication.Prohibit:
            {
                /*
                 * // for Prohibit
                 * if( unpacker.Data.Value.IsNil )
                 * {
                 *		throw SerializationEceptions.NewProhibitNullException( "..." );
                 * }
                 *
                 * // for Null, and
                 * if( unpacker.Data.Value.IsNil )
                 * {
                 *		throw SerializationEceptions.NewReadOnlyMemberItemsMustNotBeNullMethod( "..." );
                 * }
                 */
                il.EmitAnyLdarg(unpackerArgumentIndex);
                il.EmitGetProperty(Metadata._Unpacker.Data);
                var data = localHolder.UnpackedData;
                il.EmitAnyStloc(data);
                il.EmitAnyLdloca(data);
                il.EmitGetProperty(Metadata._Nullable <MessagePackObject> .Value);
                var dataValue = localHolder.UnpackedDataValue;
                il.EmitAnyStloc(dataValue);
                il.EmitAnyLdloca(dataValue);
                il.EmitGetProperty(Metadata._MessagePackObject.IsNil);
                var endIf0 = il.DefineLabel("END_IF0");
                il.EmitBrfalse_S(endIf0);
                il.EmitLdstr(member.Name);
                if (nilImplication == NilImplication.Prohibit)
                {
                    il.EmitAnyCall(SerializationExceptions.NewNullIsProhibitedMethod);
                }
                else
                {
                    // Because result member is readonly collection, so the member will not be null if packed value was nil.
                    il.EmitAnyCall(SerializationExceptions.NewReadOnlyMemberItemsMustNotBeNullMethod);
                }
                il.EmitThrow();
                il.MarkLabel(endIf0);

                break;
            }
            }

            /*
             *	if( !unpacker.IsArrayHeader && !unpacker.IsMapHeader )
             *	{
             *		throw new SerializatonException( "Cannot deserialize..." );
             *	}
             *
             *	using( var subtreeUnpacker = unpacker.ReadSubtree() )
             *	{
             *		GET_SERIALIZER.UnpackTo( unpacker, result ) )
             *	}
             *
             *	END_OF_DESERIALIZATION:
             */

            var endIf            = il.DefineLabel("THEN");
            var serializerGetter = emitter.RegisterSerializer(memberType);

            il.EmitAnyLdarg(unpackerArgumentIndex);
            il.EmitGetProperty(Metadata._Unpacker.IsArrayHeader);
            il.EmitBrtrue_S(endIf);
            il.EmitAnyLdarg(unpackerArgumentIndex);
            il.EmitGetProperty(Metadata._Unpacker.IsMapHeader);
            il.EmitBrtrue_S(endIf);
            // else
            il.EmitLdstr(member.Name);
            il.EmitAnyCall(SerializationExceptions.NewStreamDoesNotContainCollectionForMemberMethod);
            il.EmitThrow();
            // then
            var subtreeUnpacker = localHolder.SubtreeUnpacker;

            il.MarkLabel(endIf);
            EmitUnpackerBeginReadSubtree(il, unpackerArgumentIndex, subtreeUnpacker);
            serializerGetter(il, 0);
            il.EmitAnyLdloc(subtreeUnpacker);
            il.EmitAnyLdloc(target);
            Emittion.EmitLoadValue(il, member);
            il.EmitAnyCall(typeof(MessagePackSerializer <>).MakeGenericType(memberType).GetMethod("UnpackTo", new[] { typeof(Unpacker), memberType }));
            EmitUnpackerEndReadSubtree(il, subtreeUnpacker);
            il.MarkLabel(endOfDeserialization);
        }
		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();
			}
		}
		private static void CreateUnpackArrayProceduresCore( Type targetType, SerializerEmitter emitter, CollectionTraits traits )
		{
			CreateArrayUnpackFrom( targetType, emitter, traits );
			CreateArrayUnpackTo( targetType, emitter, traits );
		}
		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();
			}
		}
		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();
			}
		}
Exemplo n.º 35
0
		/// <summary>
		///		Emits unpacking method with flavor specific getter.
		/// </summary>
		/// <param name="emitter">SerializerEmitter which knows the emittion flavor.</param>
		/// <param name="il">The il generator.</param>
		/// <param name="result">A variable wich stores unpacked result.</param>
		/// <param name="unpacker">The local variable which stores current Unpacker.</param>
		public static void EmitUnpackFrom( SerializerEmitter emitter, TracingILGenerator il, LocalBuilder result, LocalBuilder unpacker )
		{
			var serializerGetter = emitter.RegisterSerializer( result.LocalType );
			serializerGetter( il, 0 );
			il.EmitAnyLdloc( unpacker );
			il.EmitAnyCall( Metadata._UnpackHelpers.InvokeUnpackFrom_1Method.MakeGenericMethod( result.LocalType ) );
			il.EmitAnyStloc( result );
		}
Exemplo n.º 36
0
		/// <summary>
		///		Emits deserializing value instructions.
		/// </summary>
		/// <param name="emitter">The emitter.</param>
		/// <param name="il">The il generator.</param>
		/// <param name="unpackerArgumentIndex">Index of the unpacker argument.</param>
		/// <param name="value">The value local variable which stores unpacked value.</param>
		/// <param name="targetType">The type of deserialzing type.</param>
		/// <param name="memberName">The name of the member.</param>
		/// <param name="localHolder">The <see cref="LocalVariableHolder"/> which holds shared local variable information.</param>
		public static void EmitDeserializeValueWithoutNilImplication( SerializerEmitter emitter, TracingILGenerator il, int unpackerArgumentIndex, LocalBuilder value, Type targetType, string memberName, LocalVariableHolder localHolder )
		{
			Contract.Requires( emitter != null );
			Contract.Requires( il != null );
			Contract.Requires( unpackerArgumentIndex >= 0 );
			Contract.Requires( value != null );

			var endOfDeserialization = il.DefineLabel( "END_OF_DESERIALIZATION" );

			/*
			 * 
			 * if( !unpacker.IsArrayHeader && !unpacker.IsMapHeader )
			 * {
			 *		valueN = GET_SERIALIZER.UnpackFrom( unpacker );
			 * }
			 * else
			 * {
			 *		using( var subtreeUnpacker = unpacker.ReadSubtree )
			 *		{
			 *			valueN = GET_SERIALIZER.UnpackFrom( unpacker );
			 *		}
			 * }
			 * 
			 * isValueNUnpacked = true;
			 * END_OF_DESERIALIZATION:
			 */

			// Nil implication is not needed.
			EmitDeserializeValueCore( emitter, il, unpackerArgumentIndex, value, targetType, null, memberName, endOfDeserialization, localHolder );

			il.MarkLabel( endOfDeserialization );
		}
		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 ) );
				}
			}
		}
Exemplo n.º 38
0
		/// <summary>
		///		Emits the serializing value instructions.
		/// </summary>
		/// <param name="emitter">The emitter.</param>
		/// <param name="il">The il generator.</param>
		/// <param name="packerArgumentIndex">Index of the packer argument.</param>
		/// <param name="valueType">Type of the current member value.</param>
		/// <param name="memberName">Name of the current member.</param>
		/// <param name="nilImplication">The nil implication of the current member.</param>
		/// <param name="loadValueEmitter">The delegate which emits case specific value loading instructions.</param>
		/// <param name="localHolder">The <see cref="LocalVariableHolder"/> which holds shared local variable information.</param>
		public static void EmitSerializeValue( SerializerEmitter emitter, TracingILGenerator il, int packerArgumentIndex, Type valueType, string memberName, NilImplication nilImplication, Action<TracingILGenerator> loadValueEmitter, LocalVariableHolder localHolder )
		{
			Contract.Requires( emitter != null );
			Contract.Requires( il != null );
			Contract.Requires( packerArgumentIndex >= 0 );
			Contract.Requires( valueType != null );
			Contract.Requires( loadValueEmitter != null );

			/*
			 * var serializingValue = LOAD_VALUE;
			 * NULL_PROHIBIT_HANDLING
			 * GET_SERIALIZER.PackTo( packer, serializingValue );
			 */
			var value = localHolder.GetSerializingValue( valueType );
			loadValueEmitter( il );
			il.EmitAnyStloc( value );
			if ( memberName != null && nilImplication == NilImplication.Prohibit )
			{
				/*
				 *	if( serializingValue == null )(
				 *	{
				 *		throw SerializationExceptions.NewNullIsProhibited();
				 *	}
				 */

				if ( !valueType.IsValueType )
				{
					il.EmitAnyLdloc( value );
					var endIf = il.DefineLabel( "END_IF" );
					il.EmitBrtrue_S( endIf );
					il.EmitLdstr( memberName );
					il.EmitAnyCall( SerializationExceptions.NewNullIsProhibitedMethod );
					il.EmitThrow();
					il.MarkLabel( endIf );
				}
				else if ( Nullable.GetUnderlyingType( valueType ) != null )
				{
					il.EmitAnyLdloca( value );
					il.EmitGetProperty( typeof( Nullable<> ).MakeGenericType( Nullable.GetUnderlyingType( valueType ) ).GetProperty( "HasValue" ) );
					var endIf = il.DefineLabel( "END_IF" );
					il.EmitBrtrue_S( endIf );
					il.EmitLdstr( memberName );
					il.EmitAnyCall( SerializationExceptions.NewNullIsProhibitedMethod );
					il.EmitThrow();
					il.MarkLabel( endIf );
				}
			}

			var serializerGetter = emitter.RegisterSerializer( valueType );
			serializerGetter( il, 0 );
			il.EmitAnyLdarg( packerArgumentIndex );
			il.EmitAnyLdloc( value );
			il.EmitAnyCall( typeof( MessagePackSerializer<> ).MakeGenericType( valueType ).GetMethod( "PackTo" ) );
		}
Exemplo n.º 39
0
        public static void EmitDeserializeCollectionValue(SerializerEmitter emitter, TracingILGenerator il, int unpackerArgumentIndex, LocalBuilder target, MemberInfo member, Type memberType, NilImplication nilImplication, LocalVariableHolder localHolder)
        {
            LocalBuilder unpackedData;
            LocalBuilder unpackedDataValue;
            Label        label2;
            Label        label3;

            Contract.Requires(emitter != null);
            Contract.Requires(il != null);
            Contract.Requires(unpackerArgumentIndex >= 0);
            Contract.Requires(target != null);
            Contract.Requires(member != null);
            Contract.Requires(memberType != null);
            Contract.Requires(localHolder != null);
            Label label = il.DefineLabel("END_OF_DESERIALIZATION");

            EmitGeneralRead(il, unpackerArgumentIndex);
            switch (nilImplication)
            {
            case NilImplication.MemberDefault:
                il.EmitAnyLdarg(unpackerArgumentIndex);
                il.EmitGetProperty(_Unpacker.Data);
                unpackedData = localHolder.UnpackedData;
                il.EmitAnyStloc(unpackedData);
                il.EmitAnyLdloca(unpackedData);
                il.EmitGetProperty(_Nullable <MessagePackObject> .Value);
                unpackedDataValue = localHolder.UnpackedDataValue;
                il.EmitAnyStloc(unpackedDataValue);
                il.EmitAnyLdloca(unpackedDataValue);
                il.EmitGetProperty(_MessagePackObject.IsNil);
                il.EmitBrtrue(label);
                goto Label_01B5;

            case NilImplication.Null:
            case NilImplication.Prohibit:
                il.EmitAnyLdarg(unpackerArgumentIndex);
                il.EmitGetProperty(_Unpacker.Data);
                unpackedData = localHolder.UnpackedData;
                il.EmitAnyStloc(unpackedData);
                il.EmitAnyLdloca(unpackedData);
                il.EmitGetProperty(_Nullable <MessagePackObject> .Value);
                unpackedDataValue = localHolder.UnpackedDataValue;
                il.EmitAnyStloc(unpackedDataValue);
                il.EmitAnyLdloca(unpackedDataValue);
                il.EmitGetProperty(_MessagePackObject.IsNil);
                label2 = il.DefineLabel("END_IF0");
                il.EmitBrfalse_S(label2);
                il.EmitLdstr(member.Name);
                if (nilImplication != NilImplication.Prohibit)
                {
                    il.EmitAnyCall(SerializationExceptions.NewReadOnlyMemberItemsMustNotBeNullMethod);
                    break;
                }
                il.EmitAnyCall(SerializationExceptions.NewNullIsProhibitedMethod);
                break;

            default:
                goto Label_01B5;
            }
            il.EmitThrow();
            il.MarkLabel(label2);
Label_01B5:
            label3 = il.DefineLabel("THEN");
            Action <TracingILGenerator, int> action = emitter.RegisterSerializer(memberType);

            il.EmitAnyLdarg(unpackerArgumentIndex);
            il.EmitGetProperty(_Unpacker.IsArrayHeader);
            il.EmitBrtrue_S(label3);
            il.EmitAnyLdarg(unpackerArgumentIndex);
            il.EmitGetProperty(_Unpacker.IsMapHeader);
            il.EmitBrtrue_S(label3);
            il.EmitLdstr(member.Name);
            il.EmitAnyCall(SerializationExceptions.NewStreamDoesNotContainCollectionForMemberMethod);
            il.EmitThrow();
            LocalBuilder subtreeUnpacker = localHolder.SubtreeUnpacker;

            il.MarkLabel(label3);
            EmitUnpackerBeginReadSubtree(il, unpackerArgumentIndex, subtreeUnpacker);
            action(il, 0);
            il.EmitAnyLdloc(subtreeUnpacker);
            il.EmitAnyLdloc(target);
            EmitLoadValue(il, member);
            il.EmitAnyCall(typeof(MessagePackSerializer <>).MakeGenericType(new Type[] { memberType }).GetMethod("UnpackTo", new Type[] { typeof(Unpacker), memberType }));
            EmitUnpackerEndReadSubtree(il, subtreeUnpacker);
            il.MarkLabel(label);
        }
		private static void CreateTuplePack( SerializerEmitter emiter, Type tupleType, IList<Type> itemTypes, Action<TracingILGenerator, LocalBuilder> loadTupleEmitter )
		{
			var il = emiter.GetPackToMethodILGenerator();
			try
			{
				/*
				 * packer.PackArrayHeader( cardinarity );
				 * _serializer0.PackTo( packer, tuple.Item1 );
				 *	:
				 * _serializer6.PackTo( packer, tuple.item7 );
				 * _serializer7.PackTo( packer, tuple.Rest.Item1 );
				 */

				var tuple = il.DeclareLocal( tupleType, "tuple" );
				loadTupleEmitter( il, tuple );
				il.EmitAnyLdarg( 1 );
				il.EmitAnyLdc_I4( itemTypes.Count );
				il.EmitAnyCall( Metadata._Packer.PackArrayHeader );
				il.EmitPop();

				var tupleTypeList = TupleItems.CreateTupleTypeList( itemTypes );

				int depth = -1;
				for ( int i = 0; i < itemTypes.Count; i++ )
				{
					if ( i % 7 == 0 )
					{
						depth++;
					}

					Emittion.EmitSerializeValue(
						emiter,
						il,
						1,
						itemTypes[ i ],
						null,
						NilImplication.MemberDefault,
						il0 =>
						{
							il0.EmitAnyLdloc( tuple );

							for ( int j = 0; j < depth; j++ )
							{
								// .TRest.TRest ...
								var rest = tupleTypeList[ j ].GetProperty( "Rest" );
								il0.EmitGetProperty( rest );
							}

							var itemn = tupleTypeList[ depth ].GetProperty( "Item" + ( ( i % 7 ) + 1 ) );
#if DEBUG
							Contract.Assert( itemn != null, tupleTypeList[ depth ].GetFullName() + "::Item" + ( ( i % 7 ) + 1 ) + " [ " + depth + " ] @ " + i );
#endif
							il0.EmitGetProperty( itemn );
						}
					);
				}
				il.EmitRet();
			}
			finally
			{
				il.FlushTrace();
			}
		}
Exemplo n.º 41
0
        /// <summary>
        /// Emits the deserialize value.
        /// </summary>
        /// <param name="emitter">The emitter.</param>
        /// <param name="il">The il generator.</param>
        /// <param name="unpackerArgumentIndex">Index of the unpacker argument.</param>
        /// <param name="value">The value local variable which stores unpacked value.</param>
        /// <param name="targetType">The type of deserialzing type.</param>
        /// <param name="member">The metadata for nil implication. Specify <c>null</c> if nil implication is not needed.</param>
        /// <param name="memberName">The name of the member.</param>
        /// <param name="endOfDeserialization">The end of deserialization label for nil implication.</param>
        /// <param name="localHolder">The <see cref="LocalVariableHolder"/> which holds shared local variable information.</param>
        private static void EmitDeserializeValueCore(SerializerEmitter emitter, TracingILGenerator il, int unpackerArgumentIndex, LocalBuilder value, Type targetType, SerializingMember?member, string memberName, Label endOfDeserialization, LocalVariableHolder localHolder)
        {
            var directUnpacking = Metadata._Unpacker.GetDirectReadMethod(value.LocalType);

            if (directUnpacking != null && (member == null || !UnpackHelpers.IsReadOnlyAppendableCollectionMember(member.Value.Member)))
            {
                var isSuccess = localHolder.IsDeserializationSucceeded;
                il.EmitLdc_I4_0();
                il.EmitAnyStloc(isSuccess);

                il.BeginExceptionBlock();
                il.EmitAnyLdarg(unpackerArgumentIndex);
                il.EmitAnyLdloca(value);
                il.EmitAnyCall(directUnpacking);
                il.EmitAnyStloc(isSuccess);
                il.BeginCatchBlock(typeof(MessageTypeException));
                var ex = localHolder.GetCatchedException(typeof(MessageTypeException));
                il.EmitAnyStloc(ex);
                il.EmitTypeOf(targetType);
                il.EmitLdstr(memberName);
                il.EmitAnyLdloc(ex);
                il.EmitAnyCall(SerializationExceptions.NewFailedToDeserializeMemberMethod);
                il.EmitThrow();
                il.EndExceptionBlock();
                var endIf0 = il.DefineLabel("END_IF");
                il.EmitAnyLdloc(isSuccess);
                il.EmitBrtrue_S(endIf0);
                il.EmitAnyCall(SerializationExceptions.NewUnexpectedEndOfStreamMethod);
                il.EmitThrow();
                il.MarkLabel(endIf0);
                if (member != null)
                {
                    // If null, nil implication is NOT needed.
                    EmitNilImplicationForPrimitive(il, member.Value, value, endOfDeserialization);
                }
            }
            else
            {
                EmitGeneralRead(il, unpackerArgumentIndex);
                if (member != null)
                {
                    // If null, nil implication is NOT needed.
                    EmitNilImplication(
                        il,
                        unpackerArgumentIndex,
                        member.Value.Contract.Name,
                        member.Value.Contract.NilImplication,
                        endOfDeserialization,
                        localHolder
                        );
                }

                var thenIffCollection = il.DefineLabel("THEN_IF_COLLECTION");
                var endIfCollection   = il.DefineLabel("END_IF_COLLECTION");

                /*
                 *	if( !unpacker.IsArrayHeader && !unpacker.IsMapHeader )
                 *	{
                 *		value = GET_SERIALIZER().UnpackFrom( unpacker );
                 *	}
                 *	else
                 *	{
                 *		using( var subtreeUnpacker = unpacker.ReadSubtree() )
                 *		{
                 *			value = GET_SERIALIZER().UnpackFrom( subtreeUnpacker );
                 *		}
                 *	}
                 */

                il.EmitAnyLdarg(unpackerArgumentIndex);
                il.EmitGetProperty(Metadata._Unpacker.IsArrayHeader);
                il.EmitAnyLdarg(unpackerArgumentIndex);
                il.EmitGetProperty(Metadata._Unpacker.IsMapHeader);
                il.EmitOr();
                il.EmitBrtrue_S(thenIffCollection);
                EmitUnpackFrom(emitter, il, value, unpackerArgumentIndex);
                il.EmitBr_S(endIfCollection);
                var subtreeUnpacker = localHolder.SubtreeUnpacker;
                il.MarkLabel(thenIffCollection);
                EmitUnpackerBeginReadSubtree(il, unpackerArgumentIndex, subtreeUnpacker);
                EmitUnpackFrom(emitter, il, value, subtreeUnpacker);
                EmitUnpackerEndReadSubtree(il, subtreeUnpacker);
                il.MarkLabel(endIfCollection);
            }
        }
		private static void CreateTupleUnpackFrom( SerializerEmitter emitter, IList<Type> itemTypes )
		{
			var il = emitter.GetUnpackFromMethodILGenerator();
			try
			{
				/*
				 * 	checked
				 * 	{
				 * 		if (!unpacker.IsArrayHeader)
				 * 		{
				 * 			throw SerializationExceptions.NewIsNotArrayHeader();
				 * 		}
				 * 		
				 * 		if ((int)unpacker.ItemsCount != n)
				 * 		{
				 * 			throw SerializationExceptions.NewTupleCardinarityIsNotMatch(n, (int)unpacker.ItemsCount);
				 * 		}
				 * 		
				 *		if (!unpacker.Read())
				 *		{
				 *			throw SerializationExceptions.NewMissingItem(0);
				 *		}
				 *		
				 *		T1 item1;
				 *		if (!unpacker.IsArrayHeader && !unpacker.IsMapHeader)
				 *		{
				 *			item1 = this._serializer0.UnpackFrom(unpacker);
				 *		}
				 *		else
				 *		{
				 *			using (Unpacker subtreeUnpacker = unpacker.ReadSubtree())
				 *			{
				 *				item1 = this._serializer0.UnpackFrom(subtreeUnpacker);
				 *			}
				 *		}
				 *		
				 *		if (!unpacker.Read())
				 *			:
				 *		
				 *		return new Tuple<...>( item1, ... , new Tuple<...>(...)...);
				 *	}
				 */

				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 itemsCount = il.DeclareLocal( typeof( int ), "itemsCount" );
				Emittion.EmitGetUnpackerItemsCountAsInt32( il, 1 );
				il.EmitAnyLdc_I4( itemTypes.Count );
				il.EmitAnyStloc( itemsCount );
				il.EmitAnyLdloc( itemsCount );
				var endIf1 = il.DefineLabel( "END_IF1" );
				il.EmitBeq_S( endIf1 );
				il.EmitAnyLdc_I4( itemTypes.Count );
				il.EmitAnyLdloc( itemsCount );
				il.EmitAnyCall( SerializationExceptions.NewTupleCardinarityIsNotMatchMethod );
				il.EmitThrow();
				il.MarkLabel( endIf1 );

				LocalBuilder[] itemLocals = new LocalBuilder[ itemTypes.Count ];
				int i = 0;
				Action<TracingILGenerator, int> unpackerReading =
					( il1, unpacker ) =>
					{
						il1.EmitAnyLdarg( unpacker );
						il1.EmitAnyCall( Metadata._Unpacker.Read );
						var endIf0 = il1.DefineLabel( "END_IF0" );
						il1.EmitBrtrue_S( endIf0 );
						il1.EmitAnyLdc_I4( i );
						il1.EmitAnyCall( SerializationExceptions.NewMissingItemMethod );
						il1.EmitThrow();
						il1.MarkLabel( endIf0 );
					};

				for ( ; i < itemTypes.Count; i++ )
				{
					itemLocals[ i ] = il.DeclareLocal( itemTypes[ i ], "item" + i );
					Emittion.EmitDeserializeValue( emitter, il, 1, itemLocals[ i ], NilImplication.MemberDefault, unpackerReading );
				}

				foreach ( var item in itemLocals )
				{
					il.EmitAnyLdloc( item );
				}

				var tupleTypeList = TupleItems.CreateTupleTypeList( itemTypes );

				for ( int depth = tupleTypeList.Count - 1; 0 <= depth; depth-- )
				{
					il.EmitNewobj( tupleTypeList[ depth ].GetConstructors().Single() );
				}

				il.EmitRet();
			}
			finally
			{
				il.FlushTrace();
			}
		}
Exemplo n.º 43
0
		/// <summary>
		/// Emits the deserialize value.
		/// </summary>
		/// <param name="emitter">The emitter.</param>
		/// <param name="il">The il generator.</param>
		/// <param name="unpackerArgumentIndex">Index of the unpacker argument.</param>
		/// <param name="result">The result local variable which represents the result of deserialization.</param>
		/// <param name="member">The metadata for nil implication. Specify <c>null</c> if nil implication is not needed.</param>
		/// <param name="localHolder">The <see cref="LocalVariableHolder"/> which holds shared local variable information.</param>
		public static void EmitDeserializeValue( SerializerEmitter emitter, TracingILGenerator il, int unpackerArgumentIndex, LocalBuilder result, SerializingMember member, LocalVariableHolder localHolder )
		{
			Contract.Requires( emitter != null );
			Contract.Requires( il != null );
			Contract.Requires( unpackerArgumentIndex >= 0 );
			Contract.Requires( result != null );

			var endOfDeserialization = il.DefineLabel( "END_OF_DESERIALIZATION" );

			/*
			 * 
			 * if( !unpacker.IsArrayHeader && !unpacker.IsMapHeader )
			 * {
			 *		valueN = GET_SERIALIZER.UnpackFrom( unpacker );
			 * }
			 * else
			 * {
			 *		using( var subtreeUnpacker = unpacker.ReadSubtree )
			 *		{
			 *			valueN = GET_SERIALIZER.UnpackFrom( unpacker );
			 *		}
			 * }
			 * 
			 * isValueNUnpacked = true;
			 * END_OF_DESERIALIZATION:
			 */
			LocalBuilder value;
			bool useDummyNullableValue = false;
			if ( member.Member.GetMemberValueType().GetIsValueType() &&
				Nullable.GetUnderlyingType( member.Member.GetMemberValueType() ) == null )
			{
				// Use temporary nullable value for nil implication.
				value = localHolder.GetDeserializedValue(
					typeof( Nullable<> ).MakeGenericType( member.Member.GetMemberValueType() ) );
				useDummyNullableValue = true;
			}
			else
			{
				value = localHolder.GetDeserializedValue( member.Member.GetMemberValueType() );
			}

			if ( value.LocalType.GetIsValueType() )
			{
				il.EmitAnyLdloca( value );
				il.EmitInitobj( value.LocalType );
			}
			else
			{
				il.EmitLdnull();
				il.EmitAnyStloc( value );
			}

			EmitDeserializeValueCore( emitter, il, unpackerArgumentIndex, value, result.LocalType, member, member.Contract.Name, endOfDeserialization, localHolder );

			if ( result.LocalType.IsValueType )
			{
				il.EmitAnyLdloca( result );
			}
			else
			{
				il.EmitAnyLdloc( result );
			}

			if ( useDummyNullableValue )
			{
				il.EmitAnyLdloca( value );
				il.EmitGetProperty( typeof( Nullable<> ).MakeGenericType( member.Member.GetMemberValueType() ).GetProperty( "Value" ) );
			}
			else
			{
				il.EmitAnyLdloc( value );
			}

			EmitStoreValue( il, member.Member );

			il.MarkLabel( endOfDeserialization );
		}
		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 );
			}
		}
Exemplo n.º 45
0
		/// <summary>
		/// Emits the deserialize value.
		/// </summary>
		/// <param name="emitter">The emitter.</param>
		/// <param name="il">The il generator.</param>
		/// <param name="unpackerArgumentIndex">Index of the unpacker argument.</param>
		/// <param name="value">The value local variable which stores unpacked value.</param>
		/// <param name="targetType">The type of deserialzing type.</param>
		/// <param name="member">The metadata for nil implication. Specify <c>null</c> if nil implication is not needed.</param>
		/// <param name="memberName">The name of the member.</param>
		/// <param name="endOfDeserialization">The end of deserialization label for nil implication.</param>
		/// <param name="localHolder">The <see cref="LocalVariableHolder"/> which holds shared local variable information.</param>
		private static void EmitDeserializeValueCore( SerializerEmitter emitter, TracingILGenerator il, int unpackerArgumentIndex, LocalBuilder value, Type targetType, SerializingMember? member, string memberName, Label endOfDeserialization, LocalVariableHolder localHolder )
		{
			var directUnpacking = Metadata._Unpacker.GetDirectReadMethod( value.LocalType );
			if ( directUnpacking != null && ( member == null || !UnpackHelpers.IsReadOnlyAppendableCollectionMember( member.Value.Member ) ) )
			{
				var isSuccess = localHolder.IsDeserializationSucceeded;
				il.EmitLdc_I4_0();
				il.EmitAnyStloc( isSuccess );

				il.BeginExceptionBlock();
				il.EmitAnyLdarg( unpackerArgumentIndex );
				il.EmitAnyLdloca( value );
				il.EmitAnyCall( directUnpacking );
				il.EmitAnyStloc( isSuccess );
				il.BeginCatchBlock( typeof( MessageTypeException ) );
				var ex = localHolder.GetCatchedException( typeof( MessageTypeException ) );
				il.EmitAnyStloc( ex );
				il.EmitTypeOf( targetType );
				il.EmitLdstr( memberName );
				il.EmitAnyLdloc( ex );
				il.EmitAnyCall( SerializationExceptions.NewFailedToDeserializeMemberMethod );
				il.EmitThrow();
				il.EndExceptionBlock();
				var endIf0 = il.DefineLabel( "END_IF" );
				il.EmitAnyLdloc( isSuccess );
				il.EmitBrtrue_S( endIf0 );
				il.EmitAnyCall( SerializationExceptions.NewUnexpectedEndOfStreamMethod );
				il.EmitThrow();
				il.MarkLabel( endIf0 );
				if ( member != null )
				{
					// If null, nil implication is NOT needed.
					EmitNilImplicationForPrimitive( il, member.Value, value, endOfDeserialization );
				}
			}
			else
			{
				EmitGeneralRead( il, unpackerArgumentIndex );
				if ( member != null )
				{
					// If null, nil implication is NOT needed.
					EmitNilImplication(
						il,
						unpackerArgumentIndex,
						member.Value.Contract.Name,
						member.Value.Contract.NilImplication,
						endOfDeserialization,
						localHolder
					);
				}

				var thenIffCollection = il.DefineLabel( "THEN_IF_COLLECTION" );
				var endIfCollection = il.DefineLabel( "END_IF_COLLECTION" );

				/*
				 *	if( !unpacker.IsArrayHeader && !unpacker.IsMapHeader )
				 *	{
				 *		value = GET_SERIALIZER().UnpackFrom( unpacker );
				 *	}
				 *	else
				 *	{
				 *		using( var subtreeUnpacker = unpacker.ReadSubtree() )
				 *		{
				 *			value = GET_SERIALIZER().UnpackFrom( subtreeUnpacker );
				 *		}
				 *	}
				 */

				il.EmitAnyLdarg( unpackerArgumentIndex );
				il.EmitGetProperty( Metadata._Unpacker.IsArrayHeader );
				il.EmitAnyLdarg( unpackerArgumentIndex );
				il.EmitGetProperty( Metadata._Unpacker.IsMapHeader );
				il.EmitOr();
				il.EmitBrtrue_S( thenIffCollection );
				EmitUnpackFrom( emitter, il, value, unpackerArgumentIndex );
				il.EmitBr_S( endIfCollection );
				var subtreeUnpacker = localHolder.SubtreeUnpacker;
				il.MarkLabel( thenIffCollection );
				EmitUnpackerBeginReadSubtree( il, unpackerArgumentIndex, subtreeUnpacker );
				EmitUnpackFrom( emitter, il, value, subtreeUnpacker );
				EmitUnpackerEndReadSubtree( il, subtreeUnpacker );
				il.MarkLabel( endIfCollection );
			}

		}
Exemplo n.º 46
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);
        }
Exemplo n.º 47
0
		/// <summary>
		/// Emits the deserialize collection value.
		/// </summary>
		/// <param name="emitter">The emitter.</param>
		/// <param name="il">The il generator.</param>
		/// <param name="unpackerArgumentIndex">Index of the unpacker argument.</param>
		/// <param name="target">The target collection variable.</param>
		/// <param name="member">The deserializing member metadata which holds the collection.</param>
		/// <param name="memberType">Type of the deserializing member.</param>
		/// <param name="nilImplication">The nil implication.</param>
		/// <param name="localHolder">The <see cref="LocalVariableHolder"/> which holds shared local variable information.</param>
		public static void EmitDeserializeCollectionValue( SerializerEmitter emitter, TracingILGenerator il, int unpackerArgumentIndex, LocalBuilder target, MemberInfo member, Type memberType, NilImplication nilImplication, LocalVariableHolder localHolder )
		{
			Contract.Requires( emitter != null );
			Contract.Requires( il != null );
			Contract.Requires( unpackerArgumentIndex >= 0 );
			Contract.Requires( target != null );
			Contract.Requires( member != null );
			Contract.Requires( memberType != null );
			Contract.Requires( localHolder != null );

			var endOfDeserialization = il.DefineLabel( "END_OF_DESERIALIZATION" );

			EmitGeneralRead( il, unpackerArgumentIndex );

			switch ( nilImplication )
			{
				case NilImplication.MemberDefault:
				{
					/*
					 * if( unpacker.Data.Value.IsNil )
					 * {
					 *		// Skip current.
					 *		goto END_OF_DESERIALIZATION;
					 * }
					 */
					il.EmitAnyLdarg( unpackerArgumentIndex );
					il.EmitGetProperty( Metadata._Unpacker.Data );
					var data = localHolder.UnpackedData;
					il.EmitAnyStloc( data );
					il.EmitAnyLdloca( data );
					il.EmitGetProperty( Metadata._Nullable<MessagePackObject>.Value );
					var dataValue = localHolder.UnpackedDataValue;
					il.EmitAnyStloc( dataValue );
					il.EmitAnyLdloca( dataValue );
					il.EmitGetProperty( Metadata._MessagePackObject.IsNil );
					il.EmitBrtrue( endOfDeserialization );

					break;
				}
				case NilImplication.Null:
				case NilImplication.Prohibit:
				{
					/*
					 * // for Prohibit
					 * if( unpacker.Data.Value.IsNil )
					 * {
					 *		throw SerializationEceptions.NewProhibitNullException( "..." );
					 * }
					 * 
					 * // for Null, and 
					 * if( unpacker.Data.Value.IsNil )
					 * {
					 *		throw SerializationEceptions.NewReadOnlyMemberItemsMustNotBeNullMethod( "..." );
					 * }
					 */
					il.EmitAnyLdarg( unpackerArgumentIndex );
					il.EmitGetProperty( Metadata._Unpacker.Data );
					var data = localHolder.UnpackedData;
					il.EmitAnyStloc( data );
					il.EmitAnyLdloca( data );
					il.EmitGetProperty( Metadata._Nullable<MessagePackObject>.Value );
					var dataValue = localHolder.UnpackedDataValue;
					il.EmitAnyStloc( dataValue );
					il.EmitAnyLdloca( dataValue );
					il.EmitGetProperty( Metadata._MessagePackObject.IsNil );
					var endIf0 = il.DefineLabel( "END_IF0" );
					il.EmitBrfalse_S( endIf0 );
					il.EmitLdstr( member.Name );
					if ( nilImplication == NilImplication.Prohibit )
					{
						il.EmitAnyCall( SerializationExceptions.NewNullIsProhibitedMethod );
					}
					else
					{
						// Because result member is readonly collection, so the member will not be null if packed value was nil.
						il.EmitAnyCall( SerializationExceptions.NewReadOnlyMemberItemsMustNotBeNullMethod );
					}
					il.EmitThrow();
					il.MarkLabel( endIf0 );

					break;
				}
			}

			/*
			 *	if( !unpacker.IsArrayHeader && !unpacker.IsMapHeader )
			 *	{
			 *		throw new SerializatonException( "Cannot deserialize..." );
			 *	}
			 * 
			 *	using( var subtreeUnpacker = unpacker.ReadSubtree() )
			 *	{
			 *		GET_SERIALIZER.UnpackTo( unpacker, result ) )
			 *	}
			 *	
			 *	END_OF_DESERIALIZATION:
			 */

			var endIf = il.DefineLabel( "THEN" );
			var serializerGetter = emitter.RegisterSerializer( memberType );

			il.EmitAnyLdarg( unpackerArgumentIndex );
			il.EmitGetProperty( Metadata._Unpacker.IsArrayHeader );
			il.EmitBrtrue_S( endIf );
			il.EmitAnyLdarg( unpackerArgumentIndex );
			il.EmitGetProperty( Metadata._Unpacker.IsMapHeader );
			il.EmitBrtrue_S( endIf );
			// else
			il.EmitLdstr( member.Name );
			il.EmitAnyCall( SerializationExceptions.NewStreamDoesNotContainCollectionForMemberMethod );
			il.EmitThrow();
			// then
			var subtreeUnpacker = localHolder.SubtreeUnpacker;
			il.MarkLabel( endIf );
			EmitUnpackerBeginReadSubtree( il, unpackerArgumentIndex, subtreeUnpacker );
			serializerGetter( il, 0 );
			il.EmitAnyLdloc( subtreeUnpacker );
			il.EmitAnyLdloc( target );
			Emittion.EmitLoadValue( il, member );
			il.EmitAnyCall( typeof( MessagePackSerializer<> ).MakeGenericType( memberType ).GetMethod( "UnpackTo", new[] { typeof( Unpacker ), memberType } ) );
			EmitUnpackerEndReadSubtree( il, subtreeUnpacker );
			il.MarkLabel( endOfDeserialization );
		}
Exemplo n.º 48
0
        /// <summary>
        /// Emits the deserialize value.
        /// </summary>
        /// <param name="emitter">The emitter.</param>
        /// <param name="il">The il generator.</param>
        /// <param name="unpackerArgumentIndex">Index of the unpacker argument.</param>
        /// <param name="result">The result local variable which represents the result of deserialization.</param>
        /// <param name="member">The metadata for nil implication. Specify <c>null</c> if nil implication is not needed.</param>
        /// <param name="localHolder">The <see cref="LocalVariableHolder"/> which holds shared local variable information.</param>
        public static void EmitDeserializeValue(SerializerEmitter emitter, TracingILGenerator il, int unpackerArgumentIndex, LocalBuilder result, SerializingMember member, LocalVariableHolder localHolder)
        {
            Contract.Requires(emitter != null);
            Contract.Requires(il != null);
            Contract.Requires(unpackerArgumentIndex >= 0);
            Contract.Requires(result != null);

            var endOfDeserialization = il.DefineLabel("END_OF_DESERIALIZATION");

            /*
             *
             * if( !unpacker.IsArrayHeader && !unpacker.IsMapHeader )
             * {
             *		valueN = GET_SERIALIZER.UnpackFrom( unpacker );
             * }
             * else
             * {
             *		using( var subtreeUnpacker = unpacker.ReadSubtree )
             *		{
             *			valueN = GET_SERIALIZER.UnpackFrom( unpacker );
             *		}
             * }
             *
             * isValueNUnpacked = true;
             * END_OF_DESERIALIZATION:
             */
            LocalBuilder value;
            bool         useDummyNullableValue = false;

            if (member.Member.GetMemberValueType().GetIsValueType() &&
                Nullable.GetUnderlyingType(member.Member.GetMemberValueType()) == null)
            {
                // Use temporary nullable value for nil implication.
                value = localHolder.GetDeserializedValue(
                    typeof(Nullable <>).MakeGenericType(member.Member.GetMemberValueType()));
                useDummyNullableValue = true;
            }
            else
            {
                value = localHolder.GetDeserializedValue(member.Member.GetMemberValueType());
            }

            if (value.LocalType.GetIsValueType())
            {
                il.EmitAnyLdloca(value);
                il.EmitInitobj(value.LocalType);
            }
            else
            {
                il.EmitLdnull();
                il.EmitAnyStloc(value);
            }

            EmitDeserializeValueCore(emitter, il, unpackerArgumentIndex, value, result.LocalType, member, member.Contract.Name, endOfDeserialization, localHolder);

            if (result.LocalType.IsValueType)
            {
                il.EmitAnyLdloca(result);
            }
            else
            {
                il.EmitAnyLdloc(result);
            }

            if (useDummyNullableValue)
            {
                il.EmitAnyLdloca(value);
                il.EmitGetProperty(typeof(Nullable <>).MakeGenericType(member.Member.GetMemberValueType()).GetProperty("Value"));
            }
            else
            {
                il.EmitAnyLdloc(value);
            }

            EmitStoreValue(il, member.Member);

            il.MarkLabel(endOfDeserialization);
        }
Exemplo n.º 49
0
		public static void EmitDeserializeValue( SerializerEmitter emitter, TracingILGenerator il, int unpackerArgumentIndex, LocalBuilder value, NilImplication nilImplication, Action<TracingILGenerator, int> customUnpackerReading )
		{
			Contract.Requires( emitter != null );
			Contract.Requires( il != null );
			Contract.Requires( unpackerArgumentIndex >= 0 );
			Contract.Requires( value != null );

			if ( customUnpackerReading != null )
			{
				customUnpackerReading( il, unpackerArgumentIndex );
			}

			var endOfDeserialization = il.DefineLabel( "END_OF_DESERIALIZATION" );

			/*
			 * 
			 * if( !unpacker.IsArrayHeader && !unpacker.IsMapHeader )
			 * {
			 *		valueN = GET_SERIALIZER.UnpackFrom( unpacker );
			 * }
			 * else
			 * {
			 *		using( var subtreeUnpacker = unpacker.ReadSubtree )
			 *		{
			 *			valueN = GET_SERIALIZER.UnpackFrom( unpacker );
			 *		}
			 * }
			 * 
			 * isValueNUnpacked = true;
			 * END_OF_DESERIALIZATION:
			 */

			var then = il.DefineLabel( "THEN" );
			var endIf = il.DefineLabel( "END_IF" );
			var serializerGetter = emitter.RegisterSerializer( value.LocalType );

			il.EmitAnyLdarg( unpackerArgumentIndex );
			il.EmitGetProperty( Metadata._Unpacker.IsArrayHeader );
			il.EmitBrtrue_S( then );
			il.EmitAnyLdarg( unpackerArgumentIndex );
			il.EmitGetProperty( Metadata._Unpacker.IsMapHeader );
			il.EmitBrtrue_S( then );
			// else
			serializerGetter( il, 0 );
			il.EmitAnyLdarg( unpackerArgumentIndex );
			il.EmitAnyCall( typeof( MessagePackSerializer<> ).MakeGenericType( value.LocalType ).GetMethod( "UnpackFrom" ) );
			il.EmitAnyStloc( value );
			il.EmitBr_S( endIf );
			// then
			var subtreeUnpacker = il.DeclareLocal( typeof( Unpacker ), "subtreeUnpacker" );
			il.MarkLabel( then );
			EmitUnpackerBeginReadSubtree( il, unpackerArgumentIndex, subtreeUnpacker );
			serializerGetter( il, 0 );
			il.EmitAnyLdloc( subtreeUnpacker );
			il.EmitAnyCall( typeof( MessagePackSerializer<> ).MakeGenericType( value.LocalType ).GetMethod( "UnpackFrom" ) );
			il.EmitAnyStloc( value );
			EmitUnpackerEndReadSubtree( il, subtreeUnpacker );
			il.MarkLabel( endIf );

			il.MarkLabel( endOfDeserialization );
		}
		private static void CreateTupleUnpackFrom( SerializerEmitter emitter, IList<Type> itemTypes )
		{
			var il = emitter.GetUnpackFromMethodILGenerator();
			var localHolder = new LocalVariableHolder( il );
			try
			{
				/*
				 * 	checked
				 * 	{
				 * 		if (!unpacker.IsArrayHeader)
				 * 		{
				 * 			throw SerializationExceptions.NewIsNotArrayHeader();
				 * 		}
				 * 		
				 * 		if ((int)unpacker.ItemsCount != n)
				 * 		{
				 * 			throw SerializationExceptions.NewTupleCardinarityIsNotMatch(n, (int)unpacker.ItemsCount);
				 * 		}
				 * 		
				 *		if (!unpacker.Read())
				 *		{
				 *			throw SerializationExceptions.NewMissingItem(0);
				 *		}
				 *		
				 *		DESERIALIZE_VALUE
				 *		
				 *			:
				 *		
				 *		return new Tuple<...>( item1, ... , new Tuple<...>(...)...);
				 *	}
				 */

				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 itemsCount = localHolder.ItemsCount;
				Emittion.EmitGetUnpackerItemsCountAsInt32( il, 1, localHolder );
				il.EmitAnyLdc_I4( itemTypes.Count );
				il.EmitAnyStloc( itemsCount );
				il.EmitAnyLdloc( itemsCount );
				var endIf1 = il.DefineLabel( "END_IF1" );
				il.EmitBeq_S( endIf1 );
				il.EmitAnyLdc_I4( itemTypes.Count );
				il.EmitAnyLdloc( itemsCount );
				il.EmitAnyCall( SerializationExceptions.NewTupleCardinarityIsNotMatchMethod );
				il.EmitThrow();
				il.MarkLabel( endIf1 );

				var itemLocals = new LocalBuilder[ itemTypes.Count ];
				var useDummyNullables = new bool[ itemTypes.Count ];

				for ( int i = 0; i < itemTypes.Count; i++ )
				{
					if ( itemTypes[ i ] != typeof( MessagePackObject ) &&
						itemTypes[ i ].GetIsValueType() &&
						Nullable.GetUnderlyingType( itemTypes[ i ] ) == null )
					{
						// Use temporary nullable value for nil implication.
						itemLocals[ i ] = il.DeclareLocal( typeof( Nullable<> ).MakeGenericType( itemTypes[ i ] ), "item" + i.ToString( CultureInfo.InvariantCulture ) );
						useDummyNullables[ i ] = true;
					}
					else
					{
						itemLocals[ i ] = il.DeclareLocal( itemTypes[ i ], "item" + i.ToString( CultureInfo.InvariantCulture ) );
					}

					// Tuple member should be NilImplication.MemberDefault.
					Emittion.EmitDeserializeValueWithoutNilImplication( emitter, il, 1, itemLocals[ i ], typeof( Tuple ), "Item" + ( i ).ToString( CultureInfo.InvariantCulture ), localHolder );
				}

				for ( int i = 0; i < itemLocals.Length; i++ )
				{
					if ( useDummyNullables[ i ] )
					{
						il.EmitAnyLdloca( itemLocals[ i ] );
						il.EmitGetProperty( typeof( Nullable<> ).MakeGenericType( itemTypes[ i ] ).GetProperty( "Value" ) );
					}
					else
					{
						il.EmitAnyLdloc( itemLocals[ i ] );
					}
				}

				var tupleTypeList = TupleItems.CreateTupleTypeList( itemTypes );

				for ( int depth = tupleTypeList.Count - 1; 0 <= depth; depth-- )
				{
					il.EmitNewobj( tupleTypeList[ depth ].GetConstructors().Single() );
				}

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