EmitAnyLdarg() public method

Emit apprpriate 'ldarg.*' instruction. Post condition is that the loaded value will be added on the evaluation stack.
public EmitAnyLdarg ( int argumentIndex ) : void
argumentIndex int /// Index of argument to be fetched. ///
return void
Ejemplo n.º 1
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 );
		}
Ejemplo n.º 2
0
		public static void EmitUnpackerBeginReadSubtree( TracingILGenerator il, int unpackerArgumentIndex, LocalBuilder subtreeUnpacker )
		{
			Contract.Requires( il != null );
			Contract.Requires( unpackerArgumentIndex >= 0 );
			Contract.Requires( subtreeUnpacker != null );

			/*
			 * subtreeUnpacker = unpacker.ReadSubtree()
			 */

			il.EmitAnyLdarg( unpackerArgumentIndex );
			il.EmitAnyCall( Metadata._Unpacker.ReadSubtree );
			il.EmitAnyStloc( subtreeUnpacker );
			il.BeginExceptionBlock();
		}
Ejemplo n.º 3
0
		/// <summary>
		///		Emits unpacking method with flavor specific getter.
		/// </summary>
		/// <param name="emitter">SerializerEmitter which knows the emittion flavor.</param>
		/// <param name="il">The il generator.</param>
		/// <param name="result">A variable wich stores unpacked result.</param>
		/// <param name="unpackerIndex">The argument index which stores current Unpacker.</param>
		public static void EmitUnpackFrom( SerializerEmitter emitter, TracingILGenerator il, LocalBuilder result, int unpackerIndex )
		{
			var serializerGetter = emitter.RegisterSerializer( result.LocalType );
			serializerGetter( il, 0 );
			il.EmitAnyLdarg( unpackerIndex );
			il.EmitAnyCall( Metadata._UnpackHelpers.InvokeUnpackFrom_1Method.MakeGenericMethod( result.LocalType ) );
			il.EmitAnyStloc( result );
		}
Ejemplo n.º 4
0
		/// <summary>
		///		Emits the nil implication.
		/// </summary>
		/// <param name="il">The il generator.</param>
		/// <param name="unpackerArgumentIndex">Index of the unpacker argument.</param>
		/// <param name="memberName">Name of the deserializing member.</param>
		/// <param name="nilImplication">The nil implication.</param>
		/// <param name="endOfDeserialization">The label to the end of deserialization.</param>
		/// <param name="localHolder">The <see cref="LocalVariableHolder"/> which holds shared local variable information.</param>
		public static void EmitNilImplication(
			TracingILGenerator il,
			int unpackerArgumentIndex,
			string memberName,
			NilImplication nilImplication,
			Label endOfDeserialization,
			LocalVariableHolder localHolder
		)
		{
			switch ( nilImplication )
			{
				case NilImplication.MemberDefault:
				{
					// TODO: This should be empty for extra items.
					/*
						 * 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.Prohibit:
				{
					/*
						 * if( unpacker.Data.Value.IsNil )
						 * {
						 *		throw SerializationEceptions.NewProhibitNullException( "..." );
						 * }
						 */
					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( memberName );
					il.EmitAnyCall( SerializationExceptions.NewNullIsProhibitedMethod );
					il.EmitThrow();
					il.MarkLabel( endIf0 );

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

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

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

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

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

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

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

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

		}
Ejemplo n.º 7
0
		/// <summary>
		///		Emits reading next item operation from the unpacker.
		/// </summary>
		/// <param name="il">Writng IL generator.</param>
		/// <param name="unpackerArgumentIndex">The index of the Unpacker argument.</param>
		public static void EmitGeneralRead( TracingILGenerator il, int unpackerArgumentIndex )
		{
			il.EmitAnyLdarg( unpackerArgumentIndex );
			il.EmitAnyCall( Metadata._Unpacker.Read );
			var endIf = il.DefineLabel( "END_IF" );
			il.EmitBrtrue_S( endIf );
			il.EmitAnyCall( SerializationExceptions.NewUnexpectedEndOfStreamMethod );
			il.EmitThrow();
			il.MarkLabel( endIf );
		}
Ejemplo n.º 8
0
		/// <summary>
		/// Emits gets <see cref="Unpacker.ItemsCount"/> with exception handling.
		/// Note that final state is the value is pushed top of the evaluation stack.
		/// </summary>
		/// <param name="il">IL generator.</param>
		/// <param name="unpackerArgumentIndex">Argument index of the unpacker.</param>
		/// <param name="localHolder">The <see cref="LocalVariableHolder"/> which holds shared local variable information.</param>
		public static void EmitGetUnpackerItemsCountAsInt32( TracingILGenerator il, int unpackerArgumentIndex, LocalVariableHolder localHolder )
		{
			Contract.Requires( il != null );
			Contract.Requires( unpackerArgumentIndex >= 0 );

			/*
			 *	long rawItemsCount;
			 *	try
			 *	{
			 *		rawItemsCount = unpacker.ItemsCount;
			 *	}
			 *	catch ( InvalidOperationException ex )
			 *	{
			 *		throw SerializationExceptions.NewIsIncorrectStream( ex );
			 *	}
			 * 
			 *	if( rawItemsCount > Int32.MaxValue )
			 *	{
			 *		throw SerializationException.NewIsTooLargeCollection(); 
			 *	}
			 * 
			 *	... unchecked( ( int )rawItemsCount );
			 */
			il.EmitAnyLdloca( localHolder.RawItemsCount );
			il.EmitInitobj( typeof( long ) );
			il.BeginExceptionBlock();
			il.EmitAnyLdarg( unpackerArgumentIndex );
			il.EmitGetProperty( Metadata._Unpacker.ItemsCount );
			il.EmitAnyStloc( localHolder.RawItemsCount );
			il.BeginCatchBlock( typeof( InvalidOperationException ) );
			il.EmitAnyCall( SerializationExceptions.NewIsIncorrectStreamMethod );
			il.EmitThrow();
			il.EndExceptionBlock();

			il.EmitAnyLdloc( localHolder.RawItemsCount );
			il.EmitLdc_I8( Int32.MaxValue );
			var endIf = il.DefineLabel();
			il.EmitBle_S( endIf );
			il.EmitAnyCall( SerializationExceptions.NewIsTooLargeCollectionMethod );
			il.EmitThrow();
			il.MarkLabel( endIf );
			il.EmitAnyLdloc( localHolder.RawItemsCount );
			il.EmitConv_I4();
		}
		private static void EmitLoadTarget( Type targetType, TracingILGenerator il, int parameterIndex )
		{
			if ( targetType.IsValueType )
			{
				il.EmitAnyLdarga( parameterIndex );
			}
			else
			{
				il.EmitAnyLdarg( parameterIndex );
			}
		}
Ejemplo n.º 10
0
		public override void LoadValue( TracingILGenerator il, bool shouldBeAddress )
		{
			this.Evaluate( il );
			il.TraceWriteLine( "// Load->: {0}", this );
			if ( this.ContextType.ResolveRuntimeType().GetIsValueType() && shouldBeAddress )
			{
				if ( this._isLocal )
				{
					il.EmitAnyLdloca( this._index );
				}
				else
				{
					il.EmitAnyLdarga( this._index );
				}
			}
			else
			{
				if ( this._isLocal )
				{
					il.EmitAnyLdloc( this._index );
				}
				else
				{
					il.EmitAnyLdarg( this._index );
				}
			}
			il.TraceWriteLine( "// ->Load: {0}", this );
		}
		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 );
			}
		}
		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 ) );
				}
			}
		}
