Esempio n. 1
0
        public object HandleFastCall(IAopProxy target, object executionTarget, int methodIndex, object[] rawParameters, Type returnType)
        {
            CallInfo info = MethodCache.GetCallInfo(methodIndex);

            MethodBase method       = info.Method;
            IList      interceptors = info.Interceptors;

            InterceptedParameter[] parameters = new InterceptedParameter[rawParameters.Length];
            int index = 0;

            foreach (InvocationParameterInfo parameterInfo in info.InvocationParameterInfos)
            {
                InterceptedParameter parameter = new InterceptedParameter(parameterInfo, rawParameters, index);
                parameters[index] = parameter;
                index++;
            }

#if NET2
            MethodInvocation invocation = new MethodInvocation(target, executionTarget, method, method, parameters, rawParameters, returnType, interceptors);
            invocation.Handler = info.Handler;
#else
            MethodInfo       wrapperMethod = (MethodInfo)MethodCache.wrapperMethodLookup[info.MethodId];
            MethodInvocation invocation    = new MethodInvocation(target, executionTarget, method, wrapperMethod, parameters, rawParameters, returnType, interceptors);
#endif

            return(invocation.Proceed());
        }
        private void BuildLookupTables(Type proxyType, IList aspects)
        {
            foreach (string methodId in wrapperMethods)
            {
                MethodInfo wrapperMethod =
                    proxyType.GetMethod(methodId,
                                        BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance |
                                        BindingFlags.DeclaredOnly);
                MethodCache.wrapperMethodLookup[methodId] = wrapperMethod;

                MethodBase baseMethod = (MethodBase)MethodCache.methodLookup[methodId];
                //array to return
                IList methodinterceptors = new ArrayList();
                //fetch all aspects from the type-aspect lookup
                foreach (IGenericAspect aspect in aspects)
                {
                    foreach (IPointcut pointcut in aspect.Pointcuts)
                    {
                        if (pointcut.IsMatch(baseMethod))
                        {
                            foreach (object interceptor in pointcut.Interceptors)
                            {
                                methodinterceptors.Add(interceptor);
                            }
                        }
                    }
                }

                MethodCache.methodInterceptorsLookup[methodId] = methodinterceptors;
                CallInfo callInfo = MethodCache.GetCallInfo(methodId);
                callInfo.Interceptors = methodinterceptors;
            }
        }
