private void BuildMethod(string methodName, TypeBuilder typeBuilder, MethodInfo method)
        {
            string wrapperName = GetMethodId(method.Name);
            wrapperMethods.Add(wrapperName);

            MethodCache.methodLookup[wrapperName] = method;

            ParameterInfo[] parameterInfos = method.GetParameters();
            Type[] parameterTypes = new Type[parameterInfos.Length];
            for (int i = 0; i < parameterInfos.Length; i++)
                parameterTypes[i] = parameterInfos[i].ParameterType;


            MethodBuilder methodBuilder =
                typeBuilder.DefineMethod(methodName,
                                         MethodAttributes.NewSlot | MethodAttributes.Private | MethodAttributes.Virtual |
                                         MethodAttributes.Final | MethodAttributes.HideBySig,
                                         CallingConventions.Standard, method.ReturnType, parameterTypes);
            for (int i = 0; i < parameterInfos.Length; i++)
            {
            }
            typeBuilder.DefineMethodOverride(methodBuilder, method);

            ILGenerator il = methodBuilder.GetILGenerator();


            LocalBuilder paramList = il.DeclareLocal(typeof (ArrayList));


            //create param arraylist
            ConstructorInfo arrayListCtor = typeof (ArrayList).GetConstructor(new Type[0]);
            il.Emit(OpCodes.Newobj, arrayListCtor);
            il.Emit(OpCodes.Stloc, paramList);


            int j = 0;
            ConstructorInfo interceptedParameterCtor = typeof (InterceptedParameter).GetConstructors()[0];
            MethodInfo arrayListAddMethod = typeof (ArrayList).GetMethod("Add");
            MethodInfo getTypeMethod = typeof (Type).GetMethod("GetType", new Type[1] {typeof (string)});

            foreach (ParameterInfo parameter in parameterInfos)
            {
                il.Emit(OpCodes.Ldloc, paramList);
                string paramName = parameter.Name;
                if (paramName == null)
                {
                    paramName = "param" + j.ToString();
                }
                il.Emit(OpCodes.Ldstr, paramName);
                il.Emit(OpCodes.Ldc_I4, j);
                il.Emit(OpCodes.Ldstr, parameter.ParameterType.FullName.Replace("&", ""));
                il.Emit(OpCodes.Call, getTypeMethod);


                il.Emit(OpCodes.Ldarg, j + 1);

                if (parameter.ParameterType.FullName.IndexOf("&") >= 0)
                {
                    il.Emit(OpCodes.Ldind_Ref);
                    Type t = Type.GetType(parameter.ParameterType.FullName.Replace("&", ""));
                    if (t.IsValueType)
                        il.Emit(OpCodes.Box, t);
                }
                if (parameter.ParameterType.IsValueType)
                {
                    il.Emit(OpCodes.Box, parameter.ParameterType);
                }
                il.Emit(OpCodes.Ldc_I4, (int) ParameterType.ByVal);
                il.Emit(OpCodes.Newobj, interceptedParameterCtor);
                il.Emit(OpCodes.Callvirt, arrayListAddMethod);
                il.Emit(OpCodes.Pop);


                j++;
            }
#if NET2
            CallInfo callInfo = new CallInfo(wrapperName, method, new ArrayList(), FastCall.GetMethodInvoker(method));
#else
			CallInfo callInfo = new CallInfo(wrapperName,method, new ArrayList());
#endif
            MethodInfo handleCallMethod = typeof(IAopProxy).GetMethod("HandleFastCall");
            int methodNr = MethodCache.AddCallInfo(callInfo, wrapperName);
            //il.Emit(OpCodes.Ldc_I4 ,methodNr);

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, that); // load the execution target
            il.Emit(OpCodes.Ldc_I4, methodNr);
            il.Emit(OpCodes.Ldloc, paramList);
            il.Emit(OpCodes.Ldstr, method.ReturnType.FullName);
            il.Emit(OpCodes.Call, getTypeMethod);
            il.Emit(OpCodes.Callvirt, handleCallMethod);
            if (method.ReturnType == typeof (void))
            {
                il.Emit(OpCodes.Pop);
            }
            else if (method.ReturnType.IsValueType)
            {
                il.Emit(OpCodes.Unbox, method.ReturnType);
                il.Emit(OpCodes.Ldobj, method.ReturnType);
            }


            j = 0;
            MethodInfo get_ItemMethod = typeof (ArrayList).GetMethod("get_Item", new Type[1] {typeof (int)});
            foreach (ParameterInfo parameter in parameterInfos)
            {
                if (parameter.ParameterType.FullName.IndexOf("&") >= 0)
                {
                    il.Emit(OpCodes.Ldarg, j + 1);
                    il.Emit(OpCodes.Ldloc, paramList);
                    il.Emit(OpCodes.Ldc_I4, j);
                    il.Emit(OpCodes.Callvirt, get_ItemMethod);
                    il.Emit(OpCodes.Castclass, typeof (InterceptedParameter));
                    FieldInfo valueField = typeof (InterceptedParameter).GetField("Value");
                    il.Emit(OpCodes.Ldfld, valueField);
                    Type t = Type.GetType(parameter.ParameterType.FullName.Replace("&", ""));
                    if (t.IsValueType)
                    {
                        il.Emit(OpCodes.Unbox, t);
                        il.Emit(OpCodes.Ldobj, t);
                        il.Emit(OpCodes.Stobj, t);
                    }
                    else
                    {
                        il.Emit(OpCodes.Castclass, t);
                        il.Emit(OpCodes.Stind_Ref);
                    }
                }
                j++;
            }


            il.Emit(OpCodes.Ret);

            BuildWrapperMethod(wrapperName, typeBuilder, method);
        }
