Fix null sessions in HttpContextWrapper.Session
[mono.git] / mcs / class / corlib / System.Reflection / MonoMethod.cs
1 //
2 // MonoMethod.cs: The class used to represent methods from the mono runtime.
3 //
4 // Authors:
5 //   Paolo Molaro (lupus@ximian.com)
6 //   Marek Safar (marek.safar@gmail.com)
7 //
8 // (C) 2001 Ximian, Inc.  http://www.ximian.com
9 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
10 // Copyright (C) 2012 Xamarin Inc (http://www.xamarin.com)
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31
32 using System.Collections.Generic;
33 using System.Globalization;
34 using System.Runtime.CompilerServices;
35 using System.Runtime.InteropServices;
36 using System.Runtime.Serialization;
37 using System.Reflection.Emit;
38 using System.Security;
39 using System.Threading;
40 using System.Text;
41 using System.Diagnostics;
42
43 namespace System.Reflection {
44         
45         internal struct MonoMethodInfo 
46         {
47 #pragma warning disable 649     
48                 private Type parent;
49                 private Type ret;
50                 internal MethodAttributes attrs;
51                 internal MethodImplAttributes iattrs;
52                 private CallingConventions callconv;
53 #pragma warning restore 649             
54
55                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
56                 static extern void get_method_info (IntPtr handle, out MonoMethodInfo info);
57                 
58                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
59                 static extern int get_method_attributes (IntPtr handle);
60                 
61                 internal static MonoMethodInfo GetMethodInfo (IntPtr handle)
62                 {
63                         MonoMethodInfo info;
64                         MonoMethodInfo.get_method_info (handle, out info);
65                         return info;
66                 }
67
68                 internal static Type GetDeclaringType (IntPtr handle)
69                 {
70                         return GetMethodInfo (handle).parent;
71                 }
72
73                 internal static Type GetReturnType (IntPtr handle)
74                 {
75                         return GetMethodInfo (handle).ret;
76                 }
77
78                 internal static MethodAttributes GetAttributes (IntPtr handle)
79                 {
80                         return (MethodAttributes)get_method_attributes (handle);
81                 }
82
83                 internal static CallingConventions GetCallingConvention (IntPtr handle)
84                 {
85                         return GetMethodInfo (handle).callconv;
86                 }
87
88                 internal static MethodImplAttributes GetMethodImplementationFlags (IntPtr handle)
89                 {
90                         return GetMethodInfo (handle).iattrs;
91                 }
92
93                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
94                 static extern ParameterInfo[] get_parameter_info (IntPtr handle, MemberInfo member);
95
96                 static internal ParameterInfo[] GetParametersInfo (IntPtr handle, MemberInfo member)
97                 {
98                         return get_parameter_info (handle, member);
99                 }
100
101                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
102                 static extern UnmanagedMarshal get_retval_marshal (IntPtr handle);
103
104                 static internal ParameterInfo GetReturnParameterInfo (MonoMethod method)
105                 {
106                         return new ParameterInfo (GetReturnType (method.mhandle), method, get_retval_marshal (method.mhandle));
107                 }
108         };
109         
110         /*
111          * Note: most of this class needs to be duplicated for the contructor, since
112          * the .NET reflection class hierarchy is so broken.
113          */
114         [Serializable()]
115         [StructLayout (LayoutKind.Sequential)]
116         internal class MonoMethod : MethodInfo, ISerializable
117         {
118 #pragma warning disable 649
119                 internal IntPtr mhandle;
120                 string name;
121                 Type reftype;
122 #pragma warning restore 649
123
124                 internal MonoMethod () {
125                 }
126
127                 internal MonoMethod (RuntimeMethodHandle mhandle) {
128                         this.mhandle = mhandle.Value;
129                 }
130                 
131                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
132                 internal static extern string get_name (MethodBase method);
133
134                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
135                 internal static extern MonoMethod get_base_method (MonoMethod method, bool definition);
136
137                 public override MethodInfo GetBaseDefinition ()
138                 {
139                         return get_base_method (this, true);
140                 }
141
142                 internal override MethodInfo GetBaseMethod ()
143                 {
144                         return get_base_method (this, false);
145                 }
146
147                 public override ParameterInfo ReturnParameter {
148                         get {
149                                 return MonoMethodInfo.GetReturnParameterInfo (this);
150                         }
151                 }
152
153                 public override Type ReturnType {
154                         get {
155                                 return MonoMethodInfo.GetReturnType (mhandle);
156                         }
157                 }
158                 public override ICustomAttributeProvider ReturnTypeCustomAttributes { 
159                         get {
160                                 return MonoMethodInfo.GetReturnParameterInfo (this);
161                         }
162                 }
163                 
164                 public override MethodImplAttributes GetMethodImplementationFlags ()
165                 {
166                         return MonoMethodInfo.GetMethodImplementationFlags (mhandle);
167                 }
168
169                 public override ParameterInfo[] GetParameters ()
170                 {
171                         ParameterInfo[] src = MonoMethodInfo.GetParametersInfo (mhandle, this);
172                         ParameterInfo[] res = new ParameterInfo [src.Length];
173                         src.CopyTo (res, 0);
174                         return res;
175                 }
176                 
177                 internal override int GetParameterCount ()
178                 {
179                         var pi = MonoMethodInfo.GetParametersInfo (mhandle, this);
180                         return pi == null ? 0 : pi.Length;
181                 }
182
183                 /*
184                  * InternalInvoke() receives the parameters correctly converted by the 
185                  * binder to match the types of the method signature.
186                  */
187                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
188                 internal extern Object InternalInvoke (Object obj, Object[] parameters, out Exception exc);
189
190                 [DebuggerHidden]
191                 [DebuggerStepThrough]
192                 public override Object Invoke (Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) 
193                 {
194                         if (binder == null)
195                                 binder = Binder.DefaultBinder;
196
197                         /*Avoid allocating an array every time*/
198                         ParameterInfo[] pinfo = MonoMethodInfo.GetParametersInfo (mhandle, this);
199                         if (!binder.ConvertArgs (parameters, pinfo, culture, (invokeAttr & BindingFlags.ExactBinding) != 0))
200                                 throw new ArgumentException ("failed to convert parameters");
201
202 #if !NET_2_1
203                         if (SecurityManager.SecurityEnabled) {
204                                 // sadly Attributes doesn't tell us which kind of security action this is so
205                                 // we must do it the hard way - and it also means that we can skip calling
206                                 // Attribute (which is another an icall)
207                                 SecurityManager.ReflectedLinkDemandInvoke (this);
208                         }
209 #endif
210
211                         if (ContainsGenericParameters)
212                                 throw new InvalidOperationException ("Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true.");
213
214                         Exception exc;
215                         object o = null;
216
217                         try {
218                                 // The ex argument is used to distinguish exceptions thrown by the icall
219                                 // from the exceptions thrown by the called method (which need to be
220                                 // wrapped in TargetInvocationException).
221                                 o = InternalInvoke (obj, parameters, out exc);
222                         } catch (ThreadAbortException) {
223                                 throw;
224 #if NET_2_1
225                         } catch (MethodAccessException) {
226                                 throw;
227 #endif
228                         } catch (Exception e) {
229                                 throw new TargetInvocationException (e);
230                         }
231
232                         if (exc != null)
233                                 throw exc;
234                         return o;
235                 }
236
237                 public override RuntimeMethodHandle MethodHandle { 
238                         get {
239                                 return new RuntimeMethodHandle (mhandle);
240                         } 
241                 }
242                 
243                 public override MethodAttributes Attributes { 
244                         get {
245                                 return MonoMethodInfo.GetAttributes (mhandle);
246                         } 
247                 }
248
249                 public override CallingConventions CallingConvention { 
250                         get {
251                                 return MonoMethodInfo.GetCallingConvention (mhandle);
252                         }
253                 }
254                 
255                 public override Type ReflectedType {
256                         get {
257                                 return reftype;
258                         }
259                 }
260                 public override Type DeclaringType {
261                         get {
262                                 return MonoMethodInfo.GetDeclaringType (mhandle);
263                         }
264                 }
265                 public override string Name {
266                         get {
267                                 if (name != null)
268                                         return name;
269                                 return get_name (this);
270                         }
271                 }
272                 
273                 public override bool IsDefined (Type attributeType, bool inherit) {
274                         return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
275                 }
276
277                 public override object[] GetCustomAttributes( bool inherit) {
278                         return MonoCustomAttrs.GetCustomAttributes (this, inherit);
279                 }
280                 public override object[] GetCustomAttributes( Type attributeType, bool inherit) {
281                         return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
282                 }
283
284                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
285                 internal static extern DllImportAttribute GetDllImportAttribute (IntPtr mhandle);
286
287                 internal object[] GetPseudoCustomAttributes ()
288                 {
289                         int count = 0;
290
291                         /* MS.NET doesn't report MethodImplAttribute */
292
293                         MonoMethodInfo info = MonoMethodInfo.GetMethodInfo (mhandle);
294                         if ((info.iattrs & MethodImplAttributes.PreserveSig) != 0)
295                                 count ++;
296                         if ((info.attrs & MethodAttributes.PinvokeImpl) != 0)
297                                 count ++;
298                         
299                         if (count == 0)
300                                 return null;
301                         object[] attrs = new object [count];
302                         count = 0;
303
304                         if ((info.iattrs & MethodImplAttributes.PreserveSig) != 0)
305                                 attrs [count ++] = new PreserveSigAttribute ();
306                         if ((info.attrs & MethodAttributes.PinvokeImpl) != 0) {
307                                 DllImportAttribute attr = GetDllImportAttribute (mhandle);
308                                 if ((info.iattrs & MethodImplAttributes.PreserveSig) != 0)
309                                         attr.PreserveSig = true;
310                                 attrs [count ++] = attr;
311                         }
312
313                         return attrs;
314                 }
315
316                 static bool ShouldPrintFullName (Type type) {
317                         return type.IsClass && (!type.IsPointer ||
318                                 (!type.GetElementType ().IsPrimitive && !type.GetElementType ().IsNested));
319                 }
320
321                 public override string ToString () {
322                         StringBuilder sb = new StringBuilder ();
323                         Type retType = ReturnType;
324                         if (ShouldPrintFullName (retType))
325                                 sb.Append (retType.ToString ());
326                         else
327                                 sb.Append (retType.Name);
328                         sb.Append (" ");
329                         sb.Append (Name);
330                         if (IsGenericMethod) {
331                                 Type[] gen_params = GetGenericArguments ();
332                                 sb.Append ("[");
333                                 for (int j = 0; j < gen_params.Length; j++) {
334                                         if (j > 0)
335                                                 sb.Append (",");
336                                         sb.Append (gen_params [j].Name);
337                                 }
338                                 sb.Append ("]");
339                         }
340                         sb.Append ("(");
341                         ParameterInfo[] p = GetParameters ();
342                         for (int i = 0; i < p.Length; ++i) {
343                                 if (i > 0)
344                                         sb.Append (", ");
345                                 Type pt = p[i].ParameterType;
346                                 bool byref = pt.IsByRef;
347                                 if (byref)
348                                         pt = pt.GetElementType ();
349                                 if (ShouldPrintFullName (pt))
350                                         sb.Append (pt.ToString ());
351                                 else
352                                         sb.Append (pt.Name);
353                                 if (byref)
354                                         sb.Append (" ByRef");
355                         }
356                         if ((CallingConvention & CallingConventions.VarArgs) != 0) {
357                                 if (p.Length > 0)
358                                         sb.Append (", ");
359                                 sb.Append ("...");
360                         }
361                         
362                         sb.Append (")");
363                         return sb.ToString ();
364                 }
365
366         
367                 // ISerializable
368                 public void GetObjectData(SerializationInfo info, StreamingContext context) 
369                 {
370                         Type[] genericArguments = IsGenericMethod && !IsGenericMethodDefinition
371                                 ? GetGenericArguments () : null;
372                         MemberInfoSerializationHolder.Serialize ( info, Name, ReflectedType, ToString(), MemberTypes.Method, genericArguments);
373                 }
374
375                 public override MethodInfo MakeGenericMethod (Type [] methodInstantiation)
376                 {
377                         if (methodInstantiation == null)
378                                 throw new ArgumentNullException ("methodInstantiation");
379
380                         if (!IsGenericMethodDefinition)
381                                 throw new InvalidOperationException ("not a generic method definition");
382
383                         /*FIXME add GetGenericArgumentsLength() internal vcall to speed this up*/
384                         if (GetGenericArguments ().Length != methodInstantiation.Length)
385                                 throw new ArgumentException ("Incorrect length");
386
387                         bool hasUserType = false;
388                         foreach (Type type in methodInstantiation) {
389                                 if (type == null)
390                                         throw new ArgumentNullException ();
391                                 if (!(type is MonoType))
392                                         hasUserType = true;
393                         }
394
395                         if (hasUserType)
396                                 return new MethodOnTypeBuilderInst (this, methodInstantiation);
397
398                         MethodInfo ret = MakeGenericMethod_impl (methodInstantiation);
399                         if (ret == null)
400                                 throw new ArgumentException (String.Format ("The method has {0} generic parameter(s) but {1} generic argument(s) were provided.", GetGenericArguments ().Length, methodInstantiation.Length));
401                         return ret;
402                 }
403
404                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
405                 extern MethodInfo MakeGenericMethod_impl (Type [] types);
406
407                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
408                 public override extern Type [] GetGenericArguments ();
409
410                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
411                 extern MethodInfo GetGenericMethodDefinition_impl ();
412
413                 public override MethodInfo GetGenericMethodDefinition ()
414                 {
415                         MethodInfo res = GetGenericMethodDefinition_impl ();
416                         if (res == null)
417                                 throw new InvalidOperationException ();
418
419                         return res;
420                 }
421
422                 public override extern bool IsGenericMethodDefinition {
423                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
424                         get;
425                 }
426
427                 public override extern bool IsGenericMethod {
428                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
429                         get;
430                 }
431
432                 public override bool ContainsGenericParameters {
433                         get {
434                                 if (IsGenericMethod) {
435                                         foreach (Type arg in GetGenericArguments ())
436                                                 if (arg.ContainsGenericParameters)
437                                                         return true;
438                                 }
439                                 return DeclaringType.ContainsGenericParameters;
440                         }
441                 }
442
443                 public override MethodBody GetMethodBody () {
444                         return GetMethodBody (mhandle);
445                 }
446
447 #if NET_4_0
448                 public override IList<CustomAttributeData> GetCustomAttributesData () {
449                         return CustomAttributeData.GetCustomAttributes (this);
450                 }
451 #endif
452         }
453         
454         [StructLayout (LayoutKind.Sequential)]
455         internal class MonoCMethod : ConstructorInfo, ISerializable
456         {
457 #pragma warning disable 649             
458                 internal IntPtr mhandle;
459                 string name;
460                 Type reftype;
461 #pragma warning restore 649             
462                 
463                 public override MethodImplAttributes GetMethodImplementationFlags ()
464                 {
465                         return MonoMethodInfo.GetMethodImplementationFlags (mhandle);
466                 }
467
468                 public override ParameterInfo[] GetParameters ()
469                 {
470                         return MonoMethodInfo.GetParametersInfo (mhandle, this);
471                 }
472
473                 internal override int GetParameterCount ()
474                 {
475                         var pi = MonoMethodInfo.GetParametersInfo (mhandle, this);
476                         return pi == null ? 0 : pi.Length;
477                 }
478
479                 /*
480                  * InternalInvoke() receives the parameters corretcly converted by the binder
481                  * to match the types of the method signature.
482                  */
483                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
484                 internal extern Object InternalInvoke (Object obj, Object[] parameters, out Exception exc);
485
486                 [DebuggerHidden]
487                 [DebuggerStepThrough]
488                 public override Object Invoke (Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) 
489                 {
490                         if (binder == null)
491                                 binder = Binder.DefaultBinder;
492
493                         ParameterInfo[] pinfo = MonoMethodInfo.GetParametersInfo (mhandle, this);
494
495                         if (!binder.ConvertArgs (parameters, pinfo, culture, (invokeAttr & BindingFlags.ExactBinding) != 0))
496                                 throw new ArgumentException ("failed to convert parameters");
497
498 #if !NET_2_1
499                         if (SecurityManager.SecurityEnabled) {
500                                 // sadly Attributes doesn't tell us which kind of security action this is so
501                                 // we must do it the hard way - and it also means that we can skip calling
502                                 // Attribute (which is another an icall)
503                                 SecurityManager.ReflectedLinkDemandInvoke (this);
504                         }
505 #endif
506
507                         if (obj == null && DeclaringType.ContainsGenericParameters)
508                                 throw new MemberAccessException ("Cannot create an instance of " + DeclaringType + " because Type.ContainsGenericParameters is true.");
509
510                         if ((invokeAttr & BindingFlags.CreateInstance) != 0 && DeclaringType.IsAbstract) {
511                                 throw new MemberAccessException (String.Format ("Cannot create an instance of {0} because it is an abstract class", DeclaringType));
512                         }
513
514                         Exception exc = null;
515                         object o = null;
516
517                         try {
518                                 o = InternalInvoke (obj, parameters, out exc);
519 #if NET_2_1
520                         } catch (MethodAccessException) {
521                                 throw;
522 #endif
523                         } catch (Exception e) {
524                                 throw new TargetInvocationException (e);
525                         }
526
527                         if (exc != null)
528                                 throw exc;
529                         return (obj == null) ? o : null;
530                 }
531
532                 [DebuggerHidden]
533                 [DebuggerStepThrough]
534                 public override Object Invoke (BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
535                 {
536                         return Invoke (null, invokeAttr, binder, parameters, culture);
537                 }
538
539                 public override RuntimeMethodHandle MethodHandle { 
540                         get {
541                                 return new RuntimeMethodHandle (mhandle);
542                         } 
543                 }
544                 
545                 public override MethodAttributes Attributes { 
546                         get {
547                                 return MonoMethodInfo.GetAttributes (mhandle);
548                         } 
549                 }
550
551                 public override CallingConventions CallingConvention { 
552                         get {
553                                 return MonoMethodInfo.GetCallingConvention (mhandle);
554                         }
555                 }
556                 
557                 public override Type ReflectedType {
558                         get {
559                                 return reftype;
560                         }
561                 }
562                 public override Type DeclaringType {
563                         get {
564                                 return MonoMethodInfo.GetDeclaringType (mhandle);
565                         }
566                 }
567                 public override string Name {
568                         get {
569                                 if (name != null)
570                                         return name;
571                                 return MonoMethod.get_name (this);
572                         }
573                 }
574
575                 public override bool IsDefined (Type attributeType, bool inherit) {
576                         return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
577                 }
578
579                 public override object[] GetCustomAttributes( bool inherit) {
580                         return MonoCustomAttrs.GetCustomAttributes (this, inherit);
581                 }
582
583                 public override object[] GetCustomAttributes( Type attributeType, bool inherit) {
584                         return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
585                 }
586
587                 public override MethodBody GetMethodBody () {
588                         return GetMethodBody (mhandle);
589                 }
590
591                 public override string ToString () {
592                         StringBuilder sb = new StringBuilder ();
593                         sb.Append ("Void ");
594                         sb.Append (Name);
595                         sb.Append ("(");
596                         ParameterInfo[] p = GetParameters ();
597                         for (int i = 0; i < p.Length; ++i) {
598                                 if (i > 0)
599                                         sb.Append (", ");
600                                 sb.Append (p[i].ParameterType.Name);
601                         }
602                         if (CallingConvention == CallingConventions.Any)
603                                 sb.Append (", ...");
604                         sb.Append (")");
605                         return sb.ToString ();
606                 }
607
608                 // ISerializable
609                 public void GetObjectData(SerializationInfo info, StreamingContext context) 
610                 {
611                         MemberInfoSerializationHolder.Serialize ( info, Name, ReflectedType, ToString(), MemberTypes.Constructor);
612                 }
613
614 #if NET_4_0
615                 public override IList<CustomAttributeData> GetCustomAttributesData () {
616                         return CustomAttributeData.GetCustomAttributes (this);
617                 }
618 #endif
619         }
620 }