public void SetMemberValue(CodeGenerator generator, ArgBuilder targetObject, string memberName, LocalBuilder memberValue) { generator.Ldarg(targetObject); generator.Load(memberName); generator.Ldloc(memberValue); // Type originalType = memberValue.LocalType.IsEnum ? typeof(int) : memberValue.LocalType; if (memberValue.LocalType.IsValueType) { generator.Box(memberValue.LocalType.IsEnum ? typeof(int) : memberValue.LocalType); } //���ֵΪ�գ����ܵ���ToString generator.Load(null); generator.If(Cmp.NotEqualTo); generator.Ldloc(memberValue); // Type originalType = memberValue.LocalType.IsEnum ? typeof(int) : memberValue.LocalType; if (memberValue.LocalType.IsValueType) { generator.Box(memberValue.LocalType.IsEnum ? typeof(int) : memberValue.LocalType); } generator.Call(typeof(object).GetMethod("ToString", Type.EmptyTypes)); generator.Else(); generator.LoadDefaultValue(memberValue.LocalType); if (memberValue.LocalType.IsValueType) { generator.Box(memberValue.LocalType.IsEnum ? typeof(int) : memberValue.LocalType); } generator.EndIf(); generator.Call(typeof(NameValueCollection).GetMethod("Add", new Type[] { typeof(string), typeof(string) })); }
public void EndSetMembers(CodeGenerator generator, ArgBuilder targetObject) { generator.Ldarg(targetObject); generator.Load(null); generator.If(Cmp.EqualTo); generator.Pop(); LocalBuilder dataRow = generator.DeclareLocal(typeof(DataRow)); generator.Ldloc(locDataTable); generator.Call(typeof(DataTable).GetMethod("NewRow")); generator.Stloc(dataRow); LocalBuilder locCurrent = generator.DeclareLocal(typeof(string)); LocalBuilder locEnumerator = generator.DeclareLocal(typeof(Dictionary<string, object>.KeyCollection.Enumerator)); generator.Ldloc(locMemberValues); generator.Call(typeof(Dictionary<string, object>).GetMethod("get_Keys")); generator.Call(typeof(Dictionary<string, object>.KeyCollection).GetMethod("GetEnumerator")); generator.Stloc(locEnumerator); MethodInfo getCurrentMethod = typeof(Dictionary<string, object>.KeyCollection.Enumerator).GetMethod("get_Current"); MethodInfo moveNextMethod = typeof(Dictionary<string, object>.KeyCollection.Enumerator).GetMethod("MoveNext"); generator.ForEach(locCurrent, typeof(string), typeof(Dictionary<string, object>.KeyCollection.Enumerator), locEnumerator, getCurrentMethod); generator.Ldloc(dataRow); generator.Ldloc(locCurrent); generator.Ldloc(locMemberValues); generator.Ldloc(locCurrent); generator.Call(typeof(Dictionary<string, object>).GetMethod("get_Item")); generator.Call(typeof(DataRow).GetMethod("set_Item", new Type[] { typeof(string), typeof(object) })); generator.EndForEach(moveNextMethod); generator.Ldloc(dataRow); generator.EndIf(); }
public void GetMemberValue(CodeGenerator generator, ArgBuilder targetObject, string memberName, ref LocalBuilder memberValue) { LocalBuilder locValue = generator.DeclareLocal(typeof(string)); Type targetType = memberValue.LocalType; Type originalType = ConvertorGeneratorHelper.GetOriginalType(targetType); generator.Ldarg(targetObject); generator.Load(memberName); generator.Call(typeof(NameValueCollection).GetMethod("get_Item", new Type[] { typeof(string) })); generator.Stloc(locValue); if (targetType.IsAssignableFrom(typeof(string))) { generator.Ldloc(locValue); generator.Stloc(memberValue); return; } else { generator.Ldloc(locValue); generator.Call(typeof(string).GetMethod("IsNullOrEmpty")); generator.Load(true); generator.If(Cmp.NotEqualTo); if (targetType == typeof(Guid)) { generator.Ldloc(locValue); generator.New(typeof(Guid).GetConstructor(new Type[] { typeof(string) })); generator.Stloc(memberValue); } else { MethodInfo parseMethod = targetType.GetMethod("Parse", new Type[] { typeof(string) }); if (parseMethod != null) { generator.Ldloc(locValue); generator.Call(parseMethod); generator.Stloc(memberValue); } else { generator.Ldloc(locValue); generator.Load(originalType); generator.Call(typeof(Convert).GetMethod("ChangeType", new Type[] { typeof(object), typeof(Type) })); if (targetType.IsValueType) { generator.UnboxAny(targetType); } generator.Stloc(memberValue); } } generator.Else(); generator.LoadDefaultValue(targetType); generator.Stloc(memberValue); generator.EndIf(); } }
public JsonFormatClassReaderDelegate GenerateClassReader(ClassDataContract classContract) { _ilg = new CodeGenerator(); bool memberAccessFlag = classContract.RequiresMemberAccessForRead(null); try { BeginMethod(_ilg, "Read" + DataContract.SanitizeTypeName(classContract.StableName.Name) + "FromJson", typeof(JsonFormatClassReaderDelegate), memberAccessFlag); } catch (SecurityException securityException) { if (memberAccessFlag) { classContract.RequiresMemberAccessForRead(securityException); } else { throw; } } InitArgs(); CreateObject(classContract); _ilg.Call(_contextArg, XmlFormatGeneratorStatics.AddNewObjectMethod, _objectLocal); InvokeOnDeserializing(classContract); if (classContract.IsISerializable) ReadISerializable(classContract); else ReadClass(classContract); if (Globals.TypeOfIDeserializationCallback.IsAssignableFrom(classContract.UnderlyingType)) { _ilg.Call(_objectLocal, JsonFormatGeneratorStatics.OnDeserializationMethod, null); } InvokeOnDeserialized(classContract); if (!InvokeFactoryMethod(classContract)) { _ilg.Load(_objectLocal); // Do a conversion back from DateTimeOffsetAdapter to DateTimeOffset after deserialization. // DateTimeOffsetAdapter is used here for deserialization purposes to bypass the ISerializable implementation // on DateTimeOffset; which does not work in partial trust. if (classContract.UnderlyingType == Globals.TypeOfDateTimeOffsetAdapter) { _ilg.ConvertValue(_objectLocal.LocalType, Globals.TypeOfDateTimeOffsetAdapter); _ilg.Call(XmlFormatGeneratorStatics.GetDateTimeOffsetMethod); _ilg.ConvertValue(Globals.TypeOfDateTimeOffset, _ilg.CurrentMethod.ReturnType); } //Copy the KeyValuePairAdapter<K,T> to a KeyValuePair<K,T>. else if (classContract.IsKeyValuePairAdapter) { _ilg.Call(classContract.GetKeyValuePairMethodInfo); _ilg.ConvertValue(Globals.TypeOfKeyValuePair.MakeGenericType(classContract.KeyValuePairGenericArguments), _ilg.CurrentMethod.ReturnType); } else { _ilg.ConvertValue(_objectLocal.LocalType, _ilg.CurrentMethod.ReturnType); } } return (JsonFormatClassReaderDelegate)_ilg.EndMethod(); }
public void SetMemberValue(CodeGenerator generator, ArgBuilder targetObject, string memberName, LocalBuilder memberValue) { generator.Ldarg(targetObject); generator.Load(memberName); generator.Ldloc(memberValue); if (memberValue.LocalType.IsValueType) { generator.Box(memberValue.LocalType.IsEnum ? typeof(int) : memberValue.LocalType); } generator.Call(typeof(IDictionary).GetMethod("Add")); }
public void GetMemberValue(CodeGenerator generator, ArgBuilder targetObject, string memberName, ref LocalBuilder memberValue) { Type inputType = targetObject.ArgType; MemberInfo memberInfo = ConvertorGeneratorHelper.GetMemberInfo(inputType, memberName); if (memberInfo == null) { return; } Type srcMemberType = ConvertorGeneratorHelper.GetMemberType(memberInfo); Type destMemberType = memberValue.LocalType; if (memberValue.LocalType.IsAssignableFrom(srcMemberType)) { generator.Ldarg(targetObject); generator.LoadMember(memberInfo); generator.Stloc(memberValue); return; } Type converTargetType = ConvertorGeneratorHelper.GetOriginalType(destMemberType); Type convertSourceType = ConvertorGeneratorHelper.GetOriginalType(srcMemberType); //ת������ if (typeof(IConvertible).IsAssignableFrom(convertSourceType)) { generator.Ldarg(targetObject); generator.LoadMember(memberInfo); if (convertSourceType.IsValueType) { generator.Box(srcMemberType); } //�Ƿ�Ϊ�� generator.Load(null); generator.If(Cmp.NotEqualTo); //�����Ϊ�գ���������ת�� generator.Ldarg(targetObject); generator.LoadMember(memberInfo); if (convertSourceType.IsValueType) { generator.Box(srcMemberType); } generator.Load(converTargetType); generator.Call(typeof(Convert).GetMethod("ChangeType", new Type[] { typeof(object), typeof(Type) })); if (destMemberType.IsValueType) { generator.UnboxAny(destMemberType); } generator.Stloc(memberValue); //���Ϊ�գ������Ĭ��ֵ generator.Else(); generator.LoadDefaultValue(destMemberType); generator.Stloc(memberValue); generator.EndIf(); } }
public JsonFormatClassReaderDelegate GenerateClassReader(ClassDataContract classContract) { ilg = new CodeGenerator(); bool memberAccessFlag = classContract.RequiresMemberAccessForRead(null); try { BeginMethod(ilg, "Read" + classContract.StableName.Name + "FromJson", typeof(JsonFormatClassReaderDelegate), memberAccessFlag); } catch (SecurityException securityException) { if (memberAccessFlag && securityException.PermissionType.Equals(typeof(ReflectionPermission))) { classContract.RequiresMemberAccessForRead(securityException); } else { throw; } } InitArgs(); DemandSerializationFormatterPermission(classContract); DemandMemberAccessPermission(memberAccessFlag); CreateObject(classContract); ilg.Call(contextArg, XmlFormatGeneratorStatics.AddNewObjectMethod, objectLocal); InvokeOnDeserializing(classContract); if (classContract.IsISerializable) ReadISerializable(classContract); else ReadClass(classContract); if (Globals.TypeOfIDeserializationCallback.IsAssignableFrom(classContract.UnderlyingType)) ilg.Call(objectLocal, JsonFormatGeneratorStatics.OnDeserializationMethod, null); InvokeOnDeserialized(classContract); if (!InvokeFactoryMethod(classContract)) { ilg.Load(objectLocal); // Do a conversion back from DateTimeOffsetAdapter to DateTimeOffset after deserialization. // DateTimeOffsetAdapter is used here for deserialization purposes to bypass the ISerializable implementation // on DateTimeOffset; which does not work in partial trust. if (classContract.UnderlyingType == Globals.TypeOfDateTimeOffsetAdapter) { ilg.ConvertValue(objectLocal.LocalType, Globals.TypeOfDateTimeOffsetAdapter); ilg.Call(XmlFormatGeneratorStatics.GetDateTimeOffsetMethod); ilg.ConvertValue(Globals.TypeOfDateTimeOffset, ilg.CurrentMethod.ReturnType); } else { ilg.ConvertValue(objectLocal.LocalType, ilg.CurrentMethod.ReturnType); } } return (JsonFormatClassReaderDelegate)ilg.EndMethod(); }
public void GetMemberValue(CodeGenerator generator, ArgBuilder targetObject, string memberName, ref LocalBuilder memberValue) { LocalBuilder tempLocal = generator.DeclareLocal(typeof(object), "dataColumn"); Type targetType = memberValue.LocalType; Type originalType = ConvertorGeneratorHelper.GetOriginalType(targetType); generator.Ldarg(targetObject); generator.Load(memberName); generator.Call(typeof(DataRow).GetMethod("get_Item", new Type[] { typeof(string) })); generator.Stloc(tempLocal); generator.Ldloc(tempLocal); generator.LoadMember(typeof(DBNull).GetField("Value", BindingFlags.Static | BindingFlags.Public)); generator.If(Cmp.EqualTo); generator.LoadDefaultValue(targetType); generator.Stloc(memberValue); generator.Else(); generator.Ldloc(tempLocal); generator.InternalILGenerator.Emit(OpCodes.Isinst, targetType); generator.InternalILGenerator.Emit(OpCodes.Ldnull); generator.InternalILGenerator.Emit(OpCodes.Cgt_Un); generator.Load(true); generator.If(Cmp.EqualTo); generator.Ldloc(tempLocal); if (targetType.IsValueType) { generator.UnboxAny(targetType); } generator.Stloc(memberValue); generator.Else(); if (targetType == typeof(Guid)) { generator.Ldloc(tempLocal); generator.InternalILGenerator.Emit(OpCodes.Isinst, typeof(string)); generator.InternalILGenerator.Emit(OpCodes.Ldnull); generator.InternalILGenerator.Emit(OpCodes.Cgt_Un); generator.Load(true); generator.If(Cmp.EqualTo); generator.Ldloc(tempLocal); generator.New(typeof(Guid).GetConstructor(new Type[] { typeof(string) })); generator.Stloc(memberValue); } else { generator.Ldloc(tempLocal); generator.InternalILGenerator.Emit(OpCodes.Isinst, typeof(IConvertible)); generator.InternalILGenerator.Emit(OpCodes.Ldnull); generator.InternalILGenerator.Emit(OpCodes.Cgt_Un); generator.Load(true); generator.If(Cmp.EqualTo); generator.Ldloc(tempLocal); generator.Load(originalType); generator.Call(typeof(Convert).GetMethod("ChangeType", new Type[] { typeof(object), typeof(Type) })); if (targetType.IsValueType) { generator.UnboxAny(targetType); } generator.Stloc(memberValue); } generator.Else(); generator.LoadDefaultValue(targetType); generator.Stloc(memberValue); generator.EndIf(); generator.EndIf(); generator.EndIf(); }
public void GetMemberValue(CodeGenerator generator, ArgBuilder targetObject, string memberName, ref LocalBuilder memberValue) { MethodInfo getMethod; bool mustBeUnBox = false; switch (Type.GetTypeCode(memberValue.LocalType)) { case TypeCode.Boolean: getMethod = typeof(IDataRecord).GetMethod("GetBoolean"); break; case TypeCode.Byte: getMethod = typeof(IDataRecord).GetMethod("GetByte"); break; case TypeCode.Char: getMethod = typeof(IDataRecord).GetMethod("GetChar"); break; case TypeCode.DateTime: getMethod = typeof(IDataRecord).GetMethod("GetDateTime"); break; case TypeCode.Decimal: getMethod = typeof(IDataRecord).GetMethod("GetDecimal"); break; //Teddy 2008-2-2: commented the lines below, because for some database, return data type of float or real could always be System.Single or System.Double //case TypeCode.Double: // getMethod = typeof(IDataRecord).GetMethod("GetDouble"); // break; //case TypeCode.Single: // getMethod = typeof(IDataRecord).GetMethod("GetFloat"); // break; case TypeCode.Int16: getMethod = typeof(IDataRecord).GetMethod("GetInt16"); break; case TypeCode.Int32: getMethod = typeof(IDataRecord).GetMethod("GetInt32"); break; case TypeCode.Int64: getMethod = typeof(IDataRecord).GetMethod("GetInt64"); break; case TypeCode.String: getMethod = typeof(IDataRecord).GetMethod("GetString"); break; default: getMethod = typeof(IDataRecord).GetMethod("GetValue"); mustBeUnBox = true; break; } if (memberValue.LocalType == typeof(Guid)) { getMethod = typeof(IDataRecord).GetMethod("GetGuid"); mustBeUnBox = false; } if (memberValue.LocalType.IsEnum) { getMethod = typeof(IDataRecord).GetMethod("GetValue"); mustBeUnBox = true; } generator.Ldarg(targetObject); generator.Load(memberName); generator.Call(typeof(IDataRecord).GetMethod("GetOrdinal")); LocalBuilder fieldOrdinalLoc = generator.DeclareLocal(typeof(int)); generator.Stloc(fieldOrdinalLoc); generator.Ldarg(targetObject); generator.Ldloc(fieldOrdinalLoc); generator.Call(typeof(IDataRecord).GetMethod("IsDBNull")); generator.IfNot(); generator.Ldarg(targetObject); generator.Ldloc(fieldOrdinalLoc); generator.Call(getMethod); //Teddy 2008-2-2: added the code section below to convert the object to the memberValue.LocalType if (!memberValue.LocalType.IsEnum && getMethod == typeof(IDataRecord).GetMethod("GetValue")) { generator.Load(Type.GetTypeCode(memberValue.LocalType)); generator.Call(typeof(Convert).GetMethod("ChangeType", BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(object), typeof(TypeCode) }, null)); } if (memberValue.LocalType.IsValueType && mustBeUnBox) { generator.UnboxAny(memberValue.LocalType); } generator.Else(); generator.LoadDefaultValue(memberValue.LocalType); generator.EndIf(); generator.Stloc(memberValue); }
/// <summary> /// Do GetStaticMethodDelegate /// </summary> /// <param name="targetModule"></param> /// <param name="genericMethodInfo"></param> /// <param name="genericParameterTypes"></param> /// <returns></returns> protected static StaticDynamicMethodProxyHandler DoGetStaticMethodDelegate( Module targetModule, MethodInfo genericMethodInfo, params Type[] genericParameterTypes) { #region Check preconditions Check.Require(targetModule, "targetModule"); Check.Require(genericMethodInfo, "genericMethodInfo"); Check.Require((genericParameterTypes == null && genericMethodInfo.GetGenericArguments().Length == 0) || genericParameterTypes.Length == genericMethodInfo.GetGenericArguments().Length, "The number of generic type parameter of genericMethodInfo and the input types must equal!"); Check.Require(genericMethodInfo.IsStatic, "genericMethodInfo must be static here!"); #endregion //Create a dynamic method proxy delegate used to call the specified methodinfo CodeGenerator gen = new CodeGenerator(targetModule); gen.BeginMethod("dm" + Guid.NewGuid().ToString("N"), typeof(StaticDynamicMethodProxyHandler)); MethodInfo makeGenericMethodInfo = MakeMethodGeneric(genericMethodInfo, genericParameterTypes); LoadParameters(gen, makeGenericMethodInfo.GetParameters(), true); gen.Call(makeGenericMethodInfo); CastValueToObject(gen, makeGenericMethodInfo.ReturnType); return (StaticDynamicMethodProxyHandler)gen.EndMethod(); }
public void SetMemberValue(CodeGenerator generator, ArgBuilder targetObject, string memberName, LocalBuilder memberValue) { generator.Ldarg(targetObject); if (memberValue.LocalType.FullName.StartsWith("System.Nullable`1[")) { generator.Ldloc(memberValue); generator.Load(null); generator.If(Cmp.EqualTo); generator.LoadMember(typeof(DBNull).GetField("Value")); generator.Stloc(memberValue); generator.EndIf(); } generator.Load(null); generator.If(Cmp.EqualTo); PropertyInfo columns = typeof(DataTable).GetProperty("Columns"); generator.Ldloc(locDataTable); generator.LoadMember(columns); generator.Load(memberName); generator.Ldtoken(CommonUtils.GetOriginalTypeOfNullableType(memberValue.LocalType.IsEnum ? typeof(int) : memberValue.LocalType)); generator.Call(typeof(Type).GetMethod("GetTypeFromHandle", new Type[] { typeof(RuntimeTypeHandle) })); generator.Call(typeof(DataColumnCollection).GetMethod("Add", new Type[] { typeof(string), typeof(Type) })); generator.Pop(); generator.Ldloc(locMemberValues); generator.Load(memberName); generator.Ldloc(memberValue); if (memberValue.LocalType.IsValueType) { generator.Box(memberValue.LocalType.IsEnum ? typeof(int) : memberValue.LocalType); } generator.Call(typeof(Dictionary<string, object>).GetMethod("Add")); generator.Else(); generator.Ldarg(targetObject); generator.Load(memberName); generator.Ldloc(memberValue); if (memberValue.LocalType.IsValueType) { generator.Box(memberValue.LocalType); } generator.Call(typeof(DataRow).GetMethod("set_Item", new Type[] { typeof(string), typeof(object) })); generator.EndIf(); }