Example #2
0
 internal static int AddCallInfo(CallInfo callInfo, string methodId)
 {
     int res = 0;
     lock(callInfos.SyncRoot)
     {
         res = callInfos.Add(callInfo);
         callInfoMapper[methodId] = callInfo;
     }
     return res;
 }
        private void BuildConstructor(ConstructorInfo constructor, TypeBuilder typeBuilder, IList mixins)
        {
            string wrapperName = GetMethodId(constructor.Name);

            wrapperMethods.Add(wrapperName);
            MethodCache.methodLookup[wrapperName] = constructor;

            ParameterInfo[] parameters = constructor.GetParameters();

            //make proxy ctor param count same as superclass
            Type[] parameterTypes = new Type[parameters.Length + 1];

            //copy super ctor param types
            for (int i = 0; i <= parameters.Length - 1; i++)
            {
                parameterTypes[i + 1] = parameters[i].ParameterType;
            }
            parameterTypes[0] = typeof(object);


            ConstructorBuilder proxyConstructor =
                typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, parameterTypes);
            ILGenerator il = proxyConstructor.GetILGenerator();

            proxyConstructor.SetCustomAttribute(DebuggerStepThroughBuilder());
            proxyConstructor.SetCustomAttribute(DebuggerHiddenBuilder());

            foreach (Type mixinType in mixins)
            {
                if (mixinType.IsInterface)
                {
                    //ignore interface type mixins , they do not have an impelemntation
                }
                else
                {
                    //				il.EmitWriteLine("setting mixin instance " + mixinType.FullName) ;
                    il.Emit(OpCodes.Ldarg_0);
                    ConstructorInfo mixinCtor = (mixinType).GetConstructor(new Type[] {});
                    il.Emit(OpCodes.Newobj, mixinCtor);
                    il.Emit(OpCodes.Stfld, GetMixinField(mixinType));
                }
            }

            //associate iproxyaware mixins with this instance
            MethodInfo setProxyMethod = typeof(IProxyAware).GetMethod("SetProxy");

            foreach (Type mixinType in mixins)
            {
                if (mixinType.IsInterface)
                {
                    //ignore interface type mixins , they do not have an impelemntation
                }
                else
                {
                    if (typeof(IProxyAware).IsAssignableFrom(mixinType))
                    {
                        il.Emit(OpCodes.Ldarg_0);
                        il.Emit(OpCodes.Ldfld, GetMixinField(mixinType));
                        il.Emit(OpCodes.Ldarg_0);
                        il.Emit(OpCodes.Callvirt, setProxyMethod);
                    }
                }
            }

            //--------------------------
            LocalBuilder paramList = il.DeclareLocal(typeof(ArrayList));


            //create param arraylist
            ConstructorInfo arrayListCtor = typeof(ArrayList).GetConstructor(new Type[0]);

            il.Emit(OpCodes.Newobj, arrayListCtor);
            il.Emit(OpCodes.Stloc, paramList);


            ConstructorInfo interceptedParameterCtor = typeof(InterceptedParameter).GetConstructors()[0];
            MethodInfo      arrayListAddMethod       = typeof(ArrayList).GetMethod("Add");
            MethodInfo      getTypeMethod            = typeof(Type).GetMethod("GetType", new Type[1] {
                typeof(string)
            });

            il.Emit(OpCodes.Ldloc, paramList);

            il.Emit(OpCodes.Ldstr, "_state");
            il.Emit(OpCodes.Ldc_I4, 0);
            il.Emit(OpCodes.Ldstr, typeof(object).FullName);
            il.Emit(OpCodes.Call, getTypeMethod);

            il.Emit(OpCodes.Ldarg, 0 + 1);

            il.Emit(OpCodes.Ldc_I4, (int)ParameterType.ByVal);
            il.Emit(OpCodes.Newobj, interceptedParameterCtor);
            il.Emit(OpCodes.Callvirt, arrayListAddMethod);
            il.Emit(OpCodes.Pop);


            int j = 1;

            foreach (ParameterInfo parameter in parameters)
            {
                il.Emit(OpCodes.Ldloc, paramList);
                string paramName = parameter.Name;
                if (paramName == null)
                {
                    paramName = "param" + j.ToString();
                }
                il.Emit(OpCodes.Ldstr, paramName);
                il.Emit(OpCodes.Ldc_I4, j);
                il.Emit(OpCodes.Ldstr, parameter.ParameterType.FullName.Replace("&", ""));
                il.Emit(OpCodes.Call, getTypeMethod);


                il.Emit(OpCodes.Ldarg, j + 1);

                if (parameter.ParameterType.FullName.IndexOf("&") >= 0)
                {
                    il.Emit(OpCodes.Ldind_Ref);
                    Type t = Type.GetType(parameter.ParameterType.FullName.Replace("&", ""));
                    if (t.IsValueType)
                    {
                        il.Emit(OpCodes.Box, t);
                    }
                }
                if (parameter.ParameterType.IsValueType)
                {
                    il.Emit(OpCodes.Box, parameter.ParameterType);
                }
                il.Emit(OpCodes.Ldc_I4, (int)ParameterType.ByVal);
                il.Emit(OpCodes.Newobj, interceptedParameterCtor);
                il.Emit(OpCodes.Callvirt, arrayListAddMethod);
                il.Emit(OpCodes.Pop);


                j++;
            }

