示例#1
0
        private static void CreateMapUnpackFrom(SerializationContext context, Type targetType, SerializerEmitter emitter, CollectionTraits traits)
        {
            var il           = emitter.GetUnpackFromMethodILGenerator();
            var localHolder  = new LocalVariableHolder(il);
            var instanceType = targetType;

            try
            {
                /*
                 *	if (!unpacker.IsMapHeader)
                 *	{
                 *		throw SerializationExceptions.NewIsNotMapHeader();
                 *	}
                 *
                 *	TDictionary<TKey, TValue> dictionary = new ...;
                 *	this.UnpackToCore(unpacker, dictionary);
                 *	return dictionary;
                 */

                if (targetType.IsInterface || targetType.IsAbstract)
                {
                    instanceType = context.DefaultCollectionTypes.GetConcreteType(targetType);
                    if (instanceType == null)
                    {
                        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(instanceType);
                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();
            }
        }
示例#2
0
        private static void CreateArrayUnpackFrom(Type targetType, SerializerEmitter emitter, CollectionTraits traits)
        {
            var il          = emitter.GetUnpackFromMethodILGenerator();
            var localHolder = new LocalVariableHolder(il);

            try
            {
                if (targetType.IsInterface || targetType.IsAbstract)
                {
                    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(targetType);
                // 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();
            }
        }
示例#3
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();
        }
        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();
        }
        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 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();
            }
        }
示例#7
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 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);
            }
        }
示例#9
0
        private static void CreateMapPack(Type targetType, SerializerEmitter emiter, CollectionTraits traits)
        {
            var il          = emiter.GetPackToMethodILGenerator();
            var localHolder = new LocalVariableHolder(il);

            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    = localHolder.GetSerializingCollection(targetType);
                var item          = localHolder.GetSerializingCollectionItem(traits.ElementType);
                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 = localHolder.PackingCollectionCount;
                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);
                        },
                            localHolder
                            );

                        Emittion.EmitSerializeValue(
                            emiter,
                            il0,
                            1,
                            traits.ElementType.GetGenericArguments()[1],
                            null,
                            NilImplication.MemberDefault,
                            il1 =>
                        {
                            il1.EmitAnyLdloca(item);
                            il1.EmitGetProperty(valueProperty);
                        },
                            localHolder
                            );
                    }
                    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));
                        },
                            localHolder
                            );

                        Emittion.EmitSerializeValue(
                            emiter,
                            il0,
                            1,
                            typeof(MessagePackObject),
                            null,
                            NilImplication.MemberDefault,
                            il1 =>
                        {
                            il0.EmitAnyLdloca(item);
                            il0.EmitGetProperty(Metadata._DictionaryEntry.Value);
                            il0.EmitUnbox_Any(typeof(MessagePackObject));
                        },
                            localHolder
                            );
                    }
                }
                    );
                il.EmitRet();
            }
            finally
            {
                il.FlushTrace();
            }
        }
示例#10
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);
        }
示例#11
0
        /// <summary>
        ///		Creates serializer for <typeparamref name="TObject"/>.
        /// </summary>
        /// <param name="entries">Serialization target members. This will not be <c>null</c> nor empty.</param>
        /// <returns>
        ///		<see cref="MessagePackSerializer{T}"/>. This value will not be <c>null</c>.
        /// </returns>
        protected sealed override MessagePackSerializer <TObject> CreateSerializer(SerializingMember[] entries)
        {
            using (var emitter = this._generatorManager.CreateEmitter(typeof(TObject), this._emitterFlavor))
            {
                try
                {
                    var packerIL = emitter.GetPackToMethodILGenerator();
                    try
                    {
                        if (typeof(IPackable).IsAssignableFrom(typeof(TObject)))
                        {
                            if (typeof(TObject).IsValueType)
                            {
                                packerIL.EmitAnyLdarga(2);
                            }
                            else
                            {
                                packerIL.EmitAnyLdarg(2);
                            }

                            packerIL.EmitAnyLdarg(1);
                            packerIL.EmitLdnull();

                            packerIL.EmitCall(typeof(TObject).GetInterfaceMap(typeof(IPackable)).TargetMethods.Single());
                            packerIL.EmitRet();
                        }
                        else
                        {
                            this.EmitPackMembers(emitter, packerIL, entries);
                        }
                    }
                    finally
                    {
                        packerIL.FlushTrace();
                    }

                    var unpackerIL = emitter.GetUnpackFromMethodILGenerator();
                    try
                    {
                        // TODO: For big struct, use Dictionary<String,SM>
                        var result = unpackerIL.DeclareLocal(typeof(TObject), "result");
                        Emittion.EmitConstruction(unpackerIL, result, null);

                        if (typeof(IUnpackable).IsAssignableFrom(typeof(TObject)))
                        {
                            if (typeof(TObject).GetIsValueType())
                            {
                                unpackerIL.EmitAnyLdloca(result);
                            }
                            else
                            {
                                unpackerIL.EmitAnyLdloc(result);
                            }

                            unpackerIL.EmitAnyLdarg(1);
                            unpackerIL.EmitCall(typeof(TObject).GetInterfaceMap(typeof(IUnpackable)).TargetMethods.Single());
                        }
                        else
                        {
                            EmitUnpackMembers(emitter, unpackerIL, entries, result);
                        }

                        unpackerIL.EmitAnyLdloc(result);
                        unpackerIL.EmitRet();
                    }
                    finally
                    {
                        unpackerIL.FlushTrace();
                    }

                    return(emitter.CreateInstance <TObject>(this.Context));
                }
                finally
                {
                    emitter.FlushTrace();
                }
            }
        }