Ejemplo n.º 13
0
		/// <summary>
		///		Emits the nil implication.
		/// </summary>
		/// <param name="il">The il generator.</param>
		/// <param name="unpackerArgumentIndex">Index of the unpacker argument.</param>
		/// <param name="member">Metadata of the serializing member.</param>
		/// <param name="endOfDeserialization">The label to the end of deserialization.</param>
		/// <param name="localHolder">The <see cref="LocalVariableHolder"/> which holds shared local variable information.</param>
		public static void EmitNilImplication(
			TracingILGenerator il,
			int unpackerArgumentIndex,
			SerializingMember member,
			Label endOfDeserialization,
			LocalVariableHolder localHolder
		)
		{
			switch ( member.Contract.NilImplication )
			{
				case NilImplication.MemberDefault:
				{
					// TODO: This should be empty for extra items.
					/*
						 * if( unpacker.Data.Value.IsNil )
						 * {
						 *		// Skip current.
						 *		goto END_OF_DESERIALIZATION;
						 * }
						 */
					il.EmitAnyLdarg( unpackerArgumentIndex );
					il.EmitGetProperty( Metadata._Unpacker.LastReadData );
					var data = localHolder.UnpackedData;
					il.EmitAnyStloc( data );
					il.EmitAnyLdloca( data );
					il.EmitGetProperty( Metadata._MessagePackObject.IsNil );
					il.EmitBrtrue( endOfDeserialization );

					break;
				}
				case NilImplication.Null:
				{
					if ( member.Member.GetMemberValueType().GetIsValueType() && Nullable.GetUnderlyingType( member.Member.GetMemberValueType() ) == null )
					{
						throw SerializationExceptions.NewValueTypeCannotBeNull(
							member.Contract.Name, member.Member.GetMemberValueType(), member.Member.DeclaringType 
						);
					}

					if ( !member.Member.CanSetValue() )
					{
						throw SerializationExceptions.NewReadOnlyMemberItemsMustNotBeNull(
							 member.Contract.Name
						);
					}

					break;
				}
				case NilImplication.Prohibit:
				{
					if ( !member.Member.CanSetValue() )
					{
						throw SerializationExceptions.NewReadOnlyMemberItemsMustNotBeNull(
							member.Contract.Name
						);
					}
					/*
						 * if( unpacker.Data.Value.IsNil )
						 * {
						 *		throw SerializationEceptions.NewProhibitNullException( "..." );
						 * }
						 */
					il.EmitAnyLdarg( unpackerArgumentIndex );
					il.EmitGetProperty( Metadata._Unpacker.LastReadData );
					var data = localHolder.UnpackedData;
					il.EmitAnyStloc( data );
					il.EmitAnyLdloca( data );
					il.EmitGetProperty( Metadata._MessagePackObject.IsNil );
					var endIf0 = il.DefineLabel( "END_IF0" );
					il.EmitBrfalse_S( endIf0 );
					il.EmitLdstr( member.Contract.Name );
					il.EmitAnyCall( SerializationExceptions.NewNullIsProhibitedMethod );
					il.EmitThrow();
					il.MarkLabel( endIf0 );

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

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

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

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

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

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

			il.MarkLabel( endOfDeserialization );
		}
Ejemplo n.º 15
0
		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 );
		}