private void GenerateCreateGetFieldIL(FieldInfo fieldInfo, ILGenerator generator)
        {
            if (!fieldInfo.IsStatic)
            {
                generator.PushInstance(fieldInfo.DeclaringType);
                generator.Emit(OpCodes.Ldfld, fieldInfo);
            }
            else
            {
                generator.Emit(OpCodes.Ldsfld, fieldInfo);
            }

            generator.BoxIfNeeded(fieldInfo.FieldType);
            generator.Return();
        }
Exemplo n.º 2
0
        // Token: 0x0600161B RID: 5659 RVA: 0x00068FE0 File Offset: 0x000671E0
        private void tmethod_4022(PropertyInfo arg_0, ILGenerator arg_1)
        {
            MethodInfo getMethod = arg_0.GetGetMethod(true);

            if (getMethod == null)
            {
                throw new ArgumentException("Property '{0}' does not have a getter.".FormatWith(CultureInfo.InvariantCulture, arg_0.Name));
            }
            if (!getMethod.IsStatic)
            {
                arg_1.PushInstance(arg_0.DeclaringType);
            }
            arg_1.CallMethod(getMethod);
            arg_1.BoxIfNeeded(arg_0.PropertyType);
            arg_1.Return();
        }
        // Token: 0x06000D80 RID: 3456 RVA: 0x0004E80C File Offset: 0x0004CA0C
        private void GenerateCreateGetPropertyIL(PropertyInfo propertyInfo, ILGenerator generator)
        {
            MethodInfo getMethod = propertyInfo.GetGetMethod(true);

            if (getMethod == null)
            {
                throw new ArgumentException("Property '{0}' does not have a getter.".FormatWith(CultureInfo.InvariantCulture, propertyInfo.Name));
            }
            if (!getMethod.IsStatic)
            {
                generator.PushInstance(propertyInfo.DeclaringType);
            }
            generator.CallMethod(getMethod);
            generator.BoxIfNeeded(propertyInfo.PropertyType);
            generator.Return();
        }
Exemplo n.º 4
0
        public static Func <object, object> CreateFieldGetterHandler(FieldInfo fieldInfo)
        {
            var         dynam = new DynamicMethod(string.Empty, typeof(object), SingleObject, Module, true);
            ILGenerator il    = dynam.GetILGenerator();

            if (!fieldInfo.IsStatic)
            {
                il.PushInstance(fieldInfo.DeclaringType);
            }

            il.Emit(OpCodes.Ldfld, fieldInfo);
            il.BoxIfNeeded(fieldInfo.FieldType);
            il.Emit(OpCodes.Ret);

            return((Func <object, object>)dynam.CreateDelegate(typeof(Func <object, object>)));
        }
Exemplo n.º 5
0
        public static LateBoundMethod CreateMethod(MethodBase method)
        {
            DynamicMethod method2     = CreateDynamicMethod(method.ToString(), typeof(object), new Type[] { typeof(object), typeof(object[]) }, method.DeclaringType);
            ILGenerator   iLGenerator = method2.GetILGenerator();

            ParameterInfo[] parameters = method.GetParameters();
            Label           label      = iLGenerator.DefineLabel();

            iLGenerator.Emit(OpCodes.Ldarg_1);
            iLGenerator.Emit(OpCodes.Ldlen);
            iLGenerator.Emit(OpCodes.Ldc_I4, parameters.Length);
            iLGenerator.Emit(OpCodes.Beq, label);
            iLGenerator.Emit(OpCodes.Newobj, typeof(TargetParameterCountException).GetConstructor(Type.EmptyTypes));
            iLGenerator.Emit(OpCodes.Throw);
            iLGenerator.MarkLabel(label);
            if (!method.IsConstructor && !method.IsStatic)
            {
                iLGenerator.PushInstance(method.DeclaringType);
            }
            for (int i = 0; i < parameters.Length; i++)
            {
                iLGenerator.Emit(OpCodes.Ldarg_1);
                iLGenerator.Emit(OpCodes.Ldc_I4, i);
                iLGenerator.Emit(OpCodes.Ldelem_Ref);
                iLGenerator.UnboxIfNeeded(parameters[i].ParameterType);
            }
            if (method.IsConstructor)
            {
                iLGenerator.Emit(OpCodes.Newobj, (ConstructorInfo)method);
            }
            else if (method.IsFinal || !method.IsVirtual)
            {
                iLGenerator.CallMethod((MethodInfo)method);
            }
            Type type = method.IsConstructor ? method.DeclaringType : ((MethodInfo)method).ReturnType;

            if (type != typeof(void))
            {
                iLGenerator.BoxIfNeeded(type);
            }
            else
            {
                iLGenerator.Emit(OpCodes.Ldnull);
            }
            iLGenerator.Return();
            return((LateBoundMethod)method2.CreateDelegate(typeof(LateBoundMethod)));
        }
Exemplo n.º 6
0
        public static LateBoundGet CreateGet(FieldInfo fieldInfo)
        {
            DynamicMethod dynamicMethod = CreateDynamicMethod("Get" + fieldInfo.Name, typeof(object), new[] { typeof(object) }, fieldInfo.DeclaringType);

            ILGenerator generator = dynamicMethod.GetILGenerator();

            if (!fieldInfo.IsStatic)
            {
                generator.PushInstance(fieldInfo.DeclaringType);
            }

            generator.Emit(OpCodes.Ldfld, fieldInfo);
            generator.BoxIfNeeded(fieldInfo.FieldType);
            generator.Return();

            return((LateBoundGet)dynamicMethod.CreateDelegate(typeof(LateBoundGet)));
        }
Exemplo n.º 7
0
        public override Func <T, object> CreateGet <T>(FieldInfo fieldInfo)
        {
            DynamicMethod dynamicMethod = CreateDynamicMethod("Get" + fieldInfo.Name, typeof(T), new[] { typeof(object) }, fieldInfo.DeclaringType);

            ILGenerator generator = dynamicMethod.GetILGenerator();

            if (!fieldInfo.IsStatic)
            {
                generator.PushInstance(fieldInfo.DeclaringType);
            }

            generator.Emit(OpCodes.Ldfld, fieldInfo);
            generator.BoxIfNeeded(fieldInfo.FieldType);
            generator.Return();

            return((Func <T, object>)dynamicMethod.CreateDelegate(typeof(Func <T, object>)));
        }
Exemplo n.º 8
0
        private void GenerateCreateMethodCallIL(MethodBase method, ILGenerator generator)
        {
            ParameterInfo[] parameters = method.GetParameters();
            Label           label      = generator.DefineLabel();

            generator.Emit(OpCodes.Ldarg_1);
            generator.Emit(OpCodes.Ldlen);
            generator.Emit(OpCodes.Ldc_I4, parameters.Length);
            generator.Emit(OpCodes.Beq, label);
            generator.Emit(OpCodes.Newobj, typeof(TargetParameterCountException).GetConstructor(ReflectionUtils.EmptyTypes));
            generator.Emit(OpCodes.Throw);
            generator.MarkLabel(label);
            if (!method.IsConstructor && !method.IsStatic)
            {
                generator.PushInstance(method.DeclaringType);
            }
            for (int i = 0; i < parameters.Length; i++)
            {
                generator.Emit(OpCodes.Ldarg_1);
                generator.Emit(OpCodes.Ldc_I4, i);
                generator.Emit(OpCodes.Ldelem_Ref);
                generator.UnboxIfNeeded(parameters[i].ParameterType);
            }
            if (method.IsConstructor)
            {
                generator.Emit(OpCodes.Newobj, (ConstructorInfo)method);
            }
            else if (method.IsFinal || !method.IsVirtual)
            {
                generator.CallMethod((MethodInfo)method);
            }
            Type type = method.IsConstructor ? method.DeclaringType : ((MethodInfo)method).ReturnType;

            if (type != typeof(void))
            {
                generator.BoxIfNeeded(type);
            }
            else
            {
                generator.Emit(OpCodes.Ldnull);
            }
            generator.Return();
        }
