Example #1
0
        public void EmitAddressOf(EmitContext ec)
        {
            int arg_idx = idx;

            if (!ec.IsStatic)
            {
                arg_idx++;
            }

            bool is_ref = (ModFlags & Modifier.ISBYREF) != 0;

            if (is_ref)
            {
                ParameterReference.EmitLdArg(ec, arg_idx);
            }
            else
            {
                if (arg_idx <= 255)
                {
                    ec.Emit(OpCodes.Ldarga_S, (byte)arg_idx);
                }
                else
                {
                    ec.Emit(OpCodes.Ldarga, arg_idx);
                }
            }
        }
Example #2
0
        /// <summary>
        ///   C# allows this kind of scenarios:
        ///   interface I { void M (); }
        ///   class X { public void M (); }
        ///   class Y : X, I { }
        ///
        ///   For that case, we create an explicit implementation function
        ///   I.M in Y.
        /// </summary>
        void DefineProxy(TypeSpec iface, MethodSpec base_method, MethodSpec iface_method)
        {
            // TODO: Handle nested iface names
            string proxy_name;
            var    ns = iface.MemberDefinition.Namespace;

            if (string.IsNullOrEmpty(ns))
            {
                proxy_name = iface.MemberDefinition.Name + "." + iface_method.Name;
            }
            else
            {
                proxy_name = ns + "." + iface.MemberDefinition.Name + "." + iface_method.Name;
            }

            var param = iface_method.Parameters;

            MethodBuilder proxy = container.TypeBuilder.DefineMethod(
                proxy_name,
                MethodAttributes.Private |
                MethodAttributes.HideBySig |
                MethodAttributes.NewSlot |
                MethodAttributes.CheckAccessOnOverride |
                MethodAttributes.Virtual | MethodAttributes.Final,
                CallingConventions.Standard | CallingConventions.HasThis,
                base_method.ReturnType.GetMetaInfo(), param.GetMetaInfo());

            if (iface_method.IsGeneric)
            {
                var gnames = iface_method.GenericDefinition.TypeParameters.Select(l => l.Name).ToArray();
                proxy.DefineGenericParameters(gnames);
            }

            for (int i = 0; i < param.Count; i++)
            {
                string name = param.FixedParameters [i].Name;
                ParameterAttributes attr = ParametersCompiled.GetParameterAttribute(param.FixedParameters [i].ModFlags);
                proxy.DefineParameter(i + 1, attr, name);
            }

            int top = param.Count;
            var ec  = new EmitContext(null, proxy.GetILGenerator(), null);

            // TODO: GetAllParametersArguments
            for (int i = 0; i <= top; i++)
            {
                ParameterReference.EmitLdArg(ec, i);
            }

            ec.Emit(OpCodes.Call, base_method);
            ec.Emit(OpCodes.Ret);

            container.TypeBuilder.DefineMethodOverride(proxy, (MethodInfo)iface_method.GetMetaInfo());
        }
Example #3
0
        public void Emit(EmitContext ec)
        {
            int arg_idx = idx;

            if (!ec.IsStatic)
            {
                arg_idx++;
            }

            ParameterReference.EmitLdArg(ec, arg_idx);
        }
Example #4
0
        /// <summary>
        ///   C# allows this kind of scenarios:
        ///   interface I { void M (); }
        ///   class X { public void M (); }
        ///   class Y : X, I { }
        ///
        ///   For that case, we create an explicit implementation function
        ///   I.M in Y.
        /// </summary>
        void DefineProxy(Type iface, MethodInfo base_method, MethodInfo iface_method,
                         AParametersCollection param)
        {
            // TODO: Handle nested iface names
            string proxy_name = SimpleName.RemoveGenericArity(iface.FullName) + "." + iface_method.Name;

            MethodBuilder proxy = container.TypeBuilder.DefineMethod(
                proxy_name,
                MethodAttributes.HideBySig |
                MethodAttributes.NewSlot |
                MethodAttributes.CheckAccessOnOverride |
                MethodAttributes.Virtual,
                CallingConventions.Standard | CallingConventions.HasThis,
                base_method.ReturnType, param.GetEmitTypes());

            Type[] gargs = TypeManager.GetGenericArguments(iface_method);
            if (gargs.Length > 0)
            {
                string[] gnames = new string[gargs.Length];
                for (int i = 0; i < gargs.Length; ++i)
                {
                    gnames[i] = gargs[i].Name;
                }

#if GMCS_SOURCE
                proxy.DefineGenericParameters(gnames);
#else
                throw new NotSupportedException();
#endif
            }

            for (int i = 0; i < param.Count; i++)
            {
                string name = param.FixedParameters [i].Name;
                ParameterAttributes attr = ParametersCompiled.GetParameterAttribute(param.FixedParameters [i].ModFlags);
                proxy.DefineParameter(i + 1, attr, name);
            }

            int         top = param.Count;
            ILGenerator ig  = proxy.GetILGenerator();

            for (int i = 0; i <= top; i++)
            {
                ParameterReference.EmitLdArg(ig, i);
            }

            ig.Emit(OpCodes.Call, base_method);
            ig.Emit(OpCodes.Ret);

            container.TypeBuilder.DefineMethodOverride(proxy, iface_method);
        }