public override void StoreValue(TracingILGenerator il) { il.TraceWriteLine("// Stor->: {0}", this); if (!this._isLocal) { throw new InvalidOperationException("Cannot overwrite argument."); } il.EmitAnyStloc(this._index); il.TraceWriteLine("// ->Stor: {0}", this); }
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(); } }
private static void EmitUnpackMembersFromArray(SerializerEmitter emitter, TracingILGenerator unpackerIL, SerializingMember[] entries, LocalBuilder result, LocalVariableHolder localHolder) { LocalBuilder itemsCount = localHolder.ItemsCount; LocalBuilder local = unpackerIL.DeclareLocal(typeof(int), "unpacked"); Emittion.EmitGetUnpackerItemsCountAsInt32(unpackerIL, 1, localHolder); unpackerIL.EmitAnyStloc(itemsCount); for (int i = 0; i < entries.Length; i++) { Label endOfDeserialization = unpackerIL.DefineLabel("END_IF"); Label target = unpackerIL.DefineLabel("ELSE"); unpackerIL.EmitAnyLdloc(local); unpackerIL.EmitAnyLdloc(itemsCount); unpackerIL.EmitBlt(target); if (entries[i].Member != null) { Emittion.EmitNilImplication(unpackerIL, 1, entries[i].Contract.Name, entries[i].Contract.NilImplication, endOfDeserialization, localHolder); } unpackerIL.EmitBr(endOfDeserialization); unpackerIL.MarkLabel(target); if (entries[i].Member == null) { Emittion.EmitGeneralRead(unpackerIL, 1); } else if (UnpackHelpers.IsReadOnlyAppendableCollectionMember(entries[i].Member)) { Emittion.EmitDeserializeCollectionValue(emitter, unpackerIL, 1, result, entries[i].Member, entries[i].Member.GetMemberValueType(), entries[i].Contract.NilImplication, localHolder); } else { Emittion.EmitDeserializeValue(emitter, unpackerIL, 1, result, entries[i], localHolder); } unpackerIL.EmitAnyLdloc(local); unpackerIL.EmitLdc_I4_1(); unpackerIL.EmitAdd(); unpackerIL.EmitAnyStloc(local); unpackerIL.MarkLabel(endOfDeserialization); } }
public static void EmitDeserializeValue(SerializerEmitter emitter, TracingILGenerator il, int unpackerArgumentIndex, LocalBuilder result, SerializingMember member, LocalVariableHolder localHolder) { LocalBuilder deserializedValue; Contract.Requires(emitter != null); Contract.Requires(il != null); Contract.Requires(unpackerArgumentIndex >= 0); Contract.Requires(result != null); Label endOfDeserialization = il.DefineLabel("END_OF_DESERIALIZATION"); bool flag = false; if (member.Member.GetMemberValueType().GetIsValueType() && (Nullable.GetUnderlyingType(member.Member.GetMemberValueType()) == null)) { deserializedValue = localHolder.GetDeserializedValue(typeof(Nullable <>).MakeGenericType(new Type[] { member.Member.GetMemberValueType() })); flag = true; } else { deserializedValue = localHolder.GetDeserializedValue(member.Member.GetMemberValueType()); } if (deserializedValue.LocalType.GetIsValueType()) { il.EmitAnyLdloca(deserializedValue); il.EmitInitobj(deserializedValue.LocalType); } else { il.EmitLdnull(); il.EmitAnyStloc(deserializedValue); } EmitDeserializeValueCore(emitter, il, unpackerArgumentIndex, deserializedValue, result.LocalType, new SerializingMember?(member), member.Contract.Name, endOfDeserialization, localHolder); if (result.LocalType.IsValueType) { il.EmitAnyLdloca(result); } else { il.EmitAnyLdloc(result); } if (flag) { il.EmitAnyLdloca(deserializedValue); il.EmitGetProperty(typeof(Nullable <>).MakeGenericType(new Type[] { member.Member.GetMemberValueType() }).GetProperty("Value")); } else { il.EmitAnyLdloc(deserializedValue); } EmitStoreValue(il, member.Member); il.MarkLabel(endOfDeserialization); }
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(); }
private static void EmitExceptionHandling( TracingILGenerator il, Type returnType, Label endOfMethod, Action <TracingILGenerator, LocalBuilder> exceptionHandlerInvocation ) { il.BeginCatchBlock(typeof(Exception)); var exception = il.DeclareLocal(typeof(Exception), "exception"); il.EmitAnyStloc(exception); exceptionHandlerInvocation(il, exception); il.EmitLeave(endOfMethod); il.EndExceptionBlock(); }
/// <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(); }
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); LocalBuilder serializingValue = localHolder.GetSerializingValue(valueType); loadValueEmitter(il); il.EmitAnyStloc(serializingValue); if ((memberName != null) && (nilImplication == NilImplication.Prohibit)) { Label label; if (!valueType.IsValueType) { il.EmitAnyLdloc(serializingValue); label = il.DefineLabel("END_IF"); il.EmitBrtrue_S(label); il.EmitLdstr(memberName); il.EmitAnyCall(SerializationExceptions.NewNullIsProhibitedMethod); il.EmitThrow(); il.MarkLabel(label); } else if (Nullable.GetUnderlyingType(valueType) != null) { il.EmitAnyLdloca(serializingValue); il.EmitGetProperty(typeof(Nullable <>).MakeGenericType(new Type[] { Nullable.GetUnderlyingType(valueType) }).GetProperty("HasValue")); label = il.DefineLabel("END_IF"); il.EmitBrtrue_S(label); il.EmitLdstr(memberName); il.EmitAnyCall(SerializationExceptions.NewNullIsProhibitedMethod); il.EmitThrow(); il.MarkLabel(label); } } emitter.RegisterSerializer(valueType)(il, 0); il.EmitAnyLdarg(packerArgumentIndex); il.EmitAnyLdloc(serializingValue); il.EmitAnyCall(typeof(MessagePackSerializer <>).MakeGenericType(new Type[] { valueType }).GetMethod("PackTo")); }
public static void EmitForEach(TracingILGenerator il, CollectionTraits traits, LocalBuilder collection, Action <TracingILGenerator, Action> bodyEmitter) { Contract.Requires(il != null); Contract.Requires(collection != null); Contract.Requires(bodyEmitter != null); LocalBuilder enumerator = il.DeclareLocal(traits.GetEnumeratorMethod.ReturnType, "enumerator"); if (collection.LocalType.IsValueType) { il.EmitAnyLdloca(collection); } else { il.EmitAnyLdloc(collection); } il.EmitAnyCall(traits.GetEnumeratorMethod); il.EmitAnyStloc(enumerator); if (typeof(IDisposable).IsAssignableFrom(traits.GetEnumeratorMethod.ReturnType)) { il.BeginExceptionBlock(); } Label label = il.DefineLabel("START_LOOP"); il.MarkLabel(label); Label target = il.DefineLabel("END_LOOP"); Type returnType = traits.GetEnumeratorMethod.ReturnType; MethodInfo method = returnType.GetMethod("MoveNext", Type.EmptyTypes); PropertyInfo currentProperty = traits.GetEnumeratorMethod.ReturnType.GetProperty("Current"); if (method == null) { method = _IEnumerator.MoveNext; } if (currentProperty == null) { if (returnType == typeof(IDictionaryEnumerator)) { currentProperty = _IDictionaryEnumerator.Current; } else if (returnType.IsInterface) { if (returnType.IsGenericType && (returnType.GetGenericTypeDefinition() == typeof(IEnumerator <>))) { currentProperty = typeof(IEnumerator <>).MakeGenericType(new Type[] { traits.ElementType }).GetProperty("Current"); } else { currentProperty = _IEnumerator.Current; } } } Contract.Assert(currentProperty != null, returnType.ToString()); if (traits.GetEnumeratorMethod.ReturnType.IsValueType) { il.EmitAnyLdloca(enumerator); } else { il.EmitAnyLdloc(enumerator); } il.EmitAnyCall(method); il.EmitBrfalse(target); bodyEmitter(il, delegate { if (traits.GetEnumeratorMethod.ReturnType.IsValueType) { il.EmitAnyLdloca(enumerator); } else { il.EmitAnyLdloc(enumerator); } il.EmitGetProperty(currentProperty); }); il.EmitBr(label); il.MarkLabel(target); if (typeof(IDisposable).IsAssignableFrom(traits.GetEnumeratorMethod.ReturnType)) { il.BeginFinallyBlock(); if (traits.GetEnumeratorMethod.ReturnType.IsValueType) { MethodInfo info2 = traits.GetEnumeratorMethod.ReturnType.GetMethod("Dispose"); if (((info2 != null) && (info2.GetParameters().Length == 0)) && (info2.ReturnType == typeof(void))) { il.EmitAnyLdloca(enumerator); il.EmitAnyCall(info2); } else { il.EmitAnyLdloc(enumerator); il.EmitBox(traits.GetEnumeratorMethod.ReturnType); il.EmitAnyCall(_IDisposable.Dispose); } } else { il.EmitAnyLdloc(enumerator); il.EmitAnyCall(_IDisposable.Dispose); } il.EndExceptionBlock(); } }
/// <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); }
private static void EmitUnpackMembersFromArray(SerializerEmitter emitter, TracingILGenerator unpackerIL, SerializingMember[] entries, LocalBuilder result, LocalVariableHolder localHolder) { /* * int unpacked = 0; * int itemsCount = unpacker.ItemsCount; * * : * if( unpacked == itemsCount ) * { * HandleNilImplication(...); * } * else * { * #if PRIMITIVE * if( !unpacker.ReadT( out local1 ) ) * { * throw SerializationExceptions.NewUnexpectedEndOfStreamMethod(); * } * #else * if( !unpacker.Read() ) * { * throw SerializationExceptions.NewUnexpectedEndOfStreamMethod(); * } * * local1 = this._serializer1.Unpack * #endif * unpacked++; * } * : */ // TODO: Supports ExtensionObject like round-tripping. var itemsCount = localHolder.ItemsCount; var unpacked = unpackerIL.DeclareLocal(typeof(int), "unpacked"); Emittion.EmitGetUnpackerItemsCountAsInt32(unpackerIL, 1, localHolder); unpackerIL.EmitAnyStloc(itemsCount); for (int i = 0; i < entries.Length; i++) { var endIf0 = unpackerIL.DefineLabel("END_IF"); var else0 = unpackerIL.DefineLabel("ELSE"); unpackerIL.EmitAnyLdloc(unpacked); unpackerIL.EmitAnyLdloc(itemsCount); unpackerIL.EmitBlt(else0); // Tail missing member handling. if (entries[i].Member != null) { // Respect nil implication. Emittion.EmitNilImplication(unpackerIL, 1, entries[i].Contract.Name, entries[i].Contract.NilImplication, endIf0, localHolder); } unpackerIL.EmitBr(endIf0); unpackerIL.MarkLabel(else0); if (entries[i].Member == null) { Emittion.EmitGeneralRead(unpackerIL, 1); // Ignore undefined member -- Nop. } else if (UnpackHelpers.IsReadOnlyAppendableCollectionMember(entries[i].Member)) { Emittion.EmitDeserializeCollectionValue( emitter, unpackerIL, 1, result, entries[i].Member, entries[i].Member.GetMemberValueType(), entries[i].Contract.NilImplication, localHolder ); } else { Emittion.EmitDeserializeValue( emitter, unpackerIL, 1, result, entries[i], localHolder ); } unpackerIL.EmitAnyLdloc(unpacked); unpackerIL.EmitLdc_I4_1(); unpackerIL.EmitAdd(); unpackerIL.EmitAnyStloc(unpacked); unpackerIL.MarkLabel(endIf0); } }
/// <summary> /// Emits helper function to avoid lexical closure emitting. /// </summary> /// <param name="il"><see cref="TracingILGenerator"/>.</param> /// <param name="targetOperation"><see cref="MethodInfo"/> of the method to be invoked.</param> /// <param name="tupleTypes">The array of <see cref="Type"/> of nested tuples. The outermost is the first, innermost is the last.</param> /// <param name="itemTypes">The array of <see cref="Type"/> of flatten tuple items.</param> private static void EmitPrivateInvoke(TracingILGenerator il, MethodInfo targetOperation, IList <Type> tupleTypes, Type[] itemTypes) { /* * private void/T PrivateInvoke( object state ) * { * T result; * Dispatcher.BeginOperation(); * try * { * var tuple = state as Tuple<...>; * result = * tuple.Item1.Target( * tuple.Item2, * : * tuple.Rest.Rest....ItemN * ); * } * catch( TheradAbortException ) * { * Dispatcher.HandleThreadAbortException( ex ); * } * finally * { * Dispatcher.EndOperation(); * } * * return result; * } */ var tuple = il.DeclareLocal(tupleTypes.First(), "tuple"); var result = targetOperation.ReturnType == typeof(void) ? null : il.DeclareLocal(targetOperation.ReturnType, "result"); il.EmitAnyLdarg(0); il.EmitCall(_dispatcherBeginOperationMethod); il.BeginExceptionBlock(); il.EmitAnyLdarg(1); il.EmitIsinst(tupleTypes.First()); il.EmitAnyStloc(tuple); int depth = -1; for (int i = 0; i < itemTypes.Length; i++) { if (i % 7 == 0) { depth++; } il.EmitAnyLdloc(tuple); for (int j = 0; j < depth; j++) { // .TRest.TRest ... var rest = tupleTypes[j].GetProperty("Rest"); il.EmitGetProperty(rest); } var itemn = tupleTypes[depth].GetProperty("Item" + ((i % 7) + 1)); il.EmitGetProperty(itemn); } il.EmitAnyCall(targetOperation); if (targetOperation.ReturnType != typeof(void)) { il.EmitAnyStloc(result); } il.BeginCatchBlock(typeof(ThreadAbortException)); var ex = il.DeclareLocal(typeof(ThreadAbortException), "ex"); il.EmitAnyStloc(ex); il.EmitAnyLdarg(0); il.EmitAnyLdloc(ex); il.EmitCall(_dispatcherHandleThreadAbortExceptionMethod); il.BeginFinallyBlock(); il.EmitAnyLdarg(0); il.EmitCall(_dispatcherEndOperationMethod); il.EndExceptionBlock(); if (targetOperation.ReturnType != typeof(void)) { il.EmitAnyLdloc(result); } il.EmitRet(); }
/// <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 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); }
private static void EmitUnpackMembersFromArray(SerializerEmitter emitter, TracingILGenerator unpackerIL, SerializingMember[] entries, LocalBuilder result, LocalVariableHolder localHolder, Label endOfDeserialization) { /* * int unpacked = 0; * int itemsCount = unpacker.ItemsCount; * * : * if( unpacked >= itemsCount ) * { * HandleNilImplication(...); * } * else * { * #if PRIMITIVE * if( !unpacker.ReadT( out local1 ) ) * { * throw SerializationExceptions.NewUnexpectedEndOfStreamMethod(); * } * #else * if( !unpacker.Read() ) * { * throw SerializationExceptions.NewUnexpectedEndOfStreamMethod(); * } * * local1 = this._serializer1.Unpack * #endif * unpacked++; * } * : */ // TODO: Supports ExtensionObject like round-tripping. var itemsCount = localHolder.ItemsCount; var unpacked = unpackerIL.DeclareLocal(typeof(int), "unpacked"); Emittion.EmitGetUnpackerItemsCountAsInt32(unpackerIL, 1, localHolder); unpackerIL.EmitAnyStloc(itemsCount); for (int i = 0; i < entries.Length; i++) { var endIf0 = unpackerIL.DefineLabel("END_IF"); var else0 = unpackerIL.DefineLabel("ELSE"); unpackerIL.EmitAnyLdloc(unpacked); unpackerIL.EmitAnyLdloc(itemsCount); unpackerIL.EmitBge(else0); if (entries[i].Member == null) { Emittion.EmitGeneralRead(unpackerIL, 1); // Ignore undefined member -- Nop. } else if (UnpackHelpers.IsReadOnlyAppendableCollectionMember(entries[i].Member)) { Emittion.EmitDeserializeCollectionValue( emitter, unpackerIL, 1, result, entries[i].Member, entries[i].Member.GetMemberValueType(), entries[i].Contract.NilImplication, localHolder ); } else { Emittion.EmitDeserializeValue( emitter, unpackerIL, 1, result, entries[i], localHolder ); } unpackerIL.EmitAnyLdloc(unpacked); unpackerIL.EmitLdc_I4_1(); unpackerIL.EmitAdd(); unpackerIL.EmitAnyStloc(unpacked); unpackerIL.EmitBr(endIf0); unpackerIL.MarkLabel(else0); if (entries[i].Member != null) { // Respect nil implication. switch (entries[i].Contract.NilImplication) { case NilImplication.MemberDefault: { unpackerIL.EmitBr(endOfDeserialization); break; } case NilImplication.Null: { if (entries[i].Member.GetMemberValueType().GetIsValueType()) { if (Nullable.GetUnderlyingType(entries[i].Member.GetMemberValueType()) == null) { // val type /* * if( value == null ) * { * throw SerializationEceptions.NewValueTypeCannotBeNull( "...", typeof( MEMBER ), typeof( TYPE ) ); * } */ unpackerIL.EmitLdstr(entries[i].Contract.Name); unpackerIL.EmitLdtoken(entries[i].Member.GetMemberValueType()); unpackerIL.EmitAnyCall(Metadata._Type.GetTypeFromHandle); unpackerIL.EmitLdtoken(entries[i].Member.DeclaringType); unpackerIL.EmitAnyCall(Metadata._Type.GetTypeFromHandle); unpackerIL.EmitAnyCall(SerializationExceptions.NewValueTypeCannotBeNull3Method); unpackerIL.EmitThrow(); } else { // nullable unpackerIL.EmitAnyLdloca(localHolder.GetDeserializedValue(entries[i].Member.GetMemberValueType())); unpackerIL.EmitInitobj(entries[i].Member.GetMemberValueType()); unpackerIL.EmitAnyLdloc(result); unpackerIL.EmitAnyLdloc(localHolder.GetDeserializedValue(entries[i].Member.GetMemberValueType())); Emittion.EmitStoreValue(unpackerIL, entries[i].Member); } } else { // ref type unpackerIL.EmitAnyLdloc(result); unpackerIL.EmitLdnull(); Emittion.EmitStoreValue(unpackerIL, entries[i].Member); } break; } case NilImplication.Prohibit: { unpackerIL.EmitLdstr(entries[i].Contract.Name); unpackerIL.EmitAnyCall(SerializationExceptions.NewNullIsProhibitedMethod); unpackerIL.EmitThrow(); break; } } } unpackerIL.MarkLabel(endIf0); } }
/// <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; } } }
public static void EmitDeserializeCollectionValue(SerializerEmitter emitter, TracingILGenerator il, int unpackerArgumentIndex, LocalBuilder target, MemberInfo member, Type memberType, NilImplication nilImplication, LocalVariableHolder localHolder) { LocalBuilder unpackedData; LocalBuilder unpackedDataValue; Label label2; Label label3; 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); Label label = il.DefineLabel("END_OF_DESERIALIZATION"); EmitGeneralRead(il, unpackerArgumentIndex); switch (nilImplication) { case NilImplication.MemberDefault: il.EmitAnyLdarg(unpackerArgumentIndex); il.EmitGetProperty(_Unpacker.Data); unpackedData = localHolder.UnpackedData; il.EmitAnyStloc(unpackedData); il.EmitAnyLdloca(unpackedData); il.EmitGetProperty(_Nullable <MessagePackObject> .Value); unpackedDataValue = localHolder.UnpackedDataValue; il.EmitAnyStloc(unpackedDataValue); il.EmitAnyLdloca(unpackedDataValue); il.EmitGetProperty(_MessagePackObject.IsNil); il.EmitBrtrue(label); goto Label_01B5; case NilImplication.Null: case NilImplication.Prohibit: il.EmitAnyLdarg(unpackerArgumentIndex); il.EmitGetProperty(_Unpacker.Data); unpackedData = localHolder.UnpackedData; il.EmitAnyStloc(unpackedData); il.EmitAnyLdloca(unpackedData); il.EmitGetProperty(_Nullable <MessagePackObject> .Value); unpackedDataValue = localHolder.UnpackedDataValue; il.EmitAnyStloc(unpackedDataValue); il.EmitAnyLdloca(unpackedDataValue); il.EmitGetProperty(_MessagePackObject.IsNil); label2 = il.DefineLabel("END_IF0"); il.EmitBrfalse_S(label2); il.EmitLdstr(member.Name); if (nilImplication != NilImplication.Prohibit) { il.EmitAnyCall(SerializationExceptions.NewReadOnlyMemberItemsMustNotBeNullMethod); break; } il.EmitAnyCall(SerializationExceptions.NewNullIsProhibitedMethod); break; default: goto Label_01B5; } il.EmitThrow(); il.MarkLabel(label2); Label_01B5: label3 = il.DefineLabel("THEN"); Action <TracingILGenerator, int> action = emitter.RegisterSerializer(memberType); il.EmitAnyLdarg(unpackerArgumentIndex); il.EmitGetProperty(_Unpacker.IsArrayHeader); il.EmitBrtrue_S(label3); il.EmitAnyLdarg(unpackerArgumentIndex); il.EmitGetProperty(_Unpacker.IsMapHeader); il.EmitBrtrue_S(label3); il.EmitLdstr(member.Name); il.EmitAnyCall(SerializationExceptions.NewStreamDoesNotContainCollectionForMemberMethod); il.EmitThrow(); LocalBuilder subtreeUnpacker = localHolder.SubtreeUnpacker; il.MarkLabel(label3); EmitUnpackerBeginReadSubtree(il, unpackerArgumentIndex, subtreeUnpacker); action(il, 0); il.EmitAnyLdloc(subtreeUnpacker); il.EmitAnyLdloc(target); EmitLoadValue(il, member); il.EmitAnyCall(typeof(MessagePackSerializer <>).MakeGenericType(new Type[] { memberType }).GetMethod("UnpackTo", new Type[] { typeof(Unpacker), memberType })); EmitUnpackerEndReadSubtree(il, subtreeUnpacker); il.MarkLabel(label); }
/// <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; } } }
/// <summary> /// Emits 'foreach' statement on the IL stream. /// </summary> /// <param name="il">IL generator to be emitted to.</param> /// <param name="traits"><see cref="CollectionTraits"/> which contains traits of the iterating collection.</param> /// <param name="collection">'collection' argument index.</param> /// <param name="bodyEmitter">Delegate to emit body statement.</param> public static void EmitForEach(TracingILGenerator il, CollectionTraits traits, LocalBuilder collection, Action <TracingILGenerator, Action> bodyEmitter) { Contract.Requires(il != null); Contract.Requires(collection != null); Contract.Requires(bodyEmitter != null); var enumerator = il.DeclareLocal(traits.GetEnumeratorMethod.ReturnType, "enumerator"); // gets enumerator if (collection.LocalType.IsValueType) { il.EmitAnyLdloca(collection); } else { il.EmitAnyLdloc(collection); } il.EmitAnyCall(traits.GetEnumeratorMethod); il.EmitAnyStloc(enumerator); if (typeof(IDisposable).IsAssignableFrom(traits.GetEnumeratorMethod.ReturnType)) { il.BeginExceptionBlock(); } var startLoop = il.DefineLabel("START_LOOP"); il.MarkLabel(startLoop); var endLoop = il.DefineLabel("END_LOOP"); var enumeratorType = traits.GetEnumeratorMethod.ReturnType; MethodInfo moveNextMethod = enumeratorType.GetMethod("MoveNext", Type.EmptyTypes); PropertyInfo currentProperty = traits.GetEnumeratorMethod.ReturnType.GetProperty("Current"); if (moveNextMethod == null) { moveNextMethod = Metadata._IEnumerator.MoveNext; } if (currentProperty == null) { if (enumeratorType == typeof(IDictionaryEnumerator)) { currentProperty = Metadata._IDictionaryEnumerator.Current; } else if (enumeratorType.IsInterface) { if (enumeratorType.IsGenericType && enumeratorType.GetGenericTypeDefinition() == typeof(IEnumerator <>)) { currentProperty = typeof(IEnumerator <>).MakeGenericType(traits.ElementType).GetProperty("Current"); } else { currentProperty = Metadata._IEnumerator.Current; } } } Contract.Assert(currentProperty != null, enumeratorType.ToString()); // iterates if (traits.GetEnumeratorMethod.ReturnType.IsValueType) { il.EmitAnyLdloca(enumerator); } else { il.EmitAnyLdloc(enumerator); } il.EmitAnyCall(moveNextMethod); il.EmitBrfalse(endLoop); bodyEmitter( il, () => { if (traits.GetEnumeratorMethod.ReturnType.IsValueType) { il.EmitAnyLdloca(enumerator); } else { il.EmitAnyLdloc(enumerator); } il.EmitGetProperty(currentProperty); } ); il.EmitBr(startLoop); il.MarkLabel(endLoop); // Dispose if (typeof(IDisposable).IsAssignableFrom(traits.GetEnumeratorMethod.ReturnType)) { il.BeginFinallyBlock(); if (traits.GetEnumeratorMethod.ReturnType.IsValueType) { var disposeMethod = traits.GetEnumeratorMethod.ReturnType.GetMethod("Dispose"); if (disposeMethod != null && disposeMethod.GetParameters().Length == 0 && disposeMethod.ReturnType == typeof(void)) { il.EmitAnyLdloca(enumerator); il.EmitAnyCall(disposeMethod); } else { il.EmitAnyLdloc(enumerator); il.EmitBox(traits.GetEnumeratorMethod.ReturnType); il.EmitAnyCall(Metadata._IDisposable.Dispose); } } else { il.EmitAnyLdloc(enumerator); il.EmitAnyCall(Metadata._IDisposable.Dispose); } il.EndExceptionBlock(); } }
private static void CreateMapPack(Type targetType, SerializerEmitter emiter, CollectionTraits traits) { TracingILGenerator packToMethodILGenerator = emiter.GetPackToMethodILGenerator(); LocalVariableHolder localHolder = new LocalVariableHolder(packToMethodILGenerator); try { < > c__DisplayClass20 class3; LocalBuilder serializingCollection = localHolder.GetSerializingCollection(targetType); LocalBuilder item = localHolder.GetSerializingCollectionItem(traits.ElementType); PropertyInfo keyProperty = traits.ElementType.GetProperty("Key"); PropertyInfo valueProperty = traits.ElementType.GetProperty("Value"); packToMethodILGenerator.EmitAnyLdarg(2); packToMethodILGenerator.EmitAnyStloc(serializingCollection); LocalBuilder packingCollectionCount = localHolder.PackingCollectionCount; EmitLoadTarget(targetType, packToMethodILGenerator, serializingCollection); packToMethodILGenerator.EmitGetProperty(traits.CountProperty); packToMethodILGenerator.EmitAnyStloc(packingCollectionCount); packToMethodILGenerator.EmitAnyLdarg(1); packToMethodILGenerator.EmitAnyLdloc(packingCollectionCount); packToMethodILGenerator.EmitAnyCall(_Packer.PackMapHeader); packToMethodILGenerator.EmitPop(); Emittion.EmitForEach(packToMethodILGenerator, traits, serializingCollection, delegate(TracingILGenerator il0, Action getCurrentEmitter) { Action <TracingILGenerator> loadValueEmitter = null; Action <TracingILGenerator> action2 = null; Action <TracingILGenerator> action3 = null; Action <TracingILGenerator> action4 = null; < > c__DisplayClass20 class1 = class3; if (traits.ElementType.IsGenericType) { Contract.Assert(traits.ElementType.GetGenericTypeDefinition() == typeof(KeyValuePair <,>)); getCurrentEmitter(); il0.EmitAnyStloc(item); if (loadValueEmitter == null) { loadValueEmitter = delegate(TracingILGenerator il1) { il1.EmitAnyLdloca(item); il1.EmitGetProperty(keyProperty); }; } Emittion.EmitSerializeValue(emiter, il0, 1, traits.ElementType.GetGenericArguments()[0], null, NilImplication.MemberDefault, loadValueEmitter, localHolder); if (action2 == null) { action2 = delegate(TracingILGenerator il1) { il1.EmitAnyLdloca(item); il1.EmitGetProperty(valueProperty); }; } Emittion.EmitSerializeValue(emiter, il0, 1, traits.ElementType.GetGenericArguments()[1], null, NilImplication.MemberDefault, action2, localHolder); } else { Contract.Assert(traits.ElementType == typeof(DictionaryEntry)); getCurrentEmitter(); il0.EmitAnyStloc(item); if (action3 == null) { action3 = delegate(TracingILGenerator il1) { il0.EmitAnyLdloca(item); il0.EmitGetProperty(_DictionaryEntry.Key); il0.EmitUnbox_Any(typeof(MessagePackObject)); }; } Emittion.EmitSerializeValue(emiter, il0, 1, typeof(MessagePackObject), null, NilImplication.MemberDefault, action3, localHolder); if (action4 == null) { action4 = delegate(TracingILGenerator il1) { il0.EmitAnyLdloca(item); il0.EmitGetProperty(_DictionaryEntry.Value); il0.EmitUnbox_Any(typeof(MessagePackObject)); }; } Emittion.EmitSerializeValue(emiter, il0, 1, typeof(MessagePackObject), null, NilImplication.MemberDefault, action4, localHolder); } });