DefineMethodOverride() public method

public DefineMethodOverride ( System methodInfoBody, System methodInfoDeclaration ) : void
methodInfoBody System
methodInfoDeclaration System
return void
		public void ImplementProxy(TypeBuilder typeBuilder)
		{
			// Implement the IProxy interface
			typeBuilder.AddInterfaceImplementation(typeof (IProxy));

			field = typeBuilder.DefineField("__interceptor", typeof (IInterceptor), FieldAttributes.Private);

			// Implement the getter
			MethodBuilder getterMethod = typeBuilder.DefineMethod("get_Interceptor", InterceptorMethodsAttributes, CallingConventions.HasThis, typeof(IInterceptor), new System.Type[0]);
			getterMethod.SetImplementationFlags(MethodImplAttributes.Managed | MethodImplAttributes.IL);

			ILGenerator IL = getterMethod.GetILGenerator();

			// This is equivalent to:
			// get { return __interceptor;
			IL.Emit(OpCodes.Ldarg_0);
			IL.Emit(OpCodes.Ldfld, field);
			IL.Emit(OpCodes.Ret);

			// Implement the setter
			MethodBuilder setterMethod = typeBuilder.DefineMethod("set_Interceptor", InterceptorMethodsAttributes, CallingConventions.HasThis, typeof (void), new[] {typeof (IInterceptor)});

			setterMethod.SetImplementationFlags(MethodImplAttributes.Managed | MethodImplAttributes.IL);
			IL = setterMethod.GetILGenerator();
			IL.Emit(OpCodes.Ldarg_0);
			IL.Emit(OpCodes.Ldarg_1);
			IL.Emit(OpCodes.Stfld, field);
			IL.Emit(OpCodes.Ret);

			MethodInfo originalSetter = typeof (IProxy).GetMethod("set_Interceptor");
			MethodInfo originalGetter = typeof (IProxy).GetMethod("get_Interceptor");

			typeBuilder.DefineMethodOverride(setterMethod, originalSetter);
			typeBuilder.DefineMethodOverride(getterMethod, originalGetter);
		}
		public void ImplementProxy(TypeBuilder typeBuilder)
		{
			typeBuilder.AddInterfaceImplementation(typeof (IProxy));
			InterceptorField = typeBuilder
				.DefineField("__interceptor",
							 typeof (Proxy.DynamicProxy.IInterceptor),
							 FieldAttributes.Private);
			var getterMethod = typeBuilder
				.DefineMethod("get_Interceptor",
							  InterceptorMethodsAttributes,
							  CallingConventions.HasThis,
							  typeof (Proxy.DynamicProxy.IInterceptor),
							  new System.Type[0]);
			getterMethod.SetImplementationFlags(MethodImplAttributes.IL);
			var il = getterMethod.GetILGenerator();
			il.Emit(OpCodes.Ldarg_0);
			il.Emit(OpCodes.Ldfld, InterceptorField);
			il.Emit(OpCodes.Ret);
			var setterMethod = typeBuilder
				.DefineMethod("set_Interceptor",
							  InterceptorMethodsAttributes,
							  CallingConventions.HasThis,
							  typeof (void),
							  new[] {typeof (Proxy.DynamicProxy.IInterceptor)});
			setterMethod.SetImplementationFlags(MethodImplAttributes.IL);
			il = setterMethod.GetILGenerator();
			il.Emit(OpCodes.Ldarg_0);
			il.Emit(OpCodes.Ldarg_1);
			il.Emit(OpCodes.Stfld, InterceptorField);
			il.Emit(OpCodes.Ret);
			var originalSetter = typeof (IProxy).GetMethod("set_Interceptor");
			var originalGetter = typeof (IProxy).GetMethod("get_Interceptor");
			typeBuilder.DefineMethodOverride(setterMethod, originalSetter);
			typeBuilder.DefineMethodOverride(getterMethod, originalGetter);
		}
Example #3
0
        /// <summary>
        /// Create property with explicit implementation of getter and setter, with no method defined.
        /// </summary>
        private PropertyDefinition AddProperty(TypeDefinition declaringType,
                                               string name,
                                               TypeReference propertyType,
                                               string explicitPrefix,
                                               PropertyInfo overridedProp)
        {
            var proxyPropDef = declaringType.DefineProperty(explicitPrefix + name,
                                                            PropertyAttributes.None | PropertyAttributes.SpecialName,
                                                            propertyType,
                                                            null);
            const MethodAttributes methodAttributes = MethodAttributes.Private
                                                      | MethodAttributes.HideBySig
                                                      | MethodAttributes.NewSlot
                                                      | MethodAttributes.Virtual
                                                      | MethodAttributes.Final
                                                      | MethodAttributes.SpecialName;

            var overridedGetMethod = overridedProp.GetGetMethod();

            if (overridedGetMethod != null)
            {
                var proxyPropGetter = declaringType.DefineMethod(
                    $"{explicitPrefix}get_{name}",
                    methodAttributes,
                    propertyType,
                    Type.EmptyTypes);
                declaringType.DefineMethodOverride(proxyPropGetter, overridedGetMethod);

                proxyPropDef.SetGetMethod(proxyPropGetter);
            }

            var overridedSetMethod = overridedProp.GetSetMethod();

            if (overridedSetMethod != null)
            {
                var proxyPropSetter = declaringType.DefineMethod(
                    $"{explicitPrefix}set_{name}",
                    methodAttributes,
                    null,
                    new[] { propertyType });

                proxyPropSetter.DefineParameter(0, ParameterAttributes.None, "value");
                declaringType.DefineMethodOverride(proxyPropSetter, overridedSetMethod);
                proxyPropDef.SetSetMethod(proxyPropSetter);
            }

            return(proxyPropDef);
        }
        /// <summary>
        /// Creates a <see cref="MethodBuilder"/> and implements a default wrapper.
        /// </summary>
        /// <param name="owner">The type that will own this method.</param>
        /// <param name="interfaceType">Type of interface implemented by the <paramref name="owner"/>.</param>
        /// <param name="overrideMethod">Method to override.</param>
        /// <param name="fieldBuilders">Fields specified by the <see paramref="owner"/>.</param>
        /// <returns>MethodBuilder with an already implemented wrapper.</returns>
        public MethodBuilder GenerateInvocation(TypeBuilder owner, Type interfaceType, MethodInfo overrideMethod, IEnumerable<FieldBuilder> fieldBuilders)
        {
            var result = owner.DefineMethod
                    (
                        overrideMethod.Name,
                        MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.Final |
                        MethodAttributes.HideBySig | MethodAttributes.NewSlot,
                        overrideMethod.ReturnType,
                        overrideMethod.GetParameters().OrderBy(p => p.Position).Select(t => t.ParameterType).ToArray()
                    );

            result.SetImplementationFlags(MethodImplAttributes.AggressiveInlining);

            var generator = result.GetILGenerator();
            var fieldName = LibraryInterfaceMapper.GetFieldNameForMethodInfo(overrideMethod);
            var field = fieldBuilders.First(f => f.Name == fieldName);
            var parameters = overrideMethod.GetParameters();
            OnInvokeBegin(owner, interfaceType, generator, overrideMethod);
            generator.Emit(OpCodes.Ldarg_0); //  this
            generator.Emit(OpCodes.Ldfld, field); // MethodNameProc _glMethodName. Initialized by constructor.
            foreach (var item in parameters.Where(p => !p.IsRetval).Select((p, i) => new { Type = p, Index = i }))
            {
                generator.Emit(OpCodes.Ldarg, item.Index + 1);
            }

            generator.EmitCall(OpCodes.Callvirt, field.FieldType.GetMethod("Invoke"), null);

            OnInvokeEnd(owner, interfaceType, generator, overrideMethod);

            generator.Emit(OpCodes.Ret);

            owner.DefineMethodOverride(result, overrideMethod);

            return result;
        }
        private static void ImplementAddInterceptionBehavior(TypeBuilder typeBuilder, FieldInfo proxyInterceptorPipelineField)
        {
            // Declaring method builder
            // Method attributes
            const MethodAttributes MethodAttributes = MethodAttributes.Private | MethodAttributes.Virtual
                | MethodAttributes.Final | MethodAttributes.HideBySig
                    | MethodAttributes.NewSlot;

            MethodBuilder methodBuilder =
                typeBuilder.DefineMethod(
                    "Microsoft.Practices.Unity.InterceptionExtension.IInterceptingProxy.AddInterceptionBehavior",
                    MethodAttributes);

            // Setting return type
            methodBuilder.SetReturnType(typeof(void));
            // Adding parameters
            methodBuilder.SetParameters(typeof(IInterceptionBehavior));
            // Parameter method
            methodBuilder.DefineParameter(1, ParameterAttributes.None, "interceptor");

            ILGenerator il = methodBuilder.GetILGenerator();
            // Writing body
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, proxyInterceptorPipelineField);
            il.Emit(OpCodes.Ldarg_1);
            il.EmitCall(OpCodes.Callvirt, InterceptionBehaviorPipelineMethods.Add, null);
            il.Emit(OpCodes.Ret);
            typeBuilder.DefineMethodOverride(methodBuilder, IInterceptingProxyMethods.AddInterceptionBehavior);
        }
        public override MethodBuilder Generate(TypeBuilder typeBuilder)
        {
            var methodBuilder = GenerateMethod(typeBuilder);

            typeBuilder.DefineMethodOverride(methodBuilder, _methodMetadata.Method);

            return methodBuilder;
        }
