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;
38 namespace System.Reflection {
40 internal struct MonoMethodInfo
44 internal MethodAttributes attrs;
45 internal MethodImplAttributes iattrs;
46 internal CallingConventions callconv;
48 [MethodImplAttribute(MethodImplOptions.InternalCall)]
49 internal static extern void get_method_info (IntPtr handle, out MonoMethodInfo info);
51 [MethodImplAttribute(MethodImplOptions.InternalCall)]
52 internal static extern ParameterInfo[] get_parameter_info (IntPtr handle);
54 [MethodImplAttribute(MethodImplOptions.InternalCall)]
55 internal static extern UnmanagedMarshal get_retval_marshal (IntPtr handle);
59 * Note: most of this class needs to be duplicated for the contructor, since
60 * the .NET reflection class hierarchy is so broken.
63 internal class MonoMethod : MethodInfo, ISerializable
65 internal IntPtr mhandle;
69 internal MonoMethod () {
72 internal MonoMethod (RuntimeMethodHandle mhandle) {
73 this.mhandle = mhandle.Value;
76 [MethodImplAttribute(MethodImplOptions.InternalCall)]
77 internal static extern MonoMethod get_base_definition (MonoMethod method);
79 public override MethodInfo GetBaseDefinition ()
81 return get_base_definition (this);
84 #if NET_2_0 || BOOTSTRAP_NET_2_0
85 public override ParameterInfo ReturnParameter {
87 return new ParameterInfo (ReturnType, this, MonoMethodInfo.get_retval_marshal (mhandle));
92 public override Type ReturnType {
95 MonoMethodInfo.get_method_info (mhandle, out info);
99 public override ICustomAttributeProvider ReturnTypeCustomAttributes {
101 return new ParameterInfo (ReturnType, this, MonoMethodInfo.get_retval_marshal (mhandle));
105 public override MethodImplAttributes GetMethodImplementationFlags() {
107 MonoMethodInfo.get_method_info (mhandle, out info);
111 public override ParameterInfo[] GetParameters() {
112 return MonoMethodInfo.get_parameter_info (mhandle);
116 * InternalInvoke() receives the parameters correctly converted by the
117 * binder to match the types of the method signature.
119 [MethodImplAttribute(MethodImplOptions.InternalCall)]
120 internal extern Object InternalInvoke (Object obj, Object[] parameters);
122 public override Object Invoke (Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
125 binder = Binder.DefaultBinder;
126 ParameterInfo[] pinfo = GetParameters ();
127 if (!Binder.ConvertArgs (binder, parameters, pinfo, culture))
128 throw new ArgumentException ("parameters");
130 if (SecurityManager.SecurityEnabled) {
131 // sadly Attributes doesn't tell us which kind of security action this is so
132 // we must do it the hard way - and it also means that we can skip calling
133 // Attribute (which is another an icall)
134 SecurityManager.ReflectedLinkDemandInvoke (this);
138 if (ContainsGenericParameters)
139 throw new InvalidOperationException ("Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true.");
143 return InternalInvoke (obj, parameters);
144 } catch (InvalidOperationException) {
146 } catch (TargetException) {
148 } catch (Exception e) {
149 throw new TargetInvocationException (e);
153 public override RuntimeMethodHandle MethodHandle {
154 get {return new RuntimeMethodHandle (mhandle);}
156 public override MethodAttributes Attributes {
159 MonoMethodInfo.get_method_info (mhandle, out info);
164 public override CallingConventions CallingConvention {
167 MonoMethodInfo.get_method_info (mhandle, out info);
168 return info.callconv;
172 public override Type ReflectedType {
177 public override Type DeclaringType {
180 MonoMethodInfo.get_method_info (mhandle, out info);
184 public override string Name {
190 public override bool IsDefined (Type attributeType, bool inherit) {
191 return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
194 public override object[] GetCustomAttributes( bool inherit) {
195 return MonoCustomAttrs.GetCustomAttributes (this, inherit);
197 public override object[] GetCustomAttributes( Type attributeType, bool inherit) {
198 return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
201 [MethodImplAttribute(MethodImplOptions.InternalCall)]
202 internal static extern DllImportAttribute GetDllImportAttribute (IntPtr mhandle);
204 internal object[] GetPseudoCustomAttributes ()
208 /* MS.NET doesn't report MethodImplAttribute */
211 MonoMethodInfo.get_method_info (mhandle, out info);
212 if ((info.iattrs & MethodImplAttributes.PreserveSig) != 0)
214 if ((info.attrs & MethodAttributes.PinvokeImpl) != 0)
219 object[] attrs = new object [count];
222 if ((info.iattrs & MethodImplAttributes.PreserveSig) != 0)
223 attrs [count ++] = new PreserveSigAttribute ();
224 if ((info.attrs & MethodAttributes.PinvokeImpl) != 0) {
225 DllImportAttribute attr = GetDllImportAttribute (mhandle);
226 if ((info.iattrs & MethodImplAttributes.PreserveSig) != 0)
227 attr.PreserveSig = true;
228 attrs [count ++] = attr;
234 public override string ToString () {
236 ParameterInfo[] p = GetParameters ();
237 for (int i = 0; i < p.Length; ++i) {
239 parms = parms + ", ";
240 Type pt = p[i].ParameterType;
241 bool byref = pt.IsByRef;
243 pt = pt.GetElementType ();
244 if (pt.IsClass && pt.Namespace != "")
245 parms = parms + pt.Namespace + "." + pt.Name;
247 parms = parms + pt.Name;
251 if (ReturnType.IsClass && ReturnType.Namespace != "")
252 return ReturnType.Namespace + "." + ReturnType.Name + " " + Name + "(" + parms + ")";
254 #if NET_2_0 || BOOTSTRAP_NET_2_0
255 if (IsGenericMethod) {
256 Type[] gen_params = GetGenericArguments ();
258 for (int j = 0; j < gen_params.Length; j++) {
261 generic += gen_params [j].Name;
266 return ReturnType.Name + " " + Name + generic + "(" + parms + ")";
271 public void GetObjectData(SerializationInfo info, StreamingContext context)
273 ReflectionSerializationHolder.Serialize ( info, Name, ReflectedType, ToString(), MemberTypes.Method);
276 #if NET_2_0 || BOOTSTRAP_NET_2_0
277 public override MethodInfo MakeGenericMethod (Type [] types)
280 throw new ArgumentNullException ("types");
281 MethodInfo ret = MakeGenericMethod_impl (types);
283 throw new ArgumentException (String.Format ("The method has {0} generic parameter(s) but {1} generic argument(s) were provided.", GetGenericArguments ().Length, types.Length));
287 [MethodImplAttribute(MethodImplOptions.InternalCall)]
288 extern MethodInfo MakeGenericMethod_impl (Type [] types);
290 [MethodImplAttribute(MethodImplOptions.InternalCall)]
291 public override extern Type [] GetGenericArguments ();
293 [MethodImplAttribute(MethodImplOptions.InternalCall)]
294 extern MethodInfo GetGenericMethodDefinition_impl ();
296 public override MethodInfo GetGenericMethodDefinition ()
298 MethodInfo res = GetGenericMethodDefinition_impl ();
300 throw new InvalidOperationException ();
305 public override extern bool IsGenericMethodDefinition {
306 [MethodImplAttribute(MethodImplOptions.InternalCall)]
310 public override extern bool IsGenericMethod {
311 [MethodImplAttribute(MethodImplOptions.InternalCall)]
315 public override bool ContainsGenericParameters {
317 if (IsGenericMethod) {
318 foreach (Type arg in GetGenericArguments ())
319 if (arg.ContainsGenericParameters)
322 return DeclaringType.ContainsGenericParameters;
328 public override MethodBody GetMethodBody () {
329 return GetMethodBody (mhandle);
334 internal class MonoCMethod : ConstructorInfo, ISerializable
336 internal IntPtr mhandle;
340 public override MethodImplAttributes GetMethodImplementationFlags() {
342 MonoMethodInfo.get_method_info (mhandle, out info);
346 public override ParameterInfo[] GetParameters() {
347 return MonoMethodInfo.get_parameter_info (mhandle);
351 * InternalInvoke() receives the parameters corretcly converted by the binder
352 * to match the types of the method signature.
354 [MethodImplAttribute(MethodImplOptions.InternalCall)]
355 internal extern Object InternalInvoke (Object obj, Object[] parameters);
357 public override Object Invoke (Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
360 binder = Binder.DefaultBinder;
361 ParameterInfo[] pinfo = GetParameters ();
362 if (!Binder.ConvertArgs (binder, parameters, pinfo, culture))
363 throw new ArgumentException ("parameters");
365 if (SecurityManager.SecurityEnabled) {
366 // sadly Attributes doesn't tell us which kind of security action this is so
367 // we must do it the hard way - and it also means that we can skip calling
368 // Attribute (which is another an icall)
369 SecurityManager.ReflectedLinkDemandInvoke (this);
373 return InternalInvoke (obj, parameters);
374 } catch (InvalidOperationException) {
376 } catch (TargetException) {
378 } catch (Exception e) {
379 throw new TargetInvocationException (e);
383 public override Object Invoke (BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) {
384 return Invoke (null, invokeAttr, binder, parameters, culture);
387 public override RuntimeMethodHandle MethodHandle {
388 get {return new RuntimeMethodHandle (mhandle);}
390 public override MethodAttributes Attributes {
393 MonoMethodInfo.get_method_info (mhandle, out info);
398 public override CallingConventions CallingConvention {
401 MonoMethodInfo.get_method_info (mhandle, out info);
402 return info.callconv;
406 public override Type ReflectedType {
411 public override Type DeclaringType {
414 MonoMethodInfo.get_method_info (mhandle, out info);
418 public override string Name {
424 public override bool IsDefined (Type attributeType, bool inherit) {
425 return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
428 public override object[] GetCustomAttributes( bool inherit) {
429 return MonoCustomAttrs.GetCustomAttributes (this, inherit);
432 public override object[] GetCustomAttributes( Type attributeType, bool inherit) {
433 return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
436 #if NET_2_0 || BOOTSTRAP_NET_2_0
437 public override bool IsGenericMethodDefinition {
443 public override bool IsGenericMethod {
451 public override MethodBody GetMethodBody () {
452 return GetMethodBody (mhandle);
456 public override string ToString () {
458 ParameterInfo[] p = GetParameters ();
459 for (int i = 0; i < p.Length; ++i) {
461 parms = parms + ", ";
462 parms = parms + p [i].ParameterType.Name;
464 return "Void "+Name+"("+parms+")";
468 public void GetObjectData(SerializationInfo info, StreamingContext context)
470 ReflectionSerializationHolder.Serialize ( info, Name, ReflectedType, ToString(), MemberTypes.Constructor);