コード例 #1
0
        private static void CreatePacking(SerializerEmitter emitter)
        {
            Action <TracingILGenerator> loadValueEmitter = null;
            TracingILGenerator          il = emitter.GetPackToMethodILGenerator();

            try
            {
                Label target = il.DefineLabel("END_IF");
                Label label2 = il.DefineLabel("END_METHOD");
                il.EmitAnyLdarga(2);
                il.EmitGetProperty(NullableMessagePackSerializer <T> ._nullableTHasValueProperty);
                il.EmitBrtrue_S(target);
                il.EmitAnyLdarg(1);
                il.EmitAnyCall(NullableMessagePackSerializer.PackerPackNull);
                il.EmitPop();
                il.EmitBr_S(label2);
                il.MarkLabel(target);
                if (loadValueEmitter == null)
                {
                    loadValueEmitter = delegate(TracingILGenerator il0) {
                        il0.EmitAnyLdarga(2);
                        il.EmitGetProperty(NullableMessagePackSerializer <T> ._nullableTValueProperty);
                    };
                }
                Emittion.EmitSerializeValue(emitter, il, 1, NullableMessagePackSerializer <T> ._nullableTValueProperty.PropertyType, null, NilImplication.MemberDefault, loadValueEmitter, new LocalVariableHolder(il));
                il.MarkLabel(label2);
                il.EmitRet();
            }
            finally
            {
                il.FlushTrace();
                emitter.FlushTrace();
            }
        }
コード例 #2
0
        internal NullableMessagePackSerializer(SerializationContext context, EmitterFlavor emitterFlavor)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            if (NullableMessagePackSerializer <T> ._nullableTImplicitOperator == null)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, "'{0}' is not nullable type.", new object[] { typeof(T) }));
            }
            SerializerEmitter emitter = SerializationMethodGeneratorManager.Get().CreateEmitter(typeof(T), emitterFlavor);

            NullableMessagePackSerializer <T> .CreatePacking(emitter);

            NullableMessagePackSerializer <T> .CreateUnpacking(emitter);

            this._underlying = emitter.CreateInstance <T>(context);
        }
コード例 #3
0
        private static void CreateUnpacking(SerializerEmitter emitter)
        {
            TracingILGenerator unpackFromMethodILGenerator = emitter.GetUnpackFromMethodILGenerator();

            try
            {
                LocalBuilder local    = unpackFromMethodILGenerator.DeclareLocal(typeof(MessagePackObject?), "mayBeNullData");
                LocalBuilder builder2 = unpackFromMethodILGenerator.DeclareLocal(typeof(MessagePackObject), "data");
                LocalBuilder builder3 = unpackFromMethodILGenerator.DeclareLocal(typeof(T), "result");
                LocalBuilder result   = unpackFromMethodILGenerator.DeclareLocal(NullableMessagePackSerializer <T> ._nullableTValueProperty.PropertyType, "value");
                Label        target   = unpackFromMethodILGenerator.DefineLabel("END_IF");
                Label        label2   = unpackFromMethodILGenerator.DefineLabel("END_METHOD");
                unpackFromMethodILGenerator.EmitAnyLdarg(1);
                unpackFromMethodILGenerator.EmitGetProperty(NullableMessagePackSerializer.UnpackerDataProperty);
                unpackFromMethodILGenerator.EmitAnyStloc(local);
                unpackFromMethodILGenerator.EmitAnyLdloca(local);
                unpackFromMethodILGenerator.EmitGetProperty(NullableMessagePackSerializer.Nullable_MessagePackObject_ValueProperty);
                unpackFromMethodILGenerator.EmitAnyStloc(builder2);
                unpackFromMethodILGenerator.EmitAnyLdloca(builder2);
                unpackFromMethodILGenerator.EmitGetProperty(NullableMessagePackSerializer.MessagePackObject_IsNilProperty);
                unpackFromMethodILGenerator.EmitBrfalse_S(target);
                unpackFromMethodILGenerator.EmitAnyLdloca(builder3);
                unpackFromMethodILGenerator.EmitInitobj(builder3.LocalType);
                unpackFromMethodILGenerator.EmitBr_S(label2);
                unpackFromMethodILGenerator.MarkLabel(target);
                Emittion.EmitUnpackFrom(emitter, unpackFromMethodILGenerator, result, 1);
                unpackFromMethodILGenerator.EmitAnyLdloc(result);
                unpackFromMethodILGenerator.EmitAnyCall(NullableMessagePackSerializer <T> ._nullableTImplicitOperator);
                unpackFromMethodILGenerator.EmitAnyStloc(builder3);
                unpackFromMethodILGenerator.MarkLabel(label2);
                unpackFromMethodILGenerator.EmitAnyLdloc(builder3);
                unpackFromMethodILGenerator.EmitRet();
            }
            finally
            {
                unpackFromMethodILGenerator.FlushTrace();
                emitter.FlushTrace();
            }
        }
コード例 #4
0
		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 ], null, null, 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();
			}
		}
コード例 #5
0
		private static void CreateTupleUnpack( SerializerEmitter emitter, IList<Type> itemTypes )
		{
			CreateTupleUnpackFrom( emitter, itemTypes );
		}
コード例 #6
0
		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();
			}
		}
コード例 #7
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 );
			}
		}
コード例 #8
0
		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();
			}
		}
