private void StoreCollectionValue(LocalBuilder collection, LocalBuilder value, CollectionDataContract collectionContract) { if (collectionContract.Kind == CollectionKind.GenericDictionary || collectionContract.Kind == CollectionKind.Dictionary) { ClassDataContract keyValuePairContract = DataContract.GetDataContract(value.LocalType) as ClassDataContract; if (keyValuePairContract == null) { DiagnosticUtility.DebugAssert("Failed to create contract for KeyValuePair type"); } DataMember keyMember = keyValuePairContract.Members[0]; DataMember valueMember = keyValuePairContract.Members[1]; LocalBuilder pairKey = _ilg.DeclareLocal(keyMember.MemberType, keyMember.Name); LocalBuilder pairValue = _ilg.DeclareLocal(valueMember.MemberType, valueMember.Name); _ilg.LoadAddress(value); _ilg.LoadMember(keyMember.MemberInfo); _ilg.Stloc(pairKey); _ilg.LoadAddress(value); _ilg.LoadMember(valueMember.MemberInfo); _ilg.Stloc(pairValue); _ilg.Call(collection, collectionContract.AddMethod, pairKey, pairValue); if (collectionContract.AddMethod.ReturnType != Globals.TypeOfVoid) { _ilg.Pop(); } } else { _ilg.Call(collection, collectionContract.AddMethod, value); if (collectionContract.AddMethod.ReturnType != Globals.TypeOfVoid) { _ilg.Pop(); } } }
private LocalBuilder UnwrapNullableObject(LocalBuilder memberValue)// Leaves !HasValue on stack { Type memberType = memberValue.LocalType; Label onNull = _ilg.DefineLabel(); Label end = _ilg.DefineLabel(); _ilg.Load(memberValue); while (memberType.IsGenericType && memberType.GetGenericTypeDefinition() == Globals.TypeOfNullable) { Type innerType = memberType.GetGenericArguments()[0]; _ilg.Dup(); _ilg.Call(XmlFormatGeneratorStatics.GetHasValueMethod.MakeGenericMethod(innerType)); _ilg.Brfalse(onNull); _ilg.Call(XmlFormatGeneratorStatics.GetNullableValueMethod.MakeGenericMethod(innerType)); memberType = innerType; } memberValue = _ilg.DeclareLocal(memberType, "nullableUnwrappedMemberValue"); _ilg.Stloc(memberValue); _ilg.Load(false); //isNull _ilg.Br(end); _ilg.MarkLabel(onNull); _ilg.Pop(); _ilg.Call(XmlFormatGeneratorStatics.GetDefaultValueMethod.MakeGenericMethod(memberType)); _ilg.Stloc(memberValue); _ilg.Load(true);//isNull _ilg.MarkLabel(end); return(memberValue); }
void ReadMembers(ClassDataContract classContract, LocalBuilder extensionDataLocal) { int memberCount = classContract.MemberNames.Length; ilg.Call(contextArg, XmlFormatGeneratorStatics.IncrementItemCountMethod, memberCount); LocalBuilder memberIndexLocal = ilg.DeclareLocal(Globals.TypeOfInt, "memberIndex", -1); int firstRequiredMember; bool[] requiredMembers = GetRequiredMembers(classContract, out firstRequiredMember); bool hasRequiredMembers = (firstRequiredMember < memberCount); LocalBuilder requiredIndexLocal = hasRequiredMembers ? ilg.DeclareLocal(Globals.TypeOfInt, "requiredIndex", firstRequiredMember) : null; object forReadElements = ilg.For(null, null, null); ilg.Call(null, XmlFormatGeneratorStatics.MoveToNextElementMethod, xmlReaderArg); ilg.IfFalseBreak(forReadElements); if (hasRequiredMembers) { ilg.Call(contextArg, XmlFormatGeneratorStatics.GetMemberIndexWithRequiredMembersMethod, xmlReaderArg, memberNamesArg, memberNamespacesArg, memberIndexLocal, requiredIndexLocal, extensionDataLocal); } else { ilg.Call(contextArg, XmlFormatGeneratorStatics.GetMemberIndexMethod, xmlReaderArg, memberNamesArg, memberNamespacesArg, memberIndexLocal, extensionDataLocal); } if (memberCount > 0) { Label[] memberLabels = ilg.Switch(memberCount); ReadMembers(classContract, requiredMembers, memberLabels, memberIndexLocal, requiredIndexLocal); ilg.EndSwitch(); } else { ilg.Pop(); } ilg.EndFor(); if (hasRequiredMembers) { ilg.If(requiredIndexLocal, Cmp.LessThan, memberCount); ilg.Call(null, XmlFormatGeneratorStatics.ThrowRequiredMemberMissingExceptionMethod, xmlReaderArg, memberIndexLocal, requiredIndexLocal, memberNamesArg); ilg.EndIf(); } }