Example #7
0
        public override void CreateDeclarations(System.Reflection.Emit.TypeBuilder typeBuilder)
        {
            this.BaseMethod = typeBuilder.BaseType.GetMethods().OfType <MethodInfo>()
                              .Where(p => p.Name == this.MemberName)
                              .FirstOrDefault(p =>
                                              p.ReturnType == this.MemberType &&
                                              p.GetParameters().Length == this.ArgumentTypes.Count &&
                                              p.GetParameters().Select((x, i) => new { Index = i, Type = x.ParameterType }).All(x => this.ArgumentTypes[x.Index] == x.Type));

            if (BaseMethod != null && !BaseMethod.IsVirtual)
            {
                throw new MemberCreationException(this.MemberName, "The method has to be declared virtual on the base class.");
            }
            else if (BaseMethod != null)
            {
                IsOverride = true;
            }

            MethodAttributes methodAttributes = MethodAttributes.Public;

            if (IsProtected)
            {
                methodAttributes = MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.SpecialName | MethodAttributes.HideBySig;
            }
            else
            {
                methodAttributes = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.SpecialName | MethodAttributes.HideBySig;
            }

            var implementationAttributes = MethodAttributes.Private | MethodAttributes.SpecialName | MethodAttributes.HideBySig;

            Method = typeBuilder.DefineMethod(this.MemberName, methodAttributes);
            ImplementationMethod = typeBuilder.DefineMethod(string.Format("{0}_Implementation", this.MemberName), implementationAttributes);

            var genericParameters = GetGenericArguments().ToList();

            if (genericParameters.Any())
            {
                this._genericParameters.AddRange(Method.DefineGenericParameters(genericParameters.ToArray()));
                this._genericImplementationParameters.AddRange(ImplementationMethod.DefineGenericParameters(genericParameters.ToArray()));
            }

            this.Method.SetReturnType(TypeLookup(this.MemberType));
            this.Method.SetParameters(TypeLookup(this.ArgumentTypes).ToArray());

            this.ImplementationMethod.SetReturnType(ImplementationTypeLookup(this.MemberType));
            this.ImplementationMethod.SetParameters(ImplementationTypeLookup(this.ArgumentTypes).ToArray());

            if (IsOverride)
            {
                typeBuilder.DefineMethodOverride(this.Method, this.BaseMethod);
            }
        }
        private void EmitOverride_GetCacheType(TypeBuilder typeBuilder, string overrideName, FieldBuilder fb_cacheType)
        {
            MethodBuilder mb = typeBuilder.DefineMethod(overrideName, MethodAttributes.Family | MethodAttributes.Virtual);
            mb.SetReturnType(typeof(Type));
            typeBuilder.DefineMethodOverride(mb,
                typeof(ReadMapper).GetMethod(overrideName, BindingFlags.NonPublic | BindingFlags.Instance));

            ILGenerator il = mb.GetILGenerator();
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, fb_cacheType);
            il.Emit(OpCodes.Ret);
        }
 public void ImplementProxy(TypeBuilder b)
 {
     var dynamicProxyType = typeof(IDynamicProxy);
     b.AddInterfaceImplementation(dynamicProxyType);
     _fieldBuilder = b.DefineField("__interceptor", typeof(IMethodInterceptor), FieldAttributes.Private);
     const MethodAttributes attributes = MethodAttributes.SpecialName | MethodAttributes.VtableLayoutMask | MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.Public;
     var getMethodBuilder = b.DefineMethod("get_Interceptor", attributes, CallingConventions.HasThis, typeof(IMethodInterceptor), new Type[0]);
     getMethodBuilder.SetImplementationFlags(MethodImplAttributes.IL);
     var w = getMethodBuilder.GetILGenerator();
     w.Emit(OpCodes.Ldarg_0);
     w.Emit(OpCodes.Ldfld, _fieldBuilder);
     w.Emit(OpCodes.Ret);
     var setMethodBuilder = b.DefineMethod("set_Interceptor", attributes, CallingConventions.HasThis, typeof(void), new Type[] { typeof(IMethodInterceptor) });
     setMethodBuilder.SetImplementationFlags(MethodImplAttributes.IL);
     w = setMethodBuilder.GetILGenerator();
     w.Emit(OpCodes.Ldarg_0);
     w.Emit(OpCodes.Ldarg_1);
     w.Emit(OpCodes.Stfld, _fieldBuilder);
     w.Emit(OpCodes.Ret);
     b.DefineMethodOverride(setMethodBuilder, dynamicProxyType.GetMethod("set_Interceptor"));
     b.DefineMethodOverride(getMethodBuilder, dynamicProxyType.GetMethod("get_Interceptor"));
 }
            private static MethodBuilder DefineMethod(TypeBuilder newType, Type interfaceType, string methodName)
            {
                MethodInfo getInterfaceMethodInfo = interfaceType.GetMethod(methodName);
                MethodBuilder getMethod = newType.DefineMethod(
                    string.Concat(interfaceType.Name, '.', getInterfaceMethodInfo.Name),
                    MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.Virtual,
                     CallingConventions.Standard,
                     getInterfaceMethodInfo.ReturnType,
                     ClassWrappers.GetParameterTypes(getInterfaceMethodInfo.GetParameters()));

                newType.DefineMethodOverride(getMethod, getInterfaceMethodInfo);
                return getMethod;
            }
        private static void WriteIsAuthorized(Type parentType, TypeBuilder builder)
        {
            MethodInfo protectedMethod = parentType.GetMethod("AuthorizeCore", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod);
            MethodBuilder implementedMethod = builder.DefineMethod("IsAuthorized", MethodAttributes.Public | MethodAttributes.Virtual, typeof(bool), new[] { typeof(HttpContextBase) });
            ILGenerator il = implementedMethod.GetILGenerator();

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Call, protectedMethod);
            il.Emit(OpCodes.Ret);

            MethodInfo interfaceMethod = authorizeAttributeType.GetMethod("IsAuthorized", BindingFlags.Public | BindingFlags.Instance);
            builder.DefineMethodOverride(implementedMethod, interfaceMethod);
        }
            private static MethodBuilder DefineMethod(TypeBuilder newType, Type interfaceType, string methodName, Type[] parameterTypes)
            {
                MethodInfo getMethod = interfaceType.GetMethod(methodName, parameterTypes);

                if (getMethod == null)
                    return null;

                MethodBuilder builder = newType.DefineMethod(
                    string.Concat(interfaceType.Name, '.', getMethod.Name),
                    MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.Virtual,
                    getMethod.ReturnType, parameterTypes);

                newType.DefineMethodOverride(builder, getMethod);

                return builder;
            }
            private static MethodBuilder DefinePropertyGetMethod(TypeBuilder newType, string propertyName, Type interfaceType)
            {
                MethodInfo getPropertyMethod = interfaceType.GetProperty(propertyName).GetGetMethod();

                if (getPropertyMethod == null)
                    return null;

                MethodBuilder builder = newType.DefineMethod(
                    string.Concat(interfaceType.Name, '.', getPropertyMethod.Name),
                    MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.Virtual,
                    getPropertyMethod.ReturnType, Type.EmptyTypes);

                newType.DefineMethodOverride(builder, getPropertyMethod);

                return builder;
            }
        private static void BuildIProxyTargetPropertyMethod(
			TypeBuilder proxyBuilder, Type targetType, Type iProxyType,
			FieldBuilder wrappedObject, TypeDebugging debug)
        {
            var attributes = MethodAttributes.HideBySig |
                 MethodAttributes.Virtual | MethodAttributes.Private;
            var method = proxyBuilder.DefineMethod(GetTargetMethod,
                 attributes, targetType, Type.EmptyTypes);
            proxyBuilder.DefineMethodOverride(method,
                iProxyType.GetProperty(TargetProperty).GetGetMethod());

            using (var generator = debug.GetMethodDebugging(method))
            {
                generator.Emit(OpCodes.Ldarg_0);
                generator.Emit(OpCodes.Ldfld, wrappedObject);
                generator.Emit(OpCodes.Ret);
            }
        }
        public override MethodBuilder Generate(TypeBuilder typeBuilder)
        {
            var targetMethodGenerator = new TargetedInvocationMethodGenerator(
                _methodMetadata,
                _targetField);

            var targetMethod = targetMethodGenerator.Generate(typeBuilder);

            var methodBuilder = GenerateMethod(
                typeBuilder,
                _methodMetadata,
                _dispatcherField,
                _methodInfoField,
                targetMethod);

            if (_methodMetadata.IsExplicitInterfaceImplementation)
            {
                typeBuilder.DefineMethodOverride(methodBuilder, _methodMetadata.Method);
            }

            return methodBuilder;
        }
        /// <summary>
        ///   CreateMethod
        /// </summary>
        /// <param name="methodInfo"></param>
        /// <param name="typeBuilder"></param>
        private static void CreateMethod(this MethodInfo methodInfo, System.Reflection.Emit.TypeBuilder typeBuilder)
        {
            // Define the method
            var methodBuilder = typeBuilder.DefineMethod(methodInfo.Name, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.Virtual, methodInfo.ReturnType, methodInfo.GetParameters().Select(parameterInfo => parameterInfo.ParameterType).ToArray());

            // The ILGenerator class is used to put op-codes (similar to assembly) into the method
            // ReSharper disable once InconsistentNaming
            var IL = methodBuilder.GetILGenerator();

            // If there's a return type, create a default value or null to return
            if (methodInfo.ReturnType != typeof(void))
            {
                var localBuilder = IL.DeclareLocal(methodInfo.ReturnType); // this declares the local object,
                // int, long, float, ect
                IL.Emit(OpCodes.Ldloc, localBuilder);                      // load the value on the stack to return
            }

            IL.Emit(OpCodes.Ret); // return

            // We need to associate our new type's method with the setter method in the interface
            typeBuilder.DefineMethodOverride(methodBuilder, methodInfo);
        }
		public static void Implement (TypeBuilder typeB, Type iface)
		{
			typeB.AddInterfaceImplementation (iface);

			foreach (MethodInfo declMethod in iface.GetMethods ()) {

				MethodBuilder method_builder = typeB.DefineMethod (declMethod.Name, MethodAttributes.Public | MethodAttributes.Virtual, declMethod.ReturnType, Mapper.GetTypes (ArgDirection.In, declMethod.GetParameters ()));
				ILGenerator ilg = method_builder.GetILGenerator ();

				//Mapper.GetTypes (ArgDirection.In, declMethod.GetParameters ())

				ParameterInfo[] delegateParms = declMethod.GetParameters ();
				Type[] hookupParms = new Type[delegateParms.Length+1];
				hookupParms[0] = typeof (BusObject);
				for (int i = 0; i < delegateParms.Length ; i++)
					hookupParms[i+1] = delegateParms[i].ParameterType;

				GenHookupMethod (ilg, declMethod, sendMethodCallMethod, Mapper.GetInterfaceName (iface), declMethod.Name, hookupParms);

				typeB.DefineMethodOverride (method_builder, declMethod);
			}
		}
        public static MethodBuilder CreateMethod(TypeBuilder typeBuilder, MethodInfo method)
        {
            var scope = method.IsPublic
                        ? MethodAttributes.Public
                        : MethodAttributes.Family;

            var parameters = method.GetParameters();

            var parameterTypes = parameters.Select(p => p.ParameterType)
                                           .ToArray();

            var methodBuilder = typeBuilder.DefineMethod(method.Name, scope | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.HideBySig, method.CallingConvention, method.ReturnType, parameterTypes);

            foreach (var parameter in parameters)
            {
                methodBuilder.DefineParameter(parameter.Position + 1, parameter.Attributes, parameter.Name);
            }

            typeBuilder.DefineMethodOverride(methodBuilder, method);

            return methodBuilder;
        }