Exemplo n.º 9
0
        public static LateBoundGet CreateGet(PropertyInfo propertyInfo)
        {
            MethodInfo getMethod = propertyInfo.GetGetMethod(true);

            if (getMethod == null)
            {
                throw new InvalidOperationException(string.Format("Property '{0}' does not have a getter.", propertyInfo.Name));
            }
            DynamicMethod method      = CreateDynamicMethod("Get" + propertyInfo.Name, typeof(object), new Type[] { typeof(object) }, propertyInfo.DeclaringType);
            ILGenerator   iLGenerator = method.GetILGenerator();

            if (!getMethod.IsStatic)
            {
                iLGenerator.PushInstance(propertyInfo.DeclaringType);
            }
            iLGenerator.CallMethod(getMethod);
            iLGenerator.BoxIfNeeded(propertyInfo.PropertyType);
            iLGenerator.Return();
            return((LateBoundGet)method.CreateDelegate(typeof(LateBoundGet)));
        }
Exemplo n.º 10
0
        public static LateBoundGet CreateGet(PropertyInfo propertyInfo)
        {
            if (propertyInfo == null)
            {
                throw new ArgumentNullException("propertyInfo");
            }
            if (!propertyInfo.CanRead)
            {
                return(null);
            }

            MethodInfo methodInfo = propertyInfo.GetGetMethod(true);

            if (methodInfo == null)
            {
                return(null);
            }

            DynamicMethod dynamicMethod = CreateDynamicMethod(
                "Get" + propertyInfo.Name,
                typeof(object),
                new[] { typeof(object) },
                propertyInfo.DeclaringType);

            ILGenerator generator = dynamicMethod.GetILGenerator();

            if (!methodInfo.IsStatic)
            {
                generator.PushInstance(propertyInfo.DeclaringType);
            }

            generator.CallMethod(methodInfo);
            generator.BoxIfNeeded(propertyInfo.PropertyType);
            generator.Return();

            return((LateBoundGet)dynamicMethod.CreateDelegate(typeof(LateBoundGet)));
        }
Exemplo n.º 11
0
        public static LateBoundGet CreateGet(PropertyInfo propertyInfo)
        {
            if (propertyInfo == null)
            {
                throw new ArgumentNullException("propertyInfo");
            }
            if (!propertyInfo.CanRead)
            {
                return(null);
            }

#if SILVERLIGHT
            var instance      = Expression.Parameter(typeof(object), "instance");
            var declaringType = propertyInfo.DeclaringType;
            var getMethod     = propertyInfo.GetGetMethod(true);

            UnaryExpression instanceCast;
            if (getMethod.IsStatic)
            {
                instanceCast = null;
            }
            else if (declaringType.IsValueType)
            {
                instanceCast = Expression.Convert(instance, declaringType);
            }
            else
            {
                instanceCast = Expression.TypeAs(instance, declaringType);
            }

            var call      = Expression.Call(instanceCast, getMethod);
            var valueCast = Expression.TypeAs(call, typeof(object));

            var lambda = Expression.Lambda <LateBoundGet>(valueCast, instance);
            return(lambda.Compile());
#else
            MethodInfo methodInfo = propertyInfo.GetGetMethod(true);
            if (methodInfo == null)
            {
                return(null);
            }

            DynamicMethod dynamicMethod = CreateDynamicMethod(
                "Get" + propertyInfo.Name,
                typeof(object),
                new[] { typeof(object) },
                propertyInfo.DeclaringType);

            ILGenerator generator = dynamicMethod.GetILGenerator();

            if (!methodInfo.IsStatic)
            {
                generator.PushInstance(propertyInfo.DeclaringType);
            }

            generator.CallMethod(methodInfo);
            generator.BoxIfNeeded(propertyInfo.PropertyType);
            generator.Return();

            return((LateBoundGet)dynamicMethod.CreateDelegate(typeof(LateBoundGet)));
#endif
        }
Exemplo n.º 12
0
        private void GenerateCreateMethodCallIL(MethodBase method, ILGenerator generator, int argsIndex)
        {
            ParameterInfo[] args = method.GetParameters();

            Label argsOk = generator.DefineLabel();

            generator.Emit(OpCodes.Ldarg, argsIndex);
            generator.Emit(OpCodes.Ldlen);
            generator.Emit(OpCodes.Ldc_I4, args.Length);
            generator.Emit(OpCodes.Beq, argsOk);

            generator.Emit(OpCodes.Newobj, typeof(TargetParameterCountException).GetConstructor(ReflectionUtils.EmptyTypes));
            generator.Emit(OpCodes.Throw);

            generator.MarkLabel(argsOk);

            if (!method.IsConstructor && !method.IsStatic)
            {
                generator.PushInstance(method.DeclaringType);
            }

            int localVariableCount = 0;

            for (int i = 0; i < args.Length; i++)
            {
                Type parameterType = args[i].ParameterType;

                generator.Emit(OpCodes.Ldarg, argsIndex);

                generator.Emit(OpCodes.Ldc_I4, i);
                generator.Emit(OpCodes.Ldelem_Ref);

                if (parameterType.IsValueType())
                {
                    // have to check that value type parameters aren't null
                    // otherwise they will error when unboxed
                    Label skipSettingDefault          = generator.DefineLabel();
                    Label finishedProcessingParameter = generator.DefineLabel();

                    // check if parameter is not null
                    generator.Emit(OpCodes.Brtrue_S, skipSettingDefault);

                    // parameter has no value, initialize to default
                    LocalBuilder localVariable = generator.DeclareLocal(parameterType);
                    generator.Emit(OpCodes.Ldloca_S, localVariable);
                    generator.Emit(OpCodes.Initobj, parameterType);
                    generator.Emit(OpCodes.Ldloc, localVariableCount);
                    generator.Emit(OpCodes.Br_S, finishedProcessingParameter);

                    // parameter has value, get value from array again and unbox
                    generator.MarkLabel(skipSettingDefault);
                    generator.Emit(OpCodes.Ldarg, argsIndex);
                    generator.Emit(OpCodes.Ldc_I4, i);
                    generator.Emit(OpCodes.Ldelem_Ref);
                    generator.UnboxIfNeeded(parameterType);

                    // parameter finished, we out!
                    generator.MarkLabel(finishedProcessingParameter);
                    localVariableCount++;
                }
                else
                {
                    generator.UnboxIfNeeded(parameterType);
                }
            }

            if (method.IsConstructor)
            {
                generator.Emit(OpCodes.Newobj, (ConstructorInfo)method);
            }
            else
            {
                generator.CallMethod((MethodInfo)method);
            }

            Type returnType = method.IsConstructor
                ? method.DeclaringType
                : ((MethodInfo)method).ReturnType;

            if (returnType != typeof(void))
            {
                generator.BoxIfNeeded(returnType);
            }
            else
            {
                generator.Emit(OpCodes.Ldnull);
            }

            generator.Return();
        }