#if NET2
            CallInfo callInfo = new CallInfo(wrapperName, constructor, new ArrayList(), FastCall.GetMethodInvoker(constructor));
#else
            CallInfo callInfo = new CallInfo(wrapperName, constructor, new ArrayList());
#endif

            MethodInfo handleCallMethod = typeof(IAopProxy).GetMethod("HandleFastCall");
            int        methodNr         = MethodCache.AddCallInfo(callInfo, wrapperName);
            //il.Emit(OpCodes.Ldc_I4 ,methodNr);


            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldc_I4, methodNr);
            il.Emit(OpCodes.Ldloc, paramList);
            il.Emit(OpCodes.Ldstr, typeof(void).FullName);
            il.Emit(OpCodes.Call, getTypeMethod);
            il.Emit(OpCodes.Callvirt, handleCallMethod);
            il.Emit(OpCodes.Pop);


            j = 1;
            MethodInfo get_ItemMethod = typeof(ArrayList).GetMethod("get_Item", new Type[1] {
                typeof(int)
            });
            foreach (ParameterInfo parameter in parameters)
            {
                if (parameter.ParameterType.FullName.IndexOf("&") >= 0)
                {
                    il.Emit(OpCodes.Ldarg, j + 1);
                    il.Emit(OpCodes.Ldloc, paramList);
                    il.Emit(OpCodes.Ldc_I4, j);
                    il.Emit(OpCodes.Callvirt, get_ItemMethod);
                    il.Emit(OpCodes.Castclass, typeof(InterceptedParameter));
                    FieldInfo valueField = typeof(InterceptedParameter).GetField("Value");
                    il.Emit(OpCodes.Ldfld, valueField);
                    Type t = Type.GetType(parameter.ParameterType.FullName.Replace("&", ""));
                    if (t.IsValueType)
                    {
                        il.Emit(OpCodes.Unbox, t);
                        il.Emit(OpCodes.Ldobj, t);
                        il.Emit(OpCodes.Stobj, t);
                    }
                    else
                    {
                        il.Emit(OpCodes.Castclass, t);
                        il.Emit(OpCodes.Stind_Ref);
                    }
                }
                j++;
            }

            il.Emit(OpCodes.Ret);
            //--------------

            BuildWrapperMethod(wrapperName, typeBuilder, constructor);
        }
        private void BuildMixinMethod(TypeBuilder typeBuilder, MethodInfo method, FieldBuilder field)
        {
            if (method.DeclaringType == typeof(IAopProxy))
            {
                BuildMixinWrapperMethod(method.Name, typeBuilder, method, field);
                return;
            }


            string wrapperName = GetMethodId(method.Name);

            wrapperMethods.Add(wrapperName);
            MethodCache.methodLookup[wrapperName] = method;
            //		MethodCache.wrapperMethodLookup[wrapperName] = method;

            ParameterInfo[] parameterInfos = method.GetParameters();
            Type[]          parameterTypes = new Type[parameterInfos.Length];
            for (int i = 0; i < parameterInfos.Length; i++)
            {
                parameterTypes[i] = parameterInfos[i].ParameterType;
            }

            MethodBuilder methodBuilder =
                typeBuilder.DefineMethod(method.Name, MethodAttributes.Public | MethodAttributes.Virtual,
                                         CallingConventions.Standard, method.ReturnType, parameterTypes);

            methodBuilder.SetCustomAttribute(DebuggerStepThroughBuilder());
            methodBuilder.SetCustomAttribute(DebuggerHiddenBuilder());

            for (int i = 0; i < parameterInfos.Length; i++)
            {
            }

            ILGenerator il = methodBuilder.GetILGenerator();

            LocalBuilder paramList = il.DeclareLocal(typeof(ArrayList));


            //create param arraylist
            ConstructorInfo arrayListCtor = typeof(ArrayList).GetConstructor(new Type[0]);

            il.Emit(OpCodes.Newobj, arrayListCtor);
            il.Emit(OpCodes.Stloc, paramList);


            int             j = 0;
            ConstructorInfo interceptedParameterCtor = typeof(InterceptedParameter).GetConstructors()[0];
            MethodInfo      arrayListAddMethod       = typeof(ArrayList).GetMethod("Add");
            MethodInfo      getTypeMethod            = typeof(Type).GetMethod("GetType", new Type[1] {
                typeof(string)
            });

            foreach (ParameterInfo parameter in parameterInfos)
            {
                il.Emit(OpCodes.Ldloc, paramList);
                string paramName = parameter.Name;
                if (paramName == null)
                {
                    paramName = "param" + j.ToString();
                }
                il.Emit(OpCodes.Ldstr, paramName);
                il.Emit(OpCodes.Ldc_I4, j);
                il.Emit(OpCodes.Ldstr, parameter.ParameterType.FullName.Replace("&", ""));
                il.Emit(OpCodes.Call, getTypeMethod);


                il.Emit(OpCodes.Ldarg, j + 1);

                if (parameter.ParameterType.FullName.IndexOf("&") >= 0)
                {
                    il.Emit(OpCodes.Ldind_Ref);
                    Type t = Type.GetType(parameter.ParameterType.FullName.Replace("&", ""));
                    if (t.IsValueType)
                    {
                        il.Emit(OpCodes.Box, t);
                    }
                }
                if (parameter.ParameterType.IsValueType)
                {
                    il.Emit(OpCodes.Box, parameter.ParameterType);
                }
                il.Emit(OpCodes.Ldc_I4, (int)ParameterType.ByVal);
                il.Emit(OpCodes.Newobj, interceptedParameterCtor);
                il.Emit(OpCodes.Callvirt, arrayListAddMethod);
                il.Emit(OpCodes.Pop);


                j++;
            }


#if NET2
            CallInfo callInfo = new CallInfo(wrapperName, method, new ArrayList(), FastCall.GetMethodInvoker(method));
#else
            CallInfo callInfo = new CallInfo(wrapperName, method, new ArrayList());
#endif

            MethodInfo handleCallMethod = typeof(IAopProxy).GetMethod("HandleFastCall");
            int        methodNr         = MethodCache.AddCallInfo(callInfo, wrapperName);
            //il.Emit(OpCodes.Ldc_I4 ,methodNr);

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, field); // set the execution target to the mixin instance
            il.Emit(OpCodes.Ldc_I4, methodNr);
            il.Emit(OpCodes.Ldloc, paramList);
            il.Emit(OpCodes.Ldstr, method.ReturnType.FullName);
            il.Emit(OpCodes.Call, getTypeMethod);
            il.Emit(OpCodes.Callvirt, handleCallMethod);
            if (method.ReturnType == typeof(void))
            {
                il.Emit(OpCodes.Pop);
            }
            else if (method.ReturnType.IsValueType)
            {
                il.Emit(OpCodes.Unbox, method.ReturnType);
                il.Emit(OpCodes.Ldobj, method.ReturnType);
            }


            j = 0;
            MethodInfo get_ItemMethod = typeof(ArrayList).GetMethod("get_Item", new Type[1] {
                typeof(int)
            });
            foreach (ParameterInfo parameter in parameterInfos)
            {
                if (parameter.ParameterType.FullName.IndexOf("&") >= 0)
                {
                    il.Emit(OpCodes.Ldarg, j + 1);
                    il.Emit(OpCodes.Ldloc, paramList);
                    il.Emit(OpCodes.Ldc_I4, j);
                    il.Emit(OpCodes.Callvirt, get_ItemMethod);
                    il.Emit(OpCodes.Castclass, typeof(InterceptedParameter));
                    FieldInfo valueField = typeof(InterceptedParameter).GetField("Value");
                    il.Emit(OpCodes.Ldfld, valueField);
                    Type t = Type.GetType(parameter.ParameterType.FullName.Replace("&", ""));
                    if (t.IsValueType)
                    {
                        il.Emit(OpCodes.Unbox, t);
                        il.Emit(OpCodes.Ldobj, t);
                        il.Emit(OpCodes.Stobj, t);
                    }
                    else
                    {
                        il.Emit(OpCodes.Castclass, t);
                        il.Emit(OpCodes.Stind_Ref);
                    }
                }
                j++;
            }


            il.Emit(OpCodes.Ret);


            BuildMixinWrapperMethod(wrapperName, typeBuilder, method, field);
        }
        private void BuildConstructor(ConstructorInfo constructor, TypeBuilder typeBuilder, IList mixins)
        {
            string wrapperName = GetMethodId(constructor.Name);
            wrapperMethods.Add(wrapperName);
            MethodCache.methodLookup[wrapperName] = constructor;

            ParameterInfo[] parameters = constructor.GetParameters();

            //make proxy ctor param count same as superclass
            Type[] parameterTypes = new Type[parameters.Length + 1];

            //copy super ctor param types
            for (int i = 0; i <= parameters.Length - 1; i++)
            {
                parameterTypes[i + 1] = parameters[i].ParameterType;
            }
            parameterTypes[0] = typeof (object);


            ConstructorBuilder proxyConstructor =
                typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, parameterTypes);
            ILGenerator il = proxyConstructor.GetILGenerator();

            proxyConstructor.SetCustomAttribute(DebuggerStepThroughBuilder());
            proxyConstructor.SetCustomAttribute(DebuggerHiddenBuilder());

            foreach (Type mixinType in mixins)
            {
                if (mixinType.IsInterface)
                {
                    //ignore interface type mixins , they do not have an impelemntation
                }
                else
                {
                    //				il.EmitWriteLine("setting mixin instance " + mixinType.FullName) ;
                    il.Emit(OpCodes.Ldarg_0);
                    ConstructorInfo mixinCtor = (mixinType).GetConstructor(new Type[] {});
                    il.Emit(OpCodes.Newobj, mixinCtor);
                    il.Emit(OpCodes.Stfld, GetMixinField(mixinType));
                }
            }

            //associate iproxyaware mixins with this instance
            MethodInfo setProxyMethod = typeof (IProxyAware).GetMethod("SetProxy");
            foreach (Type mixinType in mixins)
            {
                if (mixinType.IsInterface)
                {
                    //ignore interface type mixins , they do not have an impelemntation
                }
                else
                {
                    if (typeof (IProxyAware).IsAssignableFrom(mixinType))
                    {
                        il.Emit(OpCodes.Ldarg_0);
                        il.Emit(OpCodes.Ldfld, GetMixinField(mixinType));
                        il.Emit(OpCodes.Ldarg_0);
                        il.Emit(OpCodes.Callvirt, setProxyMethod);
                    }
                }
            }

            //--------------------------
            LocalBuilder paramList = il.DeclareLocal(typeof (ArrayList));


            //create param arraylist
            ConstructorInfo arrayListCtor = typeof (ArrayList).GetConstructor(new Type[0]);
            il.Emit(OpCodes.Newobj, arrayListCtor);
            il.Emit(OpCodes.Stloc, paramList);


            ConstructorInfo interceptedParameterCtor = typeof (InterceptedParameter).GetConstructors()[0];
            MethodInfo arrayListAddMethod = typeof (ArrayList).GetMethod("Add");
            MethodInfo getTypeMethod = typeof (Type).GetMethod("GetType", new Type[1] {typeof (string)});

            il.Emit(OpCodes.Ldloc, paramList);

            il.Emit(OpCodes.Ldstr, "_state");
            il.Emit(OpCodes.Ldc_I4, 0);
            il.Emit(OpCodes.Ldstr, typeof (object).FullName);
            il.Emit(OpCodes.Call, getTypeMethod);

            il.Emit(OpCodes.Ldarg, 0 + 1);

            il.Emit(OpCodes.Ldc_I4, (int) ParameterType.ByVal);
            il.Emit(OpCodes.Newobj, interceptedParameterCtor);
            il.Emit(OpCodes.Callvirt, arrayListAddMethod);
            il.Emit(OpCodes.Pop);


            int j = 1;
            foreach (ParameterInfo parameter in parameters)
            {
                il.Emit(OpCodes.Ldloc, paramList);
                string paramName = parameter.Name;
                if (paramName == null)
                {
                    paramName = "param" + j.ToString();
                }
                il.Emit(OpCodes.Ldstr, paramName);
                il.Emit(OpCodes.Ldc_I4, j);
                il.Emit(OpCodes.Ldstr, parameter.ParameterType.FullName.Replace("&", ""));
                il.Emit(OpCodes.Call, getTypeMethod);


                il.Emit(OpCodes.Ldarg, j + 1);

                if (parameter.ParameterType.FullName.IndexOf("&") >= 0)
                {
                    il.Emit(OpCodes.Ldind_Ref);
                    Type t = Type.GetType(parameter.ParameterType.FullName.Replace("&", ""));
                    if (t.IsValueType)
                        il.Emit(OpCodes.Box, t);
                }
                if (parameter.ParameterType.IsValueType)
                {
                    il.Emit(OpCodes.Box, parameter.ParameterType);
                }
                il.Emit(OpCodes.Ldc_I4, (int) ParameterType.ByVal);
                il.Emit(OpCodes.Newobj, interceptedParameterCtor);
                il.Emit(OpCodes.Callvirt, arrayListAddMethod);
                il.Emit(OpCodes.Pop);


                j++;
            }