コード例 #9
0
ファイル: Emittion.cs プロジェクト: davemkirk/msgpack-cli
		public static void EmitDeserializeValue( SerializerEmitter emitter, TracingILGenerator il, int unpackerArgumentIndex, LocalBuilder value, LocalBuilder isUnpacked, string memberName, 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 ( memberName != null )
			{
				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 = il.DeclareLocal( typeof( MessagePackObject? ), "data" );
						il.EmitAnyStloc( data );
						il.EmitAnyLdloca( data );
						il.EmitGetProperty( Metadata._Nullable<MessagePackObject>.Value );
						var dataValue = il.DeclareLocal( typeof( MessagePackObject ), "dataValue" );
						il.EmitAnyStloc( dataValue );
						il.EmitAnyLdloca( dataValue );
						il.EmitGetProperty( Metadata._MessagePackObject.IsNil );
						il.EmitBrtrue( endOfDeserialization );

						break;
					}
					case NilImplication.Prohibit:
					{
						/*
						 * if( unpacker.Data.Value.IsNil )
						 * {
						 *		throw SerializationEceptions.NewProhibitNullException( "..." );
						 * }
						 */
						il.EmitAnyLdarg( unpackerArgumentIndex );
						il.EmitGetProperty( Metadata._Unpacker.Data );
						var data = il.DeclareLocal( typeof( MessagePackObject? ), "data" );
						il.EmitAnyStloc( data );
						il.EmitAnyLdloca( data );
						il.EmitGetProperty( Metadata._Nullable<MessagePackObject>.Value );
						var dataValue = il.DeclareLocal( typeof( MessagePackObject ), "dataValue" );
						il.EmitAnyStloc( dataValue );
						il.EmitAnyLdloca( dataValue );
						il.EmitGetProperty( Metadata._MessagePackObject.IsNil );
						var endIf0 = il.DefineLabel( "END_IF0" );
						il.EmitBrfalse_S( endIf0 );
						il.EmitLdstr( memberName );
						il.EmitAnyCall( SerializationExceptions.NewNullIsProhibitedMethod );
						il.EmitThrow();
						il.MarkLabel( endIf0 );

						break;
					}
				}
			}

			/*
			 * 
			 * 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 );

			if ( isUnpacked != null )
			{
				il.EmitLdc_I4_1();
				il.EmitAnyStloc( isUnpacked );
			}

			il.MarkLabel( endOfDeserialization );
		}
コード例 #10
0
		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();
			}
		}
コード例 #11
0
		private static void CreateMapUnpack( Type targetType, SerializerEmitter emitter, CollectionTraits traits )
		{
			CreateMapUnpackFrom( targetType, emitter, traits );
			CreateMapUnpackTo( targetType, emitter, traits );
		}
コード例 #12
0
		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();
			}
		}
コード例 #13
0
		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 ) );
				}
			}
		}
コード例 #14
0
		private static void CreateUnpackArrayProceduresCore( Type targetType, SerializerEmitter emitter, CollectionTraits traits )
		{
			CreateArrayUnpackFrom( targetType, emitter, traits );
			CreateArrayUnpackTo( targetType, emitter, traits );
		}
コード例 #15
0
ファイル: Emittion.cs プロジェクト: davemkirk/msgpack-cli
		public static void EmitDeserializeCollectionValue( SerializerEmitter emitter, TracingILGenerator il, int unpackerArgumentIndex, LocalBuilder target, MemberInfo member, Type memberType, NilImplication nilImplication )
		{
			Contract.Requires( emitter != null );
			Contract.Requires( il != null );
			Contract.Requires( unpackerArgumentIndex >= 0 );
			Contract.Requires( target != null );
			Contract.Requires( member != null );
			Contract.Requires( memberType != null );

			var endOfDeserialization = il.DefineLabel( "END_OF_DESERIALIZATION" );
			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 = il.DeclareLocal( typeof( MessagePackObject? ), "data" );
					il.EmitAnyStloc( data );
					il.EmitAnyLdloca( data );
					il.EmitGetProperty( Metadata._Nullable<MessagePackObject>.Value );
					var dataValue = il.DeclareLocal( typeof( MessagePackObject ), "dataValue" );
					il.EmitAnyStloc( dataValue );
					il.EmitAnyLdloca( dataValue );
					il.EmitGetProperty( Metadata._MessagePackObject.IsNil );
					il.EmitBrtrue( endOfDeserialization );

					break;
				}
				case NilImplication.Null:
				case NilImplication.Prohibit:
				{
					/*
					 * if( unpacker.Data.Value.IsNil )
					 * {
					 *		throw SerializationEceptions.NewProhibitNullException( "..." );
					 * }
					 */
					il.EmitAnyLdarg( unpackerArgumentIndex );
					il.EmitGetProperty( Metadata._Unpacker.Data );
					var data = il.DeclareLocal( typeof( MessagePackObject? ), "data" );
					il.EmitAnyStloc( data );
					il.EmitAnyLdloca( data );
					il.EmitGetProperty( Metadata._Nullable<MessagePackObject>.Value );
					var dataValue = il.DeclareLocal( typeof( MessagePackObject ), "dataValue" );
					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
					{
						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, target ) )
			 *	}
			 *	
			 *	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 = il.DeclareLocal( typeof( Unpacker ), "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 );
		}
コード例 #16
0
		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();
			}
		}
コード例 #17
0
ファイル: Emittion.cs プロジェクト: davemkirk/msgpack-cli
		public static void EmitSerializeValue( SerializerEmitter emitter, TracingILGenerator il, int packerArgumentIndex, Type valueType, string memberName, NilImplication nilImplication, Action<TracingILGenerator> loadValueEmitter )
		{
			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 = il.DeclareLocal( valueType, "serializingValue" );
			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" ) );
		}