示例#12
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);
        }
示例#13
0
        private static void EmitUnpackMembersFromArray(SerializerEmitter emitter, TracingILGenerator unpackerIL, SerializingMember[] entries, LocalBuilder result, LocalVariableHolder localHolder, Label endOfDeserialization)
        {
            /*
             *  int unpacked = 0;
             *  int itemsCount = unpacker.ItemsCount;
             *
             *  :
             *  if( unpacked >= itemsCount )
             *  {
             *		HandleNilImplication(...);
             *  }
             *  else
             *  {
             *  #if PRIMITIVE
             *		if( !unpacker.ReadT( out local1 ) )
             *		{
             *			throw SerializationExceptions.NewUnexpectedEndOfStreamMethod();
             *		}
             *  #else
             *		if( !unpacker.Read() )
             *		{
             *			throw SerializationExceptions.NewUnexpectedEndOfStreamMethod();
             *		}
             *
             *		local1 = this._serializer1.Unpack
             *	#endif
             *		unpacked++;
             *	}
             *	:
             */

            // TODO: Supports ExtensionObject like round-tripping.

            var itemsCount = localHolder.ItemsCount;
            var unpacked   = unpackerIL.DeclareLocal(typeof(int), "unpacked");

            Emittion.EmitGetUnpackerItemsCountAsInt32(unpackerIL, 1, localHolder);
            unpackerIL.EmitAnyStloc(itemsCount);

            for (int i = 0; i < entries.Length; i++)
            {
                var endIf0 = unpackerIL.DefineLabel("END_IF");
                var else0  = unpackerIL.DefineLabel("ELSE");

                unpackerIL.EmitAnyLdloc(unpacked);
                unpackerIL.EmitAnyLdloc(itemsCount);
                unpackerIL.EmitBge(else0);

                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
                        );
                }

                unpackerIL.EmitAnyLdloc(unpacked);
                unpackerIL.EmitLdc_I4_1();
                unpackerIL.EmitAdd();
                unpackerIL.EmitAnyStloc(unpacked);

                unpackerIL.EmitBr(endIf0);

                unpackerIL.MarkLabel(else0);

                if (entries[i].Member != null)
                {
                    // Respect nil implication.
                    switch (entries[i].Contract.NilImplication)
                    {
                    case NilImplication.MemberDefault:
                    {
                        unpackerIL.EmitBr(endOfDeserialization);
                        break;
                    }

                    case NilImplication.Null:
                    {
                        if (entries[i].Member.GetMemberValueType().GetIsValueType())
                        {
                            if (Nullable.GetUnderlyingType(entries[i].Member.GetMemberValueType()) == null)
                            {
                                // val type

                                /*
                                 * if( value == null )
                                 * {
                                 *		throw SerializationEceptions.NewValueTypeCannotBeNull( "...", typeof( MEMBER ), typeof( TYPE ) );
                                 * }
                                 */
                                unpackerIL.EmitLdstr(entries[i].Contract.Name);
                                unpackerIL.EmitLdtoken(entries[i].Member.GetMemberValueType());
                                unpackerIL.EmitAnyCall(Metadata._Type.GetTypeFromHandle);
                                unpackerIL.EmitLdtoken(entries[i].Member.DeclaringType);
                                unpackerIL.EmitAnyCall(Metadata._Type.GetTypeFromHandle);
                                unpackerIL.EmitAnyCall(SerializationExceptions.NewValueTypeCannotBeNull3Method);
                                unpackerIL.EmitThrow();
                            }
                            else
                            {
                                // nullable
                                unpackerIL.EmitAnyLdloca(localHolder.GetDeserializedValue(entries[i].Member.GetMemberValueType()));
                                unpackerIL.EmitInitobj(entries[i].Member.GetMemberValueType());
                                unpackerIL.EmitAnyLdloc(result);
                                unpackerIL.EmitAnyLdloc(localHolder.GetDeserializedValue(entries[i].Member.GetMemberValueType()));
                                Emittion.EmitStoreValue(unpackerIL, entries[i].Member);
                            }
                        }
                        else
                        {
                            // ref type
                            unpackerIL.EmitAnyLdloc(result);
                            unpackerIL.EmitLdnull();
                            Emittion.EmitStoreValue(unpackerIL, entries[i].Member);
                        }

                        break;
                    }

                    case NilImplication.Prohibit:
                    {
                        unpackerIL.EmitLdstr(entries[i].Contract.Name);
                        unpackerIL.EmitAnyCall(SerializationExceptions.NewNullIsProhibitedMethod);
                        unpackerIL.EmitThrow();
                        break;
                    }
                    }
                }

                unpackerIL.MarkLabel(endIf0);
            }
        }
