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