Update mcs/class/System.Core/System/TimeZoneInfo.cs
[mono.git] / mcs / class / corlib / System.Reflection.Emit / MethodBuilder.cs
index c62dee74532893d0d6d419631010b95ba2397356..11644739c0b0b3664ed6cb5fa139a51ff12269da 100644 (file)
@@ -40,26 +40,28 @@ using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 using System.Diagnostics.SymbolStore;
 
-namespace System.Reflection.Emit {
-#if NET_2_0
+namespace System.Reflection.Emit
+{
        [ComVisible (true)]
        [ComDefaultInterface (typeof (_MethodBuilder))]
-#endif
        [ClassInterface (ClassInterfaceType.None)]
-       public sealed class MethodBuilder : MethodInfo, _MethodBuilder {
+       [StructLayout (LayoutKind.Sequential)]
+       public sealed class MethodBuilder : MethodInfo, _MethodBuilder
+       {
+#pragma warning disable 169, 414
                private RuntimeMethodHandle mhandle;
                private Type rtype;
-               private Type[] parameters;
-               private MethodAttributes attrs;
+               internal Type[] parameters;
+               private MethodAttributes attrs; /* It's used directly by MCS */
                private MethodImplAttributes iattrs;
                private string name;
                private int table_idx;
                private byte[] code;
                private ILGenerator ilgen;
                private TypeBuilder type;
-               private ParameterBuilder[] pinfo;
+               internal ParameterBuilder[] pinfo;
                private CustomAttributeBuilder[] cattrs;
-               private MethodInfo override_method;
+               private MethodInfo[] override_methods;
                private string pi_dll;
                private string pi_entry;
                private CharSet charset;
@@ -68,18 +70,16 @@ namespace System.Reflection.Emit {
                private CallingConventions call_conv;
                private bool init_locals = true;
                private IntPtr generic_container;
-#if NET_2_0 || BOOTSTRAP_NET_2_0
-               private GenericTypeParameterBuilder[] generic_params;
-#else
-               private Object generic_params; /* so offsets are the same */
-#endif
+               internal GenericTypeParameterBuilder[] generic_params;
                private Type[] returnModReq;
                private Type[] returnModOpt;
                private Type[][] paramModReq;
                private Type[][] paramModOpt;
                private RefEmitPermissionSet[] permissions;
+#pragma warning restore 169, 414
 
-               internal MethodBuilder (TypeBuilder tb, string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] returnModReq, Type[] returnModOpt, Type[] parameterTypes, Type[][] paramModReq, Type[][] paramModOpt) {
+               internal MethodBuilder (TypeBuilder tb, string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] returnModReq, Type[] returnModOpt, Type[] parameterTypes, Type[][] paramModReq, Type[][] paramModOpt)
+               {
                        this.name = name;
                        this.attrs = attributes;
                        this.call_conv = callingConvention;
@@ -102,19 +102,25 @@ namespace System.Reflection.Emit {
                        }
                        type = tb;
                        table_idx = get_next_table_index (this, 0x06, true);
-                       //Console.WriteLine ("index for "+name+" set to "+table_idx.ToString());
+
+                       ((ModuleBuilder)tb.Module).RegisterToken (this, GetToken ().Token);
                }
 
                internal MethodBuilder (TypeBuilder tb, string name, MethodAttributes attributes, 
                                                                CallingConventions callingConvention, Type returnType, Type[] returnModReq, Type[] returnModOpt, Type[] parameterTypes, Type[][] paramModReq, Type[][] paramModOpt, 
                        String dllName, String entryName, CallingConvention nativeCConv, CharSet nativeCharset) 
-                       : this (tb, name, attributes, callingConvention, returnType, returnModReq, returnModOpt, parameterTypes, paramModReq, paramModOpt) {
+                       : this (tb, name, attributes, callingConvention, returnType, returnModReq, returnModOpt, parameterTypes, paramModReq, paramModOpt)
+               {
                        pi_dll = dllName;
                        pi_entry = entryName;
                        native_cc = nativeCConv;
                        charset = nativeCharset;
                }
 
+               public override bool ContainsGenericParameters {
+                       get { throw new NotSupportedException (); }
+               }
+
                public bool InitLocals {
                        get {return init_locals;}
                        set {init_locals = value;}
@@ -130,16 +136,31 @@ namespace System.Reflection.Emit {
                        }
                }
 
-               public override Type ReturnType {get {return rtype;}}
-               public override Type ReflectedType {get {return type;}}
-               public override Type DeclaringType {get {return type;}}
-               public override string Name {get {return name;}}
-               public override MethodAttributes Attributes {get {return attrs;}}
+               public override Type ReturnType {
+                       get { return rtype; }
+               }
+
+               public override Type ReflectedType {
+                       get { return type; }
+               }
+
+               public override Type DeclaringType {
+                       get { return type; }
+               }
+
+               public override string Name {
+                       get { return name; }
+               }
+
+               public override MethodAttributes Attributes {
+                       get { return attrs; }
+               }
+
                public override ICustomAttributeProvider ReturnTypeCustomAttributes {
-                       get {return null;}
+                       get { return null; }
                }
 
-               public override CallingConventions CallingConvention { 
+               public override CallingConventions CallingConvention {
                        get { return call_conv; }
                }
 
@@ -178,17 +199,23 @@ namespace System.Reflection.Emit {
                        }
                }
 
-               public MethodToken GetToken() {
+               public MethodToken GetToken()
+               {
                        return new MethodToken(0x06000000 | table_idx);
                }
                
-               public override MethodInfo GetBaseDefinition() {
+               public override MethodInfo GetBaseDefinition()
+               {
                        return this;
                }
-               public override MethodImplAttributes GetMethodImplementationFlags() {
+
+               public override MethodImplAttributes GetMethodImplementationFlags()
+               {
                        return iattrs;
                }
-               public override ParameterInfo[] GetParameters() {
+
+               public override ParameterInfo[] GetParameters()
+               {
                        if (!type.is_created)
                                throw NotSupported ();
                        if (parameters == null)
@@ -209,11 +236,17 @@ namespace System.Reflection.Emit {
                        return parameters.Length;
                }
 
-               public Module GetModule () {
+               internal override Type GetParameterType (int pos) {
+                       return parameters [pos];
+               }
+
+               public Module GetModule ()
+               {
                        return type.Module;
                }
 
-               public void CreateMethodBody( byte[] il, int count) {
+               public void CreateMethodBody (byte[] il, int count)
+               {
                        if ((il != null) && ((count < 0) || (count > il.Length)))
                                throw new ArgumentOutOfRangeException ("Index was out of range.  Must be non-negative and less than the size of the collection.");
 
@@ -228,13 +261,18 @@ namespace System.Reflection.Emit {
                        }
                }
 
-               public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) {
+               public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
+               {
                        throw NotSupported ();
                }
-               public override bool IsDefined (Type attribute_type, bool inherit) {
+
+               public override bool IsDefined (Type attributeType, bool inherit)
+               {
                        throw NotSupported ();
                }
-               public override object[] GetCustomAttributes( bool inherit) {
+
+               public override object[] GetCustomAttributes (bool inherit)
+               {
                        /*
                         * On MS.NET, this always returns not_supported, but we can't do this
                         * since there would be no way to obtain custom attributes of 
@@ -246,18 +284,21 @@ namespace System.Reflection.Emit {
                                throw NotSupported ();
                }
 
-               public override object[] GetCustomAttributes( Type attributeType, bool inherit) {
+               public override object[] GetCustomAttributes (Type attributeType, bool inherit)
+               {
                        if (type.is_created)
                                return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
                        else
                                throw NotSupported ();
                }
 
-               public ILGenerator GetILGenerator () {
+               public ILGenerator GetILGenerator ()
+               {
                        return GetILGenerator (64);
                }
 
-               public ILGenerator GetILGenerator (int size) {
+               public ILGenerator GetILGenerator (int size)
+               {
                        if (((iattrs & MethodImplAttributes.CodeTypeMask) != 
                                 MethodImplAttributes.IL) ||
                                ((iattrs & MethodImplAttributes.ManagedMask) != 
@@ -286,17 +327,24 @@ namespace System.Reflection.Emit {
                        return pb;
                }
 
-               internal void fixup () {
+               internal void check_override ()
+               {
+                       if (override_methods != null) {
+                               foreach (var m in override_methods) {
+                                       if (m.IsVirtual && !IsVirtual)
+                                               throw new TypeLoadException (String.Format("Method '{0}' override '{1}' but it is not virtual", name, m));
+                               }
+                       }
+               }
+
+               internal void fixup ()
+               {
                        if (((attrs & (MethodAttributes.Abstract | MethodAttributes.PinvokeImpl)) == 0) && ((iattrs & (MethodImplAttributes.Runtime | MethodImplAttributes.InternalCall)) == 0)) {
-#if NET_2_0
                                // do not allow zero length method body on MS.NET 2.0 (and higher)
-                               if (((ilgen == null) || (ILGenerator.Mono_GetCurrentOffset (ilgen) == 0)) && (code == null || code.Length == 0))
-#else
-                               if (((ilgen == null) || (ILGenerator.Mono_GetCurrentOffset (ilgen) == 0)) && (code == null))
-#endif
+                               if (((ilgen == null) || (ilgen.ILOffset == 0)) && (code == null || code.Length == 0))
                                        throw new InvalidOperationException (
                                                                             String.Format ("Method '{0}.{1}' does not have a method body.",
-                                                                                           DeclaringType.Name, Name));
+                                                                                           DeclaringType.FullName, Name));
                        }
                        if (ilgen != null)
                                ilgen.label_fixup ();
@@ -313,75 +361,78 @@ namespace System.Reflection.Emit {
                        }
                }
 
-               public void SetCustomAttribute( CustomAttributeBuilder customBuilder) {
+               public void SetCustomAttribute (CustomAttributeBuilder customBuilder)
+               {
                        if (customBuilder == null)
                                throw new ArgumentNullException ("customBuilder");
-                       string attrname = customBuilder.Ctor.ReflectedType.FullName;
-                       if (attrname == "System.Runtime.CompilerServices.MethodImplAttribute") {
-                               byte[] data = customBuilder.Data;
-                               int impla; // the (stupid) ctor takes a short or an int ... 
-                               impla = (int)data [2];
-                               impla |= ((int)data [3]) << 8;
-                               SetImplementationFlags ((MethodImplAttributes)impla);
-                               return;
-                       }
-                       if (attrname == "System.Runtime.InteropServices.DllImportAttribute") {
-                               CustomAttributeBuilder.CustomAttributeInfo attr = CustomAttributeBuilder.decode_cattr (customBuilder);
-                               bool preserveSig = true;
-
-                               /*
-                                * It would be easier to construct a DllImportAttribute from
-                                * the custom attribute builder, but the DllImportAttribute 
-                                * does not contain all the information required here, ie.
-                                * - some parameters, like BestFitMapping has three values
-                                *   ("on", "off", "missing"), but DllImportAttribute only
-                                *   contains two (on/off).
-                                * - PreserveSig is true by default, while it is false by
-                                *   default in DllImportAttribute.
-                                */
-
-                               pi_dll = (string)attr.ctorArgs [0];
-                               if (pi_dll == null || pi_dll.Length == 0)
-                                       throw new ArgumentException ("DllName cannot be empty");
-                               
-                               native_cc = System.Runtime.InteropServices.CallingConvention.Winapi;
-
-                               for (int i = 0; i < attr.namedParamNames.Length; ++i) {
-                                       string name = attr.namedParamNames [i];
-                                       object value = attr.namedParamValues [i];
-
-                                       if (name == "CallingConvention")
-                                               native_cc = (CallingConvention)value;
-                                       else if (name == "CharSet")
-                                               charset = (CharSet)value;
-                                       else if (name == "EntryPoint")
-                                               pi_entry = (string)value;
-                                       else if (name == "ExactSpelling")
-                                               ExactSpelling = (bool)value;
-                                       else if (name == "SetLastError")
-                                               SetLastError = (bool)value;
-                                       else if (name == "PreserveSig")
-                                               preserveSig = (bool)value;
-#if NET_1_1
+
+                       switch (customBuilder.Ctor.ReflectedType.FullName) {
+                               case "System.Runtime.CompilerServices.MethodImplAttribute":
+                                       byte[] data = customBuilder.Data;
+                                       int impla; // the (stupid) ctor takes a short or an int ... 
+                                       impla = (int)data [2];
+                                       impla |= ((int)data [3]) << 8;
+                                       iattrs |= (MethodImplAttributes)impla;
+                                       return;
+
+                               case "System.Runtime.InteropServices.DllImportAttribute":
+                                       CustomAttributeBuilder.CustomAttributeInfo attr = CustomAttributeBuilder.decode_cattr (customBuilder);
+                                       bool preserveSig = true;
+
+                                       /*
+                                        * It would be easier to construct a DllImportAttribute from
+                                        * the custom attribute builder, but the DllImportAttribute 
+                                        * does not contain all the information required here, ie.
+                                        * - some parameters, like BestFitMapping has three values
+                                        *   ("on", "off", "missing"), but DllImportAttribute only
+                                        *   contains two (on/off).
+                                        * - PreserveSig is true by default, while it is false by
+                                        *   default in DllImportAttribute.
+                                        */
+
+                                       pi_dll = (string)attr.ctorArgs[0];
+                                       if (pi_dll == null || pi_dll.Length == 0)
+                                               throw new ArgumentException ("DllName cannot be empty");
+
+                                       native_cc = System.Runtime.InteropServices.CallingConvention.Winapi;
+
+                                       for (int i = 0; i < attr.namedParamNames.Length; ++i) {
+                                               string name = attr.namedParamNames [i];
+                                               object value = attr.namedParamValues [i];
+
+                                               if (name == "CallingConvention")
+                                                       native_cc = (CallingConvention)value;
+                                               else if (name == "CharSet")
+                                                       charset = (CharSet)value;
+                                               else if (name == "EntryPoint")
+                                                       pi_entry = (string)value;
+                                               else if (name == "ExactSpelling")
+                                                       ExactSpelling = (bool)value;
+                                               else if (name == "SetLastError")
+                                                       SetLastError = (bool)value;
+                                               else if (name == "PreserveSig")
+                                                       preserveSig = (bool)value;
                                        else if (name == "BestFitMapping")
                                                BestFitMapping = (bool)value;
                                        else if (name == "ThrowOnUnmappableChar")
                                                ThrowOnUnmappableChar = (bool)value;
-#endif
-                               }
+                                       }
 
-                               attrs |= MethodAttributes.PinvokeImpl;
-                               if (preserveSig)
-                                       iattrs |= MethodImplAttributes.PreserveSig;
-                               return;
-                       }
+                                       attrs |= MethodAttributes.PinvokeImpl;
+                                       if (preserveSig)
+                                               iattrs |= MethodImplAttributes.PreserveSig;
+                                       return;
 
-#if NET_2_0
-                       if (attrname == "System.Runtime.CompilerServices.SpecialNameAttribute") {
-                               attrs |= MethodAttributes.SpecialName;
-                               return;
+                               case "System.Runtime.InteropServices.PreserveSigAttribute":
+                                       iattrs |= MethodImplAttributes.PreserveSig;
+                                       return;
+                               case "System.Runtime.CompilerServices.SpecialNameAttribute":
+                                       attrs |= MethodAttributes.SpecialName;
+                                       return;
+                               case "System.Security.SuppressUnmanagedCodeSecurityAttribute":
+                                       attrs |= MethodAttributes.HasSecurity;
+                                       break;
                        }
-#endif
 
                        if (cattrs != null) {
                                CustomAttributeBuilder[] new_array = new CustomAttributeBuilder [cattrs.Length + 1];
@@ -394,22 +445,25 @@ namespace System.Reflection.Emit {
                        }
                }
 
-#if NET_2_0
                [ComVisible (true)]
-#endif
-               public void SetCustomAttribute( ConstructorInfo con, byte[] binaryAttribute) {
+               public void SetCustomAttribute (ConstructorInfo con, byte[] binaryAttribute)
+               {
                        if (con == null)
                                throw new ArgumentNullException ("con");
                        if (binaryAttribute == null)
                                throw new ArgumentNullException ("binaryAttribute");
                        SetCustomAttribute (new CustomAttributeBuilder (con, binaryAttribute));
                }
-               public void SetImplementationFlags( MethodImplAttributes attributes) {
+
+               public void SetImplementationFlags (MethodImplAttributes attributes)
+               {
                        RejectIfCreated ();
                        iattrs = attributes;
                }
 
-               public void AddDeclarativeSecurity( SecurityAction action, PermissionSet pset) {
+               public void AddDeclarativeSecurity (SecurityAction action, PermissionSet pset)
+               {
+#if !NET_2_1
                        if (pset == null)
                                throw new ArgumentNullException ("pset");
                        if ((action == SecurityAction.RequestMinimum) ||
@@ -434,11 +488,10 @@ namespace System.Reflection.Emit {
 
                        permissions [permissions.Length - 1] = new RefEmitPermissionSet (action, pset.ToXml ().ToString ());
                        attrs |= MethodAttributes.HasSecurity;
+#endif
                }
 
-#if NET_2_0
                [Obsolete ("An alternate API is available: Emit the MarshalAs custom attribute instead.")]
-#endif
                public void SetMarshal (UnmanagedMarshal unmanagedMarshal)
                {
                        RejectIfCreated ();
@@ -468,26 +521,53 @@ namespace System.Reflection.Emit {
                        return name.GetHashCode ();
                }
 
-               internal override int get_next_table_index (object obj, int table, bool inc) {
+               internal override int get_next_table_index (object obj, int table, bool inc)
+               {
                        return type.get_next_table_index (obj, table, inc);
                }
 
-               internal void set_override (MethodInfo mdecl) {
-                       override_method = mdecl;
+               void ExtendArray<T> (ref T[] array, T elem) {
+                       if (array == null) {
+                               array = new T [1];
+                       } else {
+                               var newa = new T [array.Length + 1];
+                               Array.Copy (array, newa, array.Length);
+                               array = newa;
+                       }
+                       array [array.Length - 1] = elem;
                }
 
-               private void RejectIfCreated () {
+               internal void set_override (MethodInfo mdecl)
+               {
+                       ExtendArray<MethodInfo> (ref override_methods, mdecl);
+               }
+
+               private void RejectIfCreated ()
+               {
                        if (type.is_created)
                                throw new InvalidOperationException ("Type definition of the method is complete.");
                }
 
-               private Exception NotSupported () {
+               private Exception NotSupported ()
+               {
                        return new NotSupportedException ("The invoked member is not supported in a dynamic module.");
                }
 
-#if NET_2_0 || BOOTSTRAP_NET_2_0
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               public override extern MethodInfo MakeGenericMethod (Type [] types);
+               public override MethodInfo MakeGenericMethod (params Type [] typeArguments)
+               {
+                       if (!IsGenericMethodDefinition)
+                               throw new InvalidOperationException ("Method is not a generic method definition");
+                       if (typeArguments == null)
+                               throw new ArgumentNullException ("typeArguments");
+                       if (generic_params.Length != typeArguments.Length)
+                               throw new ArgumentException ("Incorrect length", "typeArguments");
+                       foreach (Type type in typeArguments) {
+                               if (type == null)
+                                       throw new ArgumentNullException ("typeArguments");
+                       }
+
+                       return new MethodOnTypeBuilderInst (this, typeArguments);
+               }
 
                public override bool IsGenericMethodDefinition {
                        get {
@@ -512,7 +592,7 @@ namespace System.Reflection.Emit {
                public override Type[] GetGenericArguments ()
                {
                        if (generic_params == null)
-                               return new Type [0];
+                               return null;
 
                        Type[] result = new Type [generic_params.Length];
                        for (int i = 0; i < generic_params.Length; i++)
@@ -523,28 +603,22 @@ namespace System.Reflection.Emit {
 
                public GenericTypeParameterBuilder[] DefineGenericParameters (params string[] names)
                {
+                       if (names == null)
+                               throw new ArgumentNullException ("names");
+                       if (names.Length == 0)
+                               throw new ArgumentException ("names");
+
                        generic_params = new GenericTypeParameterBuilder [names.Length];
-                       for (int i = 0; i < names.Length; i++)
-                               generic_params [i] = new GenericTypeParameterBuilder (
-                                       type, this, names [i], i);
+                       for (int i = 0; i < names.Length; i++) {
+                               string item = names [i];
+                               if (item == null)
+                                       throw new ArgumentNullException ("names");
+                               generic_params [i] = new GenericTypeParameterBuilder (type, this, item, i);
+                       }
 
                        return generic_params;
                }
 
-               public void SetGenericMethodSignature (MethodAttributes attributes, CallingConventions callingConvention, Type return_type, Type[] parameter_types)
-               {
-                       RejectIfCreated ();
-
-                       this.attrs = attributes;
-                       this.call_conv = callingConvention;
-                       if ((attributes & MethodAttributes.Static) == 0)
-                               this.call_conv |= CallingConventions.HasThis;
-
-                       this.rtype = return_type;
-                       this.parameters = new Type [parameter_types.Length];
-                       System.Array.Copy (parameter_types, this.parameters, parameter_types.Length);
-               }
-
                public void SetReturnType (Type returnType)
                {
                        rtype = returnType;
@@ -562,7 +636,8 @@ namespace System.Reflection.Emit {
                        }
                }
 
-               public void SetSignature (Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers) {
+               public void SetSignature (Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
+               {
                        SetReturnType (returnType);
                        SetParameters (parameterTypes);
                        this.returnModReq = returnTypeRequiredCustomModifiers;
@@ -576,28 +651,31 @@ namespace System.Reflection.Emit {
                                return base.Module;
                        }
                }
-#endif
 
-                void _MethodBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
-                {
-                        throw new NotImplementedException ();
-                }
+               void _MethodBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
+               {
+                       throw new NotImplementedException ();
+               }
 
-                void _MethodBuilder.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo)
-                {
-                        throw new NotImplementedException ();
-                }
+               void _MethodBuilder.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo)
+               {
+                       throw new NotImplementedException ();
+               }
 
-                void _MethodBuilder.GetTypeInfoCount (out uint pcTInfo)
-                {
-                        throw new NotImplementedException ();
-                }
+               void _MethodBuilder.GetTypeInfoCount (out uint pcTInfo)
+               {
+                       throw new NotImplementedException ();
+               }
 
-                void _MethodBuilder.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
-                {
-                        throw new NotImplementedException ();
-                }
+               void _MethodBuilder.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
+               {
+                       throw new NotImplementedException ();
+               }
 
+#if NET_4_0 || MOONLIGHT
+               public override ParameterInfo ReturnParameter {
+                       get { return base.ReturnParameter; }
+               }
+#endif
        }
 }
-