示例#14
0
        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();
            }
        }
示例#15
0
        private static void CreateTuplePack(SerializerEmitter emiter, Type tupleType, IList <Type> itemTypes, Action <TracingILGenerator, LocalBuilder> loadTupleEmitter)
        {
            var il          = emiter.GetPackToMethodILGenerator();
            var localHolder = new LocalVariableHolder(il);

            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);
                    },
                        localHolder
                        );
                }
                il.EmitRet();
            }
            finally
            {
                il.FlushTrace();
            }
        }
示例#16
0
        private static void CreatePackArrayProceduresCore(Type targetType, SerializerEmitter emitter, CollectionTraits traits)
        {
            var il          = emitter.GetPackToMethodILGenerator();
            var localHolder = new LocalVariableHolder(il);

            try
            {
                // Array
                if (targetType.IsArray)
                {
                    /*
                     * // array
                     *  packer.PackArrayHeader( length );
                     * for( int i = 0; i < length; i++ )
                     * {
                     *      this._serializer.PackTo( packer, collection[ i ] );
                     * }
                     */
                    var length = localHolder.PackingCollectionCount;
                    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);
                    },
                            localHolder
                            )
                        );
                }
                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 = localHolder.GetSerializingCollection(traits.ElementType.MakeArrayType());
                    EmitLoadTarget(targetType, il, 2);
                    il.EmitAnyCall(Metadata._Enumerable.ToArray1Method.MakeGenericMethod(traits.ElementType));
                    il.EmitAnyStloc(array);
                    var length = localHolder.PackingCollectionCount;
                    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);
                    },
                            localHolder
                            )
                        );
                }
                else
                {
                    /*
                     * // Enumerable
                     *  packer.PackArrayHeader( collection.Count );
                     * foreach( var item in list )
                     * {
                     *      this._serializer.PackTo( packer, array[ i ] );
                     * }
                     */
                    var collection = localHolder.GetSerializingCollection(targetType);
                    // This instruction always ldarg, not to be ldarga
                    il.EmitAnyLdarg(2);
                    il.EmitAnyStloc(collection);
                    var count = localHolder.PackingCollectionCount;
                    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(),
                            localHolder
                            )
                        );
                }
                il.EmitRet();
            }
            finally
            {
                il.FlushTrace();
            }
        }
