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 string get_name (MethodBase method);
82 [MethodImplAttribute(MethodImplOptions.InternalCall)]
83 internal static extern MonoMethod get_base_definition (MonoMethod method);
85 public override MethodInfo GetBaseDefinition ()
87 return get_base_definition (this);
90 #if NET_2_0 || BOOTSTRAP_NET_2_0
91 public override ParameterInfo ReturnParameter {
93 return new ParameterInfo (ReturnType, this, MonoMethodInfo.get_retval_marshal (mhandle));
98 public override Type ReturnType {
101 MonoMethodInfo.get_method_info (mhandle, out info);
105 public override ICustomAttributeProvider ReturnTypeCustomAttributes {
107 return new ParameterInfo (ReturnType, this, MonoMethodInfo.get_retval_marshal (mhandle));
111 public override MethodImplAttributes GetMethodImplementationFlags() {
113 MonoMethodInfo.get_method_info (mhandle, out info);
117 public override ParameterInfo[] GetParameters() {
118 return MonoMethodInfo.get_parameter_info (mhandle);
122 * InternalInvoke() receives the parameters correctly converted by the
123 * binder to match the types of the method signature.
125 [MethodImplAttribute(MethodImplOptions.InternalCall)]
126 internal extern Object InternalInvoke (Object obj, Object[] parameters, out Exception exc);
128 public override Object Invoke (Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
131 binder = Binder.DefaultBinder;
132 ParameterInfo[] pinfo = GetParameters ();
133 if (!Binder.ConvertArgs (binder, parameters, pinfo, culture))
134 throw new ArgumentException ("parameters");
137 if (SecurityManager.SecurityEnabled) {
138 // sadly Attributes doesn't tell us which kind of security action this is so
139 // we must do it the hard way - and it also means that we can skip calling
140 // Attribute (which is another an icall)
141 SecurityManager.ReflectedLinkDemandInvoke (this);
146 if (ContainsGenericParameters)
147 throw new InvalidOperationException ("Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true.");
154 // The ex argument is used to distinguish exceptions thrown by the icall
155 // from the exceptions thrown by the called method (which need to be
156 // wrapped in TargetInvocationException).
157 o = InternalInvoke (obj, parameters, out exc);
159 } catch (ThreadAbortException) {
163 } catch (MethodAccessException) {
166 } catch (Exception e) {
167 throw new TargetInvocationException (e);
175 public override RuntimeMethodHandle MethodHandle {
176 get {return new RuntimeMethodHandle (mhandle);}
178 public override MethodAttributes Attributes {
181 MonoMethodInfo.get_method_info (mhandle, out info);
186 public override CallingConventions CallingConvention {
189 MonoMethodInfo.get_method_info (mhandle, out info);
190 return info.callconv;
194 public override Type ReflectedType {
199 public override Type DeclaringType {
202 MonoMethodInfo.get_method_info (mhandle, out info);
206 public override string Name {
210 return get_name (this);
214 public override bool IsDefined (Type attributeType, bool inherit) {
215 return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
218 public override object[] GetCustomAttributes( bool inherit) {
219 return MonoCustomAttrs.GetCustomAttributes (this, inherit);
221 public override object[] GetCustomAttributes( Type attributeType, bool inherit) {
222 return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
225 [MethodImplAttribute(MethodImplOptions.InternalCall)]
226 internal static extern DllImportAttribute GetDllImportAttribute (IntPtr mhandle);
228 internal object[] GetPseudoCustomAttributes ()
232 /* MS.NET doesn't report MethodImplAttribute */
235 MonoMethodInfo.get_method_info (mhandle, out info);
236 if ((info.iattrs & MethodImplAttributes.PreserveSig) != 0)
238 if ((info.attrs & MethodAttributes.PinvokeImpl) != 0)
243 object[] attrs = new object [count];
246 if ((info.iattrs & MethodImplAttributes.PreserveSig) != 0)
247 attrs [count ++] = new PreserveSigAttribute ();
248 if ((info.attrs & MethodAttributes.PinvokeImpl) != 0) {
249 DllImportAttribute attr = GetDllImportAttribute (mhandle);
250 if ((info.iattrs & MethodImplAttributes.PreserveSig) != 0)
251 attr.PreserveSig = true;
252 attrs [count ++] = attr;
258 public override string ToString () {
259 StringBuilder sb = new StringBuilder ();
260 if (ReturnType.IsClass)
261 sb.Append (ReturnType.ToString ());
263 sb.Append (ReturnType.Name);
266 #if NET_2_0 || BOOTSTRAP_NET_2_0
267 if (IsGenericMethod) {
268 Type[] gen_params = GetGenericArguments ();
270 for (int j = 0; j < gen_params.Length; j++) {
273 sb.Append (gen_params [j].Name);
279 ParameterInfo[] p = GetParameters ();
280 for (int i = 0; i < p.Length; ++i) {
283 Type pt = p[i].ParameterType;
284 bool byref = pt.IsByRef;
286 pt = pt.GetElementType ();
288 sb.Append (pt.ToString ());
292 sb.Append (" ByRef");
294 if ((CallingConvention & CallingConventions.VarArgs) != 0) {
301 return sb.ToString ();
306 public void GetObjectData(SerializationInfo info, StreamingContext context)
309 Type[] genericArguments = IsGenericMethod && !IsGenericMethodDefinition
310 ? GetGenericArguments () : null;
311 MemberInfoSerializationHolder.Serialize ( info, Name, ReflectedType, ToString(), MemberTypes.Method, genericArguments);
313 MemberInfoSerializationHolder.Serialize ( info, Name, ReflectedType, ToString(), MemberTypes.Method);
317 #if NET_2_0 || BOOTSTRAP_NET_2_0
318 public override MethodInfo MakeGenericMethod (Type [] methodInstantiation)
320 if (methodInstantiation == null)
321 throw new ArgumentNullException ("methodInstantiation");
322 foreach (Type type in methodInstantiation)
324 throw new ArgumentNullException ();
326 MethodInfo ret = MakeGenericMethod_impl (methodInstantiation);
328 throw new ArgumentException (String.Format ("The method has {0} generic parameter(s) but {1} generic argument(s) were provided.", GetGenericArguments ().Length, methodInstantiation.Length));
332 [MethodImplAttribute(MethodImplOptions.InternalCall)]
333 extern MethodInfo MakeGenericMethod_impl (Type [] types);
335 [MethodImplAttribute(MethodImplOptions.InternalCall)]
336 public override extern Type [] GetGenericArguments ();
338 [MethodImplAttribute(MethodImplOptions.InternalCall)]
339 extern MethodInfo GetGenericMethodDefinition_impl ();
341 public override MethodInfo GetGenericMethodDefinition ()
343 MethodInfo res = GetGenericMethodDefinition_impl ();
345 throw new InvalidOperationException ();
350 public override extern bool IsGenericMethodDefinition {
351 [MethodImplAttribute(MethodImplOptions.InternalCall)]
355 public override extern bool IsGenericMethod {
356 [MethodImplAttribute(MethodImplOptions.InternalCall)]
360 public override bool ContainsGenericParameters {
362 if (IsGenericMethod) {
363 foreach (Type arg in GetGenericArguments ())
364 if (arg.ContainsGenericParameters)
367 return DeclaringType.ContainsGenericParameters;
373 public override MethodBody GetMethodBody () {
374 return GetMethodBody (mhandle);
379 internal class MonoCMethod : ConstructorInfo, ISerializable
381 internal IntPtr mhandle;
385 public override MethodImplAttributes GetMethodImplementationFlags() {
387 MonoMethodInfo.get_method_info (mhandle, out info);
391 public override ParameterInfo[] GetParameters() {
392 return MonoMethodInfo.get_parameter_info (mhandle);
396 * InternalInvoke() receives the parameters corretcly converted by the binder
397 * to match the types of the method signature.
399 [MethodImplAttribute(MethodImplOptions.InternalCall)]
400 internal extern Object InternalInvoke (Object obj, Object[] parameters, out Exception exc);
402 public override Object Invoke (Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
405 binder = Binder.DefaultBinder;
406 ParameterInfo[] pinfo = GetParameters ();
407 if (!Binder.ConvertArgs (binder, parameters, pinfo, culture))
408 throw new ArgumentException ("parameters");
410 if (SecurityManager.SecurityEnabled) {
411 // sadly Attributes doesn't tell us which kind of security action this is so
412 // we must do it the hard way - and it also means that we can skip calling
413 // Attribute (which is another an icall)
414 SecurityManager.ReflectedLinkDemandInvoke (this);
418 if (obj == null && DeclaringType.ContainsGenericParameters)
419 throw new MemberAccessException ("Cannot create an instance of " + DeclaringType + " because Type.ContainsGenericParameters is true.");
422 Exception exc = null;
426 o = InternalInvoke (obj, parameters, out exc);
428 } catch (MethodAccessException) {
431 } catch (Exception e) {
432 throw new TargetInvocationException (e);
440 public override Object Invoke (BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) {
441 return Invoke (null, invokeAttr, binder, parameters, culture);
444 public override RuntimeMethodHandle MethodHandle {
445 get {return new RuntimeMethodHandle (mhandle);}
447 public override MethodAttributes Attributes {
450 MonoMethodInfo.get_method_info (mhandle, out info);
455 public override CallingConventions CallingConvention {
458 MonoMethodInfo.get_method_info (mhandle, out info);
459 return info.callconv;
463 public override Type ReflectedType {
468 public override Type DeclaringType {
471 MonoMethodInfo.get_method_info (mhandle, out info);
475 public override string Name {
479 return MonoMethod.get_name (this);
483 public override bool IsDefined (Type attributeType, bool inherit) {
484 return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
487 public override object[] GetCustomAttributes( bool inherit) {
488 return MonoCustomAttrs.GetCustomAttributes (this, inherit);
491 public override object[] GetCustomAttributes( Type attributeType, bool inherit) {
492 return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
496 public override MethodBody GetMethodBody () {
497 return GetMethodBody (mhandle);
501 public override string ToString () {
502 StringBuilder sb = new StringBuilder ();
506 ParameterInfo[] p = GetParameters ();
507 for (int i = 0; i < p.Length; ++i) {
510 sb.Append (p[i].ParameterType.Name);
513 return sb.ToString ();
517 public void GetObjectData(SerializationInfo info, StreamingContext context)
519 MemberInfoSerializationHolder.Serialize ( info, Name, ReflectedType, ToString(), MemberTypes.Constructor);