Example #19
0
		public static void Implement (TypeBuilder typeB, Type iface)
		{
			typeB.AddInterfaceImplementation (iface);

			foreach (MethodInfo declMethod in iface.GetMethods ()) {
				ParameterInfo[] parms = declMethod.GetParameters ();

				Type[] parmTypes = new Type[parms.Length];
				for (int i = 0 ; i < parms.Length ; i++)
					parmTypes[i] = parms[i].ParameterType;

				MethodAttributes attrs = declMethod.Attributes ^ MethodAttributes.Abstract;
				MethodBuilder method_builder = typeB.DefineMethod (declMethod.Name, attrs, declMethod.ReturnType, parmTypes);
				typeB.DefineMethodOverride (method_builder, declMethod);

				//define in/out/ref/name for each of the parameters
				for (int i = 0; i < parms.Length ; i++)
					method_builder.DefineParameter (i, parms[i].Attributes, parms[i].Name);

				ILGenerator ilg = method_builder.GetILGenerator ();
				GenHookupMethod (ilg, declMethod, sendMethodCallMethod, Mapper.GetInterfaceName (iface), declMethod.Name);
			}
		}
        private void BuildUnproxiedMethod(string wrapperName, TypeBuilder typeBuilder, MethodInfo method)
        {
            wrapperName = method.Name;

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

            Type returnType = method.ReturnType;

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

            for (int i = 0; i < parameterInfos.Length; i++)
            {
                methodBuilder.DefineParameter(i + 1, parameterInfos[i].Attributes, parameterInfos[i].Name);
            }

            ILGenerator il = methodBuilder.GetILGenerator();

            //			il.EmitWriteLine("enter "  + wrapperName) ;

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, that);
            for (int i = 0; i < parameterInfos.Length; i++)
                il.Emit(OpCodes.Ldarg, i + 1);

            il.Emit(OpCodes.Callvirt, method);

            il.Emit(OpCodes.Ret);
        }
