protected sealed override void EmitPackMembers(SerializerEmitter emitter, TracingILGenerator packerIL, SerializingMember[] entries) { var localHolder = new LocalVariableHolder(packerIL); packerIL.EmitAnyLdarg(1); packerIL.EmitAnyLdc_I4(entries.Length); packerIL.EmitAnyCall(Metadata._Packer.PackMapHeader); packerIL.EmitPop(); foreach (var entry in entries) { if (entry.Member == null) { // skip undefined member. continue; } packerIL.EmitAnyLdarg(1); packerIL.EmitLdstr(entry.Contract.Name); packerIL.EmitAnyCall(Metadata._Packer.PackString); packerIL.EmitPop(); Emittion.EmitSerializeValue( emitter, packerIL, 1, entry.Member.GetMemberValueType(), entry.Contract.Name, entry.Contract.NilImplication, il0 => { if (typeof(TObject).IsValueType) { il0.EmitAnyLdarga(2); } else { il0.EmitAnyLdarg(2); } Emittion.EmitLoadValue(il0, entry.Member); }, localHolder ); } packerIL.EmitRet(); }
protected override void EmitPackMembers(SerializerEmitter emitter, TracingILGenerator packerIL, SerializingMember[] entries) { var localHolder = new LocalVariableHolder(packerIL); packerIL.EmitAnyLdarg(1); packerIL.EmitAnyLdc_I4(entries.Length); packerIL.EmitAnyCall(Metadata._Packer.PackArrayHeader); packerIL.EmitPop(); foreach (var member in entries) { if (member.Member == null) { // missing member, always nil packerIL.EmitAnyLdarg(1); packerIL.EmitAnyCall(Metadata._Packer.PackNull); packerIL.EmitPop(); } else { Emittion.EmitSerializeValue( emitter, packerIL, 1, member.Member.GetMemberValueType(), member.Member.Name, member.Contract.NilImplication, il => { if (typeof(TObject).IsValueType) { il.EmitAnyLdarga(2); } else { il.EmitAnyLdarg(2); } Emittion.EmitLoadValue(il, member.Member); }, localHolder ); } } packerIL.EmitRet(); }
protected override void EmitPackMembers(SerializerEmitter emitter, TracingILGenerator packerIL, SerializingMember[] entries) { LocalVariableHolder localHolder = new LocalVariableHolder(packerIL); packerIL.EmitAnyLdarg(1); packerIL.EmitAnyLdc_I4(entries.Length); packerIL.EmitAnyCall(_Packer.PackArrayHeader); packerIL.EmitPop(); SerializingMember[] memberArray = entries; for (int i = 0; i < memberArray.Length; i++) { Action <TracingILGenerator> loadValueEmitter = null; SerializingMember member = memberArray[i]; if (member.Member == null) { packerIL.EmitAnyLdarg(1); packerIL.EmitAnyCall(_Packer.PackNull); packerIL.EmitPop(); } else { if (loadValueEmitter == null) { loadValueEmitter = delegate(TracingILGenerator il) { if (typeof(TObject).IsValueType) { il.EmitAnyLdarga(2); } else { il.EmitAnyLdarg(2); } Emittion.EmitLoadValue(il, member.Member); }; } Emittion.EmitSerializeValue(emitter, packerIL, 1, member.Member.GetMemberValueType(), member.Member.Name, member.Contract.NilImplication, loadValueEmitter, localHolder); } } packerIL.EmitRet(); }
/// <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); }