Exemplo n.º 13
0
        private static void DefineProperty(PropertyInfo property, TypeBuilder typeBuilder, FieldInfo field, Type objectType, PropertyInfo objectProperty)
        {
            // create the new property.
            var propertyBuilder = typeBuilder.DefineProperty(property.Name, PropertyAttributes.HasDefault, property.PropertyType, null);

            // The property "set" and property "get" methods require a special set of attributes.
            //var getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Virtual;
            const MethodAttributes getSetAttr = MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.SpecialName;

            // create the getter if we can read.
            if (property.CanRead)
            {
                // create the get method for the property.
                var getMethodName = "get_" + property.Name;
                var getMethod     = typeBuilder.DefineMethod(getMethodName, getSetAttr, property.PropertyType, Type.EmptyTypes);

                // get the IL generator to generate the required IL.
                ILGenerator il = getMethod.GetILGenerator();

                // load the first argument (the instance itself) and the field.
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, field);

                // check if the inner type is public and in the same assembly.
                if (!objectType.IsPublic)
                {
                    // required to create some reflection code to access internal and outside of the
                    // assembly properties.
                    il.EmitCall(OpCodes.Callvirt, objectType.GetMethod("GetType"), null);

                    // get the property.
                    il.Emit(OpCodes.Ldstr, objectProperty.Name);
                    il.EmitCall(OpCodes.Callvirt, typeof(Type).GetMethod("GetProperty", new[] { typeof(string) }), null);

                    // load the arguments for the next method call.
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldfld, field);
                    il.Emit(OpCodes.Ldnull);
                    il.EmitCall(OpCodes.Callvirt, typeof(PropertyInfo).GetMethod("GetValue", new[] { typeof(object), typeof(object[]) }), null);

                    // cast or unbox if required.
                    il.EmitCastToReference(property.PropertyType);
                }
                else
                {
                    // directly call the inner object's get method of the property.
                    il.EmitCall(OpCodes.Callvirt, objectProperty.GetGetMethod(), null);
                }

                il.Emit(OpCodes.Ret);

                // set the method.
                propertyBuilder.SetGetMethod(getMethod);
                typeBuilder.DefineMethodOverride(getMethod, property.ReflectedType.GetMethod(getMethodName));
            }

            // create the setter if we can read.
            if (property.CanWrite)
            {
                // create the set method of the property.
                var setMethodName = "set_" + property.Name;
                var setMethod     = typeBuilder.DefineMethod(setMethodName, getSetAttr, null, new[] { property.PropertyType });

                // get the IL generator to generate some IL.
                ILGenerator il = setMethod.GetILGenerator();

                // load the first argument (instance itself) and the field.
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, field);

                // check if the inner type is public and in the same assembly.
                if (!objectType.IsPublic)
                {
                    // required to create some reflection code to access internal and outside of the
                    // assembly properties.
                    il.EmitCall(OpCodes.Callvirt, objectType.GetMethod("GetType"), null);

                    // get the property.
                    il.Emit(OpCodes.Ldstr, objectProperty.Name);
                    il.EmitCall(OpCodes.Callvirt, typeof(Type).GetMethod("GetProperty", new[] { typeof(string) }), null);

                    // load the various arguments and items on the stack.
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldfld, field);
                    il.Emit(OpCodes.Ldarg_1);
                    // box if a value type.
                    il.BoxIfNeeded(property.PropertyType);
                    il.Emit(OpCodes.Ldnull);

                    // set the value for the property.
                    il.EmitCall(OpCodes.Callvirt, typeof(PropertyInfo).GetMethod("SetValue", new[] { typeof(object), typeof(object), typeof(object[]) }), null);

                    // check if we need to unbox or cast.
                    il.EmitCastToReference(property.PropertyType);
                }
                else
                {
                    // load the second argument (holding the value).
                    il.Emit(OpCodes.Ldarg_1);
                    // directly call the inner object's get method of the property.
                    il.EmitCall(OpCodes.Callvirt, objectProperty.GetSetMethod(), null);
                }
                il.Emit(OpCodes.Ret);

                propertyBuilder.SetSetMethod(setMethod);
                typeBuilder.DefineMethodOverride(setMethod, property.ReflectedType.GetMethod(setMethodName));
            }
        }