Example #21
0
        /// <summary>
        /// Adds a new method to the class, with the given name and method signature.
        /// </summary>
        /// <param name="name">The name of the method. name cannot contain embedded nulls. </param>
        /// <param name="methodInfoDeclaration">The method whose declaration is to be used.</param>
        /// <param name="attributes">The attributes of the method. </param>
        /// <returns>The defined method.</returns>
        public MethodBuilderHelper DefineMethod(
            string name,
            MethodInfo methodInfoDeclaration,
            MethodAttributes attributes)
        {
            if (methodInfoDeclaration == null)
            {
                throw new ArgumentNullException("methodInfoDeclaration");
            }

            MethodBuilderHelper method;

            ParameterInfo[] pi         = methodInfoDeclaration.GetParameters();
            Type[]          parameters = new Type[pi.Length];

            // When a method contains a generic parameter we need to replace all
            // generic types from methodInfoDeclaration with local ones.
            //
            if (methodInfoDeclaration.ContainsGenericParameters)
            {
                method = new MethodBuilderHelper(this, _typeBuilder.DefineMethod(name, attributes, methodInfoDeclaration.CallingConvention), false);

                Type[] genArgs = methodInfoDeclaration.GetGenericArguments();
                GenericTypeParameterBuilder[] genParams = method.MethodBuilder.DefineGenericParameters(
                    Array.ConvertAll <Type, string>(genArgs, delegate(Type t) { return(t.Name); }));

                // Copy parameter constraints.
                //
                List <Type> interfaceConstraints = null;
                for (int i = 0; i < genParams.Length; i++)
                {
                    genParams[i].SetGenericParameterAttributes(genArgs[i].GenericParameterAttributes);

                    foreach (Type constraint in genArgs[i].GetGenericParameterConstraints())
                    {
                        if (constraint.IsClass)
                        {
                            genParams[i].SetBaseTypeConstraint(constraint);
                        }
                        else
                        {
                            if (interfaceConstraints == null)
                            {
                                interfaceConstraints = new List <Type>();
                            }
                            interfaceConstraints.Add(constraint);
                        }
                    }

                    if (interfaceConstraints != null && interfaceConstraints.Count > 0)
                    {
                        genParams[i].SetInterfaceConstraints(interfaceConstraints.ToArray());
                        interfaceConstraints.Clear();
                    }
                }

                for (int i = 0; i < pi.Length; i++)
                {
                    parameters[i] = TypeHelper.TranslateGenericParameters(pi[i].ParameterType, genParams);
                }

                method.MethodBuilder.SetParameters(parameters);
                method.MethodBuilder.SetReturnType(TypeHelper.TranslateGenericParameters(
                                                       methodInfoDeclaration.ReturnType, genParams));

                // Now its safe to add a custom attribute.
                //
                method.MethodBuilder.SetCustomAttribute(method.Type.Assembly.BLToolkitAttribute);
            }
            else
            {
                for (int i = 0; i < pi.Length; i++)
                {
                    parameters[i] = pi[i].ParameterType;
                }

                method = DefineMethod(
                    name,
                    attributes,
                    methodInfoDeclaration.CallingConvention,
                    methodInfoDeclaration.ReturnType,
                    parameters);
            }

            // Compiler overrides methods only for interfaces. We do the same.
            // If we wanted to override virtual methods, then methods should've had
            // MethodAttributes.VtableLayoutMask attribute
            // and the following condition should've been used below:
            // if ((methodInfoDeclaration is FakeMethodInfo) == false)
            //
            if (methodInfoDeclaration.DeclaringType.IsInterface && !(methodInfoDeclaration is FakeMethodInfo))
            {
                OverridenMethods.Add(methodInfoDeclaration, method.MethodBuilder);
                _typeBuilder.DefineMethodOverride(method.MethodBuilder, methodInfoDeclaration);
            }

            method.OverriddenMethod = methodInfoDeclaration;

            for (int i = 0; i < pi.Length; i++)
            {
                method.MethodBuilder.DefineParameter(i + 1, pi[i].Attributes, pi[i].Name);
            }

            return(method);
        }
        private static void DefineSetMethod(TypeBuilder newType, PropertyBuilder propertyBuilder, FieldInfo fieldBuilder, PropertyInfo property)
        {
            var setMethod = property.GetSetMethod();
            if (setMethod == null) return;

            var methodBuilder = newType.DefineMethod(setMethod.Name,
                                                     MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Virtual,
                                                     null,
                                                     new[] {property.PropertyType});

            var ilg = methodBuilder.GetILGenerator();
            ilg.Emit(OpCodes.Ldarg_0);
            ilg.Emit(OpCodes.Ldarg_1);
            ilg.Emit(OpCodes.Stfld, fieldBuilder);
            ilg.Emit(OpCodes.Ret);
            propertyBuilder.SetSetMethod(methodBuilder);

            var methodInfo = methodBuilder.GetBaseDefinition();

            newType.DefineMethodOverride(methodInfo, setMethod);
        }
        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);
        }
Example #24
0
        private static MethodBuilder MakeMethod(TypeBuilder typeBuilder, MethodInfo method, Boolean createPublic)
        {
            Int32 methodNum = DynamicProxy.Register(method);

            Type[] paramTypes = ToTypes(method.GetParameters());
            Int32 paramNum = paramTypes.Length;
            Boolean[] paramsByRef = new Boolean[paramNum];

            MethodBuilder b;
            String name;
            MethodAttributes methodAttr;
            if (createPublic) {
                name = method.Name;
                methodAttr = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig;
            }
            else {
                name = method.DeclaringType.FullName + "." + method.Name;
                methodAttr = MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Final;
            }
            b = typeBuilder.DefineMethod(name, methodAttr, method.CallingConvention, method.ReturnType, paramTypes);

            ILGenerator gen = b.GetILGenerator();
            LocalBuilder parameters = gen.DeclareLocal(typeof(Object[]));
            LocalBuilder result = gen.DeclareLocal(typeof(Object));
            LocalBuilder retval = null;
            if (!method.ReturnType.Equals(typeof(void))) {
                retval = gen.DeclareLocal(method.ReturnType);
            }
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldfld, FieldInfo_handler); //this.handler
            gen.Emit(OpCodes.Ldarg_0);

            gen.Emit(OpCodes.Ldc_I4, methodNum);
            gen.Emit(OpCodes.Call, MethodInfo_GetMethod);

            gen.Emit(OpCodes.Ldc_I4, paramNum);
            gen.Emit(OpCodes.Newarr, typeof(Object)); // new Object[]
            if (paramNum > 0) {
                gen.Emit(OpCodes.Stloc, parameters);

                for (Int32 i = 0; i < paramNum; i++) {
                    gen.Emit(OpCodes.Ldloc, parameters);
                    gen.Emit(OpCodes.Ldc_I4, i);
                    gen.Emit(OpCodes.Ldarg, i + 1);
                    if (paramTypes[i].IsByRef) {
                        paramTypes[i] = paramTypes[i].GetElementType();
                        if (paramTypes[i] == typeofInt8 || paramTypes[i] == typeofBoolean) {
                            gen.Emit(OpCodes.Ldind_I1);
                        }
                        else if (paramTypes[i] == typeofUInt8) {
                            gen.Emit(OpCodes.Ldind_U1);
                        }
                        else if (paramTypes[i] == typeofInt16) {
                            gen.Emit(OpCodes.Ldind_I2);
                        }
                        else if (paramTypes[i] == typeofUInt16 || paramTypes[i] == typeofChar) {
                            gen.Emit(OpCodes.Ldind_U2);
                        }
                        else if (paramTypes[i] == typeofInt32) {
                            gen.Emit(OpCodes.Ldind_I4);
                        }
                        else if (paramTypes[i] == typeofUInt32) {
                            gen.Emit(OpCodes.Ldind_U4);
                        }
                        else if (paramTypes[i] == typeofInt64 || paramTypes[i] == typeofUInt64) {
                            gen.Emit(OpCodes.Ldind_I8);
                        }
                        else if (paramTypes[i] == typeofSingle) {
                            gen.Emit(OpCodes.Ldind_R4);
                        }
                        else if (paramTypes[i] == typeofDouble) {
                            gen.Emit(OpCodes.Ldind_R8);
                        }
                        else if (paramTypes[i].IsValueType) {
                            gen.Emit(OpCodes.Ldobj, paramTypes[i]);
                        }
                        else {
                            gen.Emit(OpCodes.Ldind_Ref);
                        }
                        paramsByRef[i] = true;
                    }
                    else {
                        paramsByRef[i] = false;
                    }
                    if (paramTypes[i].IsValueType) {
                        gen.Emit(OpCodes.Box, paramTypes[i]);
                    }
                    gen.Emit(OpCodes.Stelem_Ref);
                }

                gen.Emit(OpCodes.Ldloc, parameters);
            }

            // base.Invoke(this, method, parameters);
            gen.Emit(OpCodes.Callvirt, DynamicProxy_Invoke);
            gen.Emit(OpCodes.Stloc, result);

            for (Int32 i = 0; i < paramNum; i++) {
                if (paramsByRef[i]) {
                    gen.Emit(OpCodes.Ldarg, i + 1);
                    gen.Emit(OpCodes.Ldloc, parameters);
                    gen.Emit(OpCodes.Ldc_I4, i);
                    gen.Emit(OpCodes.Ldelem_Ref);
                    if (paramTypes[i].IsValueType) {
            #if NET1
                        gen.Emit(OpCodes.Unbox, paramTypes[i]);
                        gen.Emit(OpCodes.Ldobj, paramTypes[i]);
            #else
                        gen.Emit(OpCodes.Unbox_Any, paramTypes[i]);
            #endif
                    }
                    else {
                        gen.Emit(OpCodes.Castclass, paramTypes[i]);
                    }
                    if (paramTypes[i] == typeofInt8 || paramTypes[i] == typeofUInt8 || paramTypes[i] == typeofBoolean) {
                        gen.Emit(OpCodes.Stind_I1);
                    }
                    else if (paramTypes[i] == typeofInt16 || paramTypes[i] == typeofUInt16 || paramTypes[i] == typeofChar) {
                        gen.Emit(OpCodes.Stind_I2);
                    }
                    else if (paramTypes[i] == typeofInt32 || paramTypes[i] == typeofUInt32) {
                        gen.Emit(OpCodes.Stind_I4);
                    }
                    else if (paramTypes[i] == typeofInt64 || paramTypes[i] == typeofUInt64) {
                        gen.Emit(OpCodes.Stind_I8);
                    }
                    else if (paramTypes[i] == typeofSingle) {
                        gen.Emit(OpCodes.Stind_R4);
                    }
                    else if (paramTypes[i] == typeofDouble) {
                        gen.Emit(OpCodes.Stind_R8);
                    }
                    else if (paramTypes[i].IsValueType) {
                        gen.Emit(OpCodes.Stobj, paramTypes[i]);
                    }
                    else {
                        gen.Emit(OpCodes.Stind_Ref);
                    }
                }
            }

            if (!method.ReturnType.Equals(typeof(void))) {
                gen.Emit(OpCodes.Ldloc, result);
                if (method.ReturnType.IsValueType) {
            #if NET1
                    gen.Emit(OpCodes.Unbox, method.ReturnType);
                    gen.Emit(OpCodes.Ldobj, method.ReturnType);
            #else
                    gen.Emit(OpCodes.Unbox_Any, method.ReturnType);
            #endif
                }
                else {
                    gen.Emit(OpCodes.Castclass, method.ReturnType);
                }
                gen.Emit(OpCodes.Stloc_S, retval);
                gen.Emit(OpCodes.Ldloc_S, retval);
            }
            gen.Emit(OpCodes.Ret);

            if (!createPublic) {
                typeBuilder.DefineMethodOverride(b, method);
            }

            return b;
        }
        private static void DefineGetMethod(TypeBuilder newType, PropertyBuilder propertyBuilder, FieldInfo fieldBuilder, PropertyInfo property)
        {
            var getMethod = property.GetGetMethod();
            var methodBuilder = newType.DefineMethod(getMethod.Name,
                                                     MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Virtual,
                                                     property.PropertyType,
                                                     Type.EmptyTypes);

            var ilg = methodBuilder.GetILGenerator();

            ilg.Emit(OpCodes.Ldarg_0);
            ilg.Emit(OpCodes.Ldfld, fieldBuilder);
            ilg.Emit(OpCodes.Ret);

            propertyBuilder.SetGetMethod(methodBuilder);

            var methodInfo = methodBuilder.GetBaseDefinition();

            newType.DefineMethodOverride(methodInfo, getMethod);
        }
        // generates this explicit interface method:
        // public new Interface.Method(param0, param1, ...) {
        //   return base.Method(param0, param1, ...);
        // }
        private static void ImplementInterfaceMethod(TypeBuilder newType, MethodInfo interfaceMethod)
        {
            var parameters = interfaceMethod.GetParameters();
            var parameterTypes = (from p in parameters select p.ParameterType).ToArray();

            // based on http://msdn.microsoft.com/en-us/library/system.reflection.emit.typebuilder.definemethodoverride.aspx
            var newMethod = newType.DefineMethod(interfaceMethod.DeclaringType.Name + "." + interfaceMethod.Name,
                MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final,
                interfaceMethod.ReturnType, parameterTypes);

            var baseMethod = newType.BaseType.GetMethod(interfaceMethod.Name, parameterTypes);

            // parameter 0 is 'this', so we start at index 1
            for (int i = 0; i < parameters.Length; i++)
            {
                newMethod.DefineParameter(i + 1, parameters[i].Attributes, parameters[i].Name);
            }

            // load all arguments (including 'this') in proper order, then call and return
            var ilGen = newMethod.GetILGenerator();
            for (int i = 0; i <= parameterTypes.Length; i++)
            {
                ilGen.Emit(OpCodes.Ldarg_S, (byte)i);
            }
            ilGen.Emit(OpCodes.Call, baseMethod);
            ilGen.Emit(OpCodes.Ret);

            // finally, hook the new method up to the interface mapping
            newType.DefineMethodOverride(newMethod, interfaceMethod);
        }
