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 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);
        }
示例#3
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);
        }