Exemplo n.º 14
0
        private static void DefineIndexerProperty(PropertyInfo property, TypeBuilder typeBuilder, FieldInfo field, Type objectType, bool ignoreMappings, IEntityMap entityMap)
        {
            // create the new property.
            var propertyBuilder = typeBuilder.DefineProperty(property.Name, PropertyAttributes.HasDefault, property.PropertyType, null);

            // The property "set" and property "get" methods require a special set of attributes.
            //var getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Virtual;
            const MethodAttributes getSetAttr = MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.SpecialName;
            var columnName = MappingFactory.GetPropertyOrColumnName(property, ignoreMappings, entityMap, true);

            // create the getter if we can read.
            if (property.CanRead)
            {
                var getItemMethod = objectType.GetMethod("get_Item", new[] { typeof(string) });

                var typeConverter = MappingFactory.GetTypeConverter(getItemMethod.ReturnType, property, entityMap);

                // create the get method for the property.
                var getMethodName = "get_" + property.Name;
                var getMethod     = typeBuilder.DefineMethod(getMethodName, getSetAttr, property.PropertyType, Type.EmptyTypes);

                // get the IL generator to generate the required IL.
                ILGenerator il = getMethod.GetILGenerator();

                if (typeConverter.Item1 != null)
                {
                    //	New the converter
                    il.Emit(OpCodes.Newobj, typeConverter.Item1.GetConstructor(Type.EmptyTypes));
                }

                // load the first argument (the instance itself) and the field.
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, field);
                il.Emit(OpCodes.Ldstr, columnName);
                il.Emit(OpCodes.Callvirt, getItemMethod);
                if (typeConverter.Item1 == null)
                {
                    il.EmitCastToReference(property.PropertyType);
                }
                else
                {
                    //	Call the convert method
                    il.Emit(OpCodes.Callvirt, typeConverter.Item2.GetMethod("ConvertForward"));
                }
                il.Emit(OpCodes.Ret);

                // set the method.
                propertyBuilder.SetGetMethod(getMethod);
                typeBuilder.DefineMethodOverride(getMethod, property.ReflectedType.GetMethod(getMethodName));
            }

            // create the setter if we can read.
            if (property.CanWrite)
            {
                var setItemMethod = objectType.GetMethod("set_Item", new[] { typeof(string), typeof(object) });

                var typeConverter = MappingFactory.GetTypeConverter(setItemMethod.GetParameters()[1].ParameterType, property, entityMap);

                // create the set method of the property.
                var setMethodName = "set_" + property.Name;
                var setMethod     = typeBuilder.DefineMethod(setMethodName, getSetAttr, null, new[] { property.PropertyType });

                // get the IL generator to generate some IL.
                ILGenerator il = setMethod.GetILGenerator();

                // load the first argument (instance itself) and the field.
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, field);
                il.Emit(OpCodes.Ldstr, columnName);

                if (typeConverter.Item1 != null)
                {
                    //	New the converter
                    il.Emit(OpCodes.Newobj, typeConverter.Item1.GetConstructor(Type.EmptyTypes));
                }

                // load the second argument (holding the value).
                il.Emit(OpCodes.Ldarg_1);
                if (typeConverter.Item1 != null)
                {       //	Call the convert method
                    il.Emit(OpCodes.Callvirt, typeConverter.Item2.GetMethod("ConvertBackward"));
                }
                else
                {
                    il.BoxIfNeeded(property.PropertyType);
                }
                // directly call the inner object's get method of the property.
                il.Emit(OpCodes.Callvirt, setItemMethod);
                il.Emit(OpCodes.Ret);

                propertyBuilder.SetSetMethod(setMethod);
                typeBuilder.DefineMethodOverride(setMethod, property.ReflectedType.GetMethod(setMethodName));
            }
        }
        // Token: 0x06000D7C RID: 3452 RVA: 0x0004E264 File Offset: 0x0004C464
        private void GenerateCreateMethodCallIL(MethodBase method, ILGenerator generator, int argsIndex)
        {
            ParameterInfo[] parameters = method.GetParameters();
            Label           label      = generator.DefineLabel();

            generator.Emit(OpCodes.Ldarg, argsIndex);
            generator.Emit(OpCodes.Ldlen);
            generator.Emit(OpCodes.Ldc_I4, parameters.Length);
            generator.Emit(OpCodes.Beq, label);
            generator.Emit(OpCodes.Newobj, typeof(TargetParameterCountException).GetConstructor(ReflectionUtils.EmptyTypes));
            generator.Emit(OpCodes.Throw);
            generator.MarkLabel(label);
            if (!method.IsConstructor && !method.IsStatic)
            {
                generator.PushInstance(method.DeclaringType);
            }
            LocalBuilder local   = generator.DeclareLocal(typeof(IConvertible));
            LocalBuilder local2  = generator.DeclareLocal(typeof(object));
            OpCode       opcode  = (parameters.Length < 256) ? OpCodes.Ldloca_S : OpCodes.Ldloca;
            OpCode       opcode2 = (parameters.Length < 256) ? OpCodes.Ldloc_S : OpCodes.Ldloc;

            for (int i = 0; i < parameters.Length; i++)
            {
                ParameterInfo parameterInfo = parameters[i];
                Type          type          = parameterInfo.ParameterType;
                if (type.IsByRef)
                {
                    type = type.GetElementType();
                    LocalBuilder local3 = generator.DeclareLocal(type);
                    if (!parameterInfo.IsOut)
                    {
                        generator.PushArrayInstance(argsIndex, i);
                        if (type.IsValueType())
                        {
                            Label label2 = generator.DefineLabel();
                            Label label3 = generator.DefineLabel();
                            generator.Emit(OpCodes.Brtrue_S, label2);
                            generator.Emit(opcode, local3);
                            generator.Emit(OpCodes.Initobj, type);
                            generator.Emit(OpCodes.Br_S, label3);
                            generator.MarkLabel(label2);
                            generator.PushArrayInstance(argsIndex, i);
                            generator.UnboxIfNeeded(type);
                            generator.Emit(OpCodes.Stloc_S, local3);
                            generator.MarkLabel(label3);
                        }
                        else
                        {
                            generator.UnboxIfNeeded(type);
                            generator.Emit(OpCodes.Stloc_S, local3);
                        }
                    }
                    generator.Emit(opcode, local3);
                }
                else if (type.IsValueType())
                {
                    generator.PushArrayInstance(argsIndex, i);
                    generator.Emit(OpCodes.Stloc_S, local2);
                    Label label4 = generator.DefineLabel();
                    Label label5 = generator.DefineLabel();
                    generator.Emit(OpCodes.Ldloc_S, local2);
                    generator.Emit(OpCodes.Brtrue_S, label4);
                    LocalBuilder local4 = generator.DeclareLocal(type);
                    generator.Emit(opcode, local4);
                    generator.Emit(OpCodes.Initobj, type);
                    generator.Emit(opcode2, local4);
                    generator.Emit(OpCodes.Br_S, label5);
                    generator.MarkLabel(label4);
                    if (type.IsPrimitive())
                    {
                        MethodInfo method2 = typeof(IConvertible).GetMethod("To" + type.Name, new Type[]
                        {
                            typeof(IFormatProvider)
                        });
                        if (method2 != null)
                        {
                            Label label6 = generator.DefineLabel();
                            generator.Emit(OpCodes.Ldloc_S, local2);
                            generator.Emit(OpCodes.Isinst, type);
                            generator.Emit(OpCodes.Brtrue_S, label6);
                            generator.Emit(OpCodes.Ldloc_S, local2);
                            generator.Emit(OpCodes.Isinst, typeof(IConvertible));
                            generator.Emit(OpCodes.Stloc_S, local);
                            generator.Emit(OpCodes.Ldloc_S, local);
                            generator.Emit(OpCodes.Brfalse_S, label6);
                            generator.Emit(OpCodes.Ldloc_S, local);
                            generator.Emit(OpCodes.Ldnull);
                            generator.Emit(OpCodes.Callvirt, method2);
                            generator.Emit(OpCodes.Br_S, label5);
                            generator.MarkLabel(label6);
                        }
                    }
                    generator.Emit(OpCodes.Ldloc_S, local2);
                    generator.UnboxIfNeeded(type);
                    generator.MarkLabel(label5);
                }
                else
                {
                    generator.PushArrayInstance(argsIndex, i);
                    generator.UnboxIfNeeded(type);
                }
            }
            if (method.IsConstructor)
            {
                generator.Emit(OpCodes.Newobj, (ConstructorInfo)method);
            }
            else
            {
                generator.CallMethod((MethodInfo)method);
            }
            Type type2 = method.IsConstructor ? method.DeclaringType : ((MethodInfo)method).ReturnType;

            if (type2 != typeof(void))
            {
                generator.BoxIfNeeded(type2);
            }
            else
            {
                generator.Emit(OpCodes.Ldnull);
            }
            generator.Return();
        }
        private void GenerateCreateMethodCallIL(MethodBase method, ILGenerator generator, int argsIndex)
        {
            ParameterInfo[] parameters = method.GetParameters();
            Label           label      = generator.DefineLabel();

            generator.Emit(OpCodes.Ldarg, argsIndex);
            generator.Emit(OpCodes.Ldlen);
            generator.Emit(OpCodes.Ldc_I4, parameters.Length);
            generator.Emit(OpCodes.Beq, label);
            generator.Emit(OpCodes.Newobj, typeof(TargetParameterCountException).GetConstructor(ReflectionUtils.EmptyTypes));
            generator.Emit(OpCodes.Throw);
            generator.MarkLabel(label);
            if (!method.IsConstructor && !method.IsStatic)
            {
                generator.PushInstance(method.DeclaringType);
            }
            int arg = 0;

            for (int i = 0; i < parameters.Length; i++)
            {
                ParameterInfo info          = parameters[i];
                Type          parameterType = info.ParameterType;
                if (parameterType.IsByRef)
                {
                    parameterType = parameterType.GetElementType();
                    LocalBuilder local = generator.DeclareLocal(parameterType);
                    if (!info.IsOut)
                    {
                        generator.PushArrayInstance(argsIndex, i);
                        if (parameterType.IsValueType())
                        {
                            Label label2 = generator.DefineLabel();
                            Label label3 = generator.DefineLabel();
                            generator.Emit(OpCodes.Brtrue_S, label2);
                            generator.Emit(OpCodes.Ldloca_S, local);
                            generator.Emit(OpCodes.Initobj, parameterType);
                            generator.Emit(OpCodes.Br_S, label3);
                            generator.MarkLabel(label2);
                            generator.PushArrayInstance(argsIndex, i);
                            generator.UnboxIfNeeded(parameterType);
                            generator.Emit(OpCodes.Stloc, arg);
                            generator.MarkLabel(label3);
                        }
                        else
                        {
                            generator.UnboxIfNeeded(parameterType);
                            generator.Emit(OpCodes.Stloc, arg);
                        }
                    }
                    generator.Emit(OpCodes.Ldloca_S, local);
                    arg++;
                }
                else if (parameterType.IsValueType())
                {
                    generator.PushArrayInstance(argsIndex, i);
                    Label label4 = generator.DefineLabel();
                    Label label5 = generator.DefineLabel();
                    generator.Emit(OpCodes.Brtrue_S, label4);
                    LocalBuilder local = generator.DeclareLocal(parameterType);
                    generator.Emit(OpCodes.Ldloca_S, local);
                    generator.Emit(OpCodes.Initobj, parameterType);
                    generator.Emit(OpCodes.Ldloc, arg);
                    generator.Emit(OpCodes.Br_S, label5);
                    generator.MarkLabel(label4);
                    generator.PushArrayInstance(argsIndex, i);
                    generator.UnboxIfNeeded(parameterType);
                    generator.MarkLabel(label5);
                    arg++;
                }
                else
                {
                    generator.PushArrayInstance(argsIndex, i);
                    generator.UnboxIfNeeded(parameterType);
                }
            }
            if (method.IsConstructor)
            {
                generator.Emit(OpCodes.Newobj, (ConstructorInfo)method);
            }
            else
            {
                generator.CallMethod((MethodInfo)method);
            }
            Type type2 = method.IsConstructor ? method.DeclaringType : ((MethodInfo)method).ReturnType;

            if (type2 != typeof(void))
            {
                generator.BoxIfNeeded(type2);
            }
            else
            {
                generator.Emit(OpCodes.Ldnull);
            }
            generator.Return();
        }