Example #27
0
        /// <summary>
        /// Generates a GetHashCode method.
        /// </summary>
        /// <param name="dynamicType">A <see cref="TypeBuilder"/> to generate a GetHashCode method for.</param>
        /// <param name="fields">Fields to read in the GetHashCode method.</param>
        private static void GenerateGetHashCodeMethod(TypeBuilder dynamicType, IEnumerable<FieldBuilder> fields)
        {
            MethodBuilder method = dynamicType.DefineMethod("GetHashCode", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual, CallingConventions.Standard, typeof(int), new Type[0]);
            ILGenerator ilGen = method.GetILGenerator();

            Type eqEr = typeof(EqualityComparer<>);

            LocalBuilder localNum = ilGen.DeclareLocal(typeof(int));

            ilGen.Emit(OpCodes.Ldc_I4, new Random(unchecked((int)DateTime.Now.Ticks)).Next(int.MaxValue));
            ilGen.Emit(OpCodes.Stloc, localNum);
            foreach (FieldBuilder field in fields)
            {
                ilGen.Emit(OpCodes.Ldc_I4, 0xa5555529);
                ilGen.Emit(OpCodes.Ldloc, localNum);
                ilGen.Emit(OpCodes.Mul);

                Type genericEqer = eqEr.MakeGenericType(field.FieldType);
                MethodInfo eqDefaultMethod = eqEr.GetProperty("Default", BindingFlags.Static | BindingFlags.Public).GetGetMethod();
                MethodInfo genericEqDefaultMethod = TypeBuilder.GetMethod(genericEqer, eqDefaultMethod);
                ilGen.EmitCall(OpCodes.Call, genericEqDefaultMethod, null);
                ilGen.Emit(OpCodes.Ldarg_0);
                ilGen.Emit(OpCodes.Ldfld, field);

                Type theTofEqualizer = eqEr.GetGenericArguments()[0];
                MethodInfo eqEqualsMethod = eqEr.GetMethod("GetHashCode", BindingFlags.Public | BindingFlags.Instance, null, new[] { theTofEqualizer }, null);
                MethodInfo genericEqEqualsMethod = TypeBuilder.GetMethod(genericEqer, eqEqualsMethod);
                ilGen.EmitCall(OpCodes.Callvirt, genericEqEqualsMethod, null);
                ilGen.Emit(OpCodes.Add);
                ilGen.Emit(OpCodes.Stloc, localNum);
            }

            ilGen.Emit(OpCodes.Ldloc, localNum);
            ilGen.Emit(OpCodes.Ret);

            dynamicType.DefineMethodOverride(method, typeof(object).GetMethod("GetHashCode", BindingFlags.Public | BindingFlags.Instance));
            AddDebuggerHiddenAttribute(method);
        }
Example #28
0
        /// <summary>
        /// Adds a new method to the class, with the given name and method signature.
        /// </summary>
        /// <param name="name">The name of the method. name cannot contain embedded nulls. </param>
        /// <param name="methodInfoDeclaration">The method whose declaration is to be used.</param>
        /// <param name="attributes">The attributes of the method. </param>
        /// <returns>The defined method.</returns>
        public MethodBuilderHelper DefineMethod(
            string name,
            MethodInfo methodInfoDeclaration,
            MethodAttributes attributes)
        {
            if (methodInfoDeclaration == null)
            {
                throw new ArgumentNullException("methodInfoDeclaration");
            }

            MethodBuilderHelper method;

            ParameterInfo[] pi         = methodInfoDeclaration.GetParameters();
            Type[]          parameters = new Type[pi.Length];

            for (int i = 0; i < pi.Length; i++)
            {
                parameters[i] = pi[i].ParameterType;
            }

            if (methodInfoDeclaration.ContainsGenericParameters)
            {
                method = DefineGenericMethod(
                    name,
                    attributes,
                    methodInfoDeclaration.CallingConvention,
                    methodInfoDeclaration.GetGenericArguments(),
                    methodInfoDeclaration.ReturnType,
                    parameters);
            }
            else
            {
                method = DefineMethod(
                    name,
                    attributes,
                    methodInfoDeclaration.CallingConvention,
                    methodInfoDeclaration.ReturnType,
                    parameters);
            }

            // Compiler overrides methods only for interfaces. We do the same.
            // If we wanted to override virtual methods, then methods should've had
            // MethodAttributes.VtableLayoutMask attribute
            // and the following condition should've been used below:
            // if ((methodInfoDeclaration is FakeMethodInfo) == false)
            //
            if (methodInfoDeclaration.DeclaringType.IsInterface
#if !SILVERLIGHT
                && !(methodInfoDeclaration is FakeMethodInfo)
#endif
                )
            {
                OverriddenMethods.Add(methodInfoDeclaration, method.MethodBuilder);
                _typeBuilder.DefineMethodOverride(method.MethodBuilder, methodInfoDeclaration);
            }

            method.OverriddenMethod = methodInfoDeclaration;

            for (int i = 0; i < pi.Length; i++)
            {
                method.MethodBuilder.DefineParameter(i + 1, pi[i].Attributes, pi[i].Name);
            }

            return(method);
        }
