private static Action <TTarget, TValue> EmitPropertySetter <TTarget, TValue>( PropertyInfo propertyInfo, MethodInfo setMethod) { var propType = propertyInfo.PropertyType; var declaringType = propertyInfo.DeclaringType; var dynamicMethod = EmitUtils.CreateDynamicMethod( "$Set" + propertyInfo.Name, null, new[] { typeof(TTarget), typeof(TValue) }, declaringType); var il = dynamicMethod.GetILGenerator(); //copy the value to a local variable, unbox if needed il.DeclareLocal(propType); il.Ldarg_1(); if (!typeof(TValue).IsValueType) { il.CastValue(propType); } il.Stloc_0(); //push the instance, unbox if needed if (!setMethod.IsStatic) { il.Ldarg_0(); il.CastReference(declaringType); } //push the value and call the method il.Ldloc_0(); il.CallMethod(setMethod); il.Ret(); return((Action <TTarget, TValue>)dynamicMethod.CreateDelegate(typeof(Action <TTarget, TValue>))); }
private static Action <TTarget, TValue> EmitFieldSetter <TTarget, TValue>(FieldInfo fieldInfo) { var dynamicMethod = EmitUtils.CreateDynamicMethod( "$Set" + fieldInfo.Name, null, new[] { typeof(TTarget), typeof(TValue) }, fieldInfo.DeclaringType); var il = dynamicMethod.GetILGenerator(); //copy the value to a local variable, unbox if needed il.DeclareLocal(fieldInfo.FieldType); il.Ldarg_1(); if (!typeof(TValue).IsValueType) { il.CastValue(fieldInfo.FieldType); } il.Stloc_0(); if (fieldInfo.IsStatic) { il.Ldloc_0(); il.Stsfld(fieldInfo); } else { il.Ldarg_0(); il.CastReference(fieldInfo.DeclaringType); il.Ldloc_0(); il.Stfld(fieldInfo); } il.Ret(); return((Action <TTarget, TValue>)dynamicMethod.CreateDelegate(typeof(Action <TTarget, TValue>))); }
private static Func <object> DoCreateDelegate(Type type) { if (type.IsInterface) { throw new ArgumentException("The type is an interface.", "type"); } if (type.IsAbstract) { throw new ArgumentException("The type is abstract.", "type"); } ConstructorInfo constructorInfo = null; if (type.IsClass) { constructorInfo = type.GetConstructor(Type.EmptyTypes); if (constructorInfo == null) { throw new ArgumentException( "The type does not have a public parameterless constructor.", "type"); } } var dynamicMethod = EmitUtils.CreateDynamicMethod( "$Create" + type, typeof(object), Type.EmptyTypes, type); var il = dynamicMethod.GetILGenerator(); if (type.IsClass) { il.Newobj(constructorInfo); } else //value type { il.DeclareLocal(type); il.LoadLocalVariableAddress(0); il.Initobj(type); il.LoadLocalVariable(0); il.Box(type); } il.Ret(); return((Func <object>)dynamicMethod.CreateDelegate(typeof(Func <object>))); }
private static Func <TSource, TReturn> EmitFieldGetter <TSource, TReturn>(FieldInfo fieldInfo) { var dynamicMethod = EmitUtils.CreateDynamicMethod( "$Get" + fieldInfo.Name, typeof(TReturn), new[] { typeof(TSource) }, fieldInfo.DeclaringType); var il = dynamicMethod.GetILGenerator(); if (fieldInfo.IsStatic) { il.Ldsfld(fieldInfo); } else { //unbox the source if needed if (typeof(TSource).IsValueType) { il.Ldarga_S(0); } else { il.Ldarg_0(); il.CastReference(fieldInfo.DeclaringType); } il.Ldfld(fieldInfo); } //box the return value if needed if (!typeof(TReturn).IsValueType && fieldInfo.FieldType.IsValueType) { il.Box(fieldInfo.FieldType); } il.Ret(); return((Func <TSource, TReturn>)dynamicMethod.CreateDelegate(typeof(Func <TSource, TReturn>))); }
private static Func <TSource, TReturn> EmitPropertyGetter <TSource, TReturn>( PropertyInfo propertyInfo, MethodInfo getMethod) { var dynamicMethod = EmitUtils.CreateDynamicMethod( "$Get" + propertyInfo.Name, typeof(TReturn), new[] { typeof(TSource) }, propertyInfo.DeclaringType); var il = dynamicMethod.GetILGenerator(); if (!getMethod.IsStatic) { //unbox the input value if needed if (typeof(TSource).IsValueType) { il.Ldarga_S(0); } else { il.Ldarg_0(); il.CastReference(propertyInfo.DeclaringType); } } il.CallMethod(getMethod); //box the return value if needed if (!typeof(TReturn).IsValueType && propertyInfo.PropertyType.IsValueType) { il.Box(propertyInfo.PropertyType); } il.Ret(); return((Func <TSource, TReturn>)dynamicMethod.CreateDelegate(typeof(Func <TSource, TReturn>))); }
private static Func <object, object[], object> DoCreateDelegate(MethodInfo methodInfo, bool validateArguments) { var args = methodInfo.GetParameters(); var dynamicMethod = EmitUtils.CreateDynamicMethod( "$Call" + methodInfo.Name, typeof(object), new[] { typeof(object), typeof(object[]) }, methodInfo.DeclaringType); var il = dynamicMethod.GetILGenerator(); var lableValidationCompleted = il.DefineLabel(); if (!validateArguments || (methodInfo.IsStatic && args.Length == 0)) { il.Br_S(lableValidationCompleted); //does not need validation } else { var lableCheckArgumentsRef = il.DefineLabel(); var lableCheckArgumentsLength = il.DefineLabel(); //check if the instance is null if (!methodInfo.IsStatic) { // if (instance == null) throw new ArgumentNullExcpeiton("instance"); il.Ldarg_0(); il.Brtrue_S(args.Length > 0 ? lableCheckArgumentsRef : lableValidationCompleted); il.ThrowArgumentsNullExcpetion("instance"); } //check the arguments if (args.Length > 0) { // if (arguments == null) throw new ArgumentNullExcpeiton("arguments"); il.MarkLabel(lableCheckArgumentsRef); il.Ldarg_1(); il.Brtrue_S(lableCheckArgumentsLength); il.ThrowArgumentsNullExcpetion("arguments"); // if (arguments.Length < $(args.Length)) throw new ArgumentExcpeiton(msg, "arguments"); il.MarkLabel(lableCheckArgumentsLength); il.Ldarg_1(); il.Ldlen(); il.Conv_I4(); il.LoadInt32(args.Length); il.Bge_S(lableValidationCompleted); il.ThrowArgumentsExcpetion("Not enough arguments in the argument array.", "arguments"); } } il.MarkLabel(lableValidationCompleted); if (!methodInfo.IsStatic) { il.Ldarg_0(); il.CastReference(methodInfo.DeclaringType); } if (args.Length > 0) { for (int i = 0; i < args.Length; i++) { il.Ldarg_1(); il.LoadInt32((short)i); il.Ldelem_Ref(); il.CastValue(args[i].ParameterType); } } il.CallMethod(methodInfo); if (methodInfo.ReturnType == typeof(void)) { il.Ldc_I4_0(); //return null } else { il.BoxIfNeeded(methodInfo.ReturnType); } il.Ret(); var methodDelegate = dynamicMethod.CreateDelegate(typeof(Func <object, object[], object>)); return((Func <object, object[], object>)methodDelegate); }
private static Func <object[], object> DoCreateDelegate(ConstructorInfo constructorInfo, bool validateArguments) { var delclaringType = constructorInfo.DeclaringType; if (delclaringType.IsAbstract) { throw new ArgumentException( "The declaring type of the constructor is abstract.", "constructorInfo"); } var dynamicMethod = EmitUtils.CreateDynamicMethod( "$Create" + delclaringType.Name, typeof(object), new[] { typeof(object[]) }, constructorInfo.DeclaringType); var il = dynamicMethod.GetILGenerator(); var args = constructorInfo.GetParameters(); var lableValidationCompleted = il.DefineLabel(); if (!validateArguments || args.Length == 0) { il.Br_S(lableValidationCompleted); } else { var lableCheckArgumentsLength = il.DefineLabel(); // if (arguments == null) throw new ArgumentNullExcpeiton("arguments"); il.Ldarg_0(); il.Brtrue_S(lableCheckArgumentsLength); il.ThrowArgumentsNullExcpetion("arguments"); // if (arguments.Length < $(args.Length)) throw new ArgumentExcpeiton(msg, "arguments"); il.MarkLabel(lableCheckArgumentsLength); il.Ldarg_0(); il.Ldlen(); il.Conv_I4(); il.LoadInt32(args.Length); il.Bge_S(lableValidationCompleted); il.ThrowArgumentsExcpetion("Not enough arguments in the argument array.", "arguments"); } il.MarkLabel(lableValidationCompleted); if (args.Length > 0) { for (int i = 0; i < args.Length; i++) { il.Ldarg_0(); il.LoadInt32((short)i); il.Ldelem_Ref(); il.CastValue(args[i].ParameterType); } } il.Newobj(constructorInfo); il.Ret(); return((Func <object[], object>)dynamicMethod.CreateDelegate(typeof(Func <object[], object>))); }