Exemplo n.º 17
0
        public static MemberHandler <object> CreateMethodHandler(MethodBase method)
        {
            DynamicMethod dynamicMethod = CreateDynamicMethod(method.ToString(), typeof(object), new[] { typeof(object), typeof(object[]) }, method.DeclaringType);
            ILGenerator   generator     = dynamicMethod.GetILGenerator();

            ParameterInfo[] args = method.GetParameters();

            Label argsOk = generator.DefineLabel();

            generator.Emit(OpCodes.Ldarg_1);
            generator.Emit(OpCodes.Ldlen);
            generator.Emit(OpCodes.Ldc_I4, args.Length);
            generator.Emit(OpCodes.Beq, argsOk);

            generator.Emit(OpCodes.Newobj, typeof(TargetParameterCountException).GetConstructor(Type.EmptyTypes));
            generator.Emit(OpCodes.Throw);

            generator.MarkLabel(argsOk);

            if (!method.IsConstructor)
            {
                generator.PushInstance(method.DeclaringType);
            }

            for (int i = 0; i < args.Length; i++)
            {
                generator.Emit(OpCodes.Ldarg_1);
                generator.Emit(OpCodes.Ldc_I4, i);
                generator.Emit(OpCodes.Ldelem_Ref);

                generator.UnboxIfNeeded(args[i].ParameterType);
            }

            if (method.IsConstructor)
            {
                generator.Emit(OpCodes.Newobj, (ConstructorInfo)method);
            }
            else if (method.IsFinal || !method.IsVirtual)
            {
                generator.Emit(OpCodes.Call, (MethodInfo)method);
            }
            else
            {
                generator.Emit(OpCodes.Callvirt, (MethodInfo)method);
            }

            Type returnType = method.IsConstructor
        ? method.DeclaringType
        : ((MethodInfo)method).ReturnType;

            if (returnType != typeof(void))
            {
                generator.BoxIfNeeded(returnType);
            }
            else
            {
                generator.Emit(OpCodes.Ldnull);
            }

            generator.Emit(OpCodes.Ret);

            return((MemberHandler <object>)dynamicMethod.CreateDelegate(typeof(MemberHandler <object>)));
        }
Exemplo n.º 18
0
    internal static void Convert(this ILGenerator il, Type source, Type target)
    {
        if (source.FullName == target.FullName)
        {
            return;
        }

        if (source == typeof(object) || target == typeof(object))
        {
            if (EmitConvertMap.SearchConvertItem(source, target, out ConvertItem convertItem))
            {
                il.Convert(convertItem);
            }
            else
            {
                if (source == typeof(object))
                {
                    if (target != typeof(object))
                    {
                        il.UnBox(target);
                    }
                }
                else
                {
                    il.BoxIfNeeded(source);
                }
            }
            return;
        }

        if (target.IsAssignableFrom(source))
        {
            return;
        }

        if (!source.IsEnum)
        {
            //double Check
            if (!EmitConvertMap.s_map.ContainsKey(source))
            {
                lock (EmitConvertMap.s_map)
                {
                    if (!EmitConvertMap.s_map.ContainsKey(source))
                    {
                        EmitConvertMap.AnalyzeConverter(source);
                    }
                }
            }
        }

        if (EmitConvertMap.SearchConvertPath(source, target, out SearchResult searchResult))
        {
            foreach (ConvertItem convertItem in searchResult.Items.Select(x => x.Value))
            {
                il.Convert(convertItem);
            }
            return;
        }

        throw new InvalidCastException($"{source.Assembly.Location}/{source.FullName}-{target.Assembly.Location}/{target.FullName}");
    }
Exemplo n.º 19
0
        public static LateBoundMethod CreateMethod(MethodInfo methodInfo)
        {
            if (methodInfo == null)
            {
                throw new ArgumentNullException("methodInfo");
            }

            DynamicMethod dynamicMethod = CreateDynamicMethod(
                "Dynamic" + methodInfo.Name,
                typeof(object),
                new[] { typeof(object), typeof(object[]) },
                methodInfo.DeclaringType);

            ILGenerator il = dynamicMethod.GetILGenerator();

            ParameterInfo[] ps = methodInfo.GetParameters();

            var paramTypes = new Type[ps.Length];

            for (int i = 0; i < paramTypes.Length; i++)
            {
                if (ps[i].ParameterType.IsByRef)
                {
                    paramTypes[i] = ps[i].ParameterType.GetElementType();
                }
                else
                {
                    paramTypes[i] = ps[i].ParameterType;
                }
            }

            var locals = new LocalBuilder[paramTypes.Length];

            for (int i = 0; i < paramTypes.Length; i++)
            {
                locals[i] = il.DeclareLocal(paramTypes[i], true);
            }

            for (int i = 0; i < paramTypes.Length; i++)
            {
                il.Emit(OpCodes.Ldarg_1);
                il.FastInt(i);
                il.Emit(OpCodes.Ldelem_Ref);
                il.UnboxIfNeeded(paramTypes[i]);
                il.Emit(OpCodes.Stloc, locals[i]);
            }

            if (!methodInfo.IsStatic)
            {
                il.Emit(OpCodes.Ldarg_0);
            }

            for (int i = 0; i < paramTypes.Length; i++)
            {
                if (ps[i].ParameterType.IsByRef)
                {
                    il.Emit(OpCodes.Ldloca_S, locals[i]);
                }
                else
                {
                    il.Emit(OpCodes.Ldloc, locals[i]);
                }
            }

            if (methodInfo.IsStatic)
            {
                il.EmitCall(OpCodes.Call, methodInfo, null);
            }
            else
            {
                il.EmitCall(OpCodes.Callvirt, methodInfo, null);
            }

            if (methodInfo.ReturnType == typeof(void))
            {
                il.Emit(OpCodes.Ldnull);
            }
            else
            {
                il.BoxIfNeeded(methodInfo.ReturnType);
            }

            for (int i = 0; i < paramTypes.Length; i++)
            {
                if (!ps[i].ParameterType.IsByRef)
                {
                    continue;
                }

                il.Emit(OpCodes.Ldarg_1);
                il.FastInt(i);
                il.Emit(OpCodes.Ldloc, locals[i]);
                if (locals[i].LocalType.IsValueType)
                {
                    il.Emit(OpCodes.Box, locals[i].LocalType);
                }
                il.Emit(OpCodes.Stelem_Ref);
            }

            il.Emit(OpCodes.Ret);
            return((LateBoundMethod)dynamicMethod.CreateDelegate(typeof(LateBoundMethod)));;
        }