Example #29
0
        /*
         * Generates an overriden implementation of method inside myType that delegates
         * to a function in a Lua table with the same name, if the function exists. If it
         * doesn't the method calls the base method (or does nothing, in case of interface
         * implementations).
         */
        private void GenerateMethod(TypeBuilder myType, MethodInfo method, MethodAttributes attributes, int methodIndex,
            FieldInfo luaTableField, FieldInfo returnTypesField, bool generateBase, out Type[] returnTypes)
        {
            var paramInfo = method.GetParameters ();
            var paramTypes = new Type[paramInfo.Length];
            var returnTypesList = new List<Type> ();

            // Counts out and ref parameters, for later use,
            // and creates the list of return types
            int nOutParams = 0;
            int nOutAndRefParams = 0;
            var returnType = method.ReturnType;
            returnTypesList.Add (returnType);

            for (int i = 0; i < paramTypes.Length; i++) {
                paramTypes [i] = paramInfo [i].ParameterType;
                if ((!paramInfo [i].IsIn) && paramInfo [i].IsOut)
                    nOutParams++;

                if (paramTypes [i].IsByRef) {
                    returnTypesList.Add (paramTypes [i].GetElementType ());
                    nOutAndRefParams++;
                }
            }

            int[] refArgs = new int[nOutAndRefParams];
            returnTypes = returnTypesList.ToArray ();

            // Generates a version of the method that calls the base implementation
            // directly, for use by the base field of the table
            if (generateBase) {
                var baseMethod = myType.DefineMethod ("__luaInterface_base_" + method.Name,
                    MethodAttributes.Private | MethodAttributes.NewSlot | MethodAttributes.HideBySig,
                    returnType, paramTypes);
                ILGenerator generatorBase = baseMethod.GetILGenerator ();
                generatorBase.Emit (OpCodes.Ldarg_0);

                for (int i = 0; i < paramTypes.Length; i++)
                    generatorBase.Emit (OpCodes.Ldarg, i + 1);

                generatorBase.Emit (OpCodes.Call, method);

                if (returnType == typeof(void))
                    generatorBase.Emit (OpCodes.Pop);

                generatorBase.Emit (OpCodes.Ret);
            }

            // Defines the method
            var methodImpl = myType.DefineMethod (method.Name, attributes, returnType, paramTypes);

            // If it's an implementation of an interface tells what method it
            // is overriding
            if (myType.BaseType.Equals (typeof(object)))
                myType.DefineMethodOverride (methodImpl, method);

            ILGenerator generator = methodImpl.GetILGenerator ();
            generator.DeclareLocal (typeof(object[])); // original arguments
            generator.DeclareLocal (typeof(object[])); // with out-only arguments removed
            generator.DeclareLocal (typeof(int[])); // indexes of out and ref arguments

            if (!(returnType == typeof(void))) // return value
                generator.DeclareLocal (returnType);
            else
                generator.DeclareLocal (typeof(object));

            // Initializes local variables
            generator.Emit (OpCodes.Ldc_I4, paramTypes.Length);
            generator.Emit (OpCodes.Newarr, typeof(object));
            generator.Emit (OpCodes.Stloc_0);
            generator.Emit (OpCodes.Ldc_I4, paramTypes.Length - nOutParams + 1);
            generator.Emit (OpCodes.Newarr, typeof(object));
            generator.Emit (OpCodes.Stloc_1);
            generator.Emit (OpCodes.Ldc_I4, nOutAndRefParams);
            generator.Emit (OpCodes.Newarr, typeof(int));
            generator.Emit (OpCodes.Stloc_2);
            generator.Emit (OpCodes.Ldloc_1);
            generator.Emit (OpCodes.Ldc_I4_0);
            generator.Emit (OpCodes.Ldarg_0);
            generator.Emit (OpCodes.Ldfld, luaTableField);
            generator.Emit (OpCodes.Stelem_Ref);

            // Stores the arguments into the local variables, as needed
            for (int iArgs = 0, iInArgs = 1, iOutArgs = 0; iArgs < paramTypes.Length; iArgs++) {
                generator.Emit (OpCodes.Ldloc_0);
                generator.Emit (OpCodes.Ldc_I4, iArgs);
                generator.Emit (OpCodes.Ldarg, iArgs + 1);

                if (paramTypes [iArgs].IsByRef) {
                    if (paramTypes [iArgs].GetElementType ().IsValueType) {
                        generator.Emit (OpCodes.Ldobj, paramTypes [iArgs].GetElementType ());
                        generator.Emit (OpCodes.Box, paramTypes [iArgs].GetElementType ());
                    } else
                        generator.Emit (OpCodes.Ldind_Ref);
                } else {
                    if (paramTypes [iArgs].IsValueType)
                        generator.Emit (OpCodes.Box, paramTypes [iArgs]);
                }

                generator.Emit (OpCodes.Stelem_Ref);

                if (paramTypes [iArgs].IsByRef) {
                    generator.Emit (OpCodes.Ldloc_2);
                    generator.Emit (OpCodes.Ldc_I4, iOutArgs);
                    generator.Emit (OpCodes.Ldc_I4, iArgs);
                    generator.Emit (OpCodes.Stelem_I4);
                    refArgs [iOutArgs] = iArgs;
                    iOutArgs++;
                }

                if (paramInfo [iArgs].IsIn || (!paramInfo [iArgs].IsOut)) {
                    generator.Emit (OpCodes.Ldloc_1);
                    generator.Emit (OpCodes.Ldc_I4, iInArgs);
                    generator.Emit (OpCodes.Ldarg, iArgs + 1);

                    if (paramTypes [iArgs].IsByRef) {
                        if (paramTypes [iArgs].GetElementType ().IsValueType) {
                            generator.Emit (OpCodes.Ldobj, paramTypes [iArgs].GetElementType ());
                            generator.Emit (OpCodes.Box, paramTypes [iArgs].GetElementType ());
                        } else
                            generator.Emit (OpCodes.Ldind_Ref);
                    } else {
                        if (paramTypes [iArgs].IsValueType)
                            generator.Emit (OpCodes.Box, paramTypes [iArgs]);
                    }

                    generator.Emit (OpCodes.Stelem_Ref);
                    iInArgs++;
                }
            }

            // Gets the function the method will delegate to by calling
            // the getTableFunction method of class LuaClassHelper
            generator.Emit (OpCodes.Ldarg_0);
            generator.Emit (OpCodes.Ldfld, luaTableField);
            generator.Emit (OpCodes.Ldstr, method.Name);
            generator.Emit (OpCodes.Call, classHelper.GetMethod ("getTableFunction"));
            var lab1 = generator.DefineLabel ();
            generator.Emit (OpCodes.Dup);
            generator.Emit (OpCodes.Brtrue_S, lab1);
            // Function does not exist, call base method
            generator.Emit (OpCodes.Pop);

            if (!method.IsAbstract) {
                generator.Emit (OpCodes.Ldarg_0);

                for (int i = 0; i < paramTypes.Length; i++)
                    generator.Emit (OpCodes.Ldarg, i + 1);

                generator.Emit (OpCodes.Call, method);

                if (returnType == typeof(void))
                    generator.Emit (OpCodes.Pop);

                generator.Emit (OpCodes.Ret);
                generator.Emit (OpCodes.Ldnull);
            } else
                generator.Emit (OpCodes.Ldnull);

            var lab2 = generator.DefineLabel ();
            generator.Emit (OpCodes.Br_S, lab2);
            generator.MarkLabel (lab1);
            // Function exists, call using method callFunction of LuaClassHelper
            generator.Emit (OpCodes.Ldloc_0);
            generator.Emit (OpCodes.Ldarg_0);
            generator.Emit (OpCodes.Ldfld, returnTypesField);
            generator.Emit (OpCodes.Ldc_I4, methodIndex);
            generator.Emit (OpCodes.Ldelem_Ref);
            generator.Emit (OpCodes.Ldloc_1);
            generator.Emit (OpCodes.Ldloc_2);
            generator.Emit (OpCodes.Call, classHelper.GetMethod ("callFunction"));
            generator.MarkLabel (lab2);

            // Stores the function return value
            if (returnType == typeof(void)) {
                generator.Emit (OpCodes.Pop);
                generator.Emit (OpCodes.Ldnull);
            } else if (returnType.IsValueType) {
                generator.Emit (OpCodes.Unbox, returnType);
                generator.Emit (OpCodes.Ldobj, returnType);
            } else
                generator.Emit (OpCodes.Castclass, returnType);

            generator.Emit (OpCodes.Stloc_3);

            // Sets return values of out and ref parameters
            for (int i = 0; i < refArgs.Length; i++) {
                generator.Emit (OpCodes.Ldarg, refArgs [i] + 1);
                generator.Emit (OpCodes.Ldloc_0);
                generator.Emit (OpCodes.Ldc_I4, refArgs [i]);
                generator.Emit (OpCodes.Ldelem_Ref);

                if (paramTypes [refArgs [i]].GetElementType ().IsValueType) {
                    generator.Emit (OpCodes.Unbox, paramTypes [refArgs [i]].GetElementType ());
                    generator.Emit (OpCodes.Ldobj, paramTypes [refArgs [i]].GetElementType ());
                    generator.Emit (OpCodes.Stobj, paramTypes [refArgs [i]].GetElementType ());
                } else {
                    generator.Emit (OpCodes.Castclass, paramTypes [refArgs [i]].GetElementType ());
                    generator.Emit (OpCodes.Stind_Ref);
                }
            }

            // Returns
            if (!(returnType == typeof(void)))
                generator.Emit (OpCodes.Ldloc_3);

            generator.Emit (OpCodes.Ret);
        }
