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