Exemplo n.º 20
0
        public static LateBoundMethod CreateMethod(MethodInfo methodInfo)
        {
            if (methodInfo == null)
            {
                throw new ArgumentNullException("methodInfo");
            }

#if SILVERLIGHT
            // parameters to execute
            var instanceParameter   = Expression.Parameter(typeof(object), "instance");
            var parametersParameter = Expression.Parameter(typeof(object[]), "parameters");

            // build parameter list
            var parameterExpressions = new List <Expression>();
            var paramInfos           = methodInfo.GetParameters();
            for (int i = 0; i < paramInfos.Length; i++)
            {
                // (Ti)parameters[i]
                var valueObj = Expression.ArrayIndex(parametersParameter, Expression.Constant(i));

                Type parameterType = paramInfos[i].ParameterType;
                if (parameterType.IsByRef)
                {
                    parameterType = parameterType.GetElementType();
                }

                var valueCast = Expression.Convert(valueObj, parameterType);

                parameterExpressions.Add(valueCast);
            }

            // non-instance for static method, or ((TInstance)instance)
            var instanceCast = methodInfo.IsStatic ? null :
                               Expression.Convert(instanceParameter, methodInfo.ReflectedType);

            // static invoke or ((TInstance)instance).Method
            var methodCall = Expression.Call(instanceCast, methodInfo, parameterExpressions);

            // ((TInstance)instance).Method((T0)parameters[0], (T1)parameters[1], ...)
            if (methodCall.Type == typeof(void))
            {
                var lambda = Expression.Lambda <Action <object, object[]> >(
                    methodCall, instanceParameter, parametersParameter);

                Action <object, object[]> execute = lambda.Compile();
                return((instance, parameters) =>
                {
                    execute(instance, parameters);
                    return null;
                });
            }
            else
            {
                var castMethodCall = Expression.Convert(methodCall, typeof(object));
                var lambda         = Expression.Lambda <LateBoundMethod>(
                    castMethodCall, instanceParameter, parametersParameter);

                return(lambda.Compile());
            }
#else
            DynamicMethod dynamicMethod = CreateDynamicMethod(
                "Dynamic" + methodInfo.Name,
                typeof(object),
                new[] { typeof(object), typeof(object[]) },
                methodInfo.DeclaringType);

            ILGenerator     il = dynamicMethod.GetILGenerator();
            ParameterInfo[] ps = methodInfo.GetParameters();

            var paramTypes = new Type[ps.Length];
            for (int i = 0; i < paramTypes.Length; i++)
            {
                if (ps[i].ParameterType.IsByRef)
                {
                    paramTypes[i] = ps[i].ParameterType.GetElementType();
                }
                else
                {
                    paramTypes[i] = ps[i].ParameterType;
                }
            }

            var locals = new LocalBuilder[paramTypes.Length];
            for (int i = 0; i < paramTypes.Length; i++)
            {
                locals[i] = il.DeclareLocal(paramTypes[i], true);
            }

            for (int i = 0; i < paramTypes.Length; i++)
            {
                il.Emit(OpCodes.Ldarg_1);
                il.FastInt(i);
                il.Emit(OpCodes.Ldelem_Ref);
                il.UnboxIfNeeded(paramTypes[i]);
                il.Emit(OpCodes.Stloc, locals[i]);
            }

            if (!methodInfo.IsStatic)
            {
                il.Emit(OpCodes.Ldarg_0);
            }

            for (int i = 0; i < paramTypes.Length; i++)
            {
                if (ps[i].ParameterType.IsByRef)
                {
                    il.Emit(OpCodes.Ldloca_S, locals[i]);
                }
                else
                {
                    il.Emit(OpCodes.Ldloc, locals[i]);
                }
            }

            if (methodInfo.IsStatic)
            {
                il.EmitCall(OpCodes.Call, methodInfo, null);
            }
            else
            {
                il.EmitCall(OpCodes.Callvirt, methodInfo, null);
            }

            if (methodInfo.ReturnType == typeof(void))
            {
                il.Emit(OpCodes.Ldnull);
            }
            else
            {
                il.BoxIfNeeded(methodInfo.ReturnType);
            }

            for (int i = 0; i < paramTypes.Length; i++)
            {
                if (!ps[i].ParameterType.IsByRef)
                {
                    continue;
                }

                il.Emit(OpCodes.Ldarg_1);
                il.FastInt(i);
                il.Emit(OpCodes.Ldloc, locals[i]);
                if (locals[i].LocalType.IsValueType)
                {
                    il.Emit(OpCodes.Box, locals[i].LocalType);
                }
                il.Emit(OpCodes.Stelem_Ref);
            }

            il.Emit(OpCodes.Ret);
            return((LateBoundMethod)dynamicMethod.CreateDelegate(typeof(LateBoundMethod)));;
#endif
        }
Exemplo n.º 21
0
        public static MethodHandler CreateMethodHandler(MethodBase method, bool ctorDoNotCreate = false)
        {
            var         dynam = new DynamicMethod(string.Empty, typeof(object), ManyObjects, Module, true);
            ILGenerator il    = dynam.GetILGenerator();

            ParameterInfo[] args = method.GetParameters();

            Label argsOK = il.DefineLabel();

            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Ldlen);
            il.Emit(OpCodes.Ldc_I4, args.Length);
            il.Emit(OpCodes.Beq, argsOK);

            il.Emit(OpCodes.Newobj, typeof(TargetParameterCountException).GetTypeInfo().GetConstructor(Type.EmptyTypes));
            il.Emit(OpCodes.Throw);

            il.MarkLabel(argsOK);

            if (!method.IsConstructor || ctorDoNotCreate)
            {
                il.PushInstance(method.DeclaringType);
            }

            for (int i = 0; i < args.Length; i++)
            {
                il.Emit(OpCodes.Ldarg_1);
                il.Emit(OpCodes.Ldc_I4, i);
                il.Emit(OpCodes.Ldelem_Ref);
                il.UnboxIfNeeded(args[i].ParameterType);
            }

            if (method.IsConstructor)
            {
                if (ctorDoNotCreate)
                {
                    il.Emit(OpCodes.Call, method as ConstructorInfo);
                    throw new NotImplementedException("This is not yet working ... :'(");
                }
                else
                {
                    il.Emit(OpCodes.Newobj, method as ConstructorInfo);
                }
            }
            else if (method.IsFinal || !method.IsVirtual)
            {
                il.Emit(OpCodes.Call, method as MethodInfo);
            }
            else
            {
                il.Emit(OpCodes.Callvirt, method as MethodInfo);
            }

            Type returnType = method.IsConstructor ? method.DeclaringType : (method as MethodInfo).ReturnType;

            if (returnType != typeof(void))
            {
                il.BoxIfNeeded(returnType);
            }
            else
            {
                il.Emit(OpCodes.Ldnull);
            }

            il.Emit(OpCodes.Ret);

            return((MethodHandler)dynam.CreateDelegate(typeof(MethodHandler)));
        }
