2005-05-16 Sebastien Pouliot <sebastien@ximian.com>
[mono.git] / mcs / class / corlib / System.Reflection / MonoMethod.cs
old mode 100755 (executable)
new mode 100644 (file)
index 7c4f23b..263e4d1
@@ -6,13 +6,33 @@
 //   Paolo Molaro (lupus@ximian.com)
 //
 // (C) 2001 Ximian, Inc.  http://www.ximian.com
+// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-using System;
 using System.Globalization;
 using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 using System.Runtime.Serialization;
+using System.Security;
 
 namespace System.Reflection {
        
@@ -81,20 +101,31 @@ namespace System.Reflection {
                }
 
                /*
-                * InternalInvoke() receives the parameters corretcly converted by the binder
-                * to match the types of the method signature.
+                * InternalInvoke() receives the parameters correctly converted by the 
+                * binder to match the types of the method signature.
                 */
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                internal extern Object InternalInvoke (Object obj, Object[] parameters);
                
-               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) 
+               {
                        if (binder == null)
                                binder = Binder.DefaultBinder;
                        ParameterInfo[] pinfo = GetParameters ();
                        if (!Binder.ConvertArgs (binder, parameters, pinfo, culture))
                                throw new ArgumentException ("parameters");
+
+                       if (SecurityManager.SecurityEnabled) {
+                               // sadly Attributes doesn't tell us which kind of security action this is so
+                               // we must do it the hard way - and it also means that we can skip calling
+                               // Attribute (which is another an icall)
+                               SecurityManager.ReflectedLinkDemandInvoke (this);
+                       }
+
                        try {
                                return InternalInvoke (obj, parameters);
+                       } catch (InvalidOperationException) {
+                               throw;
                        } catch (TargetException) {
                                throw;
                        } catch (Exception e) {
@@ -150,6 +181,39 @@ namespace System.Reflection {
                        return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
                }
 
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               internal static extern DllImportAttribute GetDllImportAttribute (IntPtr mhandle);
+
+               internal object[] GetPseudoCustomAttributes ()
+               {
+                       int count = 0;
+
+                       /* MS.NET doesn't report MethodImplAttribute */
+
+                       MonoMethodInfo info;
+                       MonoMethodInfo.get_method_info (mhandle, out info);
+                       if ((info.iattrs & MethodImplAttributes.PreserveSig) != 0)
+                               count ++;
+                       if ((info.attrs & MethodAttributes.PinvokeImpl) != 0)
+                               count ++;
+                       
+                       if (count == 0)
+                               return null;
+                       object[] attrs = new object [count];
+                       count = 0;
+
+                       if ((info.iattrs & MethodImplAttributes.PreserveSig) != 0)
+                               attrs [count ++] = new PreserveSigAttribute ();
+                       if ((info.attrs & MethodAttributes.PinvokeImpl) != 0) {
+                               DllImportAttribute attr = GetDllImportAttribute (mhandle);
+                               if ((info.iattrs & MethodImplAttributes.PreserveSig) != 0)
+                                       attr.PreserveSig = true;
+                               attrs [count ++] = attr;
+                       }
+
+                       return attrs;
+               }
+
                public override string ToString () {
                        string parms = "";
                        ParameterInfo[] p = GetParameters ();
@@ -165,7 +229,7 @@ namespace System.Reflection {
                        if (ReturnType.IsClass && ReturnType.Namespace != "")
                                return ReturnType.Namespace + "." + ReturnType.Name + " " + Name + "(" + parms + ")";
                        string generic = "";
-#if NET_2_0
+#if NET_2_0 || BOOTSTRAP_NET_2_0
                        if (HasGenericParameters) {
                                Type[] gen_params = GetGenericArguments ();
                                generic = "[";
@@ -187,7 +251,7 @@ namespace System.Reflection {
                        ReflectionSerializationHolder.Serialize ( info, Name, ReflectedType, ToString(), MemberTypes.Method);\r
                }\r
 
-#if NET_2_0
+#if NET_2_0 || BOOTSTRAP_NET_2_0
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public override extern MethodInfo BindGenericParameters (Type [] types);
 
@@ -221,6 +285,12 @@ namespace System.Reflection {
                        get;
                }
 #endif
+
+#if NET_2_0
+               public override MethodBody GetMethodBody () {
+                       return GetMethodBody (mhandle);
+               }
+#endif
        }
        
        internal class MonoCMethod : ConstructorInfo, ISerializable\r
@@ -245,15 +315,26 @@ namespace System.Reflection {
                 */
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                internal extern Object InternalInvoke (Object obj, Object[] parameters);
-               
-               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) 
+               {
                        if (binder == null)
                                binder = Binder.DefaultBinder;
                        ParameterInfo[] pinfo = GetParameters ();
                        if (!Binder.ConvertArgs (binder, parameters, pinfo, culture))
                                throw new ArgumentException ("parameters");
+
+                       if (SecurityManager.SecurityEnabled) {
+                               // sadly Attributes doesn't tell us which kind of security action this is so
+                               // we must do it the hard way - and it also means that we can skip calling
+                               // Attribute (which is another an icall)
+                               SecurityManager.ReflectedLinkDemandInvoke (this);
+                       }
+
                        try {
                                return InternalInvoke (obj, parameters);
+                       } catch (InvalidOperationException) {
+                               throw;
                        } catch (TargetException) {
                                throw;
                        } catch (Exception e) {
@@ -314,7 +395,7 @@ namespace System.Reflection {
                        return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
                }
 
-#if NET_2_0
+#if NET_2_0 || BOOTSTRAP_NET_2_0
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                extern MethodInfo GetGenericMethodDefinition_impl ();
 
@@ -345,6 +426,12 @@ namespace System.Reflection {
                }
 #endif
 
+#if NET_2_0
+               public override MethodBody GetMethodBody () {
+                       return GetMethodBody (mhandle);
+               }
+#endif
+
                public override string ToString () {
                        string parms = "";
                        ParameterInfo[] p = GetParameters ();