Esempio n. 3
0
        public object HandleFastCall(IAopProxy target, object executionTarget, int methodIndex, IList parameters, Type returnType)
        {
            CallInfo info = MethodCache.GetCallInfo(methodIndex);

            MethodBase method       = info.Method;
            IList      interceptors = info.Interceptors;


#if NET2
            MethodInvocation invocation = new MethodInvocation(target, executionTarget, method, method, parameters, returnType, interceptors);
            invocation.Handler = info.Handler;
#else
            MethodInfo       wrapperMethod = (MethodInfo)MethodCache.wrapperMethodLookup[info.MethodId];
            MethodInvocation invocation    = new MethodInvocation(target, executionTarget, method, wrapperMethod, parameters, returnType, interceptors);
#endif

            return(invocation.Proceed());
        }
        private void BuildProxiedMixinMethod(TypeBuilder typeBuilder, MethodInfo method, FieldBuilder field)
        {
            if (method.DeclaringType == typeof(IAopProxy))
            {
                BuildMixinWrapperMethod(method.Name, typeBuilder, method, field);
                return;
            }

            MethodInfo getTypeHandleMethod = typeof(Type).GetMethod("GetTypeFromHandle");

            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;
            }


            string        methodName    = method.DeclaringType.FullName + "." + method.Name;
            MethodBuilder methodBuilder =
                typeBuilder.DefineMethod(methodName, MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.Final | MethodAttributes.NewSlot | MethodAttributes.Virtual,
                                         CallingConventions.Standard, method.ReturnType, parameterTypes);

            typeBuilder.DefineMethodOverride(methodBuilder, method);

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

            ILGenerator il = methodBuilder.GetILGenerator();


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

            //create param object[]
            il.Emit(OpCodes.Ldc_I4_S, parameterInfos.Length);
            il.Emit(OpCodes.Newarr, typeof(object));
            il.Emit(OpCodes.Stloc, paramList);

            int j = 0;

            foreach (ParameterInfo parameter in parameterInfos)
            {
                //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 (parameter.ParameterType.IsByRef)
                {
                    il.Emit(OpCodes.Ldind_Ref);
                    Type t = parameter.ParameterType.GetElementType();
                    if (t.IsValueType)
                    {
                        il.Emit(OpCodes.Box, t);
                    }
                }
                else if (parameter.ParameterType.IsValueType)
                {
                    il.Emit(OpCodes.Box, parameter.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, field); // set the execution target to the mixin instance
            il.Emit(OpCodes.Ldc_I4, methodNr);
            il.Emit(OpCodes.Ldloc, paramList);
            il.Emit(OpCodes.Ldtoken, method.ReturnType);
            il.Emit(OpCodes.Call, getTypeHandleMethod);

            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);


            BuildMixinWrapperMethod(wrapperName, typeBuilder, method, field);
        }
        private void BuildMethod(TypeBuilder typeBuilder, MethodInfo method)
        {
            MethodInfo getTypeHandleMethod = typeof(Type).GetMethod("GetTypeFromHandle");
            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;
            }

            string           methodName = method.Name;
            MethodAttributes modifier   = MethodAttributes.Public;

            if (method.IsFamily)
            {
                modifier = MethodAttributes.Family;
            }

            if (method.IsPublic)
            {
                modifier = MethodAttributes.Public;
            }

            if (method.IsFamilyOrAssembly)
            {
                modifier = MethodAttributes.FamORAssem;
            }

            if (method.IsFamilyAndAssembly)
            {
                modifier = MethodAttributes.FamANDAssem;
            }

            if (method.IsPrivate && methodName.IndexOf(".") >= 0)
            {
                int index = methodName.LastIndexOf(".") + 1;
                methodName = methodName.Substring(index);
                //modifier = MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.Final | MethodAttributes.NewSlot;
                modifier = MethodAttributes.Public;
            }


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

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

#if NET2
            ReApplyAttributes(method);