Example #30
0
        private static void ImplementInterfaceMethod(TypeBuilder newType, MethodInfo interfaceMethod)
        {
            ParameterInfo[] parameters = interfaceMethod.GetParameters();
            Type[] parameterTypes = new Type[parameters.Length];
            for (int idx = 0; idx < parameters.Length; idx++)
                parameterTypes[idx] = parameters[idx].ParameterType;

            MethodBuilder newMethod = newType.DefineMethod(
                interfaceMethod.DeclaringType.Name + "." + interfaceMethod.Name,
                MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final,
                interfaceMethod.ReturnType, parameterTypes
            );

            MethodInfo baseMethod = newType.BaseType.GetMethod(interfaceMethod.Name, parameterTypes);

            for (int i = 0; i < parameters.Length; i++)
                newMethod.DefineParameter(i + 1, parameters[i].Attributes, parameters[i].Name);

            ILGenerator ilGen = newMethod.GetILGenerator();

            for (int i = 0; i <= parameterTypes.Length; i++)
                ilGen.Emit(OpCodes.Ldarg_S, (byte)i);

            ilGen.Emit(OpCodes.Call, baseMethod);
            ilGen.Emit(OpCodes.Ret);

            newType.DefineMethodOverride(newMethod, interfaceMethod);
        }
Example #31
0
        private static void GenerateThunk(TypeBuilder tb, MethodInfo method) {

            ParameterInfo[] pi = method.GetParameters();
            int count = pi.Length;
            int argc = count - 1;

            Type[] args = new Type[count];
            for (int i = 0; i < count; i++) {
                args[i] = pi[i].ParameterType;
            }

            MethodBuilder mb = tb.DefineMethod(
                                  method.Name,
                                  MethodAttributes.Public | 
                                  MethodAttributes.Virtual,
                                  method.ReturnType,
                                  args
                                  );

            // Build the method signature for the actual native function.
            // This is essentially the signature of the wrapper method
            // minus the first argument (the passed in function pointer).

            Type[] nargs = new Type[argc];
            for (int i = 1; i < count; i++) {
                nargs[(i - 1)] = args[i];
            }

            // IL generation: the (implicit) first argument of the method 
            // is the 'this' pointer and the second is the function pointer.
            // This code pushes the real args onto the stack, followed by
            // the function pointer, then the calli opcode to make the call.

            ILGenerator il = mb.GetILGenerator();

            for (int i = 0; i < argc; i++) {
                il.Emit(OpCodes.Ldarg_S, (i + 2));
            }

            il.Emit(OpCodes.Ldarg_1);

            il.EmitCalli(OpCodes.Calli, 
                         CallingConvention.Cdecl, 
                         method.ReturnType, 
                         nargs
                         );

            il.Emit(OpCodes.Ret);

            tb.DefineMethodOverride(mb, method);
            return;
        }
Example #32
0
        /// <summary>
        /// Generate a ToString method.
        /// </summary>
        /// <param name="dynamicType">A <see cref="TypeBuilder"/> to generate a ToString method for.</param>
        /// <param name="propertyNames">The names of the properties of the type.</param>
        /// <param name="fields">Fields to read in the ToString method.</param>
        private static void GenerateToStringMethod(TypeBuilder dynamicType, string[] propertyNames, FieldBuilder[] fields)
        {
            MethodBuilder method = dynamicType.DefineMethod("ToString", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual, CallingConventions.Standard, typeof(string), new Type[0]);
            ILGenerator ilGen = method.GetILGenerator();

            LocalBuilder localBuilder = ilGen.DeclareLocal(typeof(StringBuilder));

            MethodInfo appendObject = typeof(StringBuilder).GetMethod("Append", BindingFlags.Instance | BindingFlags.Public, null, new[] { typeof(object) }, null);
            MethodInfo appendString = typeof(StringBuilder).GetMethod("Append", BindingFlags.Instance | BindingFlags.Public, null, new[] { typeof(string) }, null);
            MethodInfo sbToString = typeof(object).GetMethod("ToString", BindingFlags.Instance | BindingFlags.Public, null, new Type[0], null);

            ilGen.Emit(OpCodes.Newobj, typeof(StringBuilder).GetConstructor(new Type[0]));
            ilGen.Emit(OpCodes.Stloc, localBuilder);
            ilGen.Emit(OpCodes.Ldloc, localBuilder);
            ilGen.Emit(OpCodes.Ldstr, "{ ");
            ilGen.EmitCall(OpCodes.Callvirt, appendString, null);
            ilGen.Emit(OpCodes.Pop);

            bool first = true;

            for (int i = 0; i < fields.Length; i++)
            {
                FieldBuilder field = fields[i];

                ilGen.Emit(OpCodes.Ldloc, localBuilder);
                ilGen.Emit(OpCodes.Ldstr, string.Concat(first ? "" : ", ", propertyNames[i], " = "));
                ilGen.EmitCall(OpCodes.Callvirt, appendString, null);
                ilGen.Emit(OpCodes.Pop);

                ilGen.Emit(OpCodes.Ldloc, localBuilder);
                ilGen.Emit(OpCodes.Ldarg_0);
                ilGen.Emit(OpCodes.Ldfld, field);
                ilGen.Emit(OpCodes.Box, field.FieldType);
                ilGen.EmitCall(OpCodes.Callvirt, appendObject, null);
                ilGen.Emit(OpCodes.Pop);

                first = false;
            }

            ilGen.Emit(OpCodes.Ldloc, localBuilder);
            ilGen.Emit(OpCodes.Ldstr, " }");
            ilGen.EmitCall(OpCodes.Callvirt, appendString, null);
            ilGen.Emit(OpCodes.Pop);

            ilGen.Emit(OpCodes.Ldloc, localBuilder);
            ilGen.EmitCall(OpCodes.Callvirt, sbToString, null);
            ilGen.Emit(OpCodes.Ret);

            dynamicType.DefineMethodOverride(method, typeof(object).GetMethod("ToString", BindingFlags.Public | BindingFlags.Instance));
            AddDebuggerHiddenAttribute(method);
        }