Exemplo n.º 22
0
        // Token: 0x06001617 RID: 5655 RVA: 0x00068BC0 File Offset: 0x00066DC0
        private void lmethod_4018(MethodBase arg_0, ILGenerator arg_1, int sayıInt_0)
        {
            ParameterInfo[] parameters = arg_0.GetParameters();
            Label           label      = arg_1.DefineLabel();

            arg_1.Emit(OpCodes.Ldarg, sayıInt_0);
            arg_1.Emit(OpCodes.Ldlen);
            arg_1.Emit(OpCodes.Ldc_I4, parameters.Length);
            arg_1.Emit(OpCodes.Beq, label);
            arg_1.Emit(OpCodes.Newobj, typeof(TargetParameterCountException).GetConstructor(Class_514.EmptyTypes));
            arg_1.Emit(OpCodes.Throw);
            arg_1.MarkLabel(label);
            if (!arg_0.IsConstructor && !arg_0.IsStatic)
            {
                arg_1.PushInstance(arg_0.DeclaringType);
            }
            int num = 0;

            for (int i = 0; i < parameters.Length; i++)
            {
                ParameterInfo parameterInfo = parameters[i];
                Type          type          = parameterInfo.ParameterType;
                if (type.IsByRef)
                {
                    type = type.GetElementType();
                    LocalBuilder local = arg_1.DeclareLocal(type);
                    if (!parameterInfo.IsOut)
                    {
                        arg_1.PushArrayInstance(sayıInt_0, i);
                        if (type.IsValueType)
                        {
                            Label label2 = arg_1.DefineLabel();
                            Label label3 = arg_1.DefineLabel();
                            arg_1.Emit(OpCodes.Brtrue_S, label2);
                            arg_1.Emit(OpCodes.Ldloca_S, local);
                            arg_1.Emit(OpCodes.Initobj, type);
                            arg_1.Emit(OpCodes.Br_S, label3);
                            arg_1.MarkLabel(label2);
                            arg_1.PushArrayInstance(sayıInt_0, i);
                            arg_1.UnboxIfNeeded(type);
                            arg_1.Emit(OpCodes.Stloc, num);
                            arg_1.MarkLabel(label3);
                        }
                        else
                        {
                            arg_1.UnboxIfNeeded(type);
                            arg_1.Emit(OpCodes.Stloc, num);
                        }
                    }
                    arg_1.Emit(OpCodes.Ldloca_S, local);
                    num++;
                }
                else if (type.IsValueType)
                {
                    arg_1.PushArrayInstance(sayıInt_0, i);
                    Label label4 = arg_1.DefineLabel();
                    Label label5 = arg_1.DefineLabel();
                    arg_1.Emit(OpCodes.Brtrue_S, label4);
                    LocalBuilder local2 = arg_1.DeclareLocal(type);
                    arg_1.Emit(OpCodes.Ldloca_S, local2);
                    arg_1.Emit(OpCodes.Initobj, type);
                    arg_1.Emit(OpCodes.Ldloc, num);
                    arg_1.Emit(OpCodes.Br_S, label5);
                    arg_1.MarkLabel(label4);
                    arg_1.PushArrayInstance(sayıInt_0, i);
                    arg_1.UnboxIfNeeded(type);
                    arg_1.MarkLabel(label5);
                    num++;
                }
                else
                {
                    arg_1.PushArrayInstance(sayıInt_0, i);
                    arg_1.UnboxIfNeeded(type);
                }
            }
            if (arg_0.IsConstructor)
            {
                arg_1.Emit(OpCodes.Newobj, (ConstructorInfo)arg_0);
            }
            else
            {
                arg_1.CallMethod((MethodInfo)arg_0);
            }
            Type type2 = arg_0.IsConstructor ? arg_0.DeclaringType : ((MethodInfo)arg_0).ReturnType;

            if (type2 != typeof(void))
            {
                arg_1.BoxIfNeeded(type2);
            }
            else
            {
                arg_1.Emit(OpCodes.Ldnull);
            }
            arg_1.Return();
        }
        private static void GenerateCreateMethodCallIL(MethodBase method, ILGenerator generator, int argsIndex)
        {
            ParameterInfo[] args = method.GetParameters();

            Label argsOk = generator.DefineLabel();

            var exceptionCtor = typeof(TargetParameterCountException).GetConstructor(Type.EmptyTypes);

            Debug.Assert(exceptionCtor != null);

            // throw an error if the number of argument values doesn't match method parameters
            generator.Emit(OpCodes.Ldarg, argsIndex);
            generator.Emit(OpCodes.Ldlen);
            generator.Emit(OpCodes.Ldc_I4, args.Length);
            generator.Emit(OpCodes.Beq, argsOk);
            generator.Emit(OpCodes.Newobj, exceptionCtor);
            generator.Emit(OpCodes.Throw);

            generator.MarkLabel(argsOk);

            if (!method.IsConstructor && !method.IsStatic)
            {
                Debug.Assert(method.DeclaringType != null);

                generator.PushInstance(method.DeclaringType);
            }

            LocalBuilder localConvertible = generator.DeclareLocal(typeof(IConvertible));
            LocalBuilder localObject      = generator.DeclareLocal(typeof(object));

            for (int i = 0; i < args.Length; i++)
            {
                ParameterInfo parameter     = args[i];
                Type?         parameterType = parameter.ParameterType;

                if (parameterType.IsByRef)
                {
                    parameterType = parameterType.GetElementType();
                    Debug.Assert(parameterType != null);

                    LocalBuilder localVariable = generator.DeclareLocal(parameterType);

                    // don't need to set variable for 'out' parameter
                    if (!parameter.IsOut)
                    {
                        generator.PushArrayInstance(argsIndex, i);

                        if (parameterType.IsValueType)
                        {
                            Label skipSettingDefault          = generator.DefineLabel();
                            Label finishedProcessingParameter = generator.DefineLabel();

                            // check if parameter is not null
                            generator.Emit(OpCodes.Brtrue_S, skipSettingDefault);

                            // parameter has no value, initialize to default
                            generator.Emit(OpCodes.Ldloca_S, localVariable);
                            generator.Emit(OpCodes.Initobj, parameterType);
                            generator.Emit(OpCodes.Br_S, finishedProcessingParameter);

                            // parameter has value, get value from array again and unbox and set to variable
                            generator.MarkLabel(skipSettingDefault);
                            generator.PushArrayInstance(argsIndex, i);
                            generator.UnboxIfNeeded(parameterType);
                            generator.Emit(OpCodes.Stloc_S, localVariable);

                            // parameter finished, we out!
                            generator.MarkLabel(finishedProcessingParameter);
                        }
                        else
                        {
                            generator.UnboxIfNeeded(parameterType);
                            generator.Emit(OpCodes.Stloc_S, localVariable);
                        }
                    }

                    generator.Emit(OpCodes.Ldloca_S, localVariable);
                }
                else if (parameterType.IsValueType)
                {
                    generator.PushArrayInstance(argsIndex, i);
                    generator.Emit(OpCodes.Stloc_S, localObject);

                    // have to check that value type parameters aren't null
                    // otherwise they will error when unboxed
                    Label skipSettingDefault          = generator.DefineLabel();
                    Label finishedProcessingParameter = generator.DefineLabel();

                    // check if parameter is not null
                    generator.Emit(OpCodes.Ldloc_S, localObject);
                    generator.Emit(OpCodes.Brtrue_S, skipSettingDefault);

                    // parameter has no value, initialize to default
                    LocalBuilder localVariable = generator.DeclareLocal(parameterType);
                    generator.Emit(OpCodes.Ldloca_S, localVariable);
                    generator.Emit(OpCodes.Initobj, parameterType);
                    generator.Emit(OpCodes.Ldloc_S, localVariable);
                    generator.Emit(OpCodes.Br_S, finishedProcessingParameter);

                    // argument has value, try to convert it to parameter type
                    generator.MarkLabel(skipSettingDefault);

                    if (parameterType.IsPrimitive)
                    {
                        // for primitive types we need to handle type widening (e.g. short -> int)
                        MethodInfo?toParameterTypeMethod = typeof(IConvertible)
                                                           .GetMethod("To" + parameterType.Name, new[] { typeof(IFormatProvider) });

                        if (toParameterTypeMethod != null)
                        {
                            Label skipConvertible = generator.DefineLabel();

                            // check if argument type is an exact match for parameter type
                            // in this case we may use cheap unboxing instead
                            generator.Emit(OpCodes.Ldloc_S, localObject);
                            generator.Emit(OpCodes.Isinst, parameterType);
                            generator.Emit(OpCodes.Brtrue_S, skipConvertible);

                            // types don't match, check if argument implements IConvertible
                            generator.Emit(OpCodes.Ldloc_S, localObject);
                            generator.Emit(OpCodes.Isinst, typeof(IConvertible));
                            generator.Emit(OpCodes.Stloc_S, localConvertible);
                            generator.Emit(OpCodes.Ldloc_S, localConvertible);
                            generator.Emit(OpCodes.Brfalse_S, skipConvertible);

                            // convert argument to parameter type
                            generator.Emit(OpCodes.Ldloc_S, localConvertible);
                            generator.Emit(OpCodes.Ldnull);
                            generator.Emit(OpCodes.Callvirt, toParameterTypeMethod);
                            generator.Emit(OpCodes.Br_S, finishedProcessingParameter);

                            generator.MarkLabel(skipConvertible);
                        }
                    }

                    // we got here because either argument type matches parameter (conversion will succeed),
                    // or argument type doesn't match parameter, but we're out of options (conversion will fail)
                    generator.Emit(OpCodes.Ldloc_S, localObject);

                    generator.UnboxIfNeeded(parameterType);

                    // parameter finished, we out!
                    generator.MarkLabel(finishedProcessingParameter);
                }
                else
                {
                    generator.PushArrayInstance(argsIndex, i);

                    generator.UnboxIfNeeded(parameterType);
                }
            }

            if (method.IsConstructor)
            {
                generator.Emit(OpCodes.Newobj, (ConstructorInfo)method);
            }
            else
            {
                generator.CallMethod((MethodInfo)method);
            }

            Debug.Assert(method.DeclaringType != null);

            Type returnType = method.IsConstructor
                ? method.DeclaringType
                : ((MethodInfo)method).ReturnType;

            if (returnType != typeof(void))
            {
                generator.BoxIfNeeded(returnType);
            }
            else
            {
                generator.Emit(OpCodes.Ldnull);
            }

            generator.Return();
        }
        private void GenerateCreateMethodCallIL(MethodBase method, ILGenerator generator, int argsIndex)
        {
            var args   = method.GetParameters();
            var argsOk = generator.DefineLabel();

            // throw an error if the number of argument values doesn't match method parameters
            generator.Emit(OpCodes.Ldarg, argsIndex);
            generator.Emit(OpCodes.Ldlen);
            generator.Emit(OpCodes.Ldc_I4, args.Length);
            generator.Emit(OpCodes.Beq, argsOk);
            generator.Emit(OpCodes.Newobj, typeof(TargetParameterCountException).GetConstructor(ReflectionUtils.EmptyTypes));
            generator.Emit(OpCodes.Throw);

            generator.MarkLabel(argsOk);

            if (!method.IsConstructor && !method.IsStatic)
            {
                generator.PushInstance(method.DeclaringType);
            }

            var localVariableCount = 0;

            for (var i = 0; i < args.Length; i++)
            {
                var parameter     = args[i];
                var parameterType = parameter.ParameterType;

                if (parameterType.IsByRef)
                {
                    parameterType = parameterType.GetElementType();

                    var localVariable = generator.DeclareLocal(parameterType);

                    // don't need to set variable for 'out' parameter
                    if (!parameter.IsOut)
                    {
                        generator.PushArrayInstance(argsIndex, i);

                        if (parameterType.IsValueType())
                        {
                            var skipSettingDefault          = generator.DefineLabel();
                            var finishedProcessingParameter = generator.DefineLabel();

                            // check if parameter is not null
                            generator.Emit(OpCodes.Brtrue_S, skipSettingDefault);

                            // parameter has no value, initialize to default
                            generator.Emit(OpCodes.Ldloca_S, localVariable);
                            generator.Emit(OpCodes.Initobj, parameterType);
                            generator.Emit(OpCodes.Br_S, finishedProcessingParameter);

                            // parameter has value, get value from array again and unbox and set to variable
                            generator.MarkLabel(skipSettingDefault);
                            generator.PushArrayInstance(argsIndex, i);
                            generator.UnboxIfNeeded(parameterType);
                            generator.Emit(OpCodes.Stloc, localVariableCount);

                            // parameter finished, we out!
                            generator.MarkLabel(finishedProcessingParameter);
                        }
                        else
                        {
                            generator.UnboxIfNeeded(parameterType);
                            generator.Emit(OpCodes.Stloc, localVariableCount);
                        }
                    }

                    generator.Emit(OpCodes.Ldloca_S, localVariable);

                    localVariableCount++;
                }
                else if (parameterType.IsValueType())
                {
                    generator.PushArrayInstance(argsIndex, i);

                    // have to check that value type parameters aren't null
                    // otherwise they will error when unboxed
                    var skipSettingDefault          = generator.DefineLabel();
                    var finishedProcessingParameter = generator.DefineLabel();

                    // check if parameter is not null
                    generator.Emit(OpCodes.Brtrue_S, skipSettingDefault);

                    // parameter has no value, initialize to default
                    var localVariable = generator.DeclareLocal(parameterType);
                    generator.Emit(OpCodes.Ldloca_S, localVariable);
                    generator.Emit(OpCodes.Initobj, parameterType);
                    generator.Emit(OpCodes.Ldloc, localVariableCount);
                    generator.Emit(OpCodes.Br_S, finishedProcessingParameter);

                    // parameter has value, get value from array again and unbox
                    generator.MarkLabel(skipSettingDefault);
                    generator.PushArrayInstance(argsIndex, i);
                    generator.UnboxIfNeeded(parameterType);

                    // parameter finished, we out!
                    generator.MarkLabel(finishedProcessingParameter);
                    localVariableCount++;
                }
                else
                {
                    generator.PushArrayInstance(argsIndex, i);
                    generator.UnboxIfNeeded(parameterType);
                }
            }

            if (method.IsConstructor)
            {
                generator.Emit(OpCodes.Newobj, (ConstructorInfo)method);
            }
            else
            {
                generator.CallMethod((MethodInfo)method);
            }

            var returnType = method.IsConstructor ? method.DeclaringType : ((MethodInfo)method).ReturnType;

            if (returnType != typeof(void))
            {
                generator.BoxIfNeeded(returnType);
            }
            else
            {
                generator.Emit(OpCodes.Ldnull);
            }

            generator.Return();
        }