#endif

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

            ILGenerator il = methodBuilder.GetILGenerator();


            //-----------------------------------
            LocalBuilder paramList = il.DeclareLocal(typeof(object[]));
            //create param object[]
            il.Emit(OpCodes.Ldc_I4_S, parameterInfos.Length);
            il.Emit(OpCodes.Newarr, typeof(object));
            il.Emit(OpCodes.Stloc, paramList);

            int j = 0;

            foreach (ParameterInfo parameter in parameterInfos)
            {
                //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 (parameter.ParameterType.IsByRef)
                {
                    il.Emit(OpCodes.Ldind_Ref);
                    Type t = parameter.ParameterType.GetElementType();
                    if (t.IsValueType)
                    {
                        il.Emit(OpCodes.Box, t);
                    }
                }
                else if (parameter.ParameterType.IsValueType)
                {
                    il.Emit(OpCodes.Box, parameter.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.Ldc_I4, methodNr);
            il.Emit(OpCodes.Ldloc, paramList);
            il.Emit(OpCodes.Ldtoken, method.ReturnType);
            il.Emit(OpCodes.Call, getTypeHandleMethod);



            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);
        }
        private void BuildLookupTables(Type proxyType, IList aspects, IList mixins)
        {
            MethodCache.methodsLookup[proxyType] = wrapperMethods;
            MethodCache.aspectsLookup[proxyType] = aspects;
            MethodCache.mixinsLookup[proxyType]  = mixins;

            foreach (string methodId in wrapperMethods)
            {
                MethodInfo wrapperMethod =
                    proxyType.GetMethod(methodId,
                                        BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance |
                                        BindingFlags.DeclaredOnly);
                MethodCache.wrapperMethodLookup[methodId] = wrapperMethod;

                MethodBase baseMethod = (MethodBase)MethodCache.methodLookup[methodId];
                //array to return
                IList methodinterceptors = new ArrayList();
                //fetch all aspects from the type-aspect lookup
                foreach (IAspect aspect in aspects)
                {
                    IGenericAspect tmpAspect;
                    if (aspect is IGenericAspect)
                    {
                        tmpAspect = (IGenericAspect)aspect;
                    }
                    else
                    {
                        tmpAspect = TypedToGenericConverter.Convert((ITypedAspect)aspect);
                    }

                    foreach (IPointcut pointcut in tmpAspect.Pointcuts)
                    {
                        if (pointcut.IsMatch(baseMethod, proxyType))
                        {
                            foreach (object interceptor in pointcut.Interceptors)
                            {
                                methodinterceptors.Add(interceptor);
                            }
                        }
                    }
                }
                foreach (FixedInterceptorAttribute fixedInterceptorAttribute in baseMethod.GetCustomAttributes(typeof(FixedInterceptorAttribute), true))
                {
                    foreach (Type type in fixedInterceptorAttribute.Types)
                    {
                        methodinterceptors.Add(engine.GetFixedInterceptor(type));
                    }
                }
                foreach (FixedInterceptorAttribute fixedInterceptorAttribute in baseMethod.DeclaringType.GetCustomAttributes(typeof(FixedInterceptorAttribute), true))
                {
                    foreach (Type type in fixedInterceptorAttribute.Types)
                    {
                        methodinterceptors.Add(engine.GetFixedInterceptor(type));
                    }
                }

                CheckRequiredMixins(baseMethod, methodinterceptors);

                MethodCache.methodInterceptorsLookup[methodId] = methodinterceptors;
                CallInfo callInfo = MethodCache.GetCallInfo(methodId);
                callInfo.Interceptors = methodinterceptors;
            }
        }
        private void BuildConstructor(ConstructorInfo constructor, TypeBuilder typeBuilder, IList mixins, bool useCtorState)
        {
            string wrapperName = GetMethodId(constructor.Name);

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

            ParameterInfo[] parameterInfos = constructor.GetParameters();

            //make proxy ctor param count same as superclass
            Type[] parameterTypes = null;

            if (useCtorState)
            {
                //use ctor state
                parameterTypes = new Type[parameterInfos.Length + 1];
                //copy super ctor param types
                for (int i = 0; i <= parameterInfos.Length - 1; i++)
                {
                    parameterTypes[i + 1] = parameterInfos[i].ParameterType;
                }
                parameterTypes[0] = typeof(object);
            }
            else
            {
                //no ctor state
                parameterTypes = new Type[parameterInfos.Length];
                //copy super ctor param types
                for (int i = 0; i <= parameterInfos.Length - 1; i++)
                {
                    parameterTypes[i] = parameterInfos[i].ParameterType;
                }
            }


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

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

#if NET2
            ReApplyAttributes(constructor);
#endif



            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(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.CreateCallInfoForCtor(constructor, parameterInfos, wrapperName);

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


            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.Ldtoken, typeof(void));
            MethodInfo getTypeHandleMethod = typeof(Type).GetMethod("GetTypeFromHandle");
            il.Emit(OpCodes.Call, getTypeHandleMethod);

            il.Emit(OpCodes.Callvirt, handleCallMethod);
            il.Emit(OpCodes.Pop);


            MethodCache.CopyBackRefParams(il, parameterInfos, paramList);

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

            BuildWrapperMethod(wrapperName, typeBuilder, constructor);
        }
        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);
        }
Esempio n. 10
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);
        }