Example #33
0
        private static ILGen/*!*/ DefineMethodOverride(TypeBuilder/*!*/ tb, MethodInfo/*!*/ decl, out MethodBuilder/*!*/ impl) {
            impl = tb.DefineMethod(
                decl.Name,
                decl.Attributes & ~(MethodAttributes.Abstract | MethodAttributes.ReservedMask),
                decl.ReturnType,
                ReflectionUtils.GetParameterTypes(decl.GetParameters())
            );

            tb.DefineMethodOverride(impl, decl);
            return new ILGen(impl.GetILGenerator());
        }
		/// <summary>
		/// Generates a method on our <see cref="TypeBuilder"/> for the specified <see cref="MethodInfo"/>
		/// </summary>
		/// <param name="tb">The <see cref="TypeBuilder"/> we're generating our type with.</param>
		/// <param name="mi">The <see cref="MethodInfo"/> which represents the "template" method.</param>
		/// <param name="dllName">The path to the DLL that we'll put in the <see cref="DllImportAttribute"/>.</param>
		private static void GenerateMethod(TypeBuilder tb, MethodInfo mi, string dllName)
		{
			// These are all the parameters in our method
			List<ParameterInfo> pis = new List<ParameterInfo>(mi.GetParameters());

			// We need to keep the parameter types and attributes in a separate array.
			Type[] ptypes = new Type[pis.Count];
			ParameterAttributes[] attrs = new ParameterAttributes[pis.Count];
			for (int i = 0; i < pis.Count; i++)
			{
				ptypes[i] = pis[i].ParameterType;
				attrs[i] = pis[i].Attributes;
			}

			// We actually need to create TWO methods - one for the interface implementation, and one for the
			// P/Invoke declaration. We'll create the P/Invoke definition first.
			MethodBuilder smb = tb.DefineMethod(
				mi.Name, // The name is the same as the interface name
				// P/Invoke methods need special attributes...
				MethodAttributes.Static | MethodAttributes.Private | MethodAttributes.HideBySig,
				mi.ReturnType, ptypes);

			// Get the type of the DllImportAttribute, which we'll attach to this method
			Type diaType = typeof (DllImportAttribute);

			// Create a CustomAttributeBuilder for the DLLImportAttribute, specifying the constructor that takes a string argument.
			ConstructorInfo ctor = diaType.GetConstructor(new Type[] { typeof(string) });
			CustomAttributeBuilder cab = new CustomAttributeBuilder(ctor, new object[] { dllName });

			// Assign the DllImport attribute to the smb
			smb.SetCustomAttribute(cab);

			// Also, any attributes on the actual parameters need to be copied to the P/Invoke declaration as well.
			for (int i = 0; i < attrs.Length; i++)
			{
				smb.DefineParameter(i + 1, attrs[i], pis[i].Name);
			}

			// Now create the interface implementation method
			MethodBuilder mb = tb.DefineMethod(
				"IFbClient." + mi.Name, // We use the standard "Interface.Method" to do an explicit interface implementation
				MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual |
				MethodAttributes.Final,
				mi.ReturnType, ptypes);

			// Also, any attributes on the actual parameters need to be copied to the P/Invoke declaration as well.
			for (int i = 0; i < attrs.Length; i++)
			{
				mb.DefineParameter(i + 1, attrs[i], pis[i].Name);
			}

			// We need to generate a little IL here to actually call the P/Invoke declaration. Luckily for us, since we're just
			// going to pass our parameters to the P/Invoke method as-is, we don't need to muck with the eval stack ;-)
			ILGenerator il = mb.GetILGenerator();
			for (int i = 1; i <= pis.Count; i++)
			{
				if (i == 1)
				{
					il.Emit(OpCodes.Ldarg_1);
				}
				else if (i == 2)
				{
					il.Emit(OpCodes.Ldarg_2);
				}
				else if (i == 3)
				{
					il.Emit(OpCodes.Ldarg_3);
				}
				else
				{
					il.Emit(OpCodes.Ldarg_S, (short)i);
				}
			}

			il.EmitCall(OpCodes.Call, smb, null);
			il.Emit(OpCodes.Ret);

			// Define the fact that our IFbClient.Method is the explicit interface implementation of that method
			tb.DefineMethodOverride(mb, mi);
		}
Example #35
0
        private static ILGen/*!*/ DefinePrivateInterfaceMethodOverride(TypeBuilder/*!*/ tb, MethodInfo/*!*/ decl, out MethodBuilder/*!*/ impl) {
            string name = decl.DeclaringType.Name + "." + decl.Name;
            //MethodAttributes attributes = decl.Attributes & ~(MethodAttributes.Abstract | MethodAttributes.ReservedMask | MethodAttributes.MemberAccessMask)
            //    | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Private;
            MethodAttributes attributes = decl.Attributes & ~(MethodAttributes.Abstract | MethodAttributes.Public);
            attributes |= MethodAttributes.NewSlot | MethodAttributes.Final;
            impl = tb.DefineMethod(
                name,
                attributes,
                decl.ReturnType,
                ReflectionUtils.GetParameterTypes(decl.GetParameters())
            );

            tb.DefineMethodOverride(impl, decl);
            return new ILGen(impl.GetILGenerator());
        }
Example #36
0
        /// <summary>
        /// Compiles the type that is being built and returns its run-time Type.
        /// If you want to create instances directly, see the GetConstructorDelegate.
        /// </summary>
        public Type Compile()
        {
            if (_compiledType == null)
            {
                _CheckThread();

                _delegates = new Delegate[_methods.Count];

                var methodBuilders = new Dictionary <string, MethodBuilder>();
                int index          = -1;
                foreach (var method in _methods)
                {
                    index++;
                    var methodBuilder = _Compile(method, index);
                    methodBuilders[method.Name] = methodBuilder;
                }

                foreach (var property in _properties.Values)
                {
                    string name            = property.Name;
                    var    propertyBuilder = _type.DefineProperty(name, PropertyAttributes.None, property.PropertyType, Type.EmptyTypes);
                    propertyBuilder.SetGetMethod(methodBuilders["get_" + name]);
                    propertyBuilder.SetSetMethod(methodBuilders["set_" + name]);
                }

                foreach (var eventInfo in _events.Values)
                {
                    string name         = eventInfo.Name;
                    var    eventBuilder = _type.DefineEvent(name, EventAttributes.None, eventInfo.Type);

                    string addName    = "add_" + name;
                    string removeName = "remove_" + name;

                    var addMethod    = methodBuilders[addName];
                    var removeMethod = methodBuilders[removeName];
                    eventBuilder.SetAddOnMethod(addMethod);
                    eventBuilder.SetRemoveOnMethod(removeMethod);

                    foreach (var interfaceType in _interfaceTypes)
                    {
                        var method = interfaceType.GetMethod(addName);
                        if (method != null)
                        {
                            _type.DefineMethodOverride(addMethod, method);
                        }

                        method = interfaceType.GetMethod(removeName);
                        if (method != null)
                        {
                            _type.DefineMethodOverride(removeMethod, method);
                        }
                    }
                }

                var compiledType = _type.CreateType();

                var thisExpression = Expression.Parameter(compiledType, "this");
                var fields         = _fields.ToArray();
                foreach (var fieldPair in fields)
                {
                    var    leftPair   = fieldPair.Key;
                    var    field      = leftPair.Key;
                    var    rightPair  = fieldPair.Value;
                    string fieldName  = rightPair.Value;
                    var    expression = Expression.MakeMemberAccess(thisExpression, compiledType.GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic));
                    _fields[leftPair] = new KeyValuePair <MemberExpression, string>(expression, fieldName);
                }

                index = -1;
                foreach (var method in _methods)
                {
                    index++;

                    if (method._respectVisibility)
                    {
                        continue;
                    }

                    if (!method.IsStatic)
                    {
                        var firstParameter = method._parameters.Keys.First();
                        method._parameters[firstParameter] = thisExpression;
                    }

                    var compiledMethod = method._Compile(null, null);
                    _delegates[index] = compiledMethod;
                }

                var delegatesField = compiledType.GetField(".delegates", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
                delegatesField.SetValue(null, _delegates);

                _compiledType = compiledType;
            }

            return(_compiledType);
        }