#if NET2
            CallInfo callInfo = new CallInfo(wrapperName,constructor, new ArrayList(), FastCall.GetMethodInvoker(constructor));
#else
			CallInfo callInfo = new CallInfo(wrapperName,constructor, new ArrayList());
#endif

            MethodInfo handleCallMethod = typeof(IAopProxy).GetMethod("HandleFastCall");
            int methodNr = MethodCache.AddCallInfo(callInfo, wrapperName);
            //il.Emit(OpCodes.Ldc_I4 ,methodNr);


            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldc_I4, methodNr);
            il.Emit(OpCodes.Ldloc, paramList);
            il.Emit(OpCodes.Ldstr, typeof (void).FullName);
            il.Emit(OpCodes.Call, getTypeMethod);
            il.Emit(OpCodes.Callvirt, handleCallMethod);
            il.Emit(OpCodes.Pop);


            j = 1;
            MethodInfo get_ItemMethod = typeof (ArrayList).GetMethod("get_Item", new Type[1] {typeof (int)});
            foreach (ParameterInfo parameter in parameters)
            {
                if (parameter.ParameterType.FullName.IndexOf("&") >= 0)
                {
                    il.Emit(OpCodes.Ldarg, j + 1);
                    il.Emit(OpCodes.Ldloc, paramList);
                    il.Emit(OpCodes.Ldc_I4, j);
                    il.Emit(OpCodes.Callvirt, get_ItemMethod);
                    il.Emit(OpCodes.Castclass, typeof (InterceptedParameter));
                    FieldInfo valueField = typeof (InterceptedParameter).GetField("Value");
                    il.Emit(OpCodes.Ldfld, valueField);
                    Type t = Type.GetType(parameter.ParameterType.FullName.Replace("&", ""));
                    if (t.IsValueType)
                    {
                        il.Emit(OpCodes.Unbox, t);
                        il.Emit(OpCodes.Ldobj, t);
                        il.Emit(OpCodes.Stobj, t);
                    }
                    else
                    {
                        il.Emit(OpCodes.Castclass, t);
                        il.Emit(OpCodes.Stind_Ref);
                    }
                }
                j++;
            }

            il.Emit(OpCodes.Ret);
            //--------------

            BuildWrapperMethod(wrapperName, typeBuilder, constructor);
        }