示例#17
0
        private static void EmitUnpackMembersFromArray(SerializerEmitter emitter, TracingILGenerator unpackerIL, SerializingMember[] entries, LocalBuilder result, LocalVariableHolder localHolder)
        {
            /*
             *  int unpacked = 0;
             *  int itemsCount = unpacker.ItemsCount;
             *
             *  :
             *  if( unpacked == itemsCount )
             *  {
             *		HandleNilImplication(...);
             *  }
             *  else
             *  {
             *  #if PRIMITIVE
             *		if( !unpacker.ReadT( out local1 ) )
             *		{
             *			throw SerializationExceptions.NewUnexpectedEndOfStreamMethod();
             *		}
             *  #else
             *		if( !unpacker.Read() )
             *		{
             *			throw SerializationExceptions.NewUnexpectedEndOfStreamMethod();
             *		}
             *
             *		local1 = this._serializer1.Unpack
             *	#endif
             *		unpacked++;
             *	}
             *	:
             */

            // TODO: Supports ExtensionObject like round-tripping.

            var itemsCount = localHolder.ItemsCount;
            var unpacked   = unpackerIL.DeclareLocal(typeof(int), "unpacked");

            Emittion.EmitGetUnpackerItemsCountAsInt32(unpackerIL, 1, localHolder);
            unpackerIL.EmitAnyStloc(itemsCount);

            for (int i = 0; i < entries.Length; i++)
            {
                var endIf0 = unpackerIL.DefineLabel("END_IF");
                var else0  = unpackerIL.DefineLabel("ELSE");

                unpackerIL.EmitAnyLdloc(unpacked);
                unpackerIL.EmitAnyLdloc(itemsCount);
                unpackerIL.EmitBlt(else0);
                // Tail missing member handling.
                if (entries[i].Member != null)
                {
                    // Respect nil implication.
                    Emittion.EmitNilImplication(unpackerIL, 1, entries[i].Contract.Name, entries[i].Contract.NilImplication, endIf0, localHolder);
                }

                unpackerIL.EmitBr(endIf0);

                unpackerIL.MarkLabel(else0);

                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
                        );
                }

                unpackerIL.EmitAnyLdloc(unpacked);
                unpackerIL.EmitLdc_I4_1();
                unpackerIL.EmitAdd();
                unpackerIL.EmitAnyStloc(unpacked);

                unpackerIL.MarkLabel(endIf0);
            }
        }
        private static void CreateMapPack(Type targetType, SerializerEmitter emiter, CollectionTraits traits)
        {
            TracingILGenerator  packToMethodILGenerator = emiter.GetPackToMethodILGenerator();
            LocalVariableHolder localHolder             = new LocalVariableHolder(packToMethodILGenerator);

            try
            {
                < > c__DisplayClass20 class3;
                LocalBuilder serializingCollection = localHolder.GetSerializingCollection(targetType);
                LocalBuilder item          = localHolder.GetSerializingCollectionItem(traits.ElementType);
                PropertyInfo keyProperty   = traits.ElementType.GetProperty("Key");
                PropertyInfo valueProperty = traits.ElementType.GetProperty("Value");
                packToMethodILGenerator.EmitAnyLdarg(2);
                packToMethodILGenerator.EmitAnyStloc(serializingCollection);
                LocalBuilder packingCollectionCount = localHolder.PackingCollectionCount;
                EmitLoadTarget(targetType, packToMethodILGenerator, serializingCollection);
                packToMethodILGenerator.EmitGetProperty(traits.CountProperty);
                packToMethodILGenerator.EmitAnyStloc(packingCollectionCount);
                packToMethodILGenerator.EmitAnyLdarg(1);
                packToMethodILGenerator.EmitAnyLdloc(packingCollectionCount);
                packToMethodILGenerator.EmitAnyCall(_Packer.PackMapHeader);
                packToMethodILGenerator.EmitPop();
                Emittion.EmitForEach(packToMethodILGenerator, traits, serializingCollection, delegate(TracingILGenerator il0, Action getCurrentEmitter) {
                    Action <TracingILGenerator> loadValueEmitter = null;
                    Action <TracingILGenerator> action2          = null;
                    Action <TracingILGenerator> action3          = null;
                    Action <TracingILGenerator> action4          = null;
                    < > c__DisplayClass20 class1 = class3;
                    if (traits.ElementType.IsGenericType)
                    {
                        Contract.Assert(traits.ElementType.GetGenericTypeDefinition() == typeof(KeyValuePair <,>));
                        getCurrentEmitter();
                        il0.EmitAnyStloc(item);
                        if (loadValueEmitter == null)
                        {
                            loadValueEmitter = delegate(TracingILGenerator il1) {
                                il1.EmitAnyLdloca(item);
                                il1.EmitGetProperty(keyProperty);
                            };
                        }
                        Emittion.EmitSerializeValue(emiter, il0, 1, traits.ElementType.GetGenericArguments()[0], null, NilImplication.MemberDefault, loadValueEmitter, localHolder);
                        if (action2 == null)
                        {
                            action2 = delegate(TracingILGenerator il1) {
                                il1.EmitAnyLdloca(item);
                                il1.EmitGetProperty(valueProperty);
                            };
                        }
                        Emittion.EmitSerializeValue(emiter, il0, 1, traits.ElementType.GetGenericArguments()[1], null, NilImplication.MemberDefault, action2, localHolder);
                    }
                    else
                    {
                        Contract.Assert(traits.ElementType == typeof(DictionaryEntry));
                        getCurrentEmitter();
                        il0.EmitAnyStloc(item);
                        if (action3 == null)
                        {
                            action3 = delegate(TracingILGenerator il1) {
                                il0.EmitAnyLdloca(item);
                                il0.EmitGetProperty(_DictionaryEntry.Key);
                                il0.EmitUnbox_Any(typeof(MessagePackObject));
                            };
                        }
                        Emittion.EmitSerializeValue(emiter, il0, 1, typeof(MessagePackObject), null, NilImplication.MemberDefault, action3, localHolder);
                        if (action4 == null)
                        {
                            action4 = delegate(TracingILGenerator il1) {
                                il0.EmitAnyLdloca(item);
                                il0.EmitGetProperty(_DictionaryEntry.Value);
                                il0.EmitUnbox_Any(typeof(MessagePackObject));
                            };
                        }
                        Emittion.EmitSerializeValue(emiter, il0, 1, typeof(MessagePackObject), null, NilImplication.MemberDefault, action4, localHolder);
                    }
                });
        protected sealed override MessagePackSerializer <TObject> CreateSerializer(SerializingMember[] entries)
        {
            MessagePackSerializer <TObject> serializer;

            using (SerializerEmitter emitter = this._generatorManager.CreateEmitter(typeof(TObject), this._emitterFlavor))
            {
                try
                {
                    TracingILGenerator packToMethodILGenerator = emitter.GetPackToMethodILGenerator();
                    try
                    {
                        if (typeof(IPackable).IsAssignableFrom(typeof(TObject)))
                        {
                            if (typeof(TObject).IsValueType)
                            {
                                packToMethodILGenerator.EmitAnyLdarga(2);
                            }
                            else
                            {
                                packToMethodILGenerator.EmitAnyLdarg(2);
                            }
                            packToMethodILGenerator.EmitAnyLdarg(1);
                            packToMethodILGenerator.EmitLdnull();
                            packToMethodILGenerator.EmitCall(typeof(TObject).GetInterfaceMap(typeof(IPackable)).TargetMethods.Single <MethodInfo>());
                            packToMethodILGenerator.EmitRet();
                        }
                        else
                        {
                            this.EmitPackMembers(emitter, packToMethodILGenerator, entries);
                        }
                    }
                    finally
                    {
                        packToMethodILGenerator.FlushTrace();
                    }
                    TracingILGenerator unpackFromMethodILGenerator = emitter.GetUnpackFromMethodILGenerator();
                    try
                    {
                        LocalBuilder target = unpackFromMethodILGenerator.DeclareLocal(typeof(TObject), "result");
                        Emittion.EmitConstruction(unpackFromMethodILGenerator, target, null);
                        if (typeof(IUnpackable).IsAssignableFrom(typeof(TObject)))
                        {
                            if (typeof(TObject).GetIsValueType())
                            {
                                unpackFromMethodILGenerator.EmitAnyLdloca(target);
                            }
                            else
                            {
                                unpackFromMethodILGenerator.EmitAnyLdloc(target);
                            }
                            unpackFromMethodILGenerator.EmitAnyLdarg(1);
                            unpackFromMethodILGenerator.EmitCall(typeof(TObject).GetInterfaceMap(typeof(IUnpackable)).TargetMethods.Single <MethodInfo>());
                        }
                        else
                        {
                            EmittingSerializerBuilder <TObject> .EmitUnpackMembers(emitter, unpackFromMethodILGenerator, entries, target);
                        }
                        unpackFromMethodILGenerator.EmitAnyLdloc(target);
                        unpackFromMethodILGenerator.EmitRet();
                    }
                    finally
                    {
                        unpackFromMethodILGenerator.FlushTrace();
                    }
                    serializer = emitter.CreateInstance <TObject>(base.Context);
                }
                finally
                {
                    emitter.FlushTrace();
                }
            }
            return(serializer);
        }