/// <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="result">The result local variable which represents the result of deserialization.</param> /// <param name="member">The metadata for nil implication. Specify <c>null</c> if nil implication is not needed.</param> /// <param name="localHolder">The <see cref="LocalVariableHolder"/> which holds shared local variable information.</param> public static void EmitDeserializeValue( SerializerEmitter emitter, TracingILGenerator il, int unpackerArgumentIndex, LocalBuilder result, SerializingMember member, LocalVariableHolder localHolder ) { Contract.Requires( emitter != null ); Contract.Requires( il != null ); Contract.Requires( unpackerArgumentIndex >= 0 ); Contract.Requires( result != null ); 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: */ LocalBuilder value; bool useDummyNullableValue = false; if ( member.Member.GetMemberValueType().GetIsValueType() && Nullable.GetUnderlyingType( member.Member.GetMemberValueType() ) == null ) { // Use temporary nullable value for nil implication. value = localHolder.GetDeserializedValue( typeof( Nullable<> ).MakeGenericType( member.Member.GetMemberValueType() ) ); useDummyNullableValue = true; } else { value = localHolder.GetDeserializedValue( member.Member.GetMemberValueType() ); } if ( value.LocalType.GetIsValueType() ) { il.EmitAnyLdloca( value ); il.EmitInitobj( value.LocalType ); } else { il.EmitLdnull(); il.EmitAnyStloc( value ); } EmitDeserializeValueCore( emitter, il, unpackerArgumentIndex, value, result.LocalType, member, member.Contract.Name, endOfDeserialization, localHolder ); if ( result.LocalType.IsValueType ) { il.EmitAnyLdloca( result ); } else { il.EmitAnyLdloc( result ); } if ( useDummyNullableValue ) { il.EmitAnyLdloca( value ); il.EmitGetProperty( typeof( Nullable<> ).MakeGenericType( member.Member.GetMemberValueType() ).GetProperty( "Value" ) ); } else { il.EmitAnyLdloc( value ); } EmitStoreValue( il, member.Member ); il.MarkLabel( endOfDeserialization ); }
/// <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(); }