Example #6
0
        private void BuildMethod(string methodName, TypeBuilder typeBuilder, MethodInfo method)
        {
            string wrapperName = GetMethodId(method.Name);

            wrapperMethods.Add(wrapperName);

            MethodCache.methodLookup[wrapperName] = method;

            ParameterInfo[] parameterInfos = method.GetParameters();
            Type[]          parameterTypes = new Type[parameterInfos.Length];
            for (int i = 0; i < parameterInfos.Length; i++)
            {
                parameterTypes[i] = parameterInfos[i].ParameterType;
            }


            MethodBuilder methodBuilder =
                typeBuilder.DefineMethod(methodName,
                                         MethodAttributes.NewSlot | MethodAttributes.Private | MethodAttributes.Virtual |
                                         MethodAttributes.Final | MethodAttributes.HideBySig,
                                         CallingConventions.Standard, method.ReturnType, parameterTypes);

            for (int i = 0; i < parameterInfos.Length; i++)
            {
            }
            typeBuilder.DefineMethodOverride(methodBuilder, method);

            ILGenerator il = methodBuilder.GetILGenerator();

            //--------------------------
            LocalBuilder paramList = il.DeclareLocal(typeof(object[]));

            //create param object[]
            il.Emit(OpCodes.Ldc_I4_S, parameterInfos.Length + 1);
            il.Emit(OpCodes.Newarr, typeof(object));
            il.Emit(OpCodes.Stloc, paramList);
            //-----------------------------------
            int j = 0;

            foreach (Type parameterType in parameterTypes)
            {
                //load arr
                il.Emit(OpCodes.Ldloc, paramList);
                //load index
                il.Emit(OpCodes.Ldc_I4, j);
                //load arg
                il.Emit(OpCodes.Ldarg, j + 1);
                //box if needed
                if (parameterType.IsByRef)
                {
                    il.Emit(OpCodes.Ldind_Ref);
                    Type t = parameterType.GetElementType();
                    if (t.IsValueType)
                    {
                        il.Emit(OpCodes.Box, t);
                    }
                }
                else if (parameterType.IsValueType)
                {
                    il.Emit(OpCodes.Box, parameterType);
                }
                il.Emit(OpCodes.Stelem_Ref);
                j++;
            }
            //-----------------------------------

            CallInfo callInfo = MethodCache.CreateCallInfo(method, parameterInfos, wrapperName);

            MethodInfo handleCallMethod = typeof(IAopProxy).GetMethod("HandleFastCall");
            int        methodNr         = MethodCache.AddCallInfo(callInfo, wrapperName);

            //il.Emit(OpCodes.Ldc_I4 ,methodNr);

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, that); // load the execution target
            il.Emit(OpCodes.Ldc_I4, methodNr);
            il.Emit(OpCodes.Ldloc, paramList);
            il.Emit(OpCodes.Ldstr, method.ReturnType.FullName);
            MethodInfo getTypeMethod = typeof(Type).GetMethod("GetType", new Type[1] {
                typeof(string)
            });

            il.Emit(OpCodes.Call, getTypeMethod);
            il.Emit(OpCodes.Callvirt, handleCallMethod);
            if (method.ReturnType == typeof(void))
            {
                il.Emit(OpCodes.Pop);
            }
            else if (method.ReturnType.IsValueType)
            {
                il.Emit(OpCodes.Unbox, method.ReturnType);
                il.Emit(OpCodes.Ldobj, method.ReturnType);
            }


            MethodCache.CopyBackRefParams(il, parameterInfos, paramList);


            il.Emit(OpCodes.Ret);

            BuildWrapperMethod(wrapperName, typeBuilder, method);
        }