private static void EmitColumnAssignment(ILGenerator generator, short memberVariableIndex, MetaColumn member) { string memberName = member.GetMemberKey(); Label containsKeyLabel = generator.DefineLabel(); generator.Emit(OpCodes.Ldarg_2); generator.Emit(OpCodes.Ldstr, memberName); generator.Emit(OpCodes.Call, _valueSetContainsKeyMethod); generator.Emit(OpCodes.Brfalse, containsKeyLabel); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Callvirt, _metaTypeGetMembersMethod); generator.Emit(OpCodes.Ldstr, memberName); generator.Emit(OpCodes.Callvirt, _metaTypeGetMemberMethod); generator.Emit(OpCodes.Stloc, memberVariableIndex); generator.Emit(OpCodes.Ldloc, memberVariableIndex); generator.Emit(OpCodes.Callvirt, _metaMemberGetAccessorMethod); generator.Emit(OpCodes.Ldarg_1); if (member.Binder != null) { generator.Emit(OpCodes.Ldloc, memberVariableIndex); generator.Emit(OpCodes.Castclass, typeof(MetaColumn)); generator.Emit(OpCodes.Callvirt, _metaColumnGetBinderMethod); } generator.Emit(OpCodes.Ldarg_2); generator.Emit(OpCodes.Ldstr, memberName); if (member.Binder != null) { generator.Emit(OpCodes.Call, _valueSetGetItemMethod.MakeGenericMethod(typeof(object))); generator.Emit(OpCodes.Callvirt, _columnBinderToPropertyValueMethod); } else { generator.Emit(OpCodes.Call, _valueSetGetItemMethod.MakeGenericMethod(member.Type)); if (member.Type.IsValueType) { generator.Emit(OpCodes.Box, member.Type); } } generator.Emit(OpCodes.Callvirt, _metaAccessorSetValueMethod); generator.MarkLabel(containsKeyLabel); }
private static void EmitDeferredColumnAssignment(ILGenerator generator, short memberVariableIndex, MetaColumn member) { string memberName = member.GetMemberKey(); Type linkedMemberType = member.Accessor.Type; Type linkType = typeof(ILink <>).MakeGenericType(linkedMemberType); Type linkSourceType = typeof(Func <>).MakeGenericType(linkedMemberType); Type associatorLoaderType = typeof(IAssociationLoader <>).MakeGenericType(linkedMemberType); MethodInfo associationLoadMethod = associatorLoaderType.GetMethod("Load"); MethodInfo linkSourceSetterMethod = linkType.GetProperty("Source").GetSetMethod(); MethodInfo linkValueSetterMethod = linkType.GetProperty("Value").GetSetMethod(); ConstructorInfo typeConstructor = member.Type.GetConstructor(Type.EmptyTypes); ConstructorInfo linkSourceConstructor = linkSourceType.GetConstructor(new Type[] { typeof(object), typeof(IntPtr) }); short variableIndex = (short)generator.DeclareLocal(linkType).LocalIndex; Label linkIsNullLabel = generator.DefineLabel(); Label containsKeyLabel = generator.DefineLabel(); Label skipLabel = generator.DefineLabel(); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Callvirt, _metaTypeGetMembersMethod); generator.Emit(OpCodes.Ldstr, memberName); generator.Emit(OpCodes.Callvirt, _metaTypeGetMemberMethod); generator.Emit(OpCodes.Stloc, memberVariableIndex); generator.Emit(OpCodes.Ldloc, memberVariableIndex); generator.Emit(OpCodes.Callvirt, _metaMemberGetAccessorMethod); generator.Emit(OpCodes.Ldarg_1); generator.Emit(OpCodes.Callvirt, _metaAccessorGetValueMethod); generator.Emit(OpCodes.Castclass, linkType); generator.Emit(OpCodes.Stloc, variableIndex); generator.Emit(OpCodes.Ldloc, variableIndex); if (typeConstructor == null) { generator.Emit(OpCodes.Brtrue, skipLabel); } else { generator.Emit(OpCodes.Brtrue, linkIsNullLabel); } generator.Emit(OpCodes.Newobj, typeConstructor); generator.Emit(OpCodes.Stloc, variableIndex); generator.MarkLabel(linkIsNullLabel); generator.Emit(OpCodes.Ldloc, variableIndex); generator.Emit(OpCodes.Ldloc, memberVariableIndex); generator.Emit(OpCodes.Castclass, typeof(MetaColumn)); generator.Emit(OpCodes.Ldarg_2); generator.Emit(OpCodes.Call, _associationLoaderScalarMethod.MakeGenericMethod(linkedMemberType)); generator.Emit(OpCodes.Dup); generator.Emit(OpCodes.Ldvirtftn, associationLoadMethod); generator.Emit(OpCodes.Newobj, linkSourceConstructor); generator.Emit(OpCodes.Callvirt, linkSourceSetterMethod); generator.Emit(OpCodes.Ldarg_2); generator.Emit(OpCodes.Ldstr, memberName); generator.Emit(OpCodes.Call, _valueSetContainsKeyMethod); generator.Emit(OpCodes.Brfalse, containsKeyLabel); generator.Emit(OpCodes.Ldloc, variableIndex); if (member.Binder != null) { generator.Emit(OpCodes.Ldloc, memberVariableIndex); generator.Emit(OpCodes.Castclass, typeof(MetaColumn)); generator.Emit(OpCodes.Callvirt, _metaColumnGetBinderMethod); } generator.Emit(OpCodes.Ldarg_2); generator.Emit(OpCodes.Ldstr, memberName); if (member.Binder != null) { generator.Emit(OpCodes.Call, _valueSetGetItemMethod.MakeGenericMethod(typeof(object))); generator.Emit(OpCodes.Callvirt, _columnBinderToPropertyValueMethod); if (member.Type.IsValueType) { generator.Emit(OpCodes.Unbox_Any, linkedMemberType); } else { generator.Emit(OpCodes.Castclass, linkedMemberType); } } else { generator.Emit(OpCodes.Call, _valueSetGetItemMethod.MakeGenericMethod(linkedMemberType)); } generator.Emit(OpCodes.Callvirt, linkValueSetterMethod); generator.MarkLabel(containsKeyLabel); generator.Emit(OpCodes.Ldloc, memberVariableIndex); generator.Emit(OpCodes.Callvirt, _metaMemberGetAccessorMethod); generator.Emit(OpCodes.Ldarg_1); generator.Emit(OpCodes.Ldloc, variableIndex); generator.Emit(OpCodes.Callvirt, _metaAccessorSetValueMethod); generator.MarkLabel(skipLabel); }