2 // System.Reflection/MonoMethod.cs
3 // The class used to represent methods from the mono runtime.
6 // Paolo Molaro (lupus@ximian.com)
8 // (C) 2001 Ximian, Inc. http://www.ximian.com
9 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System.Globalization;
32 using System.Runtime.CompilerServices;
33 using System.Runtime.InteropServices;
34 using System.Runtime.Serialization;
35 using System.Reflection.Emit;
36 using System.Security;
37 using System.Threading;
41 namespace System.Reflection {
43 internal struct MonoMethodInfo
47 internal MethodAttributes attrs;
48 internal MethodImplAttributes iattrs;
49 internal CallingConventions callconv;
51 [MethodImplAttribute(MethodImplOptions.InternalCall)]
52 internal static extern void get_method_info (IntPtr handle, out MonoMethodInfo info);
54 [MethodImplAttribute(MethodImplOptions.InternalCall)]
55 internal static extern ParameterInfo[] get_parameter_info (IntPtr handle);
57 [MethodImplAttribute(MethodImplOptions.InternalCall)]
58 internal static extern UnmanagedMarshal get_retval_marshal (IntPtr handle);
62 * Note: most of this class needs to be duplicated for the contructor, since
63 * the .NET reflection class hierarchy is so broken.
66 internal class MonoMethod : MethodInfo, ISerializable
68 internal IntPtr mhandle;
72 internal MonoMethod () {
75 internal MonoMethod (RuntimeMethodHandle mhandle) {
76 this.mhandle = mhandle.Value;
79 [MethodImplAttribute(MethodImplOptions.InternalCall)]
80 internal static extern MonoMethod get_base_definition (MonoMethod method);
82 public override MethodInfo GetBaseDefinition ()
84 return get_base_definition (this);
87 #if NET_2_0 || BOOTSTRAP_NET_2_0
88 public override ParameterInfo ReturnParameter {
90 return new ParameterInfo (ReturnType, this, MonoMethodInfo.get_retval_marshal (mhandle));
95 public override Type ReturnType {
98 MonoMethodInfo.get_method_info (mhandle, out info);
102 public override ICustomAttributeProvider ReturnTypeCustomAttributes {
104 return new ParameterInfo (ReturnType, this, MonoMethodInfo.get_retval_marshal (mhandle));
108 public override MethodImplAttributes GetMethodImplementationFlags() {
110 MonoMethodInfo.get_method_info (mhandle, out info);
114 public override ParameterInfo[] GetParameters() {
115 return MonoMethodInfo.get_parameter_info (mhandle);
119 * InternalInvoke() receives the parameters correctly converted by the
120 * binder to match the types of the method signature.
122 [MethodImplAttribute(MethodImplOptions.InternalCall)]
123 internal extern Object InternalInvoke (Object obj, Object[] parameters);
125 public override Object Invoke (Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
128 binder = Binder.DefaultBinder;
129 ParameterInfo[] pinfo = GetParameters ();
130 if (!Binder.ConvertArgs (binder, parameters, pinfo, culture))
131 throw new ArgumentException ("parameters");
133 if (SecurityManager.SecurityEnabled) {
134 // sadly Attributes doesn't tell us which kind of security action this is so
135 // we must do it the hard way - and it also means that we can skip calling
136 // Attribute (which is another an icall)
137 SecurityManager.ReflectedLinkDemandInvoke (this);
141 if (ContainsGenericParameters)
142 throw new InvalidOperationException ("Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true.");
146 return InternalInvoke (obj, parameters);
147 } catch (InvalidOperationException) {
149 } catch (TargetException) {
152 } catch (ThreadAbortException) {
155 } catch (Exception e) {
156 throw new TargetInvocationException (e);
160 public override RuntimeMethodHandle MethodHandle {
161 get {return new RuntimeMethodHandle (mhandle);}
163 public override MethodAttributes Attributes {
166 MonoMethodInfo.get_method_info (mhandle, out info);
171 public override CallingConventions CallingConvention {
174 MonoMethodInfo.get_method_info (mhandle, out info);
175 return info.callconv;
179 public override Type ReflectedType {
184 public override Type DeclaringType {
187 MonoMethodInfo.get_method_info (mhandle, out info);
191 public override string Name {
197 public override bool IsDefined (Type attributeType, bool inherit) {
198 return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
201 public override object[] GetCustomAttributes( bool inherit) {
202 return MonoCustomAttrs.GetCustomAttributes (this, inherit);
204 public override object[] GetCustomAttributes( Type attributeType, bool inherit) {
205 return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
208 [MethodImplAttribute(MethodImplOptions.InternalCall)]
209 internal static extern DllImportAttribute GetDllImportAttribute (IntPtr mhandle);
211 internal object[] GetPseudoCustomAttributes ()
215 /* MS.NET doesn't report MethodImplAttribute */
218 MonoMethodInfo.get_method_info (mhandle, out info);
219 if ((info.iattrs & MethodImplAttributes.PreserveSig) != 0)
221 if ((info.attrs & MethodAttributes.PinvokeImpl) != 0)
226 object[] attrs = new object [count];
229 if ((info.iattrs & MethodImplAttributes.PreserveSig) != 0)
230 attrs [count ++] = new PreserveSigAttribute ();
231 if ((info.attrs & MethodAttributes.PinvokeImpl) != 0) {
232 DllImportAttribute attr = GetDllImportAttribute (mhandle);
233 if ((info.iattrs & MethodImplAttributes.PreserveSig) != 0)
234 attr.PreserveSig = true;
235 attrs [count ++] = attr;
241 public override string ToString () {
242 StringBuilder sb = new StringBuilder ();
243 if (ReturnType.IsClass)
244 sb.Append (ReturnType.ToString ());
246 sb.Append (ReturnType.Name);
249 #if NET_2_0 || BOOTSTRAP_NET_2_0
250 if (IsGenericMethod) {
251 Type[] gen_params = GetGenericArguments ();
253 for (int j = 0; j < gen_params.Length; j++) {
256 sb.Append (gen_params [j].Name);
262 ParameterInfo[] p = GetParameters ();
263 for (int i = 0; i < p.Length; ++i) {
266 Type pt = p[i].ParameterType;
267 bool byref = pt.IsByRef;
269 pt = pt.GetElementType ();
271 sb.Append (pt.ToString ());
275 sb.Append (" ByRef");
278 return sb.ToString ();
283 public void GetObjectData(SerializationInfo info, StreamingContext context)
285 ReflectionSerializationHolder.Serialize ( info, Name, ReflectedType, ToString(), MemberTypes.Method);
288 #if NET_2_0 || BOOTSTRAP_NET_2_0
289 public override MethodInfo MakeGenericMethod (Type [] types)
292 throw new ArgumentNullException ("types");
293 MethodInfo ret = MakeGenericMethod_impl (types);
295 throw new ArgumentException (String.Format ("The method has {0} generic parameter(s) but {1} generic argument(s) were provided.", GetGenericArguments ().Length, types.Length));
299 [MethodImplAttribute(MethodImplOptions.InternalCall)]
300 extern MethodInfo MakeGenericMethod_impl (Type [] types);
302 [MethodImplAttribute(MethodImplOptions.InternalCall)]
303 public override extern Type [] GetGenericArguments ();
305 [MethodImplAttribute(MethodImplOptions.InternalCall)]
306 extern MethodInfo GetGenericMethodDefinition_impl ();
308 public override MethodInfo GetGenericMethodDefinition ()
310 MethodInfo res = GetGenericMethodDefinition_impl ();
312 throw new InvalidOperationException ();
317 public override extern bool IsGenericMethodDefinition {
318 [MethodImplAttribute(MethodImplOptions.InternalCall)]
322 public override extern bool IsGenericMethod {
323 [MethodImplAttribute(MethodImplOptions.InternalCall)]
327 public override bool ContainsGenericParameters {
329 if (IsGenericMethod) {
330 foreach (Type arg in GetGenericArguments ())
331 if (arg.ContainsGenericParameters)
334 return DeclaringType.ContainsGenericParameters;
340 public override MethodBody GetMethodBody () {
341 return GetMethodBody (mhandle);
346 internal class MonoCMethod : ConstructorInfo, ISerializable
348 internal IntPtr mhandle;
352 public override MethodImplAttributes GetMethodImplementationFlags() {
354 MonoMethodInfo.get_method_info (mhandle, out info);
358 public override ParameterInfo[] GetParameters() {
359 return MonoMethodInfo.get_parameter_info (mhandle);
363 * InternalInvoke() receives the parameters corretcly converted by the binder
364 * to match the types of the method signature.
366 [MethodImplAttribute(MethodImplOptions.InternalCall)]
367 internal extern Object InternalInvoke (Object obj, Object[] parameters);
369 public override Object Invoke (Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
372 binder = Binder.DefaultBinder;
373 ParameterInfo[] pinfo = GetParameters ();
374 if (!Binder.ConvertArgs (binder, parameters, pinfo, culture))
375 throw new ArgumentException ("parameters");
377 if (SecurityManager.SecurityEnabled) {
378 // sadly Attributes doesn't tell us which kind of security action this is so
379 // we must do it the hard way - and it also means that we can skip calling
380 // Attribute (which is another an icall)
381 SecurityManager.ReflectedLinkDemandInvoke (this);
385 return InternalInvoke (obj, parameters);
386 } catch (InvalidOperationException) {
388 } catch (TargetException) {
390 } catch (Exception e) {
391 throw new TargetInvocationException (e);
395 public override Object Invoke (BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) {
396 return Invoke (null, invokeAttr, binder, parameters, culture);
399 public override RuntimeMethodHandle MethodHandle {
400 get {return new RuntimeMethodHandle (mhandle);}
402 public override MethodAttributes Attributes {
405 MonoMethodInfo.get_method_info (mhandle, out info);
410 public override CallingConventions CallingConvention {
413 MonoMethodInfo.get_method_info (mhandle, out info);
414 return info.callconv;
418 public override Type ReflectedType {
423 public override Type DeclaringType {
426 MonoMethodInfo.get_method_info (mhandle, out info);
430 public override string Name {
436 public override bool IsDefined (Type attributeType, bool inherit) {
437 return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
440 public override object[] GetCustomAttributes( bool inherit) {
441 return MonoCustomAttrs.GetCustomAttributes (this, inherit);
444 public override object[] GetCustomAttributes( Type attributeType, bool inherit) {
445 return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
449 public override MethodBody GetMethodBody () {
450 return GetMethodBody (mhandle);
454 public override string ToString () {
455 StringBuilder sb = new StringBuilder ();
459 ParameterInfo[] p = GetParameters ();
460 for (int i = 0; i < p.Length; ++i) {
463 sb.Append (p[i].ParameterType.Name);
466 return sb.ToString ();
470 public void GetObjectData(SerializationInfo info, StreamingContext context)
472 ReflectionSerializationHolder.Serialize ( info, Name, ReflectedType, ToString(), MemberTypes.Constructor);