コード例 #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
        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();
            }
        }
コード例 #4
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();
                }
            }
        }
コード例 #5
0
        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);
        }