Ejemplo n.º 1
0
        internal static CallInfo CreateCallInfo(MethodInfo method, ParameterInfo[] parameterInfos, string wrapperName)
        {
            InvocationParameterInfo[] parameters = new InvocationParameterInfo[parameterInfos.Length];
            for (int i = 0; i < parameterInfos.Length; i++)
            {
                ParameterInfo paramInfo = parameterInfos[i];
                Type          paramType = paramInfo.ParameterType;
                if (paramType.IsByRef)
                {
                    paramType = paramType.GetElementType();
                }

                InvocationParameterInfo invocationParamInfo = new InvocationParameterInfo(paramInfo.Name, i, paramType, ParameterType.ByVal);
                parameters[i] = invocationParamInfo;
            }

#if NET2
            return(new CallInfo(wrapperName, method, new ArrayList(), parameters, FastCall.GetMethodInvoker(method)));
#else
            return(new CallInfo(wrapperName, method, new ArrayList(), parameters));
#endif
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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);
        }