176fef96c62f09214d81dfd1d262182e3f8501a0
[mono.git] / mcs / class / referencesource / mscorlib / system / rttype.cs
1 // ==++==
2 // 
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 // 
5 // ==--==
6 //
7 // File: RtType.cs
8 //
9 // <OWNER>[....]</OWNER>
10 //
11 // Implements System.RuntimeType
12 //
13 // ======================================================================================
14
15
16 using System;
17 using System.Reflection;
18 using System.Runtime.ConstrainedExecution;
19 using System.Globalization;
20 using System.Threading;
21 using System.Diagnostics;
22 using System.Security.Permissions;
23 using System.Collections;
24 using System.Collections.Generic;
25 using System.Runtime;
26 using System.Runtime.Serialization;    
27 using System.Runtime.CompilerServices;
28 using System.Security;
29 using System.Text;
30 using System.Runtime.Remoting;
31 #if FEATURE_REMOTING
32 using System.Runtime.Remoting.Proxies;
33 using System.Runtime.Remoting.Messaging;
34 using System.Runtime.Remoting.Activation;
35 using System.Runtime.Remoting.Metadata;
36 #endif
37 #if !MONO
38 using MdSigCallingConvention = System.Signature.MdSigCallingConvention;
39 using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache;
40 #endif
41 using System.Runtime.InteropServices;
42 using DebuggerStepThroughAttribute = System.Diagnostics.DebuggerStepThroughAttribute;
43 #if !MONO
44 using MdToken = System.Reflection.MetadataToken;
45 #endif
46 using System.Runtime.Versioning;
47 using System.Diagnostics.Contracts;
48
49 #if MONO
50 using CustomAttribute=System.MonoCustomAttrs;
51 #endif
52
53 namespace System 
54 {
55     // this is a work around to get the concept of a calli. It's not as fast but it would be interesting to 
56     // see how it compares to the current implementation. 
57     // This delegate will disappear at some point in favor of calli 
58
59     internal delegate void CtorDelegate(Object instance);
60
61     // Keep this in [....] with FormatFlags defined in typestring.h
62     internal enum TypeNameFormatFlags
63     {
64         FormatBasic         = 0x00000000, // Not a bitmask, simply the tersest flag settings possible
65         FormatNamespace     = 0x00000001, // Include namespace and/or enclosing class names in type names
66         FormatFullInst      = 0x00000002, // Include namespace and assembly in generic types (regardless of other flag settings)
67         FormatAssembly      = 0x00000004, // Include assembly display name in type names
68         FormatSignature     = 0x00000008, // Include signature in method names
69         FormatNoVersion     = 0x00000010, // Suppress version and culture information in all assembly names
70 #if _DEBUG
71         FormatDebug         = 0x00000020, // For debug printing of types only
72 #endif
73         FormatAngleBrackets = 0x00000040, // Whether generic types are C<T> or C[T]
74         FormatStubInfo      = 0x00000080, // Include stub info like {unbox-stub}
75         FormatGenericParam  = 0x00000100, // Use !name and !!name for generic type and method parameters
76
77         // If we want to be able to distinguish between overloads whose parameter types have the same name but come from different assemblies,
78         // we can add FormatAssembly | FormatNoVersion to FormatSerialization. But we are omitting it because it is not a useful scenario
79         // and including the assembly name will normally increase the size of the serialized data and also decrease the performance.
80         FormatSerialization = FormatNamespace |
81                               FormatGenericParam |
82                               FormatFullInst
83     }
84
85     internal enum TypeNameKind
86     {
87         Name,
88         ToString,
89         SerializationName,
90         FullName,
91     }
92
93     [Serializable]
94     internal partial class RuntimeType : 
95         System.Reflection.TypeInfo, ISerializable, ICloneable
96     {
97         #region Definitions
98
99         internal enum MemberListType
100         {
101             All,
102             CaseSensitive,
103             CaseInsensitive,
104             HandleToInfo
105         }
106
107         // Helper to build lists of MemberInfos. Special cased to avoid allocations for lists of one element.
108         private struct ListBuilder<T> where T : class
109         {
110             T[] _items;
111             T _item;
112             int _count;
113             int _capacity;
114
115             public ListBuilder(int capacity)
116             {
117                 _items = null;
118                 _item = null;
119                 _count = 0;
120                 _capacity = capacity;
121             }
122
123             public T this[int index]
124             {
125                 get
126                 {
127                     Contract.Requires(index < Count);
128                     return (_items != null) ? _items[index] : _item;
129                 }
130 #if FEATURE_LEGACYNETCF
131                 // added for Dev11 466969 quirk
132                 set
133                 {
134                     Contract.Requires(index < Count);
135                     if (_items != null)
136                         _items[index] = value;
137                     else
138                         _item = value;
139                 }
140 #endif
141             }
142
143             public T[] ToArray()
144             {
145                 if (_count == 0)
146                     return EmptyArray<T>.Value;
147                 if (_count == 1)
148                     return new T[1] { _item };
149
150                 Array.Resize(ref _items, _count);
151                 _capacity = _count;
152                 return _items;
153             }
154
155             public void CopyTo(Object[] array, int index)
156             {
157                 if (_count == 0)
158                     return;
159
160                 if (_count == 1)
161                 {
162                     array[index] = _item;
163                     return;
164                 }
165
166                 Array.Copy(_items, 0, array, index, _count);
167             }
168
169             public int Count
170             {
171                 get
172                 {
173                     return _count;
174                 }
175             }
176
177             public void Add(T item)
178             {
179                 if (_count == 0)
180                 {
181                     _item = item;
182                 }
183                 else                
184                 {
185                     if (_count == 1)
186                     {
187                         if (_capacity < 2)
188                             _capacity = 4;
189                         _items = new T[_capacity];
190                         _items[0] = _item;
191                     }
192                     else
193                     if (_capacity == _count)
194                     {
195                         int newCapacity = 2 * _capacity;
196                         Array.Resize(ref _items, newCapacity);
197                         _capacity = newCapacity;
198                     }
199
200                     _items[_count] = item;
201                 }
202                 _count++;
203             }
204         }
205 #if !MONO
206         internal class RuntimeTypeCache
207         {
208             private const int MAXNAMELEN = 1024;
209
210             #region Definitions
211             internal enum CacheType
212             {
213                 Method,
214                 Constructor,
215                 Field,
216                 Property,
217                 Event,
218                 Interface,
219                 NestedType
220             }
221
222             private struct Filter
223             {
224                 private Utf8String m_name;
225                 private MemberListType m_listType;
226                 private uint m_nameHash;
227
228                 [System.Security.SecurityCritical]  // auto-generated
229                 public unsafe Filter(byte* pUtf8Name, int cUtf8Name, MemberListType listType)
230                 {
231                     this.m_name = new Utf8String((void*) pUtf8Name, cUtf8Name);
232                     this.m_listType = listType;
233                     this.m_nameHash = 0;
234
235                     if (RequiresStringComparison())
236                     {
237                         m_nameHash = m_name.HashCaseInsensitive();
238                     }
239                 }
240
241                 public bool Match(Utf8String name) 
242                 {
243                     bool retVal = true;
244                     
245                     if (m_listType == MemberListType.CaseSensitive)
246                         retVal = m_name.Equals(name);
247                     else if (m_listType == MemberListType.CaseInsensitive)
248                         retVal = m_name.EqualsCaseInsensitive(name);
249
250                     // Currently the callers of UsesStringComparison assume that if it returns false
251                     // then the match always succeeds and can be skipped.  Assert that this is maintained.
252                     Contract.Assert(retVal || RequiresStringComparison());
253
254                     return retVal;
255                 }
256
257                 // Does the current match type require a string comparison?
258                 // If not, we know Match will always return true and the call can be skipped
259                 // If so, we know we can have a valid hash to check against from GetHashToMatch
260                 public bool RequiresStringComparison()
261                 {
262                     return (m_listType == MemberListType.CaseSensitive) ||
263                            (m_listType == MemberListType.CaseInsensitive);
264                 }
265
266                 public bool CaseSensitive()
267                 {
268                     return (m_listType == MemberListType.CaseSensitive);
269                 }
270
271                 public uint GetHashToMatch()
272                 {
273                     Contract.Assert(RequiresStringComparison());
274
275                     return m_nameHash;
276                 }
277             }
278
279             private class MemberInfoCache<T> where T : MemberInfo
280             {
281                 #region Private Data Members
282
283                 // MemberInfo caches
284                 private CerHashtable<string, T[]> m_csMemberInfos;
285                 private CerHashtable<string, T[]> m_cisMemberInfos;
286                 // List of MemberInfos given out. When m_cacheComplete is false, it may have null entries at the end to avoid
287                 // reallocating the list every time a new entry is added.
288                 private T[] m_allMembers;
289                 private bool m_cacheComplete;
290 #if FEATURE_LEGACYNETCF
291                 // Dev11 466969 quirk
292                 private List<RuntimePropertyInfo> m_ambiguousProperties;
293 #endif
294
295                 // This is the strong reference back to the cache
296                 private RuntimeTypeCache m_runtimeTypeCache;
297                 #endregion
298
299                 #region Constructor
300 #if MDA_SUPPORTED
301                 [System.Security.SecuritySafeCritical]  // auto-generated
302 #endif
303                 internal MemberInfoCache(RuntimeTypeCache runtimeTypeCache)
304                 {
305 #if MDA_SUPPORTED
306                     Mda.MemberInfoCacheCreation();
307 #endif
308                     m_runtimeTypeCache = runtimeTypeCache;
309                 }
310                 
311 #if FEATURE_LEGACYNETCF
312                 // Dev11 466969 quirk
313                 internal IReadOnlyList<RuntimePropertyInfo> AmbiguousProperties { get { return m_ambiguousProperties; } }
314                 
315                 private void InitializeAndUpdateAmbiguousPropertiesList(RuntimePropertyInfo parent, RuntimePropertyInfo child)
316                 {
317                     Contract.Assert(CompatibilitySwitches.IsAppEarlierThanWindowsPhone8);
318
319                     if (m_ambiguousProperties == null)
320                     {
321                         List<RuntimePropertyInfo> newList = new List<RuntimePropertyInfo>();
322                         Interlocked.CompareExchange(ref m_ambiguousProperties, newList, null);
323                     }
324
325                     lock (m_ambiguousProperties)
326                     {
327                         // record the parent type in case it needs to be pruned later.
328                         Contract.Assert(child.DeclaringType.IsSubclassOf(parent.DeclaringType));
329                         m_ambiguousProperties.Add(parent);
330                     }
331                 }
332 #endif
333
334                 [System.Security.SecuritySafeCritical]  // auto-generated
335                 internal MethodBase AddMethod(RuntimeType declaringType, RuntimeMethodHandleInternal method, CacheType cacheType)
336                 {
337                     T[] list = null;
338                     MethodAttributes methodAttributes = RuntimeMethodHandle.GetAttributes(method);
339                     bool isPublic = (methodAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public;
340                     bool isStatic = (methodAttributes & MethodAttributes.Static) != 0;
341                     bool isInherited = declaringType != ReflectedType;
342                     BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
343                     switch (cacheType)
344                     {
345                     case CacheType.Method:
346                         list = (T[])(object)new RuntimeMethodInfo[1] {
347                             new RuntimeMethodInfo(method, declaringType, m_runtimeTypeCache, methodAttributes, bindingFlags, null)
348                         };
349                         break;
350                     case CacheType.Constructor:
351                         list = (T[])(object)new RuntimeConstructorInfo[1] { 
352                             new RuntimeConstructorInfo(method, declaringType, m_runtimeTypeCache, methodAttributes, bindingFlags) 
353                         };
354                         break;
355                     }
356
357                     Insert(ref list, null, MemberListType.HandleToInfo);
358
359                     return (MethodBase)(object)list[0];
360                 }
361
362                 [System.Security.SecuritySafeCritical]  // auto-generated
363                 internal FieldInfo AddField(RuntimeFieldHandleInternal field)
364                 {
365                     // create the runtime field info
366                     FieldAttributes fieldAttributes = RuntimeFieldHandle.GetAttributes(field);
367                     bool isPublic = (fieldAttributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Public;
368                     bool isStatic = (fieldAttributes & FieldAttributes.Static) != 0;
369                     RuntimeType approxDeclaringType = RuntimeFieldHandle.GetApproxDeclaringType(field);
370                     bool isInherited = RuntimeFieldHandle.AcquiresContextFromThis(field) ?
371                         !RuntimeTypeHandle.CompareCanonicalHandles(approxDeclaringType, ReflectedType) :
372                         approxDeclaringType != ReflectedType;
373
374                     BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
375
376                     T[] list = (T[])(object)new RuntimeFieldInfo[1] { 
377                         new RtFieldInfo(field, ReflectedType, m_runtimeTypeCache, bindingFlags)
378                     };
379
380                     Insert(ref list, null, MemberListType.HandleToInfo);
381
382                     return (FieldInfo)(object)list[0];
383                 }
384
385                 [System.Security.SecuritySafeCritical]  // auto-generated
386                 private unsafe T[] Populate(string name, MemberListType listType, CacheType cacheType)
387                 {
388                     T[] list = null;
389
390                     if (name == null || name.Length == 0 ||
391                         (cacheType == CacheType.Constructor && name.FirstChar != '.' && name.FirstChar != '*'))
392                     {
393                         list = GetListByName(null, 0, null, 0, listType, cacheType);
394                     }
395                     else
396                     {
397                         int cNameLen = name.Length;
398                         fixed (char* pName = name)
399                         {
400                             int cUtf8Name = Encoding.UTF8.GetByteCount(pName, cNameLen);
401                             // allocating on the stack is faster than allocating on the GC heap
402                             // but we surely don't want to cause a stack overflow
403                             // no one should be looking for a member whose name is longer than 1024
404                             if (cUtf8Name > MAXNAMELEN)
405                             {
406                                 fixed (byte* pUtf8Name = new byte[cUtf8Name])
407                                 {
408                                     list = GetListByName(pName, cNameLen, pUtf8Name, cUtf8Name, listType, cacheType);
409                                 }
410                             }
411                             else
412                             {
413                                 byte* pUtf8Name = stackalloc byte[cUtf8Name];
414                                 list = GetListByName(pName, cNameLen, pUtf8Name, cUtf8Name, listType, cacheType);
415                             }
416                         }
417                     }
418
419                     Insert(ref list, name, listType);
420
421                     return list;
422                 }
423
424                 [System.Security.SecurityCritical]  // auto-generated
425                 private unsafe T[] GetListByName(char* pName, int cNameLen, byte* pUtf8Name, int cUtf8Name, MemberListType listType, CacheType cacheType)
426                 {
427                     if (cNameLen != 0)
428                         Encoding.UTF8.GetBytes(pName, cNameLen, pUtf8Name, cUtf8Name);
429
430                     Filter filter = new Filter(pUtf8Name, cUtf8Name, listType);
431                     Object list = null;
432
433                     switch (cacheType)
434                     {
435                         case CacheType.Method:
436                             list = PopulateMethods(filter);
437                             break;
438                         case CacheType.Field:
439                             list = PopulateFields(filter);
440                             break;
441                         case CacheType.Constructor:
442                             list = PopulateConstructors(filter);
443                             break;
444                         case CacheType.Property:
445                             list = PopulateProperties(filter);
446                             break;
447                         case CacheType.Event:
448                             list = PopulateEvents(filter);
449                             break;
450                         case CacheType.NestedType:
451                             list = PopulateNestedClasses(filter);
452                             break;
453                         case CacheType.Interface:
454                             list = PopulateInterfaces(filter);
455                             break;
456                         default:
457                             BCLDebug.Assert(true, "Invalid CacheType");
458                             break;
459                     }
460
461                     return (T[])list;
462                 }
463
464                 // May replace the list with a new one if certain cache
465                 // lookups succeed.  Also, may modify the contents of the list
466                 // after merging these new data structures with cached ones.
467                 [System.Security.SecuritySafeCritical]  // auto-generated
468                 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
469                 internal void Insert(ref T[] list, string name, MemberListType listType)
470                 {
471                     bool lockTaken = false;
472
473                     RuntimeHelpers.PrepareConstrainedRegions();
474                     try 
475                     { 
476                         Monitor.Enter(this, ref lockTaken);
477
478                         switch (listType)
479                         {
480                             case MemberListType.CaseSensitive:
481                                 {
482                                     // Ensure we always return a list that has 
483                                     // been merged with the global list.
484                                     T[] cachedList = m_csMemberInfos[name];
485                                     if (cachedList == null)
486                                     {
487                                         MergeWithGlobalList(list);
488                                         m_csMemberInfos[name] = list;
489                                     }
490                                     else
491                                         list = cachedList;
492                                 }
493                                 break;
494
495                             case MemberListType.CaseInsensitive:
496                                 {
497                                     // Ensure we always return a list that has 
498                                     // been merged with the global list.
499                                     T[] cachedList = m_cisMemberInfos[name];
500                                     if (cachedList == null)
501                                     {
502                                         MergeWithGlobalList(list);
503                                         m_cisMemberInfos[name] = list;
504                                     }
505                                     else
506                                         list = cachedList;
507                                 }
508                                 break;
509
510                             case MemberListType.All:
511                                 if (!m_cacheComplete)
512                                 {
513                                     MergeWithGlobalList(list);
514
515                                     // Trim null entries at the end of m_allMembers array
516                                     int memberCount = m_allMembers.Length;
517                                     while (memberCount > 0)
518                                     {
519                                         if (m_allMembers[memberCount-1] != null)
520                                             break;
521                                         memberCount--;
522                                     }
523                                     Array.Resize(ref m_allMembers, memberCount);
524
525                                     Volatile.Write(ref m_cacheComplete, true);
526                                 }
527 // We want the behavior where the results are returned in the same order on the phone
528 #if !FEATURE_LEGACYNETCF
529                                 else
530 #endif
531                                 list = m_allMembers;
532                                 break;
533
534                             default:
535                                 MergeWithGlobalList(list);
536                                 break;
537                         }
538                     }
539                     finally
540                     {
541                         if (lockTaken)
542                         {
543                             Monitor.Exit(this);
544                         }
545                     }
546                 }
547
548                 // Modifies the existing list.
549                 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
550                 private void MergeWithGlobalList(T[] list)
551                 {
552                     T[] cachedMembers = m_allMembers;
553
554                     if (cachedMembers == null)
555                     {
556                         m_allMembers = list;
557                         return;
558                     }
559
560                     int cachedCount = cachedMembers.Length;
561                     int freeSlotIndex = 0;
562
563                     for (int i = 0; i < list.Length; i++)
564                     {
565                         T newMemberInfo = list[i];
566                         bool foundInCache = false;
567
568                         int cachedIndex;
569                         for (cachedIndex = 0; cachedIndex < cachedCount; cachedIndex++)
570                         {
571                             T cachedMemberInfo = cachedMembers[cachedIndex];
572                             if (cachedMemberInfo == null)
573                                 break;
574
575                             if (newMemberInfo.CacheEquals(cachedMemberInfo))
576                             {
577                                 list[i] = cachedMemberInfo;
578                                 foundInCache = true;
579                                 break;
580                             }
581                         }
582
583                         if (!foundInCache)
584                         {
585                             if (freeSlotIndex == 0)
586                                 freeSlotIndex = cachedIndex;
587
588                             if (freeSlotIndex >= cachedMembers.Length)
589                             {
590                                 int newSize;
591                                 if (m_cacheComplete)
592                                 {
593                                     //
594                                     // In theory, we should never add more elements to the cache when it is complete.
595                                     //
596                                     // Unfortunately, we shipped with bugs that cause changes of the complete cache (DevDiv #339308).
597                                     // Grow the list by exactly one element in this case to avoid null entries at the end.
598                                     //
599
600                                     // DevDiv #339308 is fixed, but we are keeping this code here for Dev11 in case there are other instances of this bug.
601                                     // Remove for Dev12.
602
603                                     Contract.Assert(false);
604
605                                     newSize = cachedMembers.Length + 1;
606                                 }
607                                 else
608                                 {
609                                     newSize = Math.Max(Math.Max(4, 2 * cachedMembers.Length), list.Length);
610                                 }
611
612                                 // Use different variable for ref argument to Array.Resize to allow enregistration of cachedMembers by the JIT
613                                 T[] cachedMembers2 = cachedMembers;
614                                 Array.Resize(ref cachedMembers2, newSize);
615                                 cachedMembers = cachedMembers2;
616                             }
617
618                             Contract.Assert(cachedMembers[freeSlotIndex] == null);
619                             cachedMembers[freeSlotIndex] = newMemberInfo;
620                             freeSlotIndex++;
621                         }
622                     }
623
624                     m_allMembers = cachedMembers;
625                 }
626                 #endregion
627
628                 #region Population Logic
629
630                 [System.Security.SecuritySafeCritical]  // auto-generated
631                 private unsafe RuntimeMethodInfo[] PopulateMethods(Filter filter)
632                 {
633                     ListBuilder<RuntimeMethodInfo> list = new ListBuilder<RuntimeMethodInfo>();
634
635                     RuntimeType declaringType = ReflectedType;
636                     Contract.Assert(declaringType != null);
637
638                     if (RuntimeTypeHandle.IsInterface(declaringType))
639                     {
640                         #region IsInterface
641
642                         foreach (RuntimeMethodHandleInternal methodHandle in RuntimeTypeHandle.GetIntroducedMethods(declaringType))
643                         {
644                             if (filter.RequiresStringComparison())
645                             {
646                                 if (!RuntimeMethodHandle.MatchesNameHash(methodHandle, filter.GetHashToMatch()))
647                                 {
648                                     Contract.Assert(!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)));
649                                     continue;
650                                 }
651
652                                 if (!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)))
653                                     continue;
654                             }
655
656                             #region Loop through all methods on the interface
657                             Contract.Assert(!methodHandle.IsNullHandle());
658                             // Except for .ctor, .cctor, IL_STUB*, and static methods, all interface methods should be abstract, virtual, and non-RTSpecialName.
659                             // Note that this assumption will become invalid when we add support for non-abstract or static methods on interfaces.
660                             Contract.Assert(
661                                 (RuntimeMethodHandle.GetAttributes(methodHandle) & (MethodAttributes.RTSpecialName | MethodAttributes.Abstract | MethodAttributes.Virtual)) == (MethodAttributes.Abstract | MethodAttributes.Virtual) ||
662                                 (RuntimeMethodHandle.GetAttributes(methodHandle) & MethodAttributes.Static) == MethodAttributes.Static ||
663                                 RuntimeMethodHandle.GetName(methodHandle).Equals(".ctor") ||
664                                 RuntimeMethodHandle.GetName(methodHandle).Equals(".cctor") ||
665                                 RuntimeMethodHandle.GetName(methodHandle).StartsWith("IL_STUB", StringComparison.Ordinal));
666
667                             #region Calculate Binding Flags
668                             MethodAttributes methodAttributes = RuntimeMethodHandle.GetAttributes(methodHandle);
669                             bool isPublic = (methodAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public;
670                             bool isStatic = (methodAttributes & MethodAttributes.Static) != 0;
671                             bool isInherited = false;
672                             BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
673                             #endregion
674
675                             if ((methodAttributes & MethodAttributes.RTSpecialName) != 0)
676                                 continue;
677
678                             // get the unboxing stub or instantiating stub if needed
679                             RuntimeMethodHandleInternal instantiatedHandle = RuntimeMethodHandle.GetStubIfNeeded(methodHandle, declaringType, null);
680
681                             RuntimeMethodInfo runtimeMethodInfo = new RuntimeMethodInfo(
682                             instantiatedHandle, declaringType, m_runtimeTypeCache, methodAttributes, bindingFlags, null);
683
684                             list.Add(runtimeMethodInfo);
685                             #endregion  
686                         }
687                         #endregion
688                     }
689                     else
690                     {
691                         #region IsClass or GenericParameter
692                         while(RuntimeTypeHandle.IsGenericVariable(declaringType))
693                             declaringType = declaringType.GetBaseType();
694
695                         bool* overrides = stackalloc bool[RuntimeTypeHandle.GetNumVirtuals(declaringType)];
696                         bool isValueType = declaringType.IsValueType;
697
698                         do
699                         {
700                             int vtableSlots = RuntimeTypeHandle.GetNumVirtuals(declaringType);
701
702                             foreach (RuntimeMethodHandleInternal methodHandle in RuntimeTypeHandle.GetIntroducedMethods(declaringType))
703                             {
704                                 if (filter.RequiresStringComparison())
705                                 {
706                                     if (!RuntimeMethodHandle.MatchesNameHash(methodHandle, filter.GetHashToMatch()))
707                                     {
708                                         Contract.Assert(!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)));
709                                         continue;
710                                     }
711
712                                     if (!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)))
713                                         continue;
714                                 }
715
716                                 #region Loop through all methods on the current type
717                                 Contract.Assert(!methodHandle.IsNullHandle());
718
719                                 MethodAttributes methodAttributes = RuntimeMethodHandle.GetAttributes(methodHandle);
720                                 MethodAttributes methodAccess = methodAttributes & MethodAttributes.MemberAccessMask;
721
722                                 #region Continue if this is a constructor
723                                 Contract.Assert(
724                                     (RuntimeMethodHandle.GetAttributes(methodHandle) & MethodAttributes.RTSpecialName) == 0 ||
725                                     RuntimeMethodHandle.GetName(methodHandle).Equals(".ctor") ||
726                                     RuntimeMethodHandle.GetName(methodHandle).Equals(".cctor"));
727
728                                 if ((methodAttributes & MethodAttributes.RTSpecialName) != 0)
729                                     continue;
730                                 #endregion
731
732                                 #region Continue if this is a private declared on a base type
733                                 bool isVirtual = false;
734                                 int methodSlot = 0;
735                                 if ((methodAttributes & MethodAttributes.Virtual) != 0)
736                                 {
737                                     // only virtual if actually in the vtableslot range, but GetSlot will
738                                     // assert if an EnC method, which can't be virtual, so narrow down first
739                                     // before calling GetSlot
740                                     methodSlot = RuntimeMethodHandle.GetSlot(methodHandle);
741                                     isVirtual = (methodSlot < vtableSlots);
742                                 }
743
744                                 bool isInherited = declaringType != ReflectedType;
745
746                                 // NetCF actually includes private methods from parent classes in Reflection results
747                                 // We will mimic that in Mango Compat mode.
748                                 if (!CompatibilitySwitches.IsAppEarlierThanWindowsPhone8)
749                                 {
750                                     bool isPrivate = methodAccess == MethodAttributes.Private;
751                                     if (isInherited && isPrivate && !isVirtual)
752                                         continue;
753                                 }
754                                 #endregion
755
756                                 #region Continue if this is a virtual and is already overridden
757                                 if (isVirtual)
758                                 {
759                                     Contract.Assert(
760                                         (methodAttributes & MethodAttributes.Abstract) != 0 ||
761                                         (methodAttributes & MethodAttributes.Virtual) != 0 ||
762                                         RuntimeMethodHandle.GetDeclaringType(methodHandle) != declaringType);
763
764                                     if (overrides[methodSlot] == true)
765                                         continue;
766
767                                     overrides[methodSlot] = true;
768                                 }
769                                 else if (isValueType)
770                                 {
771                                     if ((methodAttributes & (MethodAttributes.Virtual | MethodAttributes.Abstract)) != 0)
772                                         continue;
773                                 }
774                                 else
775                                 {
776                                     Contract.Assert((methodAttributes & (MethodAttributes.Virtual | MethodAttributes.Abstract)) == 0);
777                                 }
778                                 #endregion
779
780                                 #region Calculate Binding Flags
781                                 bool isPublic = methodAccess == MethodAttributes.Public;
782                                 bool isStatic = (methodAttributes & MethodAttributes.Static) != 0;
783                                 BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
784                                 #endregion
785
786                                 // get the unboxing stub or instantiating stub if needed
787                                 RuntimeMethodHandleInternal instantiatedHandle = RuntimeMethodHandle.GetStubIfNeeded(methodHandle, declaringType, null);
788
789                                 RuntimeMethodInfo runtimeMethodInfo = new RuntimeMethodInfo(
790                                 instantiatedHandle, declaringType, m_runtimeTypeCache, methodAttributes, bindingFlags, null);
791
792                                 list.Add(runtimeMethodInfo);
793                                 #endregion
794                             }
795
796                             declaringType = RuntimeTypeHandle.GetBaseType(declaringType);
797                         } while (declaringType != null);
798                         #endregion
799                     }
800
801                     return list.ToArray();
802                 }
803
804                 [System.Security.SecuritySafeCritical]  // auto-generated
805                 private RuntimeConstructorInfo[] PopulateConstructors(Filter filter)
806                 {
807                     if (ReflectedType.IsGenericParameter)
808                     {
809                         return EmptyArray<RuntimeConstructorInfo>.Value;
810                     }
811
812                     ListBuilder<RuntimeConstructorInfo> list = new ListBuilder<RuntimeConstructorInfo>();
813
814                     RuntimeType declaringType= ReflectedType;
815
816                     foreach (RuntimeMethodHandleInternal methodHandle in RuntimeTypeHandle.GetIntroducedMethods(declaringType))
817                     {
818                         if (filter.RequiresStringComparison())
819                         {
820                             if (!RuntimeMethodHandle.MatchesNameHash(methodHandle, filter.GetHashToMatch()))
821                             {
822                                 Contract.Assert(!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)));
823                                 continue;
824                             }
825
826                             if (!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)))
827                                 continue;
828                         }
829
830                         MethodAttributes methodAttributes = RuntimeMethodHandle.GetAttributes(methodHandle);
831
832                         Contract.Assert(!methodHandle.IsNullHandle());
833
834                         if ((methodAttributes & MethodAttributes.RTSpecialName) == 0)
835                             continue;
836
837                         // Constructors should not be virtual or abstract
838                         Contract.Assert(
839                             (methodAttributes & MethodAttributes.Abstract) == 0 &&
840                             (methodAttributes & MethodAttributes.Virtual) == 0);
841
842                         #region Calculate Binding Flags
843                         bool isPublic = (methodAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public;
844                         bool isStatic = (methodAttributes & MethodAttributes.Static) != 0;
845                         bool isInherited = false;
846                         BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
847                         #endregion
848
849                         // get the unboxing stub or instantiating stub if needed
850                         RuntimeMethodHandleInternal instantiatedHandle = RuntimeMethodHandle.GetStubIfNeeded(methodHandle, declaringType, null);
851
852                         RuntimeConstructorInfo runtimeConstructorInfo =
853                         new RuntimeConstructorInfo(instantiatedHandle, ReflectedType, m_runtimeTypeCache, methodAttributes, bindingFlags);
854
855                         list.Add(runtimeConstructorInfo);
856                     }
857
858                     return list.ToArray();
859                 }
860
861                 [System.Security.SecuritySafeCritical]  // auto-generated
862                 private unsafe RuntimeFieldInfo[] PopulateFields(Filter filter)
863                 {
864                     ListBuilder<RuntimeFieldInfo> list = new ListBuilder<RuntimeFieldInfo>();
865                     
866                     RuntimeType declaringType = ReflectedType;
867
868                     #region Populate all static, instance and literal fields
869                     while(RuntimeTypeHandle.IsGenericVariable(declaringType))
870                         declaringType = declaringType.GetBaseType();
871
872                     while(declaringType != null)
873                     {
874                         PopulateRtFields(filter, declaringType, ref list);
875
876                         PopulateLiteralFields(filter, declaringType, ref list);
877
878                         declaringType = RuntimeTypeHandle.GetBaseType(declaringType);
879                     }
880                     #endregion
881
882                     #region Populate Literal Fields on Interfaces
883                     if (ReflectedType.IsGenericParameter)
884                     {
885                         Type[] interfaces = ReflectedType.BaseType.GetInterfaces();
886                         
887                         for (int i = 0; i < interfaces.Length; i++)
888                         {
889                             // Populate literal fields defined on any of the interfaces implemented by the declaring type
890                             PopulateLiteralFields(filter, (RuntimeType)interfaces[i], ref list);
891                             PopulateRtFields(filter, (RuntimeType)interfaces[i], ref list);
892                         }                    
893                     }
894                     else
895                     {
896                         Type[] interfaces = RuntimeTypeHandle.GetInterfaces(ReflectedType);
897
898                         if (interfaces != null)
899                         {
900                             for (int i = 0; i < interfaces.Length; i++)
901                             {
902                                 // Populate literal fields defined on any of the interfaces implemented by the declaring type
903                                 PopulateLiteralFields(filter, (RuntimeType)interfaces[i], ref list);
904                                 PopulateRtFields(filter, (RuntimeType)interfaces[i], ref list);
905                             }                    
906                         }
907                     }
908                     #endregion
909
910                     return list.ToArray();
911                 }
912
913                 [System.Security.SecuritySafeCritical]  // auto-generated
914                 private unsafe void PopulateRtFields(Filter filter, RuntimeType declaringType, ref ListBuilder<RuntimeFieldInfo> list)
915                 {
916                     IntPtr* pResult = stackalloc IntPtr[64];
917                     int count = 64;
918                     
919                     if (!RuntimeTypeHandle.GetFields(declaringType, pResult, &count))
920                     {
921                         fixed(IntPtr* pBigResult = new IntPtr[count])
922                         {
923                             RuntimeTypeHandle.GetFields(declaringType, pBigResult, &count);
924                             PopulateRtFields(filter, pBigResult, count, declaringType, ref list);
925                         }
926                     }
927                     else if (count > 0)
928                     {
929                         PopulateRtFields(filter, pResult, count, declaringType, ref list);
930                     }
931                 }
932                     
933                 [System.Security.SecurityCritical]  // auto-generated
934                 private unsafe void PopulateRtFields(Filter filter,
935                     IntPtr* ppFieldHandles, int count, RuntimeType declaringType, ref ListBuilder<RuntimeFieldInfo> list)
936                 {
937                     Contract.Requires(declaringType != null);
938                     Contract.Requires(ReflectedType != null);
939
940                     bool needsStaticFieldForGeneric = RuntimeTypeHandle.HasInstantiation(declaringType) && !RuntimeTypeHandle.ContainsGenericVariables(declaringType);
941                     bool isInherited = declaringType != ReflectedType;
942
943                     for(int i = 0; i < count; i ++)
944                     {
945                         RuntimeFieldHandleInternal runtimeFieldHandle = new RuntimeFieldHandleInternal(ppFieldHandles[i]);
946
947                         if (filter.RequiresStringComparison())
948                         {
949                             if (!RuntimeFieldHandle.MatchesNameHash(runtimeFieldHandle, filter.GetHashToMatch()))
950                             {
951                                 Contract.Assert(!filter.Match(RuntimeFieldHandle.GetUtf8Name(runtimeFieldHandle)));
952                                 continue;
953                             }
954
955                             if (!filter.Match(RuntimeFieldHandle.GetUtf8Name(runtimeFieldHandle)))
956                                 continue;
957                         }
958
959                         Contract.Assert(!runtimeFieldHandle.IsNullHandle());
960
961                         FieldAttributes fieldAttributes = RuntimeFieldHandle.GetAttributes(runtimeFieldHandle);
962                         FieldAttributes fieldAccess = fieldAttributes & FieldAttributes.FieldAccessMask;
963
964                         if (isInherited)
965                         {
966                             if (fieldAccess == FieldAttributes.Private)
967                                 continue;
968                         }
969
970                         #region Calculate Binding Flags
971                         bool isPublic = fieldAccess == FieldAttributes.Public;
972                         bool isStatic = (fieldAttributes & FieldAttributes.Static) != 0;
973                         BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
974                         #endregion                        
975                         
976                         // correct the FieldDesc if needed
977                         if (needsStaticFieldForGeneric && isStatic)
978                             runtimeFieldHandle = RuntimeFieldHandle.GetStaticFieldForGenericType(runtimeFieldHandle, declaringType);
979
980                         RuntimeFieldInfo runtimeFieldInfo = 
981                             new RtFieldInfo(runtimeFieldHandle, declaringType, m_runtimeTypeCache, bindingFlags);
982
983                         list.Add(runtimeFieldInfo);
984                     }
985                 }
986
987                 [System.Security.SecuritySafeCritical]  // auto-generated
988                 private unsafe void PopulateLiteralFields(Filter filter, RuntimeType declaringType, ref ListBuilder<RuntimeFieldInfo> list)
989                 {
990                     Contract.Requires(declaringType != null);
991                     Contract.Requires(ReflectedType != null);
992
993                     int tkDeclaringType = RuntimeTypeHandle.GetToken(declaringType);
994
995                     // Our policy is that TypeDescs do not have metadata tokens
996                     if (MdToken.IsNullToken(tkDeclaringType))
997                         return;
998
999                     MetadataImport scope = RuntimeTypeHandle.GetMetadataImport(declaringType);
1000
1001                     MetadataEnumResult tkFields;
1002                     scope.EnumFields(tkDeclaringType, out tkFields);
1003
1004                     for (int i = 0; i < tkFields.Length; i++)
1005                     {
1006                         int tkField = tkFields[i];
1007                         Contract.Assert(MdToken.IsTokenOfType(tkField, MetadataTokenType.FieldDef));
1008                         Contract.Assert(!MdToken.IsNullToken(tkField));
1009
1010                         FieldAttributes fieldAttributes;
1011                         scope.GetFieldDefProps(tkField, out fieldAttributes);
1012
1013                         FieldAttributes fieldAccess = fieldAttributes & FieldAttributes.FieldAccessMask;
1014
1015                         if ((fieldAttributes & FieldAttributes.Literal) != 0)
1016                         {
1017                             bool isInherited = declaringType != ReflectedType;
1018                             if (isInherited)
1019                             {
1020                                 bool isPrivate = fieldAccess == FieldAttributes.Private;
1021                                 if (isPrivate)
1022                                     continue;
1023                             }
1024
1025                             if (filter.RequiresStringComparison())
1026                             {
1027                                 Utf8String name;
1028                                 name = scope.GetName(tkField);
1029
1030                                 if (!filter.Match(name))
1031                                     continue;
1032                             }
1033
1034                             #region Calculate Binding Flags
1035                             bool isPublic = fieldAccess == FieldAttributes.Public;
1036                             bool isStatic = (fieldAttributes & FieldAttributes.Static) != 0;
1037                             BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
1038                             #endregion                                              
1039                         
1040                             RuntimeFieldInfo runtimeFieldInfo =
1041                             new MdFieldInfo(tkField, fieldAttributes, declaringType.GetTypeHandleInternal(), m_runtimeTypeCache, bindingFlags);
1042
1043                             list.Add(runtimeFieldInfo);
1044                         }
1045                     }
1046                 }
1047
1048                 private static void AddElementTypes(Type template, IList<Type> types)
1049                 {   
1050                     if (!template.HasElementType)
1051                         return;
1052                     
1053                     AddElementTypes(template.GetElementType(), types);
1054                     
1055                     for (int i = 0; i < types.Count; i ++)
1056                     {
1057                         if (template.IsArray)
1058                         {
1059                             if (template.IsSzArray)
1060                                 types[i] = types[i].MakeArrayType();
1061                             else 
1062                                 types[i] = types[i].MakeArrayType(template.GetArrayRank());
1063                         }
1064                         else if (template.IsPointer)
1065                         {
1066                             types[i] = types[i].MakePointerType();
1067                         }
1068                     }
1069                 }
1070
1071                 private void AddSpecialInterface(ref ListBuilder<RuntimeType> list, Filter filter, RuntimeType iList, bool addSubInterface)
1072                 {
1073                     if (iList.IsAssignableFrom(ReflectedType))
1074                     {
1075                         if (filter.Match(RuntimeTypeHandle.GetUtf8Name(iList)))
1076                             list.Add(iList);
1077
1078                         if (addSubInterface)
1079                         {
1080                             Type[] iFaces = iList.GetInterfaces();
1081                             for (int j = 0; j < iFaces.Length; j++)
1082                             {
1083                                 RuntimeType iFace = (RuntimeType)iFaces[j];
1084                                 if (iFace.IsGenericType && filter.Match(RuntimeTypeHandle.GetUtf8Name(iFace)))
1085                                     list.Add(iFace);
1086                             }
1087                         }
1088                     }
1089
1090                 }
1091
1092                 [System.Security.SecuritySafeCritical]  // auto-generated
1093                 private RuntimeType[] PopulateInterfaces(Filter filter)
1094                 {
1095                     ListBuilder<RuntimeType> list = new ListBuilder<RuntimeType>();
1096
1097                     RuntimeType declaringType = ReflectedType;
1098
1099                     if (!RuntimeTypeHandle.IsGenericVariable(declaringType))
1100                     {
1101                         Type[] ifaces = RuntimeTypeHandle.GetInterfaces(declaringType);
1102
1103                         if (ifaces != null)
1104                         {
1105                             for (int i = 0; i < ifaces.Length; i++)
1106                             {
1107                                 RuntimeType interfaceType = (RuntimeType)ifaces[i];
1108
1109                                 if (filter.RequiresStringComparison())
1110                                 {
1111                                     if (!filter.Match(RuntimeTypeHandle.GetUtf8Name(interfaceType)))
1112                                         continue;
1113                                 }
1114                             
1115                                 Contract.Assert(interfaceType.IsInterface);
1116                                 list.Add(interfaceType);
1117                             }
1118                         }
1119
1120                         if (ReflectedType.IsSzArray)
1121                         {
1122                             RuntimeType arrayType = (RuntimeType)ReflectedType.GetElementType();
1123                             
1124                             if (!arrayType.IsPointer)
1125                             {
1126                                 AddSpecialInterface(ref list, filter, (RuntimeType)typeof(IList<>).MakeGenericType(arrayType), true);
1127                                 
1128                                 // To avoid adding a duplicate IEnumerable<T>, we don't add the sub interfaces of IReadOnlyList.
1129                                 // Instead, we add IReadOnlyCollection<T> separately.
1130                                 AddSpecialInterface(ref list, filter, (RuntimeType)typeof(IReadOnlyList<>).MakeGenericType(arrayType), false);
1131                                 AddSpecialInterface(ref list, filter, (RuntimeType)typeof(IReadOnlyCollection<>).MakeGenericType(arrayType), false);
1132                             }
1133                         }
1134                     }
1135                     else
1136                     {
1137                         List<RuntimeType> al = new List<RuntimeType>();
1138
1139                         // Get all constraints
1140                         Type[] constraints = declaringType.GetGenericParameterConstraints();
1141
1142                         // Populate transitive closure of all interfaces in constraint set
1143                         for (int i = 0; i < constraints.Length; i++)
1144                         {
1145                             RuntimeType constraint = (RuntimeType)constraints[i];
1146                             if (constraint.IsInterface)
1147                                 al.Add(constraint);
1148
1149                             Type[] temp = constraint.GetInterfaces();
1150                             for (int j = 0; j < temp.Length; j++)
1151                                 al.Add(temp[j] as RuntimeType);
1152                         }
1153
1154                         // Remove duplicates
1155                         Dictionary<RuntimeType, RuntimeType> ht = new Dictionary<RuntimeType, RuntimeType>();
1156                         for (int i = 0; i < al.Count; i++)
1157                         {
1158                             RuntimeType constraint = al[i];
1159                             if (!ht.ContainsKey(constraint))
1160                                 ht[constraint] = constraint;
1161                         }
1162
1163                         RuntimeType[] interfaces = new RuntimeType[ht.Values.Count];
1164                         ht.Values.CopyTo(interfaces, 0);
1165
1166                         // Populate link-list
1167                         for (int i = 0; i < interfaces.Length; i++)
1168                         {
1169                             if (filter.RequiresStringComparison())
1170                             {
1171                                 if (!filter.Match(RuntimeTypeHandle.GetUtf8Name(interfaces[i])))
1172                                     continue;
1173                             }
1174
1175                             list.Add(interfaces[i]);
1176                         }
1177                     }
1178
1179                     return list.ToArray();
1180                 }
1181
1182                 [System.Security.SecuritySafeCritical]  // auto-generated
1183                 private unsafe RuntimeType[] PopulateNestedClasses(Filter filter)
1184                 {
1185                     RuntimeType declaringType = ReflectedType;
1186
1187                     while (RuntimeTypeHandle.IsGenericVariable(declaringType))
1188                     {
1189                         declaringType = declaringType.GetBaseType();
1190                     }
1191
1192                     int tkEnclosingType = RuntimeTypeHandle.GetToken(declaringType);
1193
1194                     // For example, TypeDescs do not have metadata tokens
1195                     if (MdToken.IsNullToken(tkEnclosingType))
1196                         return EmptyArray<RuntimeType>.Value;
1197
1198                     ListBuilder<RuntimeType> list = new ListBuilder<RuntimeType>();
1199
1200                     RuntimeModule moduleHandle = RuntimeTypeHandle.GetModule(declaringType);
1201                     MetadataImport scope = ModuleHandle.GetMetadataImport(moduleHandle);
1202
1203                     MetadataEnumResult tkNestedClasses;
1204                     scope.EnumNestedTypes(tkEnclosingType, out tkNestedClasses);
1205
1206                     for (int i = 0; i < tkNestedClasses.Length; i++)
1207                     {
1208                         RuntimeType nestedType = null;
1209
1210                         try
1211                         {
1212                             nestedType = ModuleHandle.ResolveTypeHandleInternal(moduleHandle, tkNestedClasses[i], null, null);
1213                         }
1214                         catch(System.TypeLoadException)
1215                         {
1216                             // In a reflection emit scenario, we may have a token for a class which 
1217                             // has not been baked and hence cannot be loaded. 
1218                             continue;
1219                         }
1220
1221                         if (filter.RequiresStringComparison())
1222                         {
1223                             if (!filter.Match(RuntimeTypeHandle.GetUtf8Name(nestedType)))
1224                                 continue;
1225                         }
1226
1227                         list.Add(nestedType);
1228                     }
1229
1230                     return list.ToArray();
1231                 }
1232                 
1233                 [System.Security.SecuritySafeCritical]  // auto-generated
1234                 private unsafe RuntimeEventInfo[] PopulateEvents(Filter filter)
1235                 {
1236                     Contract.Requires(ReflectedType != null);
1237
1238                     // Do not create the dictionary if we are filtering the properties by name already
1239                     Dictionary<String, RuntimeEventInfo> csEventInfos = filter.CaseSensitive() ? null :
1240                         new Dictionary<String, RuntimeEventInfo>();
1241
1242                     RuntimeType declaringType = ReflectedType;
1243                     ListBuilder<RuntimeEventInfo> list = new ListBuilder<RuntimeEventInfo>();
1244
1245                     if (!RuntimeTypeHandle.IsInterface(declaringType))
1246                     {
1247                         while(RuntimeTypeHandle.IsGenericVariable(declaringType))
1248                             declaringType = declaringType.GetBaseType();
1249
1250                         // Populate associates off of the class hierarchy
1251                         while(declaringType != null)
1252                         {
1253                             PopulateEvents(filter, declaringType, csEventInfos, ref list);
1254                             declaringType = RuntimeTypeHandle.GetBaseType(declaringType);
1255                         }
1256                     }
1257                     else
1258                     {
1259                         // Populate associates for this interface 
1260                         PopulateEvents(filter, declaringType, csEventInfos, ref list);
1261                     }
1262
1263                     return list.ToArray();
1264                 }
1265
1266                 [System.Security.SecuritySafeCritical]  // auto-generated
1267                 private unsafe void PopulateEvents(
1268                     Filter filter, RuntimeType declaringType, Dictionary<String, RuntimeEventInfo> csEventInfos, ref ListBuilder<RuntimeEventInfo> list)
1269                 {
1270                     int tkDeclaringType = RuntimeTypeHandle.GetToken(declaringType);
1271
1272                     // Arrays, Pointers, ByRef types and others generated only the fly by the RT do not have tokens.
1273                     if (MdToken.IsNullToken(tkDeclaringType))
1274                         return;
1275
1276                     MetadataImport scope = RuntimeTypeHandle.GetMetadataImport(declaringType);
1277
1278                     MetadataEnumResult tkEvents;
1279                     scope.EnumEvents(tkDeclaringType, out tkEvents);
1280
1281                     for (int i = 0; i < tkEvents.Length; i++)
1282                     {
1283                         int tkEvent = tkEvents[i];
1284                         bool isPrivate;
1285
1286                         Contract.Assert(!MdToken.IsNullToken(tkEvent));
1287                         Contract.Assert(MdToken.IsTokenOfType(tkEvent, MetadataTokenType.Event));
1288
1289                         if (filter.RequiresStringComparison())
1290                         {
1291                             Utf8String name;
1292                             name = scope.GetName(tkEvent);
1293
1294                             if (!filter.Match(name))
1295                                 continue;
1296                         }
1297
1298                         RuntimeEventInfo eventInfo = new RuntimeEventInfo(
1299                             tkEvent, declaringType, m_runtimeTypeCache, out isPrivate);
1300
1301                         #region Remove Inherited Privates
1302                         if (declaringType != m_runtimeTypeCache.GetRuntimeType() && isPrivate)
1303                             continue;
1304                         #endregion
1305
1306                         #region Remove Duplicates
1307                         if (csEventInfos != null)
1308                         {
1309                             string name = eventInfo.Name;
1310
1311                             if (csEventInfos.GetValueOrDefault(name) != null)
1312                                 continue;
1313
1314                             csEventInfos[name] = eventInfo;
1315                         }
1316                         else
1317                         {
1318                             if (list.Count > 0)
1319                                 break;
1320                         }
1321                         #endregion
1322
1323                         list.Add(eventInfo);
1324                     }
1325                 }
1326
1327                 [System.Security.SecuritySafeCritical]  // auto-generated
1328                 private unsafe RuntimePropertyInfo[] PopulateProperties(Filter filter)
1329                 {
1330                     Contract.Requires(ReflectedType != null);
1331
1332                     // m_csMemberInfos can be null at this point. It will be initialized when Insert
1333                     // is called in Populate after this returns.
1334
1335                     RuntimeType declaringType = ReflectedType;
1336                     Contract.Assert(declaringType != null);
1337
1338                     ListBuilder<RuntimePropertyInfo> list = new ListBuilder<RuntimePropertyInfo>();
1339
1340                     if (!RuntimeTypeHandle.IsInterface(declaringType))
1341                     {
1342                         while(RuntimeTypeHandle.IsGenericVariable(declaringType))
1343                             declaringType = declaringType.GetBaseType();
1344
1345                         // Do not create the dictionary if we are filtering the properties by name already
1346                         Dictionary<String, List<RuntimePropertyInfo>> csPropertyInfos = filter.CaseSensitive() ? null :
1347                             new Dictionary<String, List<RuntimePropertyInfo>>();
1348
1349                         // All elements automatically initialized to false.
1350                         bool[] usedSlots = new bool[RuntimeTypeHandle.GetNumVirtuals(declaringType)];
1351
1352                         // Populate associates off of the class hierarchy
1353                         do
1354                         {
1355                             PopulateProperties(filter, declaringType, csPropertyInfos, usedSlots, ref list);
1356                             declaringType = RuntimeTypeHandle.GetBaseType(declaringType);
1357                         } while (declaringType != null);
1358                     }
1359                     else
1360                     {
1361                         // Populate associates for this interface 
1362                         PopulateProperties(filter, declaringType, null, null, ref list);
1363                     }
1364
1365                     return list.ToArray();
1366                 }
1367
1368                 [System.Security.SecuritySafeCritical]  // auto-generated
1369                 private unsafe void PopulateProperties(
1370                     Filter filter, 
1371                     RuntimeType declaringType, 
1372                     Dictionary<String, List<RuntimePropertyInfo>> csPropertyInfos,
1373                     bool[] usedSlots,
1374                     ref ListBuilder<RuntimePropertyInfo> list)
1375                 {
1376                     int tkDeclaringType = RuntimeTypeHandle.GetToken(declaringType);
1377
1378                     // Arrays, Pointers, ByRef types and others generated only the fly by the RT do not have tokens.
1379                     if (MdToken.IsNullToken(tkDeclaringType))
1380                         return;
1381
1382                     MetadataImport scope = RuntimeTypeHandle.GetMetadataImport(declaringType);
1383
1384                     MetadataEnumResult tkProperties;
1385                     scope.EnumProperties(tkDeclaringType, out tkProperties);
1386
1387                     RuntimeModule declaringModuleHandle = RuntimeTypeHandle.GetModule(declaringType);
1388
1389                     int numVirtuals = RuntimeTypeHandle.GetNumVirtuals(declaringType);
1390
1391                     Contract.Assert((declaringType.IsInterface && usedSlots == null && csPropertyInfos == null) ||
1392                                     (!declaringType.IsInterface && usedSlots != null && usedSlots.Length >= numVirtuals));
1393
1394                     for (int i = 0; i < tkProperties.Length; i++)
1395                     {
1396                         int tkProperty = tkProperties[i];
1397                         bool isPrivate;
1398
1399                         Contract.Assert(!MdToken.IsNullToken(tkProperty));
1400                         Contract.Assert(MdToken.IsTokenOfType(tkProperty, MetadataTokenType.Property));
1401
1402                         if (filter.RequiresStringComparison())
1403                         {
1404                             if (!ModuleHandle.ContainsPropertyMatchingHash(declaringModuleHandle, tkProperty, filter.GetHashToMatch()))
1405                             {
1406                                 Contract.Assert(!filter.Match(declaringType.GetRuntimeModule().MetadataImport.GetName(tkProperty)));
1407                                 continue;
1408                             }
1409
1410                             Utf8String name;
1411                             name = declaringType.GetRuntimeModule().MetadataImport.GetName(tkProperty);
1412
1413                             if (!filter.Match(name))
1414                                 continue;
1415                         }
1416
1417                         RuntimePropertyInfo propertyInfo =
1418                             new RuntimePropertyInfo(
1419                             tkProperty, declaringType, m_runtimeTypeCache, out isPrivate);
1420
1421                         // If this is a class, not an interface
1422                         if (usedSlots != null)
1423                         {
1424                             #region Remove Privates
1425                             if (declaringType != ReflectedType && isPrivate)
1426                                 continue;
1427                             #endregion
1428
1429                             #region Duplicate check based on vtable slots
1430
1431                             // The inheritance of properties are defined by the inheritance of their 
1432                             // getters and setters.
1433                             // A property on a base type is "overriden" by a property on a sub type
1434                             // if the getter/setter of the latter occupies the same vtable slot as 
1435                             // the getter/setter of the former.
1436
1437                             MethodInfo associateMethod = propertyInfo.GetGetMethod();
1438                             if (associateMethod == null)
1439                             {
1440                                 // We only need to examine the setter if a getter doesn't exist.
1441                                 // It is not logical for the getter to be virtual but not the setter.
1442                                 associateMethod = propertyInfo.GetSetMethod();
1443                             }
1444
1445                             if (associateMethod != null)
1446                             {
1447                                 int slot = RuntimeMethodHandle.GetSlot((RuntimeMethodInfo)associateMethod);
1448
1449                                 if (slot < numVirtuals)
1450                                 {
1451                                     Contract.Assert(associateMethod.IsVirtual);
1452                                     if (usedSlots[slot] == true)
1453                                         continue;
1454                                     else
1455                                         usedSlots[slot] = true;
1456                                 }
1457                             }
1458                             #endregion
1459
1460                             #region Duplicate check based on name and signature
1461
1462                             // For backward compatibility, even if the vtable slots don't match, we will still treat
1463                             // a property as duplicate if the names and signatures match.
1464
1465                             if (csPropertyInfos != null)
1466                             {
1467                                 string name = propertyInfo.Name;
1468
1469                                 List<RuntimePropertyInfo> cache = csPropertyInfos.GetValueOrDefault(name);
1470
1471                                 if (cache == null)
1472                                 {
1473                                     cache = new List<RuntimePropertyInfo>(1);
1474                                     csPropertyInfos[name] = cache;
1475                                 }
1476
1477                                 for (int j = 0; j < cache.Count; j++)
1478                                 {
1479                                     if (propertyInfo.EqualsSig(cache[j]))
1480                                     {
1481 #if FEATURE_LEGACYNETCF
1482                                         // Dev11 466969 quirk
1483                                         if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8 && !propertyInfo.HasMatchingAccessibility(cache[j]))
1484                                         {
1485                                             InitializeAndUpdateAmbiguousPropertiesList(propertyInfo, cache[j]);
1486                                         }
1487                                         else
1488 #endif
1489                                         {
1490                                             cache = null;
1491                                             break;
1492                                         }
1493                                     }
1494                                 }
1495
1496                                 if (cache == null)
1497                                     continue;
1498
1499                                 cache.Add(propertyInfo);
1500                             }
1501                             else
1502                             {
1503                                 bool duplicate = false;
1504
1505                                 for (int j = 0; j < list.Count; j++)
1506                                 {
1507                                     if (propertyInfo.EqualsSig(list[j]))
1508                                     {
1509 #if FEATURE_LEGACYNETCF
1510                                         // Dev11 466969 quirk
1511                                         if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8 && !propertyInfo.HasMatchingAccessibility(list[j]))
1512                                         {
1513                                             InitializeAndUpdateAmbiguousPropertiesList(propertyInfo, list[j]);
1514                                         }
1515                                         else
1516 #endif
1517                                         {
1518                                             duplicate = true;
1519                                             break;
1520                                         }
1521                                     }
1522                                 }
1523
1524                                 if (duplicate)
1525                                     continue;
1526                             }
1527                             #endregion
1528                         }
1529
1530                         list.Add(propertyInfo);
1531                     }
1532                 }
1533                 #endregion
1534
1535                 #region NonPrivate Members
1536                 internal T[] GetMemberList(MemberListType listType, string name, CacheType cacheType)
1537                 {
1538                     T[] list = null;
1539
1540                     switch(listType)
1541                     {
1542                         case MemberListType.CaseSensitive:
1543                             list = m_csMemberInfos[name];
1544                             if (list != null)
1545                                 return list;
1546
1547                             return Populate(name, listType, cacheType);
1548
1549                         case MemberListType.CaseInsensitive:
1550                             list = m_cisMemberInfos[name];
1551                             if (list != null)
1552                                 return list;
1553
1554                             return Populate(name, listType, cacheType);
1555
1556                         default:
1557                             Contract.Assert(listType == MemberListType.All);
1558                             if (Volatile.Read(ref m_cacheComplete))
1559                                 return m_allMembers;
1560
1561                             return Populate(null, listType, cacheType);
1562                     }
1563                 }
1564
1565                 internal RuntimeType ReflectedType
1566                 {
1567                     get
1568                     {
1569                         return m_runtimeTypeCache.GetRuntimeType();
1570                     }
1571                 }
1572                 #endregion
1573             }
1574             #endregion
1575
1576             #region Private Data Members
1577             private RuntimeType m_runtimeType;
1578             private RuntimeType m_enclosingType;
1579             private TypeCode m_typeCode;
1580             private string m_name;
1581             private string m_fullname;
1582             private string m_toString;
1583             private string m_namespace;
1584             private string m_serializationname;
1585             private bool m_isGlobal;
1586             private bool m_bIsDomainInitialized;
1587             private MemberInfoCache<RuntimeMethodInfo> m_methodInfoCache;
1588             private MemberInfoCache<RuntimeConstructorInfo> m_constructorInfoCache;
1589             private MemberInfoCache<RuntimeFieldInfo> m_fieldInfoCache;
1590             private MemberInfoCache<RuntimeType> m_interfaceCache;
1591             private MemberInfoCache<RuntimeType> m_nestedClassesCache;
1592             private MemberInfoCache<RuntimePropertyInfo> m_propertyInfoCache;
1593             private MemberInfoCache<RuntimeEventInfo> m_eventInfoCache;
1594             private static CerHashtable<RuntimeMethodInfo, RuntimeMethodInfo> s_methodInstantiations;
1595             private static Object s_methodInstantiationsLock;
1596 #if !FEATURE_CORECLR
1597             private RuntimeConstructorInfo m_serializationCtor;
1598 #endif
1599             private string m_defaultMemberName;
1600             private Object m_genericCache; // Generic cache for rare scenario specific data. It is used to cache Enum names and values.
1601             #endregion
1602
1603             #region Constructor
1604             internal RuntimeTypeCache(RuntimeType runtimeType)
1605             {
1606                 m_typeCode = TypeCode.Empty;
1607                 m_runtimeType = runtimeType;
1608                 m_isGlobal = RuntimeTypeHandle.GetModule(runtimeType).RuntimeType == runtimeType;
1609             }
1610             #endregion
1611
1612             #region Private Members
1613             private string ConstructName(ref string name, TypeNameFormatFlags formatFlags)
1614             {
1615                 if (name == null) 
1616                 {
1617                     name = new RuntimeTypeHandle(m_runtimeType).ConstructName(formatFlags);
1618                 }
1619                 return name;
1620             }
1621
1622             private T[] GetMemberList<T>(ref MemberInfoCache<T> m_cache, MemberListType listType, string name, CacheType cacheType) 
1623                 where T : MemberInfo
1624             {
1625                 MemberInfoCache<T> existingCache = GetMemberCache<T>(ref m_cache);
1626                 return existingCache.GetMemberList(listType, name, cacheType);
1627             }
1628
1629 #if FEATURE_LEGACYNETCF
1630             // Dev11 466969 quirk
1631             private T[] GetMemberList<T>(ref MemberInfoCache<T> m_cache, MemberListType listType, string name, CacheType cacheType, out IReadOnlyList<RuntimePropertyInfo> ambiguousProperties) 
1632                 where T : MemberInfo
1633             {
1634                 Contract.Assert(cacheType == CacheType.Property);
1635
1636                 MemberInfoCache<T> existingCache = GetMemberCache<T>(ref m_cache);
1637                 T[] results = existingCache.GetMemberList(listType, name, cacheType);
1638
1639                 // must access property after GetMemberList() has been called
1640                 ambiguousProperties = existingCache.AmbiguousProperties;
1641
1642                 // we should only have an ambiguous properties list in Mango-compat mode
1643                 Contract.Assert(ambiguousProperties == null || CompatibilitySwitches.IsAppEarlierThanWindowsPhone8);
1644                 return results;
1645             }
1646 #endif
1647             
1648             private MemberInfoCache<T> GetMemberCache<T>(ref MemberInfoCache<T> m_cache) 
1649                 where T : MemberInfo
1650             {
1651                 MemberInfoCache<T> existingCache = m_cache;
1652
1653                 if (existingCache == null)
1654                 {
1655                     MemberInfoCache<T> newCache = new MemberInfoCache<T>(this);
1656                     existingCache = Interlocked.CompareExchange(ref m_cache, newCache, null);
1657                     if (existingCache == null)
1658                         existingCache = newCache;
1659                 }
1660
1661                 return existingCache;
1662             }
1663             #endregion
1664
1665             #region Internal Members
1666
1667             internal Object GenericCache
1668             {
1669                 get { return m_genericCache; }
1670                 set { m_genericCache = value; }
1671             }
1672
1673             internal bool DomainInitialized
1674             {
1675                 get { return m_bIsDomainInitialized; }
1676                 set { m_bIsDomainInitialized = value; }
1677             }
1678             
1679             internal string GetName(TypeNameKind kind)
1680             {
1681                 switch (kind)
1682                 {
1683                     case TypeNameKind.Name:
1684                         // No namespace, full instantiation, and assembly.
1685                         return ConstructName(ref m_name, TypeNameFormatFlags.FormatBasic);
1686
1687                     case TypeNameKind.FullName:
1688                         // We exclude the types that contain generic parameters because their names cannot be roundtripped.
1689                         // We allow generic type definitions (and their refs, ptrs, and arrays) because their names can be roundtriped.
1690                         // Theoretically generic types instantiated with generic type definitions can be roundtripped, e.g. List`1<Dictionary`2>.
1691                         // But these kind of types are useless, rare, and hard to identity. We would need to recursively examine all the 
1692                         // generic arguments with the same criteria. We will exclude them unless we see a real user scenario.
1693                         if (!m_runtimeType.GetRootElementType().IsGenericTypeDefinition && m_runtimeType.ContainsGenericParameters)
1694                             return null;
1695
1696                         // No assembly.
1697                         return ConstructName(ref m_fullname, TypeNameFormatFlags.FormatNamespace | TypeNameFormatFlags.FormatFullInst);
1698
1699                     case TypeNameKind.ToString:
1700                         // No full instantiation and assembly.
1701                         return ConstructName(ref m_toString, TypeNameFormatFlags.FormatNamespace);
1702
1703                     case TypeNameKind.SerializationName:
1704                         // Use FormatGenericParam in serialization. Otherwise we won't be able 
1705                         // to distinguish between a generic parameter and a normal type with the same name.
1706                         // e.g. Foo<T>.Bar(T t), the parameter type T could be !1 or a real type named "T".
1707                         // Excluding the version number in the assembly name for VTS.
1708                         return ConstructName(ref m_serializationname, TypeNameFormatFlags.FormatSerialization);
1709
1710                     default:
1711                         throw new InvalidOperationException();
1712                 }
1713             }
1714
1715             [System.Security.SecuritySafeCritical]
1716             internal unsafe string GetNameSpace()
1717             {
1718                 // @Optimization - Use ConstructName to populate m_namespace
1719                 if (m_namespace == null)
1720                 {   
1721                     Type type = m_runtimeType;
1722                     type = type.GetRootElementType();
1723                     
1724                     while (type.IsNested)                       
1725                         type = type.DeclaringType;
1726
1727                     m_namespace = RuntimeTypeHandle.GetMetadataImport((RuntimeType)type).GetNamespace(type.MetadataToken).ToString();
1728                 }
1729
1730                 return m_namespace;
1731             }
1732
1733             internal TypeCode TypeCode
1734             {
1735                 get { return m_typeCode; }
1736                 set { m_typeCode = value; } 
1737             }
1738
1739             [System.Security.SecuritySafeCritical]  // auto-generated
1740             internal unsafe RuntimeType GetEnclosingType()
1741             { 
1742                 if (m_enclosingType == null)
1743                 {
1744                     // Use void as a marker of null enclosing type
1745                     RuntimeType enclosingType = RuntimeTypeHandle.GetDeclaringType(GetRuntimeType());
1746                     Contract.Assert(enclosingType != typeof(void));
1747                     m_enclosingType = enclosingType ?? (RuntimeType)typeof(void);
1748                 }
1749
1750                 return (m_enclosingType == typeof(void)) ? null : m_enclosingType;
1751             }
1752
1753             internal RuntimeType GetRuntimeType()
1754             {
1755                 return m_runtimeType;
1756             }
1757
1758             internal bool IsGlobal 
1759             { 
1760                 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
1761                 get { return m_isGlobal; } 
1762             }
1763
1764             internal void InvalidateCachedNestedType()
1765             {
1766                 m_nestedClassesCache = null;
1767             }
1768
1769 #if !FEATURE_CORECLR
1770             internal RuntimeConstructorInfo GetSerializationCtor()
1771             {
1772                 if (m_serializationCtor == null)
1773                 {
1774                     if (s_SICtorParamTypes == null)
1775                         s_SICtorParamTypes = new Type[] { typeof(SerializationInfo), typeof(StreamingContext) };
1776
1777                     m_serializationCtor = m_runtimeType.GetConstructor(
1778                         BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
1779                         null,
1780                         CallingConventions.Any,
1781                         s_SICtorParamTypes,
1782                         null) as RuntimeConstructorInfo;
1783                 }
1784
1785                 return m_serializationCtor;
1786             }
1787 #endif //!FEATURE_CORECLR
1788
1789             internal string GetDefaultMemberName()
1790             {
1791                 if (m_defaultMemberName == null)
1792                 {
1793                     CustomAttributeData attr = null;
1794                     Type DefaultMemberAttrType = typeof(DefaultMemberAttribute);
1795                     for (RuntimeType t = m_runtimeType; t != null; t = t.GetBaseType())
1796                     {
1797                         IList<CustomAttributeData> attrs = CustomAttributeData.GetCustomAttributes(t);
1798                         for (int i = 0; i < attrs.Count; i++)
1799                         {
1800                             if (Object.ReferenceEquals(attrs[i].Constructor.DeclaringType, DefaultMemberAttrType))
1801                             {
1802                                 attr = attrs[i];
1803                                 break;
1804                             }
1805                         }
1806
1807                         if (attr != null)
1808                         {
1809                             m_defaultMemberName = attr.ConstructorArguments[0].Value as string;
1810                             break;
1811                         }
1812                     }
1813                 }
1814
1815                 return m_defaultMemberName;
1816             }
1817             #endregion
1818
1819             #region Caches Accessors
1820             [System.Security.SecurityCritical]  // auto-generated
1821             internal MethodInfo GetGenericMethodInfo(RuntimeMethodHandleInternal genericMethod)
1822             {
1823                 LoaderAllocator la = RuntimeMethodHandle.GetLoaderAllocator(genericMethod);
1824
1825                 RuntimeMethodInfo rmi = new RuntimeMethodInfo(
1826                     genericMethod, RuntimeMethodHandle.GetDeclaringType(genericMethod), this,
1827                     RuntimeMethodHandle.GetAttributes(genericMethod), (BindingFlags)(-1), la);
1828
1829                 RuntimeMethodInfo crmi;
1830                 if (la != null)
1831                 {
1832                     crmi = la.m_methodInstantiations[rmi];
1833                 }
1834                 else
1835                 {
1836                     crmi = s_methodInstantiations[rmi];
1837                 }
1838                 if (crmi != null)
1839                     return crmi;
1840
1841                 if (s_methodInstantiationsLock == null)
1842                     Interlocked.CompareExchange(ref s_methodInstantiationsLock, new Object(), null);
1843
1844                 bool lockTaken = false;
1845                 RuntimeHelpers.PrepareConstrainedRegions();
1846                 try
1847                 {
1848                     Monitor.Enter(s_methodInstantiationsLock, ref lockTaken);
1849
1850                     if (la != null)
1851                     {
1852                         crmi = la.m_methodInstantiations[rmi];
1853                         if (crmi != null)
1854                             return crmi;
1855                         la.m_methodInstantiations[rmi] = rmi;
1856                     }
1857                     else
1858                     {
1859                         crmi = s_methodInstantiations[rmi];
1860                         if (crmi != null)
1861                             return crmi;
1862                         s_methodInstantiations[rmi] = rmi;
1863                     }
1864                 }
1865                 finally
1866                 {
1867                     if (lockTaken)
1868                     {
1869                         Monitor.Exit(s_methodInstantiationsLock);
1870                     }
1871                 }
1872
1873                 return rmi;
1874             }
1875
1876             internal RuntimeMethodInfo[] GetMethodList(MemberListType listType, string name) 
1877             { 
1878                 return GetMemberList<RuntimeMethodInfo>(ref m_methodInfoCache, listType, name, CacheType.Method);
1879             }
1880
1881             internal RuntimeConstructorInfo[] GetConstructorList(MemberListType listType, string name)
1882             { 
1883                 return GetMemberList<RuntimeConstructorInfo>(ref m_constructorInfoCache, listType, name, CacheType.Constructor);
1884             }
1885
1886             internal RuntimePropertyInfo[] GetPropertyList(MemberListType listType, string name)
1887             { 
1888                 return GetMemberList<RuntimePropertyInfo>(ref m_propertyInfoCache, listType, name, CacheType.Property);
1889             }
1890
1891 #if FEATURE_LEGACYNETCF
1892             // Dev11 466969 quirk
1893             internal RuntimePropertyInfo[] GetPropertyList(MemberListType listType, string name, out IReadOnlyList<RuntimePropertyInfo> ambiguousProperties)
1894             { 
1895                 return GetMemberList<RuntimePropertyInfo>(ref m_propertyInfoCache, listType, name, CacheType.Property, out ambiguousProperties);
1896             }
1897 #endif
1898
1899             internal RuntimeEventInfo[] GetEventList(MemberListType listType, string name)
1900             { 
1901                 return GetMemberList<RuntimeEventInfo>(ref m_eventInfoCache, listType, name, CacheType.Event);
1902             }
1903
1904             internal RuntimeFieldInfo[] GetFieldList(MemberListType listType, string name)
1905             { 
1906                 return GetMemberList<RuntimeFieldInfo>(ref m_fieldInfoCache, listType, name, CacheType.Field);
1907             }
1908
1909             internal RuntimeType[] GetInterfaceList(MemberListType listType, string name)
1910             { 
1911                 return GetMemberList<RuntimeType>(ref m_interfaceCache, listType, name, CacheType.Interface);
1912             }
1913
1914             internal RuntimeType[] GetNestedTypeList(MemberListType listType, string name)
1915             { 
1916                 return GetMemberList<RuntimeType>(ref m_nestedClassesCache, listType, name, CacheType.NestedType);
1917             }
1918
1919             internal MethodBase GetMethod(RuntimeType declaringType, RuntimeMethodHandleInternal method) 
1920             { 
1921                 GetMemberCache<RuntimeMethodInfo>(ref m_methodInfoCache);
1922                 return m_methodInfoCache.AddMethod(declaringType, method, CacheType.Method);
1923             }
1924
1925             internal MethodBase GetConstructor(RuntimeType declaringType, RuntimeMethodHandleInternal constructor)
1926             { 
1927                 GetMemberCache<RuntimeConstructorInfo>(ref m_constructorInfoCache);
1928                 return m_constructorInfoCache.AddMethod(declaringType, constructor, CacheType.Constructor);
1929             }
1930
1931             internal FieldInfo GetField(RuntimeFieldHandleInternal field)
1932             { 
1933                 GetMemberCache<RuntimeFieldInfo>(ref m_fieldInfoCache);
1934                 return m_fieldInfoCache.AddField(field);
1935             }
1936
1937             #endregion
1938         }
1939 #endif
1940         #endregion
1941
1942 #if FEATURE_REMOTING && !MONO
1943         #region Legacy Remoting Cache
1944         // The size of CachedData is accounted for by BaseObjectWithCachedData in object.h.
1945         // This member is currently being used by Remoting for caching remoting data. If you
1946         // need to cache data here, talk to the Remoting team to work out a mechanism, so that
1947         // both caching systems can happily work together.
1948         private RemotingTypeCachedData m_cachedData;
1949
1950         internal RemotingTypeCachedData RemotingCache
1951         {
1952             get
1953             {
1954                 // This grabs an internal copy of m_cachedData and uses
1955                 // that instead of looking at m_cachedData directly because
1956                 // the cache may get cleared asynchronously.  This prevents
1957                 // us from having to take a lock.
1958                 RemotingTypeCachedData cache = m_cachedData;
1959                 if (cache == null)
1960                 {
1961                     cache = new RemotingTypeCachedData(this);
1962                     RemotingTypeCachedData ret = Interlocked.CompareExchange(ref m_cachedData, cache, null);
1963                     if (ret != null)
1964                         cache = ret;
1965                 }
1966                 return cache;
1967             }
1968         }
1969         #endregion
1970 #endif //FEATURE_REMOTING
1971
1972         #region Static Members
1973
1974         #region Internal
1975 #if !MONO
1976         internal static RuntimeType GetType(String typeName, bool throwOnError, bool ignoreCase, bool reflectionOnly,
1977             ref StackCrawlMark stackMark)
1978         {
1979             if (typeName == null)
1980                 throw new ArgumentNullException("typeName");
1981             Contract.EndContractBlock();
1982
1983 #if FEATURE_LEGACYNETCF
1984             if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8 && typeName.Length == 0)
1985                 throw new TypeLoadException(Environment.GetResourceString("Arg_TypeLoadNullStr"));
1986 #endif
1987
1988             return RuntimeTypeHandle.GetTypeByName(
1989                 typeName, throwOnError, ignoreCase, reflectionOnly, ref stackMark, false);
1990         }
1991
1992         internal static MethodBase GetMethodBase(RuntimeModule scope, int typeMetadataToken)
1993         {
1994             return GetMethodBase(ModuleHandle.ResolveMethodHandleInternal(scope, typeMetadataToken));
1995         }
1996
1997         internal static MethodBase GetMethodBase(IRuntimeMethodInfo methodHandle)
1998         {
1999             return GetMethodBase(null, methodHandle);
2000         }
2001
2002         [System.Security.SecuritySafeCritical]
2003         internal static MethodBase GetMethodBase(RuntimeType reflectedType, IRuntimeMethodInfo methodHandle)
2004         {
2005             MethodBase retval = RuntimeType.GetMethodBase(reflectedType, methodHandle.Value);
2006             GC.KeepAlive(methodHandle);
2007             return retval;
2008         }
2009
2010         [System.Security.SecurityCritical]  // auto-generated
2011         internal unsafe static MethodBase GetMethodBase(RuntimeType reflectedType, RuntimeMethodHandleInternal methodHandle)
2012         {
2013             Contract.Assert(!methodHandle.IsNullHandle());
2014
2015             if (RuntimeMethodHandle.IsDynamicMethod(methodHandle))
2016             {
2017                 Resolver resolver = RuntimeMethodHandle.GetResolver(methodHandle);
2018
2019                 if (resolver != null)
2020                     return resolver.GetDynamicMethod();
2021
2022                 return null;
2023             }
2024
2025             // verify the type/method relationship
2026             RuntimeType declaredType = RuntimeMethodHandle.GetDeclaringType(methodHandle);
2027
2028             RuntimeType[] methodInstantiation = null;
2029
2030             if (reflectedType == null)
2031                 reflectedType = declaredType as RuntimeType;
2032
2033             if (reflectedType != declaredType && !reflectedType.IsSubclassOf(declaredType))
2034             {
2035                 // object[] is assignable from string[].
2036                 if (reflectedType.IsArray)
2037                 {
2038                     // 
2039
2040                     // The whole purpose of this chunk of code is not only for error checking.
2041                     // GetMember has a side effect of populating the member cache of reflectedType,
2042                     // doing so will ensure we construct the correct MethodInfo/ConstructorInfo objects.
2043                     // Without this the reflectedType.Cache.GetMethod call below may return a MethodInfo
2044                     // object whose ReflectedType is string[] and DeclaringType is object[]. That would
2045                     // be (arguabally) incorrect because string[] is not a subclass of object[].
2046                     MethodBase[] methodBases = reflectedType.GetMember(
2047                         RuntimeMethodHandle.GetName(methodHandle), MemberTypes.Constructor | MemberTypes.Method,
2048                         BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) as MethodBase[];
2049
2050                     bool loaderAssuredCompatible = false;
2051                     for (int i = 0; i < methodBases.Length; i++)
2052                     {
2053                         IRuntimeMethodInfo rmi = (IRuntimeMethodInfo)methodBases[i];
2054                         if (rmi.Value.Value == methodHandle.Value)
2055                             loaderAssuredCompatible = true;
2056                     }
2057
2058                     if (!loaderAssuredCompatible)
2059                         throw new ArgumentException(String.Format(
2060                             CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_ResolveMethodHandle"),
2061                             reflectedType.ToString(), declaredType.ToString()));
2062                 }
2063                 // Action<in string> is assignable from, but not a subclass of Action<in object>.
2064                 else if (declaredType.IsGenericType)
2065                 {
2066                     // ignoring instantiation is the ReflectedType a subtype of the DeclaringType
2067                     RuntimeType declaringDefinition = (RuntimeType)declaredType.GetGenericTypeDefinition();
2068
2069                     RuntimeType baseType = reflectedType;
2070
2071                     while (baseType != null)
2072                     {
2073                         RuntimeType baseDefinition = baseType;
2074
2075                         if (baseDefinition.IsGenericType && !baseType.IsGenericTypeDefinition)
2076                             baseDefinition = (RuntimeType)baseDefinition.GetGenericTypeDefinition();
2077
2078                         if (baseDefinition == declaringDefinition)
2079                             break;
2080
2081                         baseType = baseType.GetBaseType();
2082                     }
2083
2084                     if (baseType == null)
2085                     {
2086                         // ignoring instantiation is the ReflectedType is not a subtype of the DeclaringType
2087                         throw new ArgumentException(String.Format(
2088                             CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_ResolveMethodHandle"),
2089                             reflectedType.ToString(), declaredType.ToString()));
2090                     }
2091
2092                     // remap the method to same method on the subclass ReflectedType
2093                     declaredType = baseType;
2094
2095                     // if the original methodHandle was the definition then we don't need to rebind generic method arguments
2096                     // because all RuntimeMethodHandles retrieved off of the canonical method table are definitions. That's 
2097                     // why for everything else we need to rebind the generic method arguments. 
2098                     if (!RuntimeMethodHandle.IsGenericMethodDefinition(methodHandle))
2099                     {
2100                         methodInstantiation = RuntimeMethodHandle.GetMethodInstantiationInternal(methodHandle);
2101                     }
2102
2103                     // lookup via v-table slot the RuntimeMethodHandle on the new declaring type
2104                     methodHandle = RuntimeMethodHandle.GetMethodFromCanonical(methodHandle, declaredType);
2105                 }
2106                 else if (!declaredType.IsAssignableFrom(reflectedType))
2107                 {
2108                     // declaredType is not Array, not generic, and not assignable from reflectedType
2109                     throw new ArgumentException(String.Format(
2110                         CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_ResolveMethodHandle"),
2111                         reflectedType.ToString(), declaredType.ToString()));
2112                 }
2113             }
2114
2115             // If methodInstantiation is not null, GetStubIfNeeded will rebind the generic method arguments
2116             // if declaredType is an instantiated generic type and methodHandle is not generic, get the instantiated MethodDesc (if needed)
2117             // if declaredType is a value type, get the unboxing stub (if needed)
2118
2119             // this is so that our behavior here is consistent with that of Type.GetMethod
2120             // See MemberInfoCache<RuntimeConstructorInfo>.PopulateMethods and MemberInfoCache<RuntimeMethodInfoInfo>.PopulateConstructors
2121
2122             methodHandle = RuntimeMethodHandle.GetStubIfNeeded(methodHandle, declaredType, methodInstantiation);
2123             MethodBase retval;
2124
2125             if (RuntimeMethodHandle.IsConstructor(methodHandle))
2126             {
2127                 // Constructor case: constructors cannot be generic
2128                 retval = reflectedType.Cache.GetConstructor(declaredType, methodHandle);
2129             }
2130             else
2131             {
2132                 // Method case
2133                 if (RuntimeMethodHandle.HasMethodInstantiation(methodHandle) && !RuntimeMethodHandle.IsGenericMethodDefinition(methodHandle))
2134                     retval = reflectedType.Cache.GetGenericMethodInfo(methodHandle);
2135                 else
2136                     retval = reflectedType.Cache.GetMethod(declaredType, methodHandle);
2137             }
2138
2139             GC.KeepAlive(methodInstantiation);
2140             return retval;
2141         }
2142
2143         internal Object GenericCache
2144         {
2145             get { return Cache.GenericCache; }
2146             set { Cache.GenericCache = value; }
2147         }
2148
2149         internal bool DomainInitialized
2150         {
2151             get { return Cache.DomainInitialized; }
2152             set { Cache.DomainInitialized = value; }
2153         }
2154
2155         [System.Security.SecuritySafeCritical]  // auto-generated
2156         internal unsafe static FieldInfo GetFieldInfo(IRuntimeFieldInfo fieldHandle)
2157         {
2158             return GetFieldInfo(RuntimeFieldHandle.GetApproxDeclaringType(fieldHandle), fieldHandle);
2159         }
2160
2161         [System.Security.SecuritySafeCritical]  // auto-generated
2162         internal unsafe static FieldInfo GetFieldInfo(RuntimeType reflectedType, IRuntimeFieldInfo field)
2163         {
2164             RuntimeFieldHandleInternal fieldHandle = field.Value;
2165
2166             // verify the type/method relationship
2167             if (reflectedType == null) 
2168             {
2169                 reflectedType = RuntimeFieldHandle.GetApproxDeclaringType(fieldHandle);
2170             }
2171             else
2172             {
2173                 RuntimeType declaredType = RuntimeFieldHandle.GetApproxDeclaringType(fieldHandle);
2174                 if (reflectedType != declaredType)
2175                 {
2176                     if (!RuntimeFieldHandle.AcquiresContextFromThis(fieldHandle) ||
2177                         !RuntimeTypeHandle.CompareCanonicalHandles(declaredType, reflectedType))
2178                     {
2179                         throw new ArgumentException(String.Format(
2180                             CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_ResolveFieldHandle"),
2181                             reflectedType.ToString(),
2182                             declaredType.ToString()));
2183                     }
2184                 }
2185             }
2186
2187             FieldInfo retVal = reflectedType.Cache.GetField(fieldHandle);
2188             GC.KeepAlive(field);
2189             return retVal;
2190         }
2191
2192         // Called internally
2193         private unsafe static PropertyInfo GetPropertyInfo(RuntimeType reflectedType, int tkProperty)
2194         {
2195             RuntimePropertyInfo property = null;
2196             RuntimePropertyInfo[] candidates = 
2197                 reflectedType.Cache.GetPropertyList(MemberListType.All, null);
2198
2199             for (int i = 0; i < candidates.Length; i++)
2200             {
2201                 property = candidates[i];
2202                 if (property.MetadataToken == tkProperty)
2203                     return property;
2204             }
2205
2206             Contract.Assume(false, "Unreachable code");
2207             throw new SystemException();
2208         }
2209 #endif
2210         private static void ThrowIfTypeNeverValidGenericArgument(RuntimeType type)
2211         {
2212             if (type.IsPointer || type.IsByRef || type == typeof(void))
2213                 throw new ArgumentException(
2214                     Environment.GetResourceString("Argument_NeverValidGenericArgument", type.ToString()));
2215         }
2216
2217
2218         internal static void SanityCheckGenericArguments(RuntimeType[] genericArguments, RuntimeType[] genericParamters)
2219         {
2220             if (genericArguments == null)
2221                 throw new ArgumentNullException();
2222             Contract.EndContractBlock();
2223
2224             for(int i = 0; i < genericArguments.Length; i++)
2225             {                
2226                 if (genericArguments[i] == null)
2227                     throw new ArgumentNullException();
2228                 
2229                 ThrowIfTypeNeverValidGenericArgument(genericArguments[i]);
2230             }
2231
2232             if (genericArguments.Length != genericParamters.Length)
2233                 throw new ArgumentException(
2234                     Environment.GetResourceString("Argument_NotEnoughGenArguments", genericArguments.Length, genericParamters.Length));
2235         }
2236 #if !MONO
2237         [System.Security.SecuritySafeCritical]  // auto-generated
2238         internal static void ValidateGenericArguments(MemberInfo definition, RuntimeType[] genericArguments, Exception e)
2239         {
2240             RuntimeType[] typeContext = null;
2241             RuntimeType[] methodContext = null;
2242             RuntimeType[] genericParamters = null;
2243         
2244             if (definition is Type)
2245             {
2246                 RuntimeType genericTypeDefinition = (RuntimeType)definition;
2247                 genericParamters = genericTypeDefinition.GetGenericArgumentsInternal();               
2248                 typeContext = genericArguments;
2249             }
2250             else
2251             {
2252                 RuntimeMethodInfo genericMethodDefinition = (RuntimeMethodInfo)definition;
2253                 genericParamters = genericMethodDefinition.GetGenericArgumentsInternal();
2254                 methodContext = genericArguments;
2255                 
2256                 RuntimeType declaringType = (RuntimeType)genericMethodDefinition.DeclaringType;
2257                 if (declaringType != null)
2258                 {
2259                     typeContext = declaringType.GetTypeHandleInternal().GetInstantiationInternal();
2260                 }
2261             }
2262             
2263             for (int i = 0; i < genericArguments.Length; i++)
2264             {
2265                 Type genericArgument = genericArguments[i];
2266                 Type genericParameter = genericParamters[i];
2267
2268                 if (!RuntimeTypeHandle.SatisfiesConstraints(genericParameter.GetTypeHandleInternal().GetTypeChecked(),
2269                     typeContext, methodContext, genericArgument.GetTypeHandleInternal().GetTypeChecked()))
2270                 {
2271                     throw new ArgumentException(
2272                         Environment.GetResourceString("Argument_GenConstraintViolation", 
2273                         i.ToString(CultureInfo.CurrentCulture), genericArgument.ToString(), definition.ToString(), genericParameter.ToString()), e);
2274                 }
2275             }
2276         }
2277 #endif
2278         private static void SplitName(string fullname, out string name, out string ns)
2279         {
2280             name = null;
2281             ns = null;
2282
2283             if (fullname == null)
2284                 return;
2285
2286             // Get namespace
2287             int nsDelimiter = fullname.LastIndexOf(".", StringComparison.Ordinal);
2288             if (nsDelimiter != -1 )     
2289             {
2290                 ns = fullname.Substring(0, nsDelimiter);
2291                 int nameLength = fullname.Length - ns.Length - 1;
2292                 if (nameLength != 0)
2293                     name = fullname.Substring(nsDelimiter + 1, nameLength);
2294                 else
2295                     name = "";
2296                 Contract.Assert(fullname.Equals(ns + "." + name));
2297             }
2298             else
2299             {
2300                 name = fullname;
2301             }
2302
2303         }
2304         #endregion
2305
2306         #region Filters
2307         internal static BindingFlags FilterPreCalculate(bool isPublic, bool isInherited, bool isStatic)
2308         {
2309             BindingFlags bindingFlags = isPublic ? BindingFlags.Public : BindingFlags.NonPublic;
2310
2311             if (isInherited) 
2312             {   
2313                 // We arrange things so the DeclaredOnly flag means "include inherited members"
2314                 bindingFlags |= BindingFlags.DeclaredOnly; 
2315
2316                 if (isStatic)
2317                 {
2318                     bindingFlags |= BindingFlags.Static | BindingFlags.FlattenHierarchy;
2319                 }
2320                 else
2321                 {
2322                     bindingFlags |= BindingFlags.Instance;
2323                 }
2324             }
2325             else
2326             {
2327                 if (isStatic)
2328                 {
2329                     bindingFlags |= BindingFlags.Static;
2330                 }
2331                 else
2332                 {
2333                     bindingFlags |= BindingFlags.Instance;
2334                 }
2335             }
2336
2337             return bindingFlags;
2338         }
2339
2340         // Calculate prefixLookup, ignoreCase, and listType for use by GetXXXCandidates
2341         private static void FilterHelper(
2342             BindingFlags bindingFlags, ref string name, bool allowPrefixLookup, out bool prefixLookup, 
2343             out bool ignoreCase, out MemberListType listType)
2344         {
2345             prefixLookup = false;
2346             ignoreCase = false;
2347
2348             if (name != null)
2349             {
2350                 if ((bindingFlags & BindingFlags.IgnoreCase) != 0)
2351                 {
2352                     name = name.ToLower(CultureInfo.InvariantCulture);
2353                     ignoreCase = true;
2354                     listType = MemberListType.CaseInsensitive;
2355                 }
2356                 else
2357                 {
2358                     listType = MemberListType.CaseSensitive;
2359                 }
2360
2361                 if (allowPrefixLookup && name.EndsWith("*", StringComparison.Ordinal))
2362                 {
2363                     // We set prefixLookup to true if name ends with a "*".
2364                     // We will also set listType to All so that all members are included in 
2365                     // the candidates which are later filtered by FilterApplyPrefixLookup.
2366                     name = name.Substring(0, name.Length - 1);
2367                     prefixLookup = true;
2368                     listType = MemberListType.All;
2369                 }
2370             }
2371             else
2372             {
2373                 listType = MemberListType.All;
2374             }
2375         }
2376
2377         // Used by the singular GetXXX APIs (Event, Field, Interface, NestedType) where prefixLookup is not supported.
2378         private static void FilterHelper(BindingFlags bindingFlags, ref string name, out bool ignoreCase, out MemberListType listType)
2379         {
2380             bool prefixLookup;
2381             FilterHelper(bindingFlags, ref name, false, out prefixLookup, out ignoreCase, out listType);
2382         }
2383
2384         // Only called by GetXXXCandidates, GetInterfaces, and GetNestedTypes when FilterHelper has set "prefixLookup" to true.
2385         // Most of the plural GetXXX methods allow prefix lookups while the singular GetXXX methods mostly do not.
2386         private static bool FilterApplyPrefixLookup(MemberInfo memberInfo, string name, bool ignoreCase)
2387         {
2388             Contract.Assert(name != null);
2389
2390             if (ignoreCase)
2391             {
2392                 if (!memberInfo.Name.StartsWith(name, StringComparison.OrdinalIgnoreCase))
2393                     return false;
2394             }
2395             else
2396             {
2397                 if (!memberInfo.Name.StartsWith(name, StringComparison.Ordinal))
2398                     return false;
2399             }            
2400
2401             return true;
2402         }
2403
2404
2405         // Used by FilterApplyType to perform all the filtering based on name and BindingFlags
2406         private static bool FilterApplyBase(
2407             MemberInfo memberInfo, BindingFlags bindingFlags, bool isPublic, bool isNonProtectedInternal, bool isStatic,
2408             string name, bool prefixLookup)
2409         {
2410             #region Preconditions
2411             Contract.Requires(memberInfo != null);
2412             Contract.Requires(name == null || (bindingFlags & BindingFlags.IgnoreCase) == 0 || (name.ToLower(CultureInfo.InvariantCulture).Equals(name)));
2413             #endregion
2414
2415             #region Filter by Public & Private
2416             if (isPublic)
2417             {
2418                 if ((bindingFlags & BindingFlags.Public) == 0)
2419                     return false;
2420             }
2421             else
2422             {
2423                 if ((bindingFlags & BindingFlags.NonPublic) == 0)
2424                     return false;
2425             }
2426             #endregion
2427
2428             bool isInherited = !Object.ReferenceEquals(memberInfo.DeclaringType, memberInfo.ReflectedType);
2429
2430             #region Filter by DeclaredOnly
2431             if ((bindingFlags & BindingFlags.DeclaredOnly) != 0 && isInherited)
2432                 return false;
2433             #endregion
2434
2435             #region Filter by Static & Instance
2436             if (memberInfo.MemberType != MemberTypes.TypeInfo && 
2437                 memberInfo.MemberType != MemberTypes.NestedType)
2438             {
2439                 if (isStatic)
2440                 {
2441                     if ((bindingFlags & BindingFlags.FlattenHierarchy) == 0 && isInherited)
2442                         return false;
2443
2444                     if ((bindingFlags & BindingFlags.Static) == 0)
2445                         return false;
2446                 }
2447                 else
2448                 {
2449                     if ((bindingFlags & BindingFlags.Instance) == 0)
2450                         return false;
2451                 }
2452             }
2453             #endregion
2454
2455             #region Filter by name wrt prefixLookup and implicitly by case sensitivity
2456             if (prefixLookup == true)
2457             {
2458                 if (!FilterApplyPrefixLookup(memberInfo, name, (bindingFlags & BindingFlags.IgnoreCase) != 0))
2459                     return false;
2460             }
2461             #endregion
2462
2463             #region Asymmetries
2464             // @Asymmetry - Internal, inherited, instance, non-protected, non-virtual, non-abstract members returned 
2465             //              iff BindingFlags !DeclaredOnly, Instance and Public are present except for fields
2466             if (((bindingFlags & BindingFlags.DeclaredOnly) == 0) &&        // DeclaredOnly not present
2467                  isInherited  &&                                            // Is inherited Member
2468     
2469                 (isNonProtectedInternal) &&                                 // Is non-protected internal member
2470                 ((bindingFlags & BindingFlags.NonPublic) != 0) &&           // BindingFlag.NonPublic present 
2471
2472                 (!isStatic) &&                                              // Is instance member
2473                 ((bindingFlags & BindingFlags.Instance) != 0))              // BindingFlag.Instance present 
2474             {
2475                 MethodInfo methodInfo = memberInfo as MethodInfo;
2476
2477                 if (methodInfo == null)
2478                     return false;
2479
2480                 if (!methodInfo.IsVirtual && !methodInfo.IsAbstract)
2481                     return false;
2482             }
2483             #endregion
2484
2485             return true;
2486         }
2487
2488
2489         // Used by GetInterface and GetNestedType(s) which don't need parameter type filtering.
2490         private static bool FilterApplyType(
2491             Type type, BindingFlags bindingFlags, string name, bool prefixLookup, string ns)
2492         {
2493             Contract.Requires((object)type != null);
2494             Contract.Assert(type is RuntimeType);
2495
2496             bool isPublic = type.IsNestedPublic || type.IsPublic;
2497             bool isStatic = false;
2498
2499             if (!RuntimeType.FilterApplyBase(type, bindingFlags, isPublic, type.IsNestedAssembly, isStatic, name, prefixLookup))
2500                 return false;
2501
2502             if (ns != null && !type.Namespace.Equals(ns))
2503                 return false;
2504
2505             return true;
2506         }
2507
2508
2509         private static bool FilterApplyMethodInfo(
2510             RuntimeMethodInfo method, BindingFlags bindingFlags, CallingConventions callConv, Type[] argumentTypes)
2511         {
2512             // Optimization: Pre-Calculate the method binding flags to avoid casting.
2513             return FilterApplyMethodBase(method, method.BindingFlags, bindingFlags, callConv, argumentTypes);
2514         }
2515
2516         private static bool FilterApplyConstructorInfo(
2517             RuntimeConstructorInfo constructor, BindingFlags bindingFlags, CallingConventions callConv, Type[] argumentTypes)
2518         {
2519             // Optimization: Pre-Calculate the method binding flags to avoid casting.
2520             return FilterApplyMethodBase(constructor, constructor.BindingFlags, bindingFlags, callConv, argumentTypes);
2521         }
2522
2523         // Used by GetMethodCandidates/GetConstructorCandidates, InvokeMember, and CreateInstanceImpl to perform the necessary filtering.
2524         // Should only be called by FilterApplyMethodInfo and FilterApplyConstructorInfo.
2525         private static bool FilterApplyMethodBase(
2526             MethodBase methodBase, BindingFlags methodFlags, BindingFlags bindingFlags, CallingConventions callConv, Type[] argumentTypes)
2527         {
2528             Contract.Requires(methodBase != null);
2529
2530             bindingFlags ^= BindingFlags.DeclaredOnly;
2531 #if !MONO
2532             #region Apply Base Filter
2533             if ((bindingFlags & methodFlags) != methodFlags)
2534                 return false;
2535             #endregion
2536 #endif
2537             #region Check CallingConvention
2538             if ((callConv & CallingConventions.Any) == 0)
2539             {
2540                 if ((callConv & CallingConventions.VarArgs) != 0 && 
2541                     (methodBase.CallingConvention & CallingConventions.VarArgs) == 0)
2542                     return false;
2543
2544                 if ((callConv & CallingConventions.Standard) != 0 && 
2545                     (methodBase.CallingConvention & CallingConventions.Standard) == 0)
2546                     return false;
2547             }
2548             #endregion
2549
2550             #region If argumentTypes supplied
2551             if (argumentTypes != null)
2552             {
2553                 ParameterInfo[] parameterInfos = methodBase.GetParametersNoCopy();
2554
2555                 if (argumentTypes.Length != parameterInfos.Length)
2556                 {
2557                     #region Invoke Member, Get\Set & Create Instance specific case
2558                     // If the number of supplied arguments differs than the number in the signature AND
2559                     // we are not filtering for a dynamic call -- InvokeMethod or CreateInstance -- filter out the method.
2560                     if ((bindingFlags & 
2561                         (BindingFlags.InvokeMethod | BindingFlags.CreateInstance | BindingFlags.GetProperty | BindingFlags.SetProperty)) == 0)
2562                         return false;
2563                     
2564                     bool testForParamArray = false;
2565                     bool excessSuppliedArguments = argumentTypes.Length > parameterInfos.Length;
2566
2567                     if (excessSuppliedArguments) 
2568                     { // more supplied arguments than parameters, additional arguments could be vararg
2569                         #region Varargs
2570                         // If method is not vararg, additional arguments can not be passed as vararg
2571                         if ((methodBase.CallingConvention & CallingConventions.VarArgs) == 0)
2572                         {
2573                             testForParamArray = true;
2574                         }
2575                         else 
2576                         {
2577                             // If Binding flags did not include varargs we would have filtered this vararg method.
2578                             // This Invariant established during callConv check.
2579                             Contract.Assert((callConv & CallingConventions.VarArgs) != 0);
2580                         }
2581                         #endregion
2582                     }
2583                     else 
2584                     {// fewer supplied arguments than parameters, missing arguments could be optional
2585                         #region OptionalParamBinding
2586                         if ((bindingFlags & BindingFlags.OptionalParamBinding) == 0)
2587                         {
2588                             testForParamArray = true;
2589                         }
2590                         else
2591                         {
2592                             // From our existing code, our policy here is that if a parameterInfo 
2593                             // is optional then all subsequent parameterInfos shall be optional. 
2594
2595                             // Thus, iff the first parameterInfo is not optional then this MethodInfo is no longer a canidate.
2596                             if (!parameterInfos[argumentTypes.Length].IsOptional)
2597                                 testForParamArray = true;
2598                         }
2599                         #endregion
2600                     }
2601
2602                     #region ParamArray
2603                     if (testForParamArray)
2604                     {
2605                         if  (parameterInfos.Length == 0)
2606                             return false;
2607
2608                         // The last argument of the signature could be a param array. 
2609                         bool shortByMoreThanOneSuppliedArgument = argumentTypes.Length < parameterInfos.Length - 1;
2610
2611                         if (shortByMoreThanOneSuppliedArgument)
2612                             return false;
2613
2614                         ParameterInfo lastParameter = parameterInfos[parameterInfos.Length - 1];
2615
2616                         if (!lastParameter.ParameterType.IsArray)
2617                             return false;
2618
2619                         if (!lastParameter.IsDefined(typeof(ParamArrayAttribute), false))
2620                             return false;
2621                     }
2622                     #endregion
2623
2624                     #endregion
2625                 }
2626                 else
2627                 {
2628                     #region Exact Binding
2629                     if ((bindingFlags & BindingFlags.ExactBinding) != 0)
2630                     {
2631                         // Legacy behavior is to ignore ExactBinding when InvokeMember is specified.
2632                         // Why filter by InvokeMember? If the answer is we leave this to the binder then why not leave
2633                         // all the rest of this  to the binder too? Further, what other semanitc would the binder
2634                         // use for BindingFlags.ExactBinding besides this one? Further, why not include CreateInstance 
2635                         // in this if statement? That's just InvokeMethod with a constructor, right?
2636                         if ((bindingFlags & (BindingFlags.InvokeMethod)) == 0)
2637                         {
2638                             for(int i = 0; i < parameterInfos.Length; i ++)
2639                             {
2640                                 // a null argument type implies a null arg which is always a perfect match
2641                                 if ((object)argumentTypes[i] != null && !Object.ReferenceEquals(parameterInfos[i].ParameterType, argumentTypes[i]))
2642                                     return false;
2643                             }
2644                         }
2645                     }
2646                     #endregion
2647                 }
2648             }
2649             #endregion
2650         
2651             return true;
2652         }
2653
2654         #endregion
2655
2656         #endregion
2657
2658         #region Private Data Members
2659 #if !MONO
2660         private object m_keepalive; // This will be filled with a LoaderAllocator reference when this RuntimeType represents a collectible type
2661         private IntPtr m_cache;
2662         internal IntPtr m_handle;
2663 #endif
2664 #if FEATURE_APPX
2665         private INVOCATION_FLAGS m_invocationFlags;
2666
2667         internal bool IsNonW8PFrameworkAPI()
2668         {
2669             if (IsGenericParameter)
2670                 return false;
2671
2672             if (HasElementType)
2673                 return ((RuntimeType)GetElementType()).IsNonW8PFrameworkAPI();
2674
2675             if (IsSimpleTypeNonW8PFrameworkAPI())
2676                 return true;
2677
2678             if (IsGenericType && !IsGenericTypeDefinition)
2679             {
2680                 foreach (Type t in GetGenericArguments())
2681                 {
2682                     if (((RuntimeType)t).IsNonW8PFrameworkAPI())
2683                         return true;
2684                 }
2685             }
2686
2687             return false;
2688         }
2689
2690         private bool IsSimpleTypeNonW8PFrameworkAPI()
2691         {
2692             RuntimeAssembly rtAssembly = GetRuntimeAssembly();
2693             if (rtAssembly.IsFrameworkAssembly())
2694             {
2695                 int ctorToken = rtAssembly.InvocableAttributeCtorToken;
2696                 if (System.Reflection.MetadataToken.IsNullToken(ctorToken) ||
2697                     !CustomAttribute.IsAttributeDefined(GetRuntimeModule(), MetadataToken, ctorToken))
2698                     return true;
2699             }
2700
2701             return false;
2702         }
2703
2704         internal INVOCATION_FLAGS InvocationFlags
2705         {
2706             get
2707             {
2708                 if ((m_invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED) == 0)
2709                 {
2710                     INVOCATION_FLAGS invocationFlags = INVOCATION_FLAGS.INVOCATION_FLAGS_UNKNOWN;
2711
2712                     if (AppDomain.ProfileAPICheck && IsNonW8PFrameworkAPI())
2713                         invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API;
2714
2715                     m_invocationFlags = invocationFlags | INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED;
2716                 }
2717
2718                 return m_invocationFlags;
2719             }
2720         }
2721 #endif // FEATURE_APPX
2722
2723         internal static readonly RuntimeType ValueType = (RuntimeType)typeof(System.ValueType);
2724         internal static readonly RuntimeType EnumType = (RuntimeType)typeof(System.Enum);
2725
2726         private static readonly RuntimeType ObjectType = (RuntimeType)typeof(System.Object);
2727         private static readonly RuntimeType StringType = (RuntimeType)typeof(System.String);
2728         private static readonly RuntimeType DelegateType = (RuntimeType)typeof(System.Delegate);
2729
2730         private static Type[] s_SICtorParamTypes;
2731         #endregion
2732
2733         #region Constructor
2734         internal RuntimeType() { throw new NotSupportedException(); }
2735         #endregion
2736
2737         #region Private\Internal Members
2738 #if !MONO
2739         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
2740         internal override bool CacheEquals(object o)
2741         {
2742             RuntimeType m = o as RuntimeType;
2743
2744             if (m == null)
2745                 return false;
2746
2747             return m.m_handle.Equals(m_handle);
2748         }
2749
2750         private RuntimeTypeCache Cache
2751         {
2752             [System.Security.SecuritySafeCritical]  // auto-generated
2753             [ResourceExposure(ResourceScope.None)]
2754             [ResourceConsumption(ResourceScope.AppDomain, ResourceScope.AppDomain)]
2755             get
2756             {
2757                 if (m_cache.IsNull())
2758                 {
2759                     IntPtr newgcHandle = new RuntimeTypeHandle(this).GetGCHandle(GCHandleType.WeakTrackResurrection);
2760                     IntPtr gcHandle = Interlocked.CompareExchange(ref m_cache, newgcHandle, (IntPtr)0);
2761                     // Leak the handle if the type is collectible. It will be reclaimed when
2762                     // the type goes away.
2763                     if (!gcHandle.IsNull() && !IsCollectible()) 
2764                         GCHandle.InternalFree(newgcHandle);
2765                 }
2766
2767                 RuntimeTypeCache cache = GCHandle.InternalGet(m_cache) as RuntimeTypeCache;
2768                 if (cache == null) 
2769                 {
2770                     cache = new RuntimeTypeCache(this);
2771                     RuntimeTypeCache existingCache = GCHandle.InternalCompareExchange(m_cache, cache, null, false) as RuntimeTypeCache;
2772                     if (existingCache != null) 
2773                         cache = existingCache;
2774                 }
2775
2776                 Contract.Assert(cache != null);
2777                 return cache;
2778             }
2779         }
2780 #endif
2781         internal bool IsSpecialSerializableType()
2782         {
2783             RuntimeType rt = this;
2784             do
2785             {
2786                 // In all sane cases we only need to compare the direct level base type with
2787                 // System.Enum and System.MulticastDelegate. However, a generic argument can
2788                 // have a base type constraint that is Delegate or even a real delegate type.
2789                 // Let's maintain compatibility and return true for them.
2790                 if (rt == RuntimeType.DelegateType || rt == RuntimeType.EnumType)
2791                     return true;
2792
2793                 rt = rt.GetBaseType();
2794             } while (rt != null);
2795
2796             return false;
2797         }
2798 #if !MONO
2799         private string GetDefaultMemberName()
2800         {
2801             return Cache.GetDefaultMemberName();
2802         }
2803
2804 #if !FEATURE_CORECLR
2805         internal RuntimeConstructorInfo GetSerializationCtor()
2806         {
2807             return Cache.GetSerializationCtor();
2808         }
2809 #endif
2810 #endif
2811         #endregion
2812
2813         #region Type Overrides
2814
2815         #region Get XXXInfo Candidates
2816         private ListBuilder<MethodInfo> GetMethodCandidates(
2817             String name, BindingFlags bindingAttr, CallingConventions callConv,
2818             Type[] types, bool allowPrefixLookup)
2819         {
2820             bool prefixLookup, ignoreCase;
2821             MemberListType listType;
2822             RuntimeType.FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out listType);
2823
2824 #if MONO
2825             RuntimeMethodInfo[] cache = GetMethodsByName (name, bindingAttr, ignoreCase, this);
2826 #else
2827             RuntimeMethodInfo[] cache = Cache.GetMethodList(listType, name);
2828 #endif
2829             ListBuilder<MethodInfo> candidates = new ListBuilder<MethodInfo>(cache.Length);
2830             for (int i = 0; i < cache.Length; i++)
2831             {
2832                 RuntimeMethodInfo methodInfo = cache[i];
2833                 if (FilterApplyMethodInfo(methodInfo, bindingAttr, callConv, types) &&
2834                     (!prefixLookup || RuntimeType.FilterApplyPrefixLookup(methodInfo, name, ignoreCase)))
2835                 {
2836                     candidates.Add(methodInfo);
2837                 }
2838             }
2839
2840             return candidates;
2841         }
2842
2843         private ListBuilder<ConstructorInfo> GetConstructorCandidates(
2844             string name, BindingFlags bindingAttr, CallingConventions callConv, 
2845             Type[] types, bool allowPrefixLookup)
2846         {
2847             bool prefixLookup, ignoreCase;
2848             MemberListType listType;
2849             RuntimeType.FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out listType);
2850
2851 #if MONO
2852             if (name != null && name != ConstructorInfo.ConstructorName && name != ConstructorInfo.TypeConstructorName)
2853                 return new ListBuilder<ConstructorInfo> (0);
2854             RuntimeConstructorInfo[] cache = GetConstructors_internal (bindingAttr, this);
2855 #else
2856             RuntimeConstructorInfo[] cache = Cache.GetConstructorList(listType, name);
2857 #endif
2858             ListBuilder<ConstructorInfo> candidates = new ListBuilder<ConstructorInfo>(cache.Length);
2859             for (int i = 0; i < cache.Length; i++)
2860             {
2861                 RuntimeConstructorInfo constructorInfo = cache[i];
2862                 if (FilterApplyConstructorInfo(constructorInfo, bindingAttr, callConv, types) &&
2863                     (!prefixLookup || RuntimeType.FilterApplyPrefixLookup(constructorInfo, name, ignoreCase)))
2864                 {                    
2865                     candidates.Add(constructorInfo);
2866                 }
2867             }
2868
2869             return candidates;
2870         }
2871
2872
2873         private ListBuilder<PropertyInfo> GetPropertyCandidates(
2874             String name, BindingFlags bindingAttr, Type[] types, bool allowPrefixLookup)
2875         {           
2876             bool prefixLookup, ignoreCase;
2877             MemberListType listType;
2878             RuntimeType.FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out listType);
2879
2880 #if MONO
2881             RuntimePropertyInfo[] cache = GetPropertiesByName (name, bindingAttr, ignoreCase, this);
2882 #else
2883 #if FEATURE_LEGACYNETCF
2884             // Dev11 466969 quirk
2885             IReadOnlyList<RuntimePropertyInfo> ambiguousProperties = null;
2886             RuntimePropertyInfo[] cache = Cache.GetPropertyList(listType, name, out ambiguousProperties);
2887 #else
2888             RuntimePropertyInfo[] cache = Cache.GetPropertyList(listType, name);
2889 #endif
2890 #endif
2891             bindingAttr ^= BindingFlags.DeclaredOnly;
2892
2893             ListBuilder<PropertyInfo> candidates = new ListBuilder<PropertyInfo>(cache.Length);
2894             for (int i = 0; i < cache.Length; i++)
2895             {
2896                 RuntimePropertyInfo propertyInfo = cache[i];
2897                 if ((bindingAttr & propertyInfo.BindingFlags) == propertyInfo.BindingFlags &&
2898                     (!prefixLookup || RuntimeType.FilterApplyPrefixLookup(propertyInfo, name, ignoreCase)) &&
2899                     (types == null || (propertyInfo.GetIndexParameters().Length == types.Length)))
2900                 {
2901                     candidates.Add(propertyInfo);
2902                 }
2903             }
2904
2905 #if FEATURE_LEGACYNETCF
2906             // Dev11 466969 quirk
2907             if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8 &&
2908                 candidates.Count > 1 &&
2909                 ambiguousProperties != null &&
2910                 ambiguousProperties.Count > 0)
2911             {
2912                 return PruneAmbiguousProperties(candidates, ambiguousProperties);
2913             }
2914 #endif
2915
2916             return candidates;
2917         }
2918
2919 #if FEATURE_LEGACYNETCF
2920         private ListBuilder<PropertyInfo> PruneAmbiguousProperties(ListBuilder<PropertyInfo> candidates, IReadOnlyList<RuntimePropertyInfo> ambiguousProperties)
2921         {
2922             Contract.Assert(CompatibilitySwitches.IsAppEarlierThanWindowsPhone8);
2923             Contract.Assert(candidates.Count > 1);
2924             Contract.Assert(ambiguousProperties != null && ambiguousProperties.Count > 0);
2925
2926             ListBuilder<PropertyInfo> newCandidates = candidates;
2927
2928             // Dev11 466969 quirk
2929             // NetCF reflection will differentiate properties by sig and by accessibility.
2930             // Consider the following:
2931             //
2932             // class FooBase
2933             // {
2934             //     public int Prop { get; set; }
2935             // }
2936             //
2937             // class FooDerived : FooBase
2938             // {
2939             //     private int Prop { get; set; }
2940             // }
2941             //
2942             // In Mango one can reflect on FooDerived for property "Prop" with *Public*
2943             // binding flags and get an answer.  On desktop CLR/CoreCLR you get back null
2944             // since FooBase.Prop is considered a duplicate and thus removed from the
2945             // list of candidate properties.  To make this distinction the method
2946             // RuntimePropertyInfo.HasMatchingAccessibility() was added.
2947             //
2948             // There is a wrinkle here though, when reflecting on FooDerived for
2949             // property "Prop" with Public and NonPublic binding flags the answer
2950             // will always be the most-derived type, so FooDerived in this example.
2951             // The purpose of PruneAmbiguousProperties() is to apply this invariant. 
2952             //
2953
2954             int countRemoved = 0;
2955
2956             lock (ambiguousProperties)
2957             {
2958                 for (int outerIndex = 0; outerIndex < ambiguousProperties.Count; ++outerIndex)
2959                 {
2960                     for (int innerIndex = 0; innerIndex < candidates.Count; ++innerIndex)
2961                     {
2962                         if (candidates[innerIndex] != null &&
2963                             candidates[innerIndex] == ambiguousProperties[outerIndex])
2964                         {
2965                             candidates[innerIndex] = null;
2966                             ++countRemoved;
2967                         }
2968                     }
2969                 }
2970             }
2971             
2972             // should have only gone down this code path because we knew
2973             // that at least one ambiguous property needed to be pruned.
2974             Contract.Assert(countRemoved > 0);
2975
2976             if (countRemoved > 0)
2977             {
2978                 newCandidates = new ListBuilder<PropertyInfo>(candidates.Count - countRemoved);
2979                 for (int index = 0; index < candidates.Count; ++index)
2980                 {
2981                     if (candidates[index] != null)
2982                         newCandidates.Add(candidates[index]);
2983                 }
2984                 
2985                 Contract.Assert(newCandidates.Count == (candidates.Count - countRemoved));
2986             }
2987             
2988             return newCandidates;
2989         }
2990 #endif
2991
2992         private ListBuilder<EventInfo> GetEventCandidates(String name, BindingFlags bindingAttr, bool allowPrefixLookup)
2993         {
2994             bool prefixLookup, ignoreCase;
2995             MemberListType listType;
2996             RuntimeType.FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out listType);
2997
2998 #if MONO
2999             RuntimeEventInfo[] cache = GetEvents_internal (name, bindingAttr, this);
3000 #else
3001             RuntimeEventInfo[] cache = Cache.GetEventList(listType, name);
3002 #endif
3003             bindingAttr ^= BindingFlags.DeclaredOnly;
3004
3005             ListBuilder<EventInfo> candidates = new ListBuilder<EventInfo>(cache.Length);
3006             for (int i = 0; i < cache.Length; i++)
3007             {
3008                 RuntimeEventInfo eventInfo = cache[i];
3009                 if ((bindingAttr & eventInfo.BindingFlags) == eventInfo.BindingFlags &&
3010                     (!prefixLookup || RuntimeType.FilterApplyPrefixLookup(eventInfo, name, ignoreCase)))
3011                 {
3012                     candidates.Add(eventInfo);
3013                 }
3014             }
3015
3016             return candidates;
3017         }
3018
3019         private ListBuilder<FieldInfo> GetFieldCandidates(String name, BindingFlags bindingAttr, bool allowPrefixLookup)
3020         {
3021             bool prefixLookup, ignoreCase;
3022             MemberListType listType;
3023             RuntimeType.FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out listType);
3024
3025 #if MONO
3026             RuntimeFieldInfo[] cache = GetFields_internal (name, bindingAttr, this);
3027 #else
3028             RuntimeFieldInfo[] cache = Cache.GetFieldList(listType, name);
3029 #endif
3030             bindingAttr ^= BindingFlags.DeclaredOnly;
3031
3032             ListBuilder<FieldInfo> candidates = new ListBuilder<FieldInfo>(cache.Length);
3033             for (int i = 0; i < cache.Length; i++)
3034             {
3035                 RuntimeFieldInfo fieldInfo = cache[i];
3036                 if ((bindingAttr & fieldInfo.BindingFlags) == fieldInfo.BindingFlags && 
3037                     (!prefixLookup || FilterApplyPrefixLookup(fieldInfo, name, ignoreCase)))
3038                 {
3039                     candidates.Add(fieldInfo);
3040                 }
3041             }
3042
3043             return candidates;
3044         }
3045
3046         private ListBuilder<Type> GetNestedTypeCandidates(String fullname, BindingFlags bindingAttr, bool allowPrefixLookup)
3047         {
3048             bool prefixLookup, ignoreCase;
3049             bindingAttr &= ~BindingFlags.Static;
3050             string name, ns;
3051             MemberListType listType;
3052             SplitName(fullname, out name, out ns);            
3053             RuntimeType.FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out listType);
3054
3055 #if MONO
3056             RuntimeType[] cache = GetNestedTypes_internal (name, bindingAttr);
3057 #else
3058             RuntimeType[] cache = Cache.GetNestedTypeList(listType, name);
3059 #endif
3060             ListBuilder<Type> candidates = new ListBuilder<Type>(cache.Length);
3061             for (int i = 0; i < cache.Length; i++)
3062             {
3063                 RuntimeType nestedClass = cache[i];
3064                 if (RuntimeType.FilterApplyType(nestedClass, bindingAttr, name, prefixLookup, ns))
3065                 {
3066                     candidates.Add(nestedClass);
3067                 }
3068             }
3069
3070             return candidates;
3071         }
3072
3073         #endregion
3074
3075         #region Get All XXXInfos
3076         public override MethodInfo[] GetMethods(BindingFlags bindingAttr)
3077         {
3078             return GetMethodCandidates(null, bindingAttr, CallingConventions.Any, null, false).ToArray();
3079         }
3080
3081 [System.Runtime.InteropServices.ComVisible(true)]
3082         public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr)
3083         {
3084             return GetConstructorCandidates(null, bindingAttr, CallingConventions.Any, null, false).ToArray();
3085         }
3086
3087         public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
3088         {
3089             return GetPropertyCandidates(null, bindingAttr, null, false).ToArray();
3090         }
3091
3092         public override EventInfo[] GetEvents(BindingFlags bindingAttr)
3093         {
3094             return GetEventCandidates(null, bindingAttr, false).ToArray();
3095         }
3096
3097         public override FieldInfo[] GetFields(BindingFlags bindingAttr)
3098         {
3099             return GetFieldCandidates(null, bindingAttr, false).ToArray();
3100         }
3101 #if !MONO
3102         [System.Security.SecuritySafeCritical]  // auto-generated
3103         public override Type[] GetInterfaces()
3104         {
3105               RuntimeType[] candidates = this.Cache.GetInterfaceList(MemberListType.All, null);
3106               Type[] interfaces = new Type[candidates.Length];
3107               for (int i = 0; i < candidates.Length; i++)
3108                   JitHelpers.UnsafeSetArrayElement(interfaces, i, candidates[i]);
3109
3110               return interfaces;
3111         }
3112 #endif
3113         public override Type[] GetNestedTypes(BindingFlags bindingAttr)
3114         {
3115             return GetNestedTypeCandidates(null, bindingAttr, false).ToArray();
3116         }
3117
3118         public override MemberInfo[] GetMembers(BindingFlags bindingAttr)
3119         {
3120             ListBuilder<MethodInfo> methods = GetMethodCandidates(null, bindingAttr, CallingConventions.Any, null, false);
3121             ListBuilder<ConstructorInfo> constructors = GetConstructorCandidates(null, bindingAttr, CallingConventions.Any, null, false);
3122             ListBuilder<PropertyInfo> properties = GetPropertyCandidates(null, bindingAttr, null, false);
3123             ListBuilder<EventInfo> events = GetEventCandidates(null, bindingAttr, false);
3124             ListBuilder<FieldInfo> fields = GetFieldCandidates(null, bindingAttr, false);
3125             ListBuilder<Type> nestedTypes = GetNestedTypeCandidates(null, bindingAttr, false);
3126             // Interfaces are excluded from the result of GetMembers
3127
3128             MemberInfo[] members = new MemberInfo[
3129                 methods.Count +
3130                 constructors.Count +
3131                 properties.Count +
3132                 events.Count +
3133                 fields.Count +
3134                 nestedTypes.Count];
3135
3136             int i = 0;
3137             methods.CopyTo(members, i); i += methods.Count;
3138             constructors.CopyTo(members, i); i += constructors.Count;
3139             properties.CopyTo(members, i); i += properties.Count;
3140             events.CopyTo(members, i); i += events.Count;
3141             fields.CopyTo(members, i); i += fields.Count;
3142             nestedTypes.CopyTo(members, i); i += nestedTypes.Count;
3143             Contract.Assert(i == members.Length);
3144
3145             return members;
3146         }
3147 #if !MONO
3148         [System.Security.SecuritySafeCritical]  // auto-generated
3149         public override InterfaceMapping GetInterfaceMap(Type ifaceType)
3150         {
3151             if (IsGenericParameter)
3152                 throw new InvalidOperationException(Environment.GetResourceString("Arg_GenericParameter"));
3153         
3154             if ((object)ifaceType == null)
3155                 throw new ArgumentNullException("ifaceType");
3156             Contract.EndContractBlock();
3157
3158             RuntimeType ifaceRtType = ifaceType as RuntimeType;
3159
3160             if (ifaceRtType == null)
3161                 throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "ifaceType");
3162
3163             RuntimeTypeHandle ifaceRtTypeHandle = ifaceRtType.GetTypeHandleInternal();
3164
3165             GetTypeHandleInternal().VerifyInterfaceIsImplemented(ifaceRtTypeHandle);
3166             Contract.Assert(ifaceType.IsInterface);  // VerifyInterfaceIsImplemented enforces this invariant
3167             Contract.Assert(!IsInterface); // VerifyInterfaceIsImplemented enforces this invariant
3168
3169             // SZArrays implement the methods on IList`1, IEnumerable`1, and ICollection`1 with
3170             // SZArrayHelper and some runtime magic. We don't have accurate interface maps for them.
3171             if (IsSzArray && ifaceType.IsGenericType)
3172                 throw new ArgumentException(Environment.GetResourceString("Argument_ArrayGetInterfaceMap"));
3173
3174             int ifaceInstanceMethodCount = RuntimeTypeHandle.GetNumVirtuals(ifaceRtType);
3175
3176             InterfaceMapping im;
3177             im.InterfaceType = ifaceType;
3178             im.TargetType = this;
3179             im.InterfaceMethods = new MethodInfo[ifaceInstanceMethodCount];
3180             im.TargetMethods = new MethodInfo[ifaceInstanceMethodCount];
3181
3182             for (int i = 0; i < ifaceInstanceMethodCount; i++)
3183             {
3184                 RuntimeMethodHandleInternal ifaceRtMethodHandle = RuntimeTypeHandle.GetMethodAt(ifaceRtType, i);
3185
3186                 // GetMethodBase will convert this to the instantiating/unboxing stub if necessary
3187                 MethodBase ifaceMethodBase = RuntimeType.GetMethodBase(ifaceRtType, ifaceRtMethodHandle);
3188                 Contract.Assert(ifaceMethodBase is RuntimeMethodInfo);
3189                 im.InterfaceMethods[i] = (MethodInfo)ifaceMethodBase;
3190
3191                 // If the slot is -1, then virtual stub dispatch is active.
3192                 int slot = GetTypeHandleInternal().GetInterfaceMethodImplementationSlot(ifaceRtTypeHandle, ifaceRtMethodHandle);
3193
3194                 if (slot == -1) continue;
3195
3196                 RuntimeMethodHandleInternal classRtMethodHandle = RuntimeTypeHandle.GetMethodAt(this, slot);
3197
3198                 // GetMethodBase will convert this to the instantiating/unboxing stub if necessary
3199                 MethodBase rtTypeMethodBase = RuntimeType.GetMethodBase(this, classRtMethodHandle);
3200                 // a class may not implement all the methods of an interface (abstract class) so null is a valid value 
3201                 Contract.Assert(rtTypeMethodBase == null || rtTypeMethodBase is RuntimeMethodInfo);
3202                 im.TargetMethods[i] = (MethodInfo)rtTypeMethodBase;
3203             }
3204
3205             return im;
3206         }
3207 #endif
3208         #endregion
3209
3210         #region Find XXXInfo
3211         protected override MethodInfo GetMethodImpl(
3212             String name, BindingFlags bindingAttr, Binder binder, CallingConventions callConv, 
3213             Type[] types, ParameterModifier[] modifiers) 
3214         {       
3215             ListBuilder<MethodInfo> candidates = GetMethodCandidates(name, bindingAttr, callConv, types, false);
3216             if (candidates.Count == 0) 
3217                 return null;
3218
3219             if (types == null || types.Length == 0) 
3220             {
3221                 MethodInfo firstCandidate = candidates[0];
3222
3223                 if (candidates.Count == 1)
3224                 {
3225                     return firstCandidate;
3226                 }
3227                 else if (types == null) 
3228                 { 
3229                     for (int j = 1; j < candidates.Count; j++)
3230                     {
3231                         MethodInfo methodInfo = candidates[j];
3232                         if (!System.DefaultBinder.CompareMethodSigAndName(methodInfo, firstCandidate))
3233                         {
3234                             throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
3235                         }
3236                     }
3237
3238                     // All the methods have the exact same name and sig so return the most derived one.
3239                     return System.DefaultBinder.FindMostDerivedNewSlotMeth(candidates.ToArray(), candidates.Count) as MethodInfo;
3240                 }
3241             }   
3242
3243             if (binder == null) 
3244                 binder = DefaultBinder;
3245
3246             return binder.SelectMethod(bindingAttr, candidates.ToArray(), types, modifiers) as MethodInfo;                  
3247         }
3248
3249
3250         protected override ConstructorInfo GetConstructorImpl(
3251             BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, 
3252             Type[] types, ParameterModifier[] modifiers) 
3253         {
3254             ListBuilder<ConstructorInfo> candidates = GetConstructorCandidates(null, bindingAttr, CallingConventions.Any, types, false);
3255
3256             if (candidates.Count == 0)
3257                 return null;
3258             
3259             if (types.Length == 0 && candidates.Count == 1) 
3260             {
3261                 ConstructorInfo firstCandidate = candidates[0];
3262
3263                 ParameterInfo[] parameters = firstCandidate.GetParametersNoCopy();
3264                 if (parameters == null || parameters.Length == 0) 
3265                 {
3266                     return firstCandidate;
3267                 }
3268             }
3269
3270             if ((bindingAttr & BindingFlags.ExactBinding) != 0)
3271                 return System.DefaultBinder.ExactBinding(candidates.ToArray(), types, modifiers) as ConstructorInfo;
3272
3273             if (binder == null)
3274                 binder = DefaultBinder;
3275
3276             return binder.SelectMethod(bindingAttr, candidates.ToArray(), types, modifiers) as ConstructorInfo;
3277         }
3278
3279
3280         protected override PropertyInfo GetPropertyImpl(
3281             String name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) 
3282         {
3283             if (name == null) throw new ArgumentNullException();
3284             Contract.EndContractBlock();
3285
3286             ListBuilder<PropertyInfo> candidates = GetPropertyCandidates(name, bindingAttr, types, false);
3287
3288             if (candidates.Count == 0)
3289                 return null;
3290             
3291             if (types == null || types.Length == 0) 
3292             {
3293                 // no arguments
3294                 if (candidates.Count == 1) 
3295                 {
3296                     PropertyInfo firstCandidate = candidates[0];
3297
3298                     if ((object)returnType != null && !returnType.IsEquivalentTo(firstCandidate.PropertyType))
3299                         return null;
3300
3301                     return firstCandidate;
3302                 }
3303                 else 
3304                 {
3305                     if ((object)returnType == null)
3306                         // if we are here we have no args or property type to select over and we have more than one property with that name
3307                         throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
3308                 }
3309             }
3310             
3311             if ((bindingAttr & BindingFlags.ExactBinding) != 0)
3312                 return System.DefaultBinder.ExactPropertyBinding(candidates.ToArray(), returnType, types, modifiers);
3313
3314             if (binder == null)
3315                 binder = DefaultBinder;
3316             
3317             return binder.SelectProperty(bindingAttr, candidates.ToArray(), returnType, types, modifiers);
3318         }
3319
3320         public override EventInfo GetEvent(String name, BindingFlags bindingAttr) 
3321         {
3322             if (name == null) throw new ArgumentNullException();
3323             Contract.EndContractBlock();
3324
3325             bool ignoreCase;
3326             MemberListType listType;
3327             RuntimeType.FilterHelper(bindingAttr, ref name, out ignoreCase, out listType);
3328
3329 #if MONO
3330             RuntimeEventInfo[] cache = GetEvents_internal (name, bindingAttr, this);
3331 #else
3332             RuntimeEventInfo[] cache = Cache.GetEventList(listType, name);
3333 #endif
3334             EventInfo match = null;
3335
3336             bindingAttr ^= BindingFlags.DeclaredOnly;
3337
3338             for (int i = 0; i < cache.Length; i++)
3339             {
3340                 RuntimeEventInfo eventInfo = cache[i];
3341                 if ((bindingAttr & eventInfo.BindingFlags) == eventInfo.BindingFlags)
3342                 {
3343                     if (match != null)
3344                         throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
3345
3346                     match = eventInfo;
3347                 }
3348             }
3349
3350             return match;
3351         }
3352
3353         public override FieldInfo GetField(String name, BindingFlags bindingAttr) 
3354         {
3355             if (name == null) throw new ArgumentNullException();
3356             Contract.EndContractBlock();
3357
3358             bool ignoreCase;
3359             MemberListType listType;
3360             RuntimeType.FilterHelper(bindingAttr, ref name, out ignoreCase, out listType);
3361
3362 #if MONO
3363             RuntimeFieldInfo[] cache = GetFields_internal (name, bindingAttr, this); 
3364 #else
3365             RuntimeFieldInfo[] cache = Cache.GetFieldList(listType, name);
3366 #endif
3367             FieldInfo match = null;
3368
3369             bindingAttr ^= BindingFlags.DeclaredOnly;
3370             bool multipleStaticFieldMatches = false;
3371
3372             for (int i = 0; i < cache.Length; i++)
3373             {
3374                 RuntimeFieldInfo fieldInfo = cache[i];
3375                 if ((bindingAttr & fieldInfo.BindingFlags) == fieldInfo.BindingFlags)
3376                 {
3377                     if (match != null)
3378                     {
3379                         if (Object.ReferenceEquals(fieldInfo.DeclaringType, match.DeclaringType))
3380                             throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
3381
3382                         if ((match.DeclaringType.IsInterface == true) && (fieldInfo.DeclaringType.IsInterface == true))
3383                             multipleStaticFieldMatches = true;
3384                     }
3385                 
3386                     if (match == null || fieldInfo.DeclaringType.IsSubclassOf(match.DeclaringType) || match.DeclaringType.IsInterface)
3387                         match = fieldInfo;
3388                 }
3389             }
3390
3391             if (multipleStaticFieldMatches && match.DeclaringType.IsInterface)
3392                 throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
3393
3394             return match;
3395         }
3396
3397         public override Type GetInterface(String fullname, bool ignoreCase) 
3398         {
3399             if (fullname == null) throw new ArgumentNullException();
3400             Contract.EndContractBlock();
3401
3402             BindingFlags bindingAttr = BindingFlags.Public | BindingFlags.NonPublic;
3403             
3404             bindingAttr &= ~BindingFlags.Static;
3405
3406             if (ignoreCase)
3407                 bindingAttr |= BindingFlags.IgnoreCase;
3408
3409             string name, ns;
3410             MemberListType listType;
3411             SplitName(fullname, out name, out ns);            
3412             RuntimeType.FilterHelper(bindingAttr, ref name, out ignoreCase, out listType);
3413
3414 #if MONO
3415             List<RuntimeType> list = null;
3416             foreach (RuntimeType t in GetInterfaces ()) {
3417                 if (t.Name != name)
3418                     continue;
3419
3420                 if (list == null)
3421                     list = new List<RuntimeType> (2);
3422
3423                 list.Add (t);
3424             }
3425
3426             if (list == null)
3427                 return null;
3428
3429             var cache = list.ToArray ();
3430 #else
3431             RuntimeType[] cache = Cache.GetInterfaceList(listType, name);
3432 #endif
3433             RuntimeType match = null;
3434
3435             for (int i = 0; i < cache.Length; i++)
3436             {
3437                 RuntimeType iface = cache[i];
3438                 if (RuntimeType.FilterApplyType(iface, bindingAttr, name, false, ns))
3439                 {
3440                     if (match != null)
3441                         throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
3442
3443                     match = iface;
3444                 }
3445             }
3446
3447             return match;
3448         }
3449
3450         public override Type GetNestedType(String fullname, BindingFlags bindingAttr) 
3451         {
3452             if (fullname == null) throw new ArgumentNullException();
3453             Contract.EndContractBlock();
3454
3455             bool ignoreCase;
3456             bindingAttr &= ~BindingFlags.Static;
3457             string name, ns;
3458             MemberListType listType;
3459             SplitName(fullname, out name, out ns);            
3460             RuntimeType.FilterHelper(bindingAttr, ref name, out ignoreCase, out listType);
3461 #if MONO
3462             RuntimeType[] cache = GetNestedTypes_internal (name, bindingAttr);
3463 #else
3464             RuntimeType[] cache = Cache.GetNestedTypeList(listType, name);
3465 #endif
3466             RuntimeType match = null;
3467
3468             for (int i = 0; i < cache.Length; i++)
3469             {
3470                 RuntimeType nestedType = cache[i];
3471                 if (RuntimeType.FilterApplyType(nestedType, bindingAttr, name, false, ns))
3472                 {
3473                     if (match != null)
3474                         throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
3475
3476                     match = nestedType;
3477                 }
3478             }
3479
3480             return match;
3481         }
3482
3483         public override MemberInfo[] GetMember(String name, MemberTypes type, BindingFlags bindingAttr) 
3484         {
3485             if (name == null) throw new ArgumentNullException();
3486             Contract.EndContractBlock();
3487
3488             ListBuilder<MethodInfo> methods = new ListBuilder<MethodInfo>();
3489             ListBuilder<ConstructorInfo> constructors = new ListBuilder<ConstructorInfo>();
3490             ListBuilder<PropertyInfo> properties = new ListBuilder<PropertyInfo>();
3491             ListBuilder<EventInfo> events = new ListBuilder<EventInfo>();
3492             ListBuilder<FieldInfo> fields = new ListBuilder<FieldInfo>(); 
3493             ListBuilder<Type> nestedTypes = new ListBuilder<Type>();
3494
3495             int totalCount = 0;
3496
3497             // Methods
3498             if ((type & MemberTypes.Method) != 0)
3499             {
3500                 methods = GetMethodCandidates(name, bindingAttr, CallingConventions.Any, null, true);
3501                 if (type == MemberTypes.Method)
3502                     return methods.ToArray();
3503                 totalCount += methods.Count;
3504             }
3505
3506             // Constructors
3507             if ((type & MemberTypes.Constructor) != 0)
3508             {
3509                 constructors = GetConstructorCandidates(name, bindingAttr, CallingConventions.Any, null, true);
3510                 if (type == MemberTypes.Constructor)
3511                     return constructors.ToArray();
3512                 totalCount += constructors.Count;
3513             }
3514
3515             // Properties
3516             if ((type & MemberTypes.Property) != 0)
3517             {
3518                 properties = GetPropertyCandidates(name, bindingAttr, null, true);
3519                 if (type == MemberTypes.Property)
3520                     return properties.ToArray();
3521                 totalCount += properties.Count;
3522             }
3523
3524             // Events
3525             if ((type & MemberTypes.Event) != 0)
3526             {
3527                 events = GetEventCandidates(name, bindingAttr, true);
3528                 if (type == MemberTypes.Event)
3529                     return events.ToArray();
3530                 totalCount += events.Count;
3531             }
3532
3533             // Fields
3534             if ((type & MemberTypes.Field) != 0)
3535             {
3536                 fields = GetFieldCandidates(name, bindingAttr, true);
3537                 if (type == MemberTypes.Field)
3538                     return fields.ToArray();
3539                 totalCount += fields.Count;
3540             }
3541
3542             // NestedTypes
3543             if ((type & (MemberTypes.NestedType | MemberTypes.TypeInfo)) != 0)
3544             {
3545                 nestedTypes = GetNestedTypeCandidates(name, bindingAttr, true);
3546                 if (type == MemberTypes.NestedType || type == MemberTypes.TypeInfo)
3547                     return nestedTypes.ToArray();
3548                 totalCount += nestedTypes.Count;
3549             }
3550
3551             MemberInfo[] compressMembers = (type == (MemberTypes.Method | MemberTypes.Constructor)) ?
3552                 new MethodBase[totalCount] : new MemberInfo[totalCount];
3553
3554             int i = 0;
3555             methods.CopyTo(compressMembers, i); i += methods.Count;
3556             constructors.CopyTo(compressMembers, i); i += constructors.Count;
3557             properties.CopyTo(compressMembers, i); i += properties.Count;
3558             events.CopyTo(compressMembers, i); i += events.Count;
3559             fields.CopyTo(compressMembers, i); i += fields.Count;
3560             nestedTypes.CopyTo(compressMembers, i); i += nestedTypes.Count;
3561             Contract.Assert(i == compressMembers.Length);
3562
3563             return compressMembers;
3564         }
3565         #endregion
3566
3567         #region Identity
3568
3569         public override Module Module
3570         {
3571             get
3572             {
3573                 return GetRuntimeModule();
3574             }
3575         }
3576
3577         internal RuntimeModule GetRuntimeModule()
3578         {
3579             return RuntimeTypeHandle.GetModule(this);
3580         }
3581
3582         public override Assembly Assembly 
3583         {
3584             get 
3585             {
3586                 return GetRuntimeAssembly();
3587             }
3588         }
3589
3590         internal RuntimeAssembly GetRuntimeAssembly()
3591         {
3592             return RuntimeTypeHandle.GetAssembly(this);
3593         }
3594
3595         public override RuntimeTypeHandle TypeHandle 
3596         {
3597             get 
3598             {
3599                 return new RuntimeTypeHandle(this);
3600             }
3601         }
3602
3603         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
3604         internal sealed override RuntimeTypeHandle GetTypeHandleInternal()
3605         {
3606             return new RuntimeTypeHandle(this);
3607         }
3608 #if !MONO
3609         [System.Security.SecuritySafeCritical]
3610         internal bool IsCollectible()
3611         {
3612             return RuntimeTypeHandle.IsCollectible(GetTypeHandleInternal());
3613         }
3614
3615         [System.Security.SecuritySafeCritical]  // auto-generated
3616         protected override TypeCode GetTypeCodeImpl() 
3617         {
3618             TypeCode typeCode = Cache.TypeCode;
3619
3620             if (typeCode != TypeCode.Empty)
3621                 return typeCode;
3622
3623             CorElementType corElementType = RuntimeTypeHandle.GetCorElementType(this);
3624             switch (corElementType) 
3625             {
3626                 case CorElementType.Boolean:
3627                     typeCode = TypeCode.Boolean; break;
3628                 case CorElementType.Char:
3629                     typeCode = TypeCode.Char; break;
3630                 case CorElementType.I1:
3631                     typeCode = TypeCode.SByte; break;
3632                 case CorElementType.U1:
3633                     typeCode = TypeCode.Byte; break;
3634                 case CorElementType.I2:
3635                     typeCode = TypeCode.Int16; break;
3636                 case CorElementType.U2:
3637                     typeCode = TypeCode.UInt16; break;
3638                 case CorElementType.I4:
3639                     typeCode = TypeCode.Int32; break;
3640                 case CorElementType.U4:
3641                     typeCode = TypeCode.UInt32; break;
3642                 case CorElementType.I8:
3643                     typeCode = TypeCode.Int64; break;
3644                 case CorElementType.U8:
3645                     typeCode = TypeCode.UInt64; break;
3646                 case CorElementType.R4:
3647                     typeCode = TypeCode.Single; break;
3648                 case CorElementType.R8:
3649                     typeCode = TypeCode.Double; break;
3650                 case CorElementType.String:
3651                     typeCode = TypeCode.String; break;
3652                 case CorElementType.ValueType:
3653                     if (this == Convert.ConvertTypes[(int)TypeCode.Decimal])
3654                         typeCode = TypeCode.Decimal;
3655                     else if (this == Convert.ConvertTypes[(int)TypeCode.DateTime])
3656                         typeCode = TypeCode.DateTime;
3657                     else if (this.IsEnum)
3658                         typeCode = Type.GetTypeCode(Enum.GetUnderlyingType(this));
3659                     else
3660                         typeCode = TypeCode.Object;                    
3661                     break;
3662                 default:
3663                     if (this == Convert.ConvertTypes[(int)TypeCode.DBNull])
3664                         typeCode = TypeCode.DBNull;
3665                     else if (this == Convert.ConvertTypes[(int)TypeCode.String])
3666                         typeCode = TypeCode.String;
3667                     else
3668                         typeCode = TypeCode.Object;
3669                     break;
3670             }
3671
3672             Cache.TypeCode = typeCode;
3673
3674             return typeCode;
3675         }
3676
3677         public override MethodBase DeclaringMethod
3678         {
3679             get
3680             {
3681                 if (!IsGenericParameter)
3682                     throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
3683                 Contract.EndContractBlock();
3684
3685                 IRuntimeMethodInfo declaringMethod = RuntimeTypeHandle.GetDeclaringMethod(this);
3686
3687                 if (declaringMethod == null)
3688                     return null;
3689
3690                 return GetMethodBase(RuntimeMethodHandle.GetDeclaringType(declaringMethod), declaringMethod);
3691             }
3692         }
3693 #endif
3694         #endregion
3695
3696         #region Hierarchy
3697         [System.Security.SecuritySafeCritical]  // auto-generated
3698         public override bool IsInstanceOfType(Object o)
3699         {
3700             return RuntimeTypeHandle.IsInstanceOfType(this, o);
3701         }
3702
3703         [System.Runtime.InteropServices.ComVisible(true)]
3704         [Pure]
3705         public override bool IsSubclassOf(Type type) 
3706         {
3707             if ((object)type == null)
3708                 throw new ArgumentNullException("type");
3709             Contract.EndContractBlock();
3710             RuntimeType rtType = type as RuntimeType;
3711             if (rtType == null)
3712                 return false;
3713
3714             RuntimeType baseType = GetBaseType();
3715
3716             while (baseType != null)
3717             {
3718                 if (baseType == rtType)
3719                     return true;
3720
3721                 baseType = baseType.GetBaseType();
3722             }
3723
3724             // pretty much everything is a subclass of object, even interfaces
3725             // notice that interfaces are really odd because they do not have a BaseType
3726             // yet IsSubclassOf(typeof(object)) returns true
3727             if (rtType == RuntimeType.ObjectType && rtType != this) 
3728                 return true;
3729
3730             return false;
3731         }
3732
3733         public override bool IsAssignableFrom(System.Reflection.TypeInfo typeInfo){
3734             if(typeInfo==null) return false;
3735             return IsAssignableFrom(typeInfo.AsType());
3736         }
3737
3738         public override bool IsAssignableFrom(Type c)
3739         {
3740             if ((object)c == null)
3741                 return false;
3742
3743             if (Object.ReferenceEquals(c, this))
3744                 return true;
3745
3746             RuntimeType fromType = c.UnderlyingSystemType as RuntimeType;
3747
3748             // For runtime type, let the VM decide.
3749             if (fromType != null)
3750             {
3751                 // both this and c (or their underlying system types) are runtime types
3752                 return RuntimeTypeHandle.CanCastTo(fromType, this);
3753             }
3754 #if !FULL_AOT_RUNTIME
3755             // Special case for TypeBuilder to be backward-compatible.
3756             if (c is System.Reflection.Emit.TypeBuilder)
3757             {
3758                 // If c is a subclass of this class, then c can be cast to this type.
3759                 if (c.IsSubclassOf(this))
3760                     return true;
3761
3762                 if (this.IsInterface)
3763                 {
3764                     return c.ImplementInterface(this);
3765                 }
3766                 else if (this.IsGenericParameter)
3767                 {
3768                     Type[] constraints = GetGenericParameterConstraints();
3769                     for (int i = 0; i < constraints.Length; i++)
3770                         if (!constraints[i].IsAssignableFrom(c))
3771                             return false;
3772
3773                     return true;
3774                 }
3775             }
3776 #endif
3777             // For anything else we return false.
3778             return false;
3779         }
3780
3781 #if !FEATURE_CORECLR
3782         // Reflexive, symmetric, transitive.
3783         public override bool IsEquivalentTo(Type other)
3784         {
3785             RuntimeType otherRtType = other as RuntimeType;
3786             if ((object)otherRtType == null)
3787                 return false;
3788
3789             if (otherRtType == this)
3790                 return true;
3791
3792             // It's not worth trying to perform further checks in managed
3793             // as they would lead to FCalls anyway.
3794             return RuntimeTypeHandle.IsEquivalentTo(this, otherRtType);
3795         }
3796 #endif // FEATURE_CORECLR
3797
3798         public override Type BaseType 
3799         {
3800             get 
3801             {
3802                 return GetBaseType();
3803             }
3804         }
3805
3806         private RuntimeType GetBaseType()
3807         {
3808             if (IsInterface)
3809                 return null;
3810
3811             if (RuntimeTypeHandle.IsGenericVariable(this))
3812             {
3813                 Type[] constraints = GetGenericParameterConstraints();
3814
3815                 RuntimeType baseType = RuntimeType.ObjectType;
3816
3817                 for (int i = 0; i < constraints.Length; i++)
3818                 {
3819                     RuntimeType constraint = (RuntimeType)constraints[i];
3820
3821                     if (constraint.IsInterface)
3822                         continue;
3823
3824                     if (constraint.IsGenericParameter)
3825                     {
3826                         GenericParameterAttributes special;
3827                         special = constraint.GenericParameterAttributes & GenericParameterAttributes.SpecialConstraintMask;
3828
3829                         if ((special & GenericParameterAttributes.ReferenceTypeConstraint) == 0 &&
3830                             (special & GenericParameterAttributes.NotNullableValueTypeConstraint) == 0)
3831                             continue;
3832                     }
3833
3834                     baseType = constraint;
3835                 }
3836
3837                 if (baseType == RuntimeType.ObjectType)
3838                 {
3839                     GenericParameterAttributes special;
3840                     special = GenericParameterAttributes & GenericParameterAttributes.SpecialConstraintMask;
3841                     if ((special & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0)
3842                         baseType = RuntimeType.ValueType;
3843                 }
3844
3845                 return baseType;
3846             }
3847
3848             return RuntimeTypeHandle.GetBaseType(this);
3849         }
3850
3851         public override Type UnderlyingSystemType 
3852         {
3853             get 
3854             {
3855                 return this;
3856             }
3857         }
3858         #endregion
3859 #if !MONO
3860         #region Name
3861         public override String FullName 
3862         {
3863             get 
3864             {
3865                 return GetCachedName(TypeNameKind.FullName);
3866             }
3867         }
3868
3869         public override String AssemblyQualifiedName 
3870         {
3871             get 
3872             {
3873                 string fullname = FullName;
3874
3875                 // FullName is null if this type contains generic parameters but is not a generic type definition.
3876                 if (fullname == null)
3877                     return null;
3878                 
3879                 return Assembly.CreateQualifiedName(this.Assembly.FullName, fullname); 
3880             }
3881         }
3882
3883         public override String Namespace 
3884         {
3885             get 
3886             {
3887                 string ns = Cache.GetNameSpace();
3888                 
3889                 if (ns == null || ns.Length == 0)
3890                     return null;
3891
3892                 return ns;
3893             }
3894         }
3895         #endregion
3896 #endif
3897         #region Attributes
3898         [System.Security.SecuritySafeCritical]  // auto-generated
3899         protected override TypeAttributes GetAttributeFlagsImpl() 
3900         {
3901             return RuntimeTypeHandle.GetAttributes(this);
3902         }
3903 #if !MONO
3904         public override Guid GUID 
3905         {
3906             [System.Security.SecuritySafeCritical]  // auto-generated
3907             get 
3908             {
3909                 Guid result = new Guid ();
3910                 GetGUID(ref result);
3911                 return result;
3912             }
3913         }
3914         
3915         [System.Security.SecurityCritical]  // auto-generated
3916         [ResourceExposure(ResourceScope.None)]
3917         [MethodImplAttribute(MethodImplOptions.InternalCall)]
3918         private extern void GetGUID(ref Guid result);
3919 #endif
3920         [System.Security.SecuritySafeCritical]  // auto-generated
3921         protected override bool IsContextfulImpl() 
3922         {
3923             return RuntimeTypeHandle.IsContextful(this);
3924         }
3925
3926         /*
3927         protected override bool IsMarshalByRefImpl() 
3928         {
3929             return GetTypeHandleInternal().IsMarshalByRef();
3930         }
3931         */
3932
3933         protected override bool IsByRefImpl() 
3934         {
3935             return RuntimeTypeHandle.IsByRef(this);
3936         }
3937
3938         protected override bool IsPrimitiveImpl() 
3939         {
3940             return RuntimeTypeHandle.IsPrimitive(this);
3941         }
3942
3943         protected override bool IsPointerImpl() 
3944         {
3945             return RuntimeTypeHandle.IsPointer(this);
3946         }
3947
3948         [System.Security.SecuritySafeCritical]  // auto-generated
3949         protected override bool IsCOMObjectImpl() 
3950         {
3951             return RuntimeTypeHandle.IsComObject(this, false);
3952         }
3953
3954 #if FEATURE_COMINTEROP
3955         [SecuritySafeCritical]
3956         internal override bool IsWindowsRuntimeObjectImpl()
3957         {
3958             return IsWindowsRuntimeObjectType(this);
3959         }
3960
3961         [SecuritySafeCritical]
3962         internal override bool IsExportedToWindowsRuntimeImpl()
3963         {
3964             return IsTypeExportedToWindowsRuntime(this);
3965         }
3966
3967         [MethodImplAttribute(MethodImplOptions.InternalCall)]
3968         [SecurityCritical]
3969         private static extern bool IsWindowsRuntimeObjectType(RuntimeType type);
3970
3971         [MethodImplAttribute(MethodImplOptions.InternalCall)]
3972         [SecurityCritical]
3973         private static extern bool IsTypeExportedToWindowsRuntime(RuntimeType type);
3974
3975 #endif // FEATURE_COMINTEROP
3976
3977         [System.Security.SecuritySafeCritical]  // auto-generated
3978         internal override bool HasProxyAttributeImpl() 
3979         {
3980             return RuntimeTypeHandle.HasProxyAttribute(this);
3981         }
3982
3983         internal bool IsDelegate()
3984         {
3985             return GetBaseType() == typeof(System.MulticastDelegate);
3986         }
3987
3988         protected override bool IsValueTypeImpl()
3989         {
3990             // We need to return true for generic parameters with the ValueType constraint.
3991             // So we cannot use the faster RuntimeTypeHandle.IsValueType because it returns 
3992             // false for all generic parameters.
3993             if (this == typeof(ValueType) || this == typeof(Enum)) 
3994                 return false;
3995
3996             return IsSubclassOf(typeof(ValueType));
3997         }
3998
3999 #if !FEATURE_CORECLR
4000         public override bool IsEnum
4001         {
4002             get
4003             {
4004                 return GetBaseType() == RuntimeType.EnumType; 
4005             }
4006         }
4007 #endif
4008
4009         protected override bool HasElementTypeImpl() 
4010         {
4011             return RuntimeTypeHandle.HasElementType(this);
4012         }
4013
4014         public override GenericParameterAttributes GenericParameterAttributes
4015         {
4016             [System.Security.SecuritySafeCritical]  // auto-generated
4017             get
4018             {
4019                 if (!IsGenericParameter)
4020                     throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
4021                 Contract.EndContractBlock();
4022
4023 #if MONO
4024                 return GetGenericParameterAttributes ();
4025 #else
4026                 GenericParameterAttributes attributes;
4027
4028                 RuntimeTypeHandle.GetMetadataImport(this).GetGenericParamProps(MetadataToken, out attributes);
4029
4030                 return attributes;
4031 #endif
4032             }
4033         }
4034 #if !MONO
4035         public override bool IsSecurityCritical 
4036         {
4037             get { return new RuntimeTypeHandle(this).IsSecurityCritical(); } 
4038         }
4039         public override bool IsSecuritySafeCritical
4040         {
4041             get { return new RuntimeTypeHandle(this).IsSecuritySafeCritical(); }
4042         }
4043         public override bool IsSecurityTransparent
4044         {
4045             get { return new RuntimeTypeHandle(this).IsSecurityTransparent(); }
4046         }
4047 #endif
4048         #endregion
4049
4050         #region Arrays
4051         internal override bool IsSzArray
4052         {
4053             get 
4054             {
4055                 return RuntimeTypeHandle.IsSzArray(this);
4056             }
4057         }
4058
4059         protected override bool IsArrayImpl() 
4060         {
4061             return RuntimeTypeHandle.IsArray(this);
4062         }
4063
4064         [System.Security.SecuritySafeCritical]  // auto-generated
4065         public override int GetArrayRank() 
4066         {
4067             if (!IsArrayImpl())
4068                 throw new ArgumentException(Environment.GetResourceString("Argument_HasToBeArrayClass"));
4069
4070             return RuntimeTypeHandle.GetArrayRank(this);
4071         }
4072
4073         public override Type GetElementType() 
4074         {
4075             return RuntimeTypeHandle.GetElementType(this);
4076         }
4077         #endregion
4078
4079         #region Enums
4080         public override string[] GetEnumNames()
4081         {
4082             if (!IsEnum)
4083                 throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
4084             Contract.EndContractBlock();
4085
4086             String[] ret = Enum.InternalGetNames(this);
4087
4088             // Make a copy since we can't hand out the same array since users can modify them
4089             String[] retVal = new String[ret.Length];
4090
4091             Array.Copy(ret, retVal, ret.Length);
4092
4093             return retVal;
4094         }
4095
4096         [SecuritySafeCritical]
4097         public override Array GetEnumValues()
4098         {
4099             if (!IsEnum)
4100                 throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
4101             Contract.EndContractBlock();
4102
4103             // Get all of the values
4104             ulong[] values = Enum.InternalGetValues(this);
4105
4106             // Create a generic Array
4107             Array ret = Array.UnsafeCreateInstance(this, values.Length);
4108
4109             for (int i = 0; i < values.Length; i++)
4110             {
4111                 Object val = Enum.ToObject(this, values[i]);
4112                 ret.SetValue(val, i);
4113             }
4114
4115             return ret;
4116         }
4117
4118         public override Type GetEnumUnderlyingType()
4119         {
4120             if (!IsEnum)
4121                 throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
4122             Contract.EndContractBlock();
4123
4124             return Enum.InternalGetUnderlyingType(this);
4125         }
4126
4127         public override bool IsEnumDefined(object value)
4128         {
4129             if (value == null)
4130                 throw new ArgumentNullException("value");
4131             Contract.EndContractBlock();
4132
4133             // Check if both of them are of the same type
4134             RuntimeType valueType = (RuntimeType)value.GetType();
4135
4136             // If the value is an Enum then we need to extract the underlying value from it
4137             if (valueType.IsEnum)
4138             {
4139                 if (!valueType.IsEquivalentTo(this))
4140                     throw new ArgumentException(Environment.GetResourceString("Arg_EnumAndObjectMustBeSameType", valueType.ToString(), this.ToString()));
4141
4142                 valueType = (RuntimeType)valueType.GetEnumUnderlyingType();
4143             }
4144
4145             // If a string is passed in
4146             if (valueType == RuntimeType.StringType)
4147             {
4148                 // Get all of the Fields, calling GetHashEntry directly to avoid copying
4149                 string[] names = Enum.InternalGetNames(this);
4150                 if (Array.IndexOf(names, value) >= 0)
4151                     return true;
4152                 else
4153                     return false;
4154             }
4155
4156             // If an enum or integer value is passed in
4157             if (Type.IsIntegerType(valueType))
4158             {
4159                 RuntimeType underlyingType = Enum.InternalGetUnderlyingType(this);
4160                 if (underlyingType != valueType)
4161                     throw new ArgumentException(Environment.GetResourceString("Arg_EnumUnderlyingTypeAndObjectMustBeSameType", valueType.ToString(), underlyingType.ToString()));
4162
4163                 ulong[] ulValues = Enum.InternalGetValues(this);
4164                 ulong ulValue = Enum.ToUInt64(value);
4165
4166                 return (Array.BinarySearch(ulValues, ulValue) >= 0);
4167             }
4168             else if (CompatibilitySwitches.IsAppEarlierThanWindowsPhone8)
4169             {
4170                 // if at this point the value type is not an integer type, then its type doesn't match the enum type
4171                 // NetCF used to throw an argument exception in this case
4172                 throw new ArgumentException(Environment.GetResourceString("Arg_EnumUnderlyingTypeAndObjectMustBeSameType", valueType.ToString(), GetEnumUnderlyingType()));
4173             }
4174             else
4175             {
4176                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_UnknownEnumType"));
4177             }
4178         }
4179
4180         public override string GetEnumName(object value)
4181         {
4182             if (value == null)
4183                 throw new ArgumentNullException("value");
4184             Contract.EndContractBlock();
4185
4186             Type valueType = value.GetType();
4187
4188             if (!(valueType.IsEnum || IsIntegerType(valueType)))
4189                 throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnumBaseTypeOrEnum"), "value");
4190
4191             ulong[] ulValues = Enum.InternalGetValues(this);
4192             ulong ulValue = Enum.ToUInt64(value);
4193             int index = Array.BinarySearch(ulValues, ulValue);
4194
4195             if (index >= 0)
4196             {
4197                 string[] names = Enum.InternalGetNames(this);
4198                 return names[index];
4199             }
4200
4201             return null;
4202         }
4203         #endregion
4204
4205         #region Generics
4206
4207         internal RuntimeType[] GetGenericArgumentsInternal()
4208         {
4209 #if MONO
4210             return (RuntimeType[]) GetGenericArgumentsInternal (true);
4211 #else
4212             return GetRootElementType().GetTypeHandleInternal().GetInstantiationInternal();
4213 #endif
4214         }
4215
4216         public override Type[] GetGenericArguments() 
4217         {
4218 #if MONO
4219             Type[] types = GetGenericArgumentsInternal (false);
4220 #else
4221             Type[] types = GetRootElementType().GetTypeHandleInternal().GetInstantiationPublic();
4222 #endif
4223
4224             if (types == null)
4225                 types = EmptyArray<Type>.Value;
4226
4227             return types;
4228         }
4229
4230         [System.Security.SecuritySafeCritical]  // auto-generated
4231         public override Type MakeGenericType(Type[] instantiation)
4232         {
4233             if (instantiation == null)
4234                 throw new ArgumentNullException("instantiation");
4235             Contract.EndContractBlock();
4236
4237             RuntimeType[] instantiationRuntimeType = new RuntimeType[instantiation.Length];
4238
4239             if (!IsGenericTypeDefinition)
4240                 throw new InvalidOperationException(
4241                     Environment.GetResourceString("Arg_NotGenericTypeDefinition", this));
4242
4243             if (GetGenericArguments().Length != instantiation.Length)
4244                 throw new ArgumentException(Environment.GetResourceString("Argument_GenericArgsCount"), "instantiation");
4245
4246             for (int i = 0; i < instantiation.Length; i ++)
4247             {
4248                 Type instantiationElem = instantiation[i];
4249                 if (instantiationElem == null)
4250                     throw new ArgumentNullException();
4251
4252                 RuntimeType rtInstantiationElem = instantiationElem as RuntimeType;
4253
4254                 if (rtInstantiationElem == null)
4255                 {
4256                     Type[] instantiationCopy = new Type[instantiation.Length];
4257                     for (int iCopy = 0; iCopy < instantiation.Length; iCopy++)
4258                         instantiationCopy[iCopy] = instantiation[iCopy];
4259                     instantiation = instantiationCopy;
4260                     return System.Reflection.Emit.TypeBuilderInstantiation.MakeGenericType(this, instantiation);
4261                 }
4262
4263                 instantiationRuntimeType[i] = rtInstantiationElem;
4264             }
4265
4266             RuntimeType[] genericParameters = GetGenericArgumentsInternal();
4267
4268             SanityCheckGenericArguments(instantiationRuntimeType, genericParameters);
4269
4270             Type ret = null;
4271 #if MONO
4272             ret = MakeGenericType (this, instantiationRuntimeType);
4273             if (ret == null)
4274                 throw new TypeLoadException ();
4275 #else
4276             try 
4277             {
4278                 ret = new RuntimeTypeHandle(this).Instantiate(instantiationRuntimeType);
4279             }
4280             catch (TypeLoadException e)
4281             {
4282                 ValidateGenericArguments(this, instantiationRuntimeType, e);
4283                 throw e;
4284             }
4285 #endif
4286             return ret;
4287         }
4288
4289         public override bool IsGenericTypeDefinition
4290         {
4291             get { return RuntimeTypeHandle.IsGenericTypeDefinition(this); }
4292         }
4293
4294         public override bool IsGenericParameter
4295         {
4296             get { return RuntimeTypeHandle.IsGenericVariable(this); }
4297         }
4298
4299         public override int GenericParameterPosition
4300         {
4301             get 
4302             {
4303                 if (!IsGenericParameter)
4304                     throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
4305                 Contract.EndContractBlock();
4306 #if MONO
4307                 return GetGenericParameterPosition ();
4308 #else
4309                 return new RuntimeTypeHandle(this).GetGenericVariableIndex(); 
4310 #endif
4311             }
4312         }
4313
4314         public override Type GetGenericTypeDefinition() 
4315         {
4316             if (!IsGenericType)
4317                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotGenericType"));
4318             Contract.EndContractBlock();
4319
4320             return RuntimeTypeHandle.GetGenericTypeDefinition(this);
4321         }
4322
4323         public override bool IsGenericType
4324         {
4325             get { return RuntimeTypeHandle.HasInstantiation(this); }
4326         }
4327
4328         public override bool IsConstructedGenericType
4329         {
4330             get { return IsGenericType && !IsGenericTypeDefinition; }
4331         }
4332 #if !MONO
4333         public override bool ContainsGenericParameters
4334         {
4335             get { return GetRootElementType().GetTypeHandleInternal().ContainsGenericVariables(); } 
4336         }
4337
4338         public override Type[] GetGenericParameterConstraints()
4339         {
4340             if (!IsGenericParameter)
4341                 throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
4342             Contract.EndContractBlock();
4343
4344             Type[] constraints = new RuntimeTypeHandle(this).GetConstraints();
4345
4346             if (constraints == null)
4347                 constraints = EmptyArray<Type>.Value;
4348
4349             return constraints;
4350         }
4351 #endif
4352         #endregion
4353 #if !MONO
4354         #region Misc
4355         [System.Security.SecuritySafeCritical]  // auto-generated
4356         public override Type MakePointerType() { return new RuntimeTypeHandle(this).MakePointer(); }
4357         public override Type MakeByRefType() { return new RuntimeTypeHandle(this).MakeByRef(); }
4358         public override Type MakeArrayType() { return new RuntimeTypeHandle(this).MakeSZArray(); }
4359         public override Type MakeArrayType(int rank) 
4360         {
4361             if (rank <= 0)
4362                 throw new IndexOutOfRangeException();
4363             Contract.EndContractBlock();
4364
4365             return new RuntimeTypeHandle(this).MakeArray(rank); 
4366         }
4367         public override StructLayoutAttribute StructLayoutAttribute
4368         {
4369             [System.Security.SecuritySafeCritical] // overrides transparent public member             
4370             get 
4371             { 
4372                 return (StructLayoutAttribute)StructLayoutAttribute.GetCustomAttribute(this); 
4373             } 
4374         }
4375         #endregion
4376 #endif
4377         #region Invoke Member
4378         private const BindingFlags MemberBindingMask        = (BindingFlags)0x000000FF;
4379         private const BindingFlags InvocationMask           = (BindingFlags)0x0000FF00;
4380         private const BindingFlags BinderNonCreateInstance  = BindingFlags.InvokeMethod | BinderGetSetField | BinderGetSetProperty;
4381         private const BindingFlags BinderGetSetProperty     = BindingFlags.GetProperty | BindingFlags.SetProperty;
4382         private const BindingFlags BinderSetInvokeProperty  = BindingFlags.InvokeMethod | BindingFlags.SetProperty;
4383         private const BindingFlags BinderGetSetField        = BindingFlags.GetField | BindingFlags.SetField;
4384         private const BindingFlags BinderSetInvokeField     = BindingFlags.SetField | BindingFlags.InvokeMethod;
4385         private const BindingFlags BinderNonFieldGetSet     = (BindingFlags)0x00FFF300;
4386         private const BindingFlags ClassicBindingMask       = 
4387             BindingFlags.InvokeMethod | BindingFlags.GetProperty | BindingFlags.SetProperty | 
4388             BindingFlags.PutDispProperty | BindingFlags.PutRefDispProperty;
4389         private static RuntimeType s_typedRef = (RuntimeType)typeof(TypedReference);
4390 #if !MONO
4391         [System.Security.SecurityCritical]  // auto-generated
4392         [ResourceExposure(ResourceScope.None)]
4393         [MethodImplAttribute(MethodImplOptions.InternalCall)]
4394         static private extern bool CanValueSpecialCast(RuntimeType valueType, RuntimeType targetType);
4395         
4396         [System.Security.SecurityCritical]  // auto-generated
4397         [ResourceExposure(ResourceScope.None)]
4398         [MethodImplAttribute(MethodImplOptions.InternalCall)]
4399         static private extern Object AllocateValueType(RuntimeType type, object value, bool fForceTypeChange); 
4400
4401         [System.Security.SecuritySafeCritical]  // auto-generated
4402         internal unsafe Object CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr) 
4403         {
4404             // this method is used by invocation in reflection to check whether a value can be assigned to type.
4405             if (IsInstanceOfType(value))
4406             {
4407                 // Since this cannot be a generic parameter, we use RuntimeTypeHandle.IsValueType here
4408                 // because it is faster than RuntimeType.IsValueType
4409                 Contract.Assert(!IsGenericParameter);
4410
4411                 Type type = null;
4412
4413 #if FEATURE_REMOTING
4414                 // For the remoting objects Object.GetType goes through proxy. Avoid the proxy call and just get
4415                 // the type directly. It is necessary to support proxies that do not handle GetType.
4416                 RealProxy realProxy = System.Runtime.Remoting.RemotingServices.GetRealProxy(value);
4417
4418                 if (realProxy != null)
4419                 {
4420                     type = realProxy.GetProxiedType();
4421                 }
4422                 else
4423                 {
4424                     type = value.GetType();
4425                 }
4426 #else
4427                 type = value.GetType();
4428 #endif
4429
4430                 if (!Object.ReferenceEquals(type, this) && RuntimeTypeHandle.IsValueType(this))
4431                 {
4432                     // must be an equivalent type, re-box to the target type
4433                     return AllocateValueType(this, value, true);
4434                 }
4435                 else
4436                 {
4437                     return value;
4438                 }
4439             }
4440
4441             // if this is a ByRef get the element type and check if it's compatible
4442             bool isByRef = IsByRef;
4443             if (isByRef) 
4444             {
4445                 RuntimeType elementType = RuntimeTypeHandle.GetElementType(this);
4446                 if (elementType.IsInstanceOfType(value) || value == null) 
4447                 {
4448                     // need to create an instance of the ByRef if null was provided, but only if primitive, enum or value type
4449                     return AllocateValueType(elementType, value, false);
4450                 }
4451             }
4452             else if (value == null) 
4453                 return value;
4454             else if (this == s_typedRef)
4455                 // everything works for a typedref
4456                 return value;
4457
4458             // check the strange ones courtesy of reflection:
4459             // - implicit cast between primitives
4460             // - enum treated as underlying type
4461             // - IntPtr and System.Reflection.Pointer to pointer types
4462             bool needsSpecialCast = IsPointer || IsEnum || IsPrimitive;
4463             if (needsSpecialCast) 
4464             {
4465                 RuntimeType valueType;
4466                 Pointer pointer = value as Pointer;
4467                 if (pointer != null) 
4468                     valueType = pointer.GetPointerType();
4469                 else
4470                     valueType = (RuntimeType)value.GetType();
4471
4472                 if (CanValueSpecialCast(valueType, this))
4473                 {
4474                     if (pointer != null) 
4475                         return pointer.GetPointerValue();
4476                     else
4477                         return value;
4478                 }
4479             }
4480             
4481             if ((invokeAttr & BindingFlags.ExactBinding) == BindingFlags.ExactBinding)
4482                 throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Arg_ObjObjEx"), value.GetType(), this));
4483
4484             return TryChangeType(value, binder, culture, needsSpecialCast);
4485         }
4486
4487         // Factored out of CheckValue to reduce code complexity.
4488         [System.Security.SecurityCritical]
4489         private Object TryChangeType(Object value, Binder binder, CultureInfo culture, bool needsSpecialCast)
4490         {
4491             if (binder != null && binder != Type.DefaultBinder) 
4492             {
4493                 value = binder.ChangeType(value, this, culture); 
4494                 if (IsInstanceOfType(value)) 
4495                     return value;
4496                 // if this is a ByRef get the element type and check if it's compatible
4497                 if (IsByRef) 
4498                 {
4499                     RuntimeType elementType = RuntimeTypeHandle.GetElementType(this);
4500                     if (elementType.IsInstanceOfType(value) || value == null) 
4501                         return AllocateValueType(elementType, value, false);
4502                 }
4503                 else if (value == null) 
4504                     return value;
4505                 if (needsSpecialCast) 
4506                 {
4507                     RuntimeType valueType;
4508                     Pointer pointer = value as Pointer;
4509                     if (pointer != null) 
4510                         valueType = pointer.GetPointerType();
4511                     else
4512                         valueType = (RuntimeType)value.GetType();
4513
4514                     if (CanValueSpecialCast(valueType, this)) 
4515                     {
4516                         if (pointer != null) 
4517                             return pointer.GetPointerValue();
4518                         else
4519                             return value;
4520                     }
4521                 }
4522             }
4523
4524             throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Arg_ObjObjEx"), value.GetType(), this));
4525         }
4526 #endif
4527         // GetDefaultMembers
4528         // This will return a MemberInfo that has been marked with the [DefaultMemberAttribute]
4529         public override MemberInfo[] GetDefaultMembers()
4530         {
4531             // See if we have cached the default member name
4532             MemberInfo[] members = null;
4533
4534             String defaultMemberName = GetDefaultMemberName();
4535             if (defaultMemberName != null)
4536             {
4537                 members = GetMember(defaultMemberName);
4538             }
4539
4540             if (members == null)
4541                 members = EmptyArray<MemberInfo>.Value;
4542
4543             return members;
4544         }
4545
4546 #if FEATURE_COMINTEROP
4547         [System.Security.SecuritySafeCritical]  // auto-generated
4548 #endif
4549         [DebuggerStepThroughAttribute]
4550         [Diagnostics.DebuggerHidden]
4551         public override Object InvokeMember(
4552             String name, BindingFlags bindingFlags, Binder binder, Object target, 
4553             Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams) 
4554         {
4555             if (IsGenericParameter)
4556                 throw new InvalidOperationException(Environment.GetResourceString("Arg_GenericParameter"));
4557             Contract.EndContractBlock();
4558         
4559             #region Preconditions
4560             if ((bindingFlags & InvocationMask) == 0)
4561                 // "Must specify binding flags describing the invoke operation required."
4562                 throw new ArgumentException(Environment.GetResourceString("Arg_NoAccessSpec"),"bindingFlags");
4563
4564             // Provide a default binding mask if none is provided 
4565             if ((bindingFlags & MemberBindingMask) == 0) 
4566             {
4567                 bindingFlags |= BindingFlags.Instance | BindingFlags.Public;
4568
4569                 if ((bindingFlags & BindingFlags.CreateInstance) == 0) 
4570                     bindingFlags |= BindingFlags.Static;
4571             }
4572
4573             // There must not be more named parameters than provided arguments
4574             if (namedParams != null)
4575             {
4576                 if (providedArgs != null)
4577                 {
4578                     if (namedParams.Length > providedArgs.Length)
4579                         // "Named parameter array can not be bigger than argument array."
4580                         throw new ArgumentException(Environment.GetResourceString("Arg_NamedParamTooBig"), "namedParams");
4581                 }
4582                 else
4583                 {
4584                     if (namedParams.Length != 0)
4585                         // "Named parameter array can not be bigger than argument array."
4586                         throw new ArgumentException(Environment.GetResourceString("Arg_NamedParamTooBig"), "namedParams");
4587                 }
4588             }
4589             #endregion
4590
4591             #region COM Interop
4592 #if FEATURE_COMINTEROP && FEATURE_USE_LCID
4593             if (target != null && target.GetType().IsCOMObject)
4594             {
4595                 #region Preconditions
4596                 if ((bindingFlags & ClassicBindingMask) == 0)
4597                     throw new ArgumentException(Environment.GetResourceString("Arg_COMAccess"), "bindingFlags");
4598
4599                 if ((bindingFlags & BindingFlags.GetProperty) != 0 && (bindingFlags & ClassicBindingMask & ~(BindingFlags.GetProperty | BindingFlags.InvokeMethod)) != 0)
4600                     throw new ArgumentException(Environment.GetResourceString("Arg_PropSetGet"), "bindingFlags");
4601
4602                 if ((bindingFlags & BindingFlags.InvokeMethod) != 0 && (bindingFlags & ClassicBindingMask & ~(BindingFlags.GetProperty | BindingFlags.InvokeMethod)) != 0)
4603                     throw new ArgumentException(Environment.GetResourceString("Arg_PropSetInvoke"), "bindingFlags");
4604
4605                 if ((bindingFlags & BindingFlags.SetProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.SetProperty) != 0)
4606                     throw new ArgumentException(Environment.GetResourceString("Arg_COMPropSetPut"), "bindingFlags");
4607
4608                 if ((bindingFlags & BindingFlags.PutDispProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.PutDispProperty) != 0)
4609                     throw new ArgumentException(Environment.GetResourceString("Arg_COMPropSetPut"), "bindingFlags");
4610
4611                 if ((bindingFlags & BindingFlags.PutRefDispProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.PutRefDispProperty) != 0)
4612                     throw new ArgumentException(Environment.GetResourceString("Arg_COMPropSetPut"), "bindingFlags");
4613                 #endregion
4614
4615 #if FEATURE_REMOTING
4616                 if(!RemotingServices.IsTransparentProxy(target))
4617 #endif
4618                 {
4619                     #region Non-TransparentProxy case
4620                     if (name == null)
4621                         throw new ArgumentNullException("name");
4622
4623                     bool[] isByRef = modifiers == null ? null : modifiers[0].IsByRefArray;
4624                     
4625                     // pass LCID_ENGLISH_US if no explicit culture is specified to match the behavior of VB
4626                     int lcid = (culture == null ? 0x0409 : culture.LCID);
4627
4628 #if MONO
4629                     throw new NotImplementedException ();
4630 #else
4631                     return InvokeDispMethod(name, bindingFlags, target, providedArgs, isByRef, lcid, namedParams);
4632 #endif
4633                     #endregion
4634                 }
4635 #if FEATURE_REMOTING
4636                 else
4637                 {
4638 #if MONO
4639                     throw new NotImplementedException ();
4640 #else
4641                     #region TransparentProxy case
4642                     return ((MarshalByRefObject)target).InvokeMember(name, bindingFlags, binder, providedArgs, modifiers, culture, namedParams);
4643                     #endregion
4644 #endif
4645                 }
4646 #endif // FEATURE_REMOTING
4647             }
4648 #endif // FEATURE_COMINTEROP && FEATURE_USE_LCID
4649             #endregion
4650                 
4651             #region Check that any named paramters are not null
4652             if (namedParams != null && Array.IndexOf(namedParams, null) != -1)
4653                 // "Named parameter value must not be null."
4654                 throw new ArgumentException(Environment.GetResourceString("Arg_NamedParamNull"),"namedParams");
4655             #endregion
4656
4657             int argCnt = (providedArgs != null) ? providedArgs.Length : 0;
4658             
4659             #region Get a Binder
4660             if (binder == null)
4661                 binder = DefaultBinder;
4662
4663             bool bDefaultBinder = (binder == DefaultBinder);
4664             #endregion
4665             
4666             #region Delegate to Activator.CreateInstance
4667             if ((bindingFlags & BindingFlags.CreateInstance) != 0) 
4668             {
4669                 if ((bindingFlags & BindingFlags.CreateInstance) != 0 && (bindingFlags & BinderNonCreateInstance) != 0)
4670                     // "Can not specify both CreateInstance and another access type."
4671                     throw new ArgumentException(Environment.GetResourceString("Arg_CreatInstAccess"),"bindingFlags");
4672
4673                 return Activator.CreateInstance(this, bindingFlags, binder, providedArgs, culture);
4674             }
4675             #endregion
4676
4677             // PutDispProperty and\or PutRefDispProperty ==> SetProperty.
4678             if ((bindingFlags & (BindingFlags.PutDispProperty | BindingFlags.PutRefDispProperty)) != 0)
4679                 bindingFlags |= BindingFlags.SetProperty;
4680
4681             #region Name
4682             if (name == null)
4683                 throw new ArgumentNullException("name");
4684                 
4685             if (name.Length == 0 || name.Equals(@"[DISPID=0]")) 
4686             {
4687                 name = GetDefaultMemberName();
4688
4689                 if (name == null) 
4690                 {
4691                     // in InvokeMember we always pretend there is a default member if none is provided and we make it ToString
4692                     name = "ToString";
4693                 }
4694             }
4695             #endregion
4696
4697             #region GetField or SetField
4698             bool IsGetField = (bindingFlags & BindingFlags.GetField) != 0;
4699             bool IsSetField = (bindingFlags & BindingFlags.SetField) != 0;
4700
4701             if (IsGetField || IsSetField)
4702             {
4703                 #region Preconditions
4704                 if (IsGetField)
4705                 {
4706                     if (IsSetField)
4707                         // "Can not specify both Get and Set on a field."
4708                         throw new ArgumentException(Environment.GetResourceString("Arg_FldSetGet"),"bindingFlags");
4709
4710                     if ((bindingFlags & BindingFlags.SetProperty) != 0)
4711                         // "Can not specify both GetField and SetProperty."
4712                         throw new ArgumentException(Environment.GetResourceString("Arg_FldGetPropSet"),"bindingFlags");
4713                 }
4714                 else
4715                 {
4716                     Contract.Assert(IsSetField);
4717
4718                     if (providedArgs == null) 
4719                         throw new ArgumentNullException("providedArgs");
4720
4721                     if ((bindingFlags & BindingFlags.GetProperty) != 0)
4722                         // "Can not specify both SetField and GetProperty."
4723                         throw new ArgumentException(Environment.GetResourceString("Arg_FldSetPropGet"),"bindingFlags");
4724
4725                     if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
4726                         // "Can not specify Set on a Field and Invoke on a method."
4727                         throw new ArgumentException(Environment.GetResourceString("Arg_FldSetInvoke"),"bindingFlags");
4728                 }
4729                 #endregion
4730                         
4731                 #region Lookup Field
4732                 FieldInfo selFld = null;                
4733                 FieldInfo[] flds = GetMember(name, MemberTypes.Field, bindingFlags) as FieldInfo[];
4734
4735                 Contract.Assert(flds != null);
4736
4737                 if (flds.Length == 1)
4738                 {
4739                     selFld = flds[0];
4740                 }
4741                 else if (flds.Length > 0)
4742                 {
4743                     selFld = binder.BindToField(bindingFlags, flds, IsGetField ? Empty.Value : providedArgs[0], culture);
4744                 }
4745                 #endregion
4746                 
4747                 if (selFld != null) 
4748                 {
4749                     #region Invocation on a field
4750                     if (selFld.FieldType.IsArray || Object.ReferenceEquals(selFld.FieldType, typeof(System.Array)))
4751                     {
4752                         #region Invocation of an array Field
4753                         int idxCnt;
4754
4755                         if ((bindingFlags & BindingFlags.GetField) != 0) 
4756                         {
4757                             idxCnt = argCnt;                                                        
4758                         }
4759                         else
4760                         {
4761                             idxCnt = argCnt - 1;
4762                         }
4763
4764                         if (idxCnt > 0) 
4765                         {
4766                             // Verify that all of the index values are ints
4767                             int[] idx = new int[idxCnt];
4768                             for (int i=0;i<idxCnt;i++) 
4769                             {
4770                                 try 
4771                                 {
4772                                     idx[i] = ((IConvertible)providedArgs[i]).ToInt32(null);
4773                                 }
4774                                 catch (InvalidCastException)
4775                                 {
4776                                     throw new ArgumentException(Environment.GetResourceString("Arg_IndexMustBeInt"));
4777                                 }
4778                             }
4779                             
4780                             // Set or get the value...
4781                             Array a = (Array) selFld.GetValue(target);
4782                             
4783                             // Set or get the value in the array
4784                             if ((bindingFlags & BindingFlags.GetField) != 0) 
4785                             {
4786                                 return a.GetValue(idx);
4787                             }
4788                             else 
4789                             {
4790                                 a.SetValue(providedArgs[idxCnt],idx);
4791                                 return null;
4792                             }                                               
4793                         }
4794                         #endregion
4795                     }
4796                     
4797                     if (IsGetField)
4798                     {
4799                         #region Get the field value
4800                         if (argCnt != 0)
4801                             throw new ArgumentException(Environment.GetResourceString("Arg_FldGetArgErr"),"bindingFlags");
4802
4803                         return selFld.GetValue(target);
4804                         #endregion
4805                     }
4806                     else
4807                     {
4808                         #region Set the field Value
4809                         if (argCnt != 1)
4810                             throw new ArgumentException(Environment.GetResourceString("Arg_FldSetArgErr"),"bindingFlags");
4811
4812                         selFld.SetValue(target,providedArgs[0],bindingFlags,binder,culture);
4813
4814                         return null;
4815                         #endregion
4816                     }
4817                     #endregion
4818                 }
4819
4820                 if ((bindingFlags & BinderNonFieldGetSet) == 0) 
4821                     throw new MissingFieldException(FullName, name);
4822             }
4823             #endregion                    
4824
4825             #region Caching Logic
4826             /*
4827             bool useCache = false;
4828
4829             // Note that when we add something to the cache, we are careful to ensure
4830             // that the actual providedArgs matches the parameters of the method.  Otherwise,
4831             // some default argument processing has occurred.  We don't want anyone
4832             // else with the same (insufficient) number of actual arguments to get a
4833             // cache hit because then they would bypass the default argument processing
4834             // and the invocation would fail.
4835             if (bDefaultBinder && namedParams == null && argCnt < 6)
4836                 useCache = true;
4837
4838             if (useCache)
4839             {
4840                 MethodBase invokeMethod = GetMethodFromCache (name, bindingFlags, argCnt, providedArgs);
4841
4842                 if (invokeMethod != null)
4843                     return ((MethodInfo) invokeMethod).Invoke(target, bindingFlags, binder, providedArgs, culture);
4844             }
4845             */
4846             #endregion
4847
4848             #region Property PreConditions
4849             // @Legacy - This is RTM behavior
4850             bool isGetProperty = (bindingFlags & BindingFlags.GetProperty) != 0;
4851             bool isSetProperty = (bindingFlags & BindingFlags.SetProperty) != 0;
4852
4853             if (isGetProperty || isSetProperty) 
4854             {
4855                 #region Preconditions
4856                 if (isGetProperty)
4857                 {
4858                     Contract.Assert(!IsSetField);
4859
4860                     if (isSetProperty)
4861                         throw new ArgumentException(Environment.GetResourceString("Arg_PropSetGet"), "bindingFlags");
4862                 }
4863                 else
4864                 {
4865                     Contract.Assert(isSetProperty);
4866
4867                     Contract.Assert(!IsGetField);
4868                     
4869                     if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
4870                         throw new ArgumentException(Environment.GetResourceString("Arg_PropSetInvoke"), "bindingFlags");
4871                 }
4872                 #endregion
4873             }
4874             #endregion
4875
4876             MethodInfo[] finalists = null;
4877             MethodInfo finalist = null;
4878
4879             #region BindingFlags.InvokeMethod
4880             if ((bindingFlags & BindingFlags.InvokeMethod) != 0) 
4881             {
4882                 #region Lookup Methods
4883                 MethodInfo[] semiFinalists = GetMember(name, MemberTypes.Method, bindingFlags) as MethodInfo[];
4884                 List<MethodInfo> results = null;
4885                 
4886                 for(int i = 0; i < semiFinalists.Length; i ++)
4887                 {
4888                     MethodInfo semiFinalist = semiFinalists[i];
4889                     Contract.Assert(semiFinalist != null);
4890
4891                     if (!FilterApplyMethodInfo((RuntimeMethodInfo)semiFinalist, bindingFlags, CallingConventions.Any, new Type[argCnt]))
4892                         continue;
4893                     
4894                     if (finalist == null)
4895                     {
4896                         finalist = semiFinalist;
4897                     }
4898                     else
4899                     {
4900                         if (results == null)
4901                         {
4902                             results = new List<MethodInfo>(semiFinalists.Length);
4903                             results.Add(finalist);
4904                         }
4905
4906                         results.Add(semiFinalist);
4907                     }
4908                 }
4909                 
4910                 if (results != null)
4911                 {
4912                     Contract.Assert(results.Count > 1);
4913                     finalists = new MethodInfo[results.Count];
4914                     results.CopyTo(finalists);
4915                 }
4916                 #endregion
4917             }
4918             #endregion
4919             
4920             Contract.Assert(finalists == null || finalist != null);
4921
4922             #region BindingFlags.GetProperty or BindingFlags.SetProperty
4923             if (finalist == null && isGetProperty || isSetProperty) 
4924             {
4925                 #region Lookup Property
4926                 PropertyInfo[] semiFinalists = GetMember(name, MemberTypes.Property, bindingFlags) as PropertyInfo[];                        
4927                 List<MethodInfo> results = null;
4928
4929                 for(int i = 0; i < semiFinalists.Length; i ++)
4930                 {
4931                     MethodInfo semiFinalist = null;
4932
4933                     if (isSetProperty)
4934                     {
4935                         semiFinalist = semiFinalists[i].GetSetMethod(true);
4936                     }
4937                     else
4938                     {
4939                         semiFinalist = semiFinalists[i].GetGetMethod(true);
4940                     }
4941
4942                     if (semiFinalist == null)
4943                         continue;
4944
4945                     if (!FilterApplyMethodInfo((RuntimeMethodInfo)semiFinalist, bindingFlags, CallingConventions.Any, new Type[argCnt]))
4946                         continue;
4947                     
4948                     if (finalist == null)
4949                     {
4950                         finalist = semiFinalist;
4951                     }
4952                     else
4953                     {
4954                         if (results == null)
4955                         {
4956                             results = new List<MethodInfo>(semiFinalists.Length);
4957                             results.Add(finalist);
4958                         }
4959
4960                         results.Add(semiFinalist);
4961                     }
4962                 }
4963
4964                 if (results != null)
4965                 {
4966                     Contract.Assert(results.Count > 1);
4967                     finalists = new MethodInfo[results.Count];
4968                     results.CopyTo(finalists);
4969                 }
4970                 #endregion            
4971             }
4972             #endregion
4973
4974             if (finalist != null) 
4975             {
4976                 #region Invoke
4977                 if (finalists == null && 
4978                     argCnt == 0 && 
4979                     finalist.GetParametersNoCopy().Length == 0 && 
4980                     (bindingFlags & BindingFlags.OptionalParamBinding) == 0)
4981                 {
4982                     //if (useCache && argCnt == props[0].GetParameters().Length)
4983                     //    AddMethodToCache(name, bindingFlags, argCnt, providedArgs, props[0]);
4984
4985                     return finalist.Invoke(target, bindingFlags, binder, providedArgs, culture);
4986                 }
4987                 
4988                 if (finalists == null)
4989                     finalists = new MethodInfo[] { finalist };
4990
4991                 if (providedArgs == null)
4992                         providedArgs = EmptyArray<Object>.Value;
4993
4994                 Object state = null;
4995
4996                 
4997                 MethodBase invokeMethod = null;
4998
4999                 try { invokeMethod = binder.BindToMethod(bindingFlags, finalists, ref providedArgs, modifiers, culture, namedParams, out state); }
5000                 catch(MissingMethodException) { }
5001
5002                 if (invokeMethod == null)
5003                     throw new MissingMethodException(FullName, name);
5004
5005                 //if (useCache && argCnt == invokeMethod.GetParameters().Length)
5006                 //    AddMethodToCache(name, bindingFlags, argCnt, providedArgs, invokeMethod);
5007
5008                 Object result = ((MethodInfo)invokeMethod).Invoke(target, bindingFlags, binder, providedArgs, culture);
5009
5010                 if (state != null)
5011                     binder.ReorderArgumentArray(ref providedArgs, state);
5012
5013                 return result;
5014                 #endregion
5015             }
5016             
5017             throw new MissingMethodException(FullName, name);
5018         }        
5019         #endregion
5020
5021         #endregion
5022
5023         #region Object Overrides
5024         [Pure]
5025         public override bool Equals(object obj)
5026         {
5027             // ComObjects are identified by the instance of the Type object and not the TypeHandle.
5028             return obj == (object)this;
5029         }
5030
5031         public override int GetHashCode() 
5032         {
5033             return RuntimeHelpers.GetHashCode(this);
5034         }
5035
5036 #if !FEATURE_CORECLR
5037         public static bool operator ==(RuntimeType left, RuntimeType right)
5038         {
5039             return object.ReferenceEquals(left, right);
5040         }
5041
5042         public static bool operator !=(RuntimeType left, RuntimeType right)
5043         {
5044             return !object.ReferenceEquals(left, right);
5045         }
5046 #endif // !FEATURE_CORECLR
5047 #if !MONO
5048         public override String ToString() 
5049         {
5050             return GetCachedName(TypeNameKind.ToString);
5051         }
5052 #endif
5053         #endregion
5054
5055         #region ICloneable
5056         public Object Clone() 
5057         {
5058             return this;
5059         }
5060         #endregion
5061
5062         #region ISerializable
5063         [System.Security.SecurityCritical]  // auto-generated
5064         public void GetObjectData(SerializationInfo info, StreamingContext context) 
5065         {
5066             if (info==null) 
5067                 throw new ArgumentNullException("info");
5068             Contract.EndContractBlock();
5069
5070             UnitySerializationHolder.GetUnitySerializationInfo(info, this);
5071         }
5072         #endregion
5073
5074         #region ICustomAttributeProvider
5075         [System.Security.SecuritySafeCritical]  // auto-generated
5076         public override Object[] GetCustomAttributes(bool inherit)
5077         {
5078             return CustomAttribute.GetCustomAttributes(this, RuntimeType.ObjectType, inherit);
5079         }
5080
5081         [System.Security.SecuritySafeCritical]  // auto-generated
5082         public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
5083         {
5084             if ((object)attributeType == null)
5085                 throw new ArgumentNullException("attributeType");
5086             Contract.EndContractBlock();
5087
5088             RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
5089
5090             if (attributeRuntimeType == null) 
5091                 throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
5092
5093             return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType, inherit);
5094         }
5095
5096         [System.Security.SecuritySafeCritical]  // auto-generated
5097         public override bool IsDefined(Type attributeType, bool inherit)
5098         {
5099             if ((object)attributeType == null)
5100                 throw new ArgumentNullException("attributeType");
5101             Contract.EndContractBlock();
5102
5103             RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
5104
5105             if (attributeRuntimeType == null) 
5106                 throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
5107
5108             return CustomAttribute.IsDefined(this, attributeRuntimeType, inherit);
5109         }
5110
5111         public override IList<CustomAttributeData> GetCustomAttributesData()
5112         {
5113             return CustomAttributeData.GetCustomAttributesInternal(this);
5114         }
5115         #endregion
5116
5117         #region MemberInfo Overrides
5118 #if !MONO
5119         public override String Name 
5120         {
5121             get 
5122             {
5123                 return GetCachedName(TypeNameKind.Name);
5124             }
5125         }
5126
5127 #endif
5128         // This is used by the ToString() overrides of all reflection types. The legacy behavior has the following problems:
5129         //  1. Use only Name for nested types, which can be confused with global types and generic parameters of the same name.
5130         //  2. Use only Name for generic parameters, which can be confused with nested types and global types of the same name.
5131         //  3. Remove the namespace ("System") for all primitive types, which is not language neutral.
5132         //  4. MethodBase.ToString() use "ByRef" for byref parameters which is different than Type.ToString().
5133         //  5. ConstructorInfo.ToString() outputs "Void" as the return type. Why Void?
5134         // Since it could be a breaking changes to fix these legacy behaviors, we only use the better and more unambiguous format
5135         // in serialization (MemberInfoSerializationHolder).
5136         internal override string FormatTypeName(bool serialization)
5137         {
5138             if (serialization)
5139             {
5140                 return GetCachedName(TypeNameKind.SerializationName);
5141             }
5142             else
5143             {
5144                 Type elementType = GetRootElementType();
5145
5146                 // Legacy: this doesn't make sense, why use only Name for nested types but otherwise
5147                 // ToString() which contains namespace.
5148                 if (elementType.IsNested)
5149                     return Name;
5150
5151                 string typeName = ToString();
5152
5153                 // Legacy: why removing "System"? Is it just because C# has keywords for these types?
5154                 // If so why don't we change it to lower case to match the C# keyword casing?
5155                 if (elementType.IsPrimitive ||
5156                     elementType == typeof(void) ||
5157                     elementType == typeof(TypedReference))
5158                 {
5159                     typeName = typeName.Substring(@"System.".Length);
5160                 }
5161
5162                 return typeName;
5163             }
5164         }
5165 #if !MONO
5166
5167         private string GetCachedName(TypeNameKind kind)
5168         {
5169             return Cache.GetName(kind);
5170         }
5171 #endif
5172         public override MemberTypes MemberType 
5173         {
5174             get 
5175             {
5176                 if (this.IsPublic || this.IsNotPublic)
5177                     return MemberTypes.TypeInfo;
5178                 else
5179                     return MemberTypes.NestedType;
5180             }
5181         }
5182 #if !MONO
5183         public override Type DeclaringType 
5184         {
5185             get 
5186             {
5187                 return Cache.GetEnclosingType();
5188             }
5189         }
5190 #endif
5191         public override Type ReflectedType 
5192         {
5193             get 
5194             {
5195                 return DeclaringType;
5196             }
5197         }
5198
5199         public override int MetadataToken
5200         {
5201             [System.Security.SecuritySafeCritical]  // auto-generated
5202             get 
5203             {
5204                 return RuntimeTypeHandle.GetToken(this);
5205             }
5206         }
5207         #endregion
5208
5209         #region Legacy Internal
5210         private void CreateInstanceCheckThis()
5211         {
5212             if (this is ReflectionOnlyType)
5213                 throw new ArgumentException(Environment.GetResourceString("Arg_ReflectionOnlyInvoke"));
5214
5215             if (ContainsGenericParameters)
5216                 throw new ArgumentException(
5217                     Environment.GetResourceString("Acc_CreateGenericEx", this));
5218             Contract.EndContractBlock();
5219
5220             Type elementType = this.GetRootElementType();
5221
5222             if (Object.ReferenceEquals(elementType, typeof(ArgIterator)))
5223                 throw new NotSupportedException(Environment.GetResourceString("Acc_CreateArgIterator"));
5224
5225             if (Object.ReferenceEquals(elementType, typeof(void)))
5226                 throw new NotSupportedException(Environment.GetResourceString("Acc_CreateVoid"));
5227         }
5228         
5229         [System.Security.SecurityCritical]  // auto-generated
5230         internal Object CreateInstanceImpl(
5231             BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, ref StackCrawlMark stackMark)
5232         {            
5233             CreateInstanceCheckThis();
5234             
5235             Object server = null;
5236
5237             try
5238             {
5239                 try
5240                 {
5241                     // Store the activation attributes in thread local storage.
5242                     // These attributes are later picked up by specialized 
5243                     // activation services like remote activation services to
5244                     // influence the activation.
5245 #if FEATURE_REMOTING                                    
5246                     if(null != activationAttributes)
5247                     {
5248                         ActivationServices.PushActivationAttributes(this, activationAttributes);
5249                     }
5250 #endif                    
5251                     
5252                     if (args == null)
5253                         args = EmptyArray<Object>.Value;
5254
5255                     int argCnt = args.Length;
5256
5257                     // Without a binder we need to do use the default binder...
5258                     if (binder == null)
5259                         binder = DefaultBinder;
5260
5261                     // deal with the __COMObject case first. It is very special because from a reflection point of view it has no ctors
5262                     // so a call to GetMemberCons would fail
5263                     if (argCnt == 0 && (bindingAttr & BindingFlags.Public) != 0 && (bindingAttr & BindingFlags.Instance) != 0
5264                         && (IsGenericCOMObjectImpl() || IsValueType)) 
5265                     {
5266                         server = CreateInstanceDefaultCtor((bindingAttr & BindingFlags.NonPublic) == 0 , false, true, ref stackMark);
5267                     }
5268                     else 
5269                     {
5270                         ConstructorInfo[] candidates = GetConstructors(bindingAttr);
5271                         List<MethodBase> matches = new List<MethodBase>(candidates.Length);
5272
5273                         // We cannot use Type.GetTypeArray here because some of the args might be null
5274                         Type[] argsType = new Type[argCnt];
5275                         for (int i = 0; i < argCnt; i++)
5276                         {
5277                             if (args[i] != null)
5278                             {
5279                                 argsType[i] = args[i].GetType();
5280                             }
5281                         }
5282
5283                         for(int i = 0; i < candidates.Length; i ++)
5284                         {
5285                             if (FilterApplyConstructorInfo((RuntimeConstructorInfo)candidates[i], bindingAttr, CallingConventions.Any, argsType))
5286                                 matches.Add(candidates[i]);
5287                         }
5288
5289                         MethodBase[] cons = new MethodBase[matches.Count];
5290                         matches.CopyTo(cons);
5291                         if (cons != null && cons.Length == 0)
5292                             cons = null;
5293
5294                         if (cons == null) 
5295                         {
5296                             // Null out activation attributes before throwing exception
5297 #if FEATURE_REMOTING                                            
5298                             if(null != activationAttributes)
5299                             {
5300                                 ActivationServices.PopActivationAttributes(this);
5301                                 activationAttributes = null;
5302                             }
5303 #endif                            
5304                             throw new MissingMethodException(Environment.GetResourceString("MissingConstructor_Name", FullName));
5305                         }
5306
5307                         MethodBase invokeMethod;
5308                         Object state = null;
5309
5310                         try
5311                         {
5312                             invokeMethod = binder.BindToMethod(bindingAttr, cons, ref args, null, culture, null, out state);
5313                         }
5314                         catch (MissingMethodException) { invokeMethod = null; }
5315
5316                         if (invokeMethod == null)
5317                         {
5318 #if FEATURE_REMOTING                                            
5319                             // Null out activation attributes before throwing exception
5320                             if(null != activationAttributes)
5321                             {
5322                                 ActivationServices.PopActivationAttributes(this);
5323                                 activationAttributes = null;
5324                             }                  
5325 #endif                                
5326                             throw new MissingMethodException(Environment.GetResourceString("MissingConstructor_Name", FullName));
5327                         }
5328
5329 #if !DISABLE_CAS_USE
5330                         // If we're creating a delegate, we're about to call a
5331                         // constructor taking an integer to represent a target
5332                         // method. Since this is very difficult (and expensive)
5333                         // to verify, we're just going to demand UnmanagedCode
5334                         // permission before allowing this. Partially trusted
5335                         // clients can instead use Delegate.CreateDelegate,
5336                         // which allows specification of the target method via
5337                         // name or MethodInfo.
5338                         //if (isDelegate)
5339                         if (RuntimeType.DelegateType.IsAssignableFrom(invokeMethod.DeclaringType))
5340                         {
5341 #if FEATURE_CORECLR
5342                             // In CoreCLR, CAS is not exposed externally. So what we really are looking
5343                             // for is to see if the external caller of this API is transparent or not.
5344                             // We get that information from the fact that a Demand will succeed only if
5345                             // the external caller is not transparent. 
5346                             try
5347                             {
5348 #pragma warning disable 618
5349                                 new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
5350 #pragma warning restore 618
5351                             }
5352                             catch
5353                             {
5354                                 throw new NotSupportedException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("NotSupported_DelegateCreationFromPT")));
5355                             }
5356 #else // FEATURE_CORECLR
5357                             new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
5358 #endif // FEATURE_CORECLR
5359                         }
5360 #endif // !DISABLE_CAS_USE
5361                         if (invokeMethod.GetParametersNoCopy().Length == 0)
5362                         {
5363                             if (args.Length != 0)
5364                             {
5365
5366                                 Contract.Assert((invokeMethod.CallingConvention & CallingConventions.VarArgs) == 
5367                                                  CallingConventions.VarArgs); 
5368                                 throw new NotSupportedException(String.Format(CultureInfo.CurrentCulture, 
5369                                     Environment.GetResourceString("NotSupported_CallToVarArg")));
5370                             }
5371
5372 #if MONO && FEATURE_REMOTING
5373                             if (activationAttributes != null && activationAttributes.Length != 0) {
5374                                 server = ActivationCreateInstance (invokeMethod, bindingAttr, binder, args, culture, activationAttributes);
5375                             } else {
5376 #endif
5377                             // fast path??
5378                             server = Activator.CreateInstance(this, true);
5379
5380 #if MONO && FEATURE_REMOTING
5381                             }
5382 #endif
5383                         }
5384                         else
5385                         {
5386 #if MONO && FEATURE_REMOTING
5387
5388                             if (activationAttributes != null && activationAttributes.Length != 0) {
5389                                 server = ActivationCreateInstance (invokeMethod, bindingAttr, binder, args, culture, activationAttributes);
5390                             } else {
5391 #endif
5392                             server = ((ConstructorInfo)invokeMethod).Invoke(bindingAttr, binder, args, culture);
5393 #if MONO && FEATURE_REMOTING
5394                             }
5395 #endif
5396
5397                             if (state != null)
5398                                 binder.ReorderArgumentArray(ref args, state);
5399                         }
5400                     }
5401                 }                    
5402                 finally
5403                 {
5404 #if FEATURE_REMOTING                
5405                     // Reset the TLS to null
5406                     if(null != activationAttributes)
5407                     {
5408                           ActivationServices.PopActivationAttributes(this);
5409                           activationAttributes = null;
5410                     }
5411 #endif                    
5412                 }
5413             }
5414             catch (Exception)
5415             {
5416                 throw;
5417             }
5418             
5419             //Console.WriteLine(server);
5420             return server;                                
5421         }
5422
5423 #if MONO
5424 #if FEATURE_REMOTING
5425         //
5426         // .NET seems to do this deep in method invocation which looks odd as it
5427         // needs extra push/pop as PushActivationAttributes/PopActivationAttributes.
5428         // We let them do nothing and have all logic here without complicated checks
5429         // inside fast path invoke.
5430         //
5431         object ActivationCreateInstance (MethodBase invokeMethod, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
5432         {
5433             var server = ActivationServices.CreateProxyFromAttributes (this, activationAttributes);
5434             if (server != null)
5435                 invokeMethod.Invoke (server, bindingAttr, binder, args, culture);
5436
5437             return server;
5438         }
5439 #endif
5440 #else
5441         // the cache entry
5442         class ActivatorCacheEntry
5443         {
5444             // the type to cache
5445             internal readonly RuntimeType m_type;
5446             // the delegate containing the call to the ctor, will be replaced by an IntPtr to feed a calli with
5447             internal volatile CtorDelegate m_ctor;
5448             internal readonly RuntimeMethodHandleInternal m_hCtorMethodHandle;
5449             internal readonly MethodAttributes m_ctorAttributes;
5450             // Is a security check needed before this constructor is invoked?
5451             internal readonly bool m_bNeedSecurityCheck;
5452             // Lazy initialization was performed
5453             internal volatile bool m_bFullyInitialized;
5454
5455             [System.Security.SecurityCritical]
5456             internal ActivatorCacheEntry(RuntimeType t, RuntimeMethodHandleInternal rmh, bool bNeedSecurityCheck)
5457             {
5458                 m_type = t;
5459                 m_bNeedSecurityCheck = bNeedSecurityCheck;
5460                 m_hCtorMethodHandle = rmh;
5461                 if (!m_hCtorMethodHandle.IsNullHandle())
5462                     m_ctorAttributes = RuntimeMethodHandle.GetAttributes(m_hCtorMethodHandle);
5463             }
5464         }
5465
5466         //ActivatorCache
5467         class ActivatorCache
5468         {
5469             const int CACHE_SIZE = 16;
5470             volatile int hash_counter; //Counter for wrap around
5471             readonly ActivatorCacheEntry[] cache = new ActivatorCacheEntry[CACHE_SIZE];
5472
5473             volatile ConstructorInfo     delegateCtorInfo;
5474             volatile PermissionSet       delegateCreatePermissions;
5475
5476             private void InitializeDelegateCreator() {
5477                 // No synchronization needed here. In the worst case we create extra garbage
5478                 PermissionSet ps = new PermissionSet(PermissionState.None);
5479                 ps.AddPermission(new ReflectionPermission(ReflectionPermissionFlag.MemberAccess));
5480 #pragma warning disable 618
5481                 ps.AddPermission(new SecurityPermission(SecurityPermissionFlag.UnmanagedCode));
5482 #pragma warning restore 618
5483                 delegateCreatePermissions = ps;
5484
5485                 ConstructorInfo ctorInfo = typeof(CtorDelegate).GetConstructor(new Type[] {typeof(Object), typeof(IntPtr)});
5486                 delegateCtorInfo = ctorInfo; // this assignment should be last
5487             }
5488
5489             [System.Security.SecuritySafeCritical]  // auto-generated
5490             private void InitializeCacheEntry(ActivatorCacheEntry ace)
5491             {
5492                 if (!ace.m_type.IsValueType)
5493                 {
5494                     Contract.Assert(!ace.m_hCtorMethodHandle.IsNullHandle(), "Expected the default ctor method handle for a reference type.");
5495                     
5496                     if (delegateCtorInfo == null)
5497                         InitializeDelegateCreator();
5498                     delegateCreatePermissions.Assert();
5499
5500                     // No synchronization needed here. In the worst case we create extra garbage
5501                     CtorDelegate ctor = (CtorDelegate)delegateCtorInfo.Invoke(new Object[] { null, RuntimeMethodHandle.GetFunctionPointer(ace.m_hCtorMethodHandle) });
5502                     ace.m_ctor = ctor;
5503                 }
5504                 ace.m_bFullyInitialized = true;
5505             }
5506
5507             internal ActivatorCacheEntry GetEntry(RuntimeType t)
5508             {
5509                 int index = hash_counter;
5510                 for(int i = 0; i < CACHE_SIZE; i++)
5511                 {
5512                     ActivatorCacheEntry ace = Volatile.Read(ref cache[index]);
5513                     if (ace != null && ace.m_type == t) //check for type match..
5514                     {
5515                         if (!ace.m_bFullyInitialized)
5516                             InitializeCacheEntry(ace);
5517                         return ace;
5518                     }
5519                     index = (index+1)&(ActivatorCache.CACHE_SIZE-1);
5520                 }
5521                 return null;
5522             }
5523
5524             internal void SetEntry(ActivatorCacheEntry ace)
5525             {
5526                 // fill the the array backwards to hit the most recently filled entries first in GetEntry
5527                 int index = (hash_counter-1)&(ActivatorCache.CACHE_SIZE-1);
5528                 hash_counter = index;
5529                 Volatile.Write(ref cache[index], ace);
5530             }
5531         }
5532
5533         private static volatile ActivatorCache s_ActivatorCache;
5534
5535         // the slow path of CreateInstanceDefaultCtor
5536         [System.Security.SecuritySafeCritical]  // auto-generated
5537         internal Object CreateInstanceSlow(bool publicOnly, bool skipCheckThis, bool fillCache, ref StackCrawlMark stackMark)
5538         {
5539             RuntimeMethodHandleInternal runtime_ctor = default(RuntimeMethodHandleInternal);
5540             bool bNeedSecurityCheck = true;
5541             bool bCanBeCached = false;
5542             bool bSecurityCheckOff = false;
5543
5544             if (!skipCheckThis)
5545                 CreateInstanceCheckThis();
5546
5547             if (!fillCache)
5548                 bSecurityCheckOff = true;
5549
5550 #if FEATURE_APPX
5551             INVOCATION_FLAGS invocationFlags = InvocationFlags;
5552             if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0)
5553             {
5554                 RuntimeAssembly caller = RuntimeAssembly.GetExecutingAssembly(ref stackMark);
5555                 if (caller != null && !caller.IsSafeForReflection())
5556                     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", this.FullName));
5557                 
5558                 // Allow it because the caller is framework code, but don't cache the result
5559                 // because we need to do the stack walk every time this type is instantiated.
5560                 bSecurityCheckOff = false;
5561                 bCanBeCached = false;
5562             }
5563 #endif
5564
5565             Object instance = RuntimeTypeHandle.CreateInstance(this, publicOnly, bSecurityCheckOff, ref bCanBeCached, ref runtime_ctor, ref bNeedSecurityCheck);
5566
5567             if (bCanBeCached && fillCache)
5568             {
5569                 ActivatorCache activatorCache = s_ActivatorCache;
5570                 if (activatorCache == null)
5571                 {
5572                     // No synchronization needed here. In the worst case we create extra garbage
5573                     activatorCache = new ActivatorCache();
5574                     s_ActivatorCache = activatorCache;
5575                 }
5576
5577                 // cache the ctor
5578                 ActivatorCacheEntry ace = new ActivatorCacheEntry(this, runtime_ctor, bNeedSecurityCheck);
5579                 activatorCache.SetEntry(ace);
5580             }
5581
5582             return instance;
5583         }
5584 #endif
5585         // Helper to invoke the default (parameterless) ctor.
5586         // fillCache is set in the SL2/3 compat mode or when called from Marshal.PtrToStructure.
5587         [System.Security.SecuritySafeCritical]  // auto-generated
5588         [DebuggerStepThroughAttribute]
5589         [Diagnostics.DebuggerHidden]
5590         internal Object CreateInstanceDefaultCtor(bool publicOnly, bool skipCheckThis, bool fillCache, ref StackCrawlMark stackMark)
5591         {
5592             if (GetType() == typeof(ReflectionOnlyType))
5593                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInReflectionOnly"));
5594 #if !MONO
5595             ActivatorCache activatorCache = s_ActivatorCache;
5596             if (activatorCache != null)
5597             {
5598                 ActivatorCacheEntry ace = activatorCache.GetEntry(this);
5599                 if (ace != null)
5600                 {
5601                     if (publicOnly)
5602                     {
5603                         if (ace.m_ctor != null && 
5604                             (ace.m_ctorAttributes & MethodAttributes.MemberAccessMask) != MethodAttributes.Public)
5605                         {
5606                             throw new MissingMethodException(Environment.GetResourceString("Arg_NoDefCTor"));
5607                         }
5608                     }
5609                             
5610                     // Allocate empty object
5611                     Object instance = RuntimeTypeHandle.Allocate(this);
5612                     
5613                     // if m_ctor is null, this type doesn't have a default ctor
5614                     Contract.Assert(ace.m_ctor != null || this.IsValueType);
5615
5616                     if (ace.m_ctor != null)
5617                     {
5618                         // Perform security checks if needed
5619                         if (ace.m_bNeedSecurityCheck)
5620                             RuntimeMethodHandle.PerformSecurityCheck(instance, ace.m_hCtorMethodHandle, this, (uint)INVOCATION_FLAGS.INVOCATION_FLAGS_CONSTRUCTOR_INVOKE);
5621
5622                         // Call ctor (value types wont have any)
5623                         try
5624                         {
5625                             ace.m_ctor(instance);
5626                         }
5627                         catch (Exception e)
5628                         {
5629                             throw new TargetInvocationException(e);
5630                         }
5631                     }
5632                     return instance;
5633                 }
5634             }
5635 #endif
5636             return CreateInstanceSlow(publicOnly, skipCheckThis, fillCache, ref stackMark);
5637         }
5638 #if !MONO
5639         internal void InvalidateCachedNestedType()
5640         {
5641             Cache.InvalidateCachedNestedType();
5642         }
5643
5644         [System.Security.SecuritySafeCritical]  // auto-generated
5645         internal bool IsGenericCOMObjectImpl()
5646         {
5647             return RuntimeTypeHandle.IsComObject(this, true);
5648         }
5649 #endif
5650         #endregion
5651 #if !MONO
5652         #region Legacy Static Internal
5653         [System.Security.SecurityCritical]
5654         [ResourceExposure(ResourceScope.None)]
5655         [MethodImplAttribute(MethodImplOptions.InternalCall)]
5656         private static extern Object _CreateEnum(RuntimeType enumType, long value);
5657         [System.Security.SecuritySafeCritical]  // auto-generated
5658         internal static Object CreateEnum(RuntimeType enumType, long value)
5659         {
5660             return _CreateEnum(enumType, value);
5661         }
5662
5663 #if FEATURE_COMINTEROP
5664         [System.Security.SecurityCritical]  // auto-generated
5665         [ResourceExposure(ResourceScope.None)]
5666         [MethodImplAttribute(MethodImplOptions.InternalCall)]
5667         private extern Object InvokeDispMethod(
5668             String name, BindingFlags invokeAttr, Object target, Object[] args,
5669             bool[] byrefModifiers, int culture, String[] namedParameters);
5670
5671 #if FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
5672         [System.Security.SecurityCritical]  // auto-generated
5673         [ResourceExposure(ResourceScope.None)]
5674         [MethodImplAttribute(MethodImplOptions.InternalCall)]
5675         internal static extern Type GetTypeFromProgIDImpl(String progID, String server, bool throwOnError);
5676
5677         [System.Security.SecurityCritical]  // auto-generated
5678         [ResourceExposure(ResourceScope.None)]
5679         [MethodImplAttribute(MethodImplOptions.InternalCall)]
5680         internal static extern Type GetTypeFromCLSIDImpl(Guid clsid, String server, bool throwOnError);
5681 #else // FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
5682         internal static Type GetTypeFromProgIDImpl(String progID, String server, bool throwOnError)
5683         {
5684             throw new NotImplementedException("CoreCLR_REMOVED -- Unmanaged activation removed"); // @
5685         }
5686
5687         internal static Type GetTypeFromCLSIDImpl(Guid clsid, String server, bool throwOnError)
5688         {
5689             throw new NotImplementedException("CoreCLR_REMOVED -- Unmanaged activation removed"); // @
5690         }
5691 #endif // FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
5692 #endif
5693
5694         #endregion
5695 #endif
5696         #region COM
5697 #if FEATURE_COMINTEROP && FEATURE_REMOTING && !MONO
5698         [System.Security.SecuritySafeCritical]  // auto-generated
5699         private Object ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, int[] aWrapperTypes, ref MessageData msgData)
5700         {
5701             ParameterModifier[] aParamMod = null;
5702             Object ret = null;
5703
5704             // Allocate a new message
5705             Message reqMsg = new Message();
5706             reqMsg.InitFields(msgData);
5707
5708             // Retrieve the required information from the message object.
5709             MethodInfo meth = (MethodInfo)reqMsg.GetMethodBase();
5710             Object[] aArgs = reqMsg.Args;
5711             int cArgs = aArgs.Length;
5712
5713             // Retrieve information from the method we are invoking on.
5714             ParameterInfo[] aParams = meth.GetParametersNoCopy();
5715
5716             // If we have arguments, then set the byref flags to true for byref arguments. 
5717             // We also wrap the arguments that require wrapping.
5718             if (cArgs > 0)
5719             {
5720                 ParameterModifier paramMod = new ParameterModifier(cArgs);
5721                 for (int i = 0; i < cArgs; i++)
5722                 {
5723                     if (aParams[i].ParameterType.IsByRef)
5724                         paramMod[i] = true;
5725                 }
5726
5727                 aParamMod = new ParameterModifier[1];
5728                 aParamMod[0] = paramMod;
5729
5730                 if (aWrapperTypes != null)
5731                     WrapArgsForInvokeCall(aArgs, aWrapperTypes);
5732             }
5733             
5734             // If the method has a void return type, then set the IgnoreReturn binding flag.
5735             if (Object.ReferenceEquals(meth.ReturnType, typeof(void)))
5736                 flags |= BindingFlags.IgnoreReturn;
5737
5738             try
5739             {
5740                 // Invoke the method using InvokeMember().
5741                 ret = InvokeMember(memberName, flags, null, target, aArgs, aParamMod, null, null);
5742             }
5743             catch (TargetInvocationException e)
5744             {
5745                 // For target invocation exceptions, we need to unwrap the inner exception and
5746                 // re-throw it.
5747                 throw e.InnerException;
5748             }
5749
5750             // Convert each byref argument that is not of the proper type to
5751             // the parameter type using the OleAutBinder.
5752             for (int i = 0; i < cArgs; i++)
5753             {
5754                 if (aParamMod[0][i] && aArgs[i] != null)
5755                 {
5756                     // The parameter is byref.
5757                     Type paramType = aParams[i].ParameterType.GetElementType();
5758                     if (!Object.ReferenceEquals(paramType, aArgs[i].GetType()))
5759                         aArgs[i] = ForwardCallBinder.ChangeType(aArgs[i], paramType, null);
5760                 }
5761             }
5762
5763             // If the return type is not of the proper type, then convert it
5764             // to the proper type using the OleAutBinder.
5765             if (ret != null)
5766             {
5767                 Type retType = meth.ReturnType;
5768                 if (!Object.ReferenceEquals(retType, ret.GetType()))
5769                     ret = ForwardCallBinder.ChangeType(ret, retType, null);
5770             }
5771
5772             // Propagate the out parameters
5773             RealProxy.PropagateOutParameters(reqMsg, aArgs, ret);
5774
5775             // Return the value returned by the InvokeMember call.
5776             return ret;
5777         }
5778
5779         [SecuritySafeCritical]
5780         private void WrapArgsForInvokeCall(Object[] aArgs, int[] aWrapperTypes)
5781         {
5782             int cArgs = aArgs.Length;
5783             for (int i = 0; i < cArgs; i++)
5784             {
5785                 if (aWrapperTypes[i] == 0)
5786                     continue;
5787
5788                 if (((DispatchWrapperType)aWrapperTypes[i] & DispatchWrapperType.SafeArray) != 0)
5789                 {
5790                     Type wrapperType = null;
5791                     bool isString = false;
5792
5793                     // Determine the type of wrapper to use.
5794                     switch ((DispatchWrapperType)aWrapperTypes[i] & ~DispatchWrapperType.SafeArray)
5795                     {
5796                         case DispatchWrapperType.Unknown:
5797                             wrapperType = typeof(UnknownWrapper);
5798                             break;
5799                         case DispatchWrapperType.Dispatch:
5800                             wrapperType = typeof(DispatchWrapper);
5801                             break;
5802                         case DispatchWrapperType.Error:   
5803                             wrapperType = typeof(ErrorWrapper);
5804                             break;
5805                         case DispatchWrapperType.Currency:
5806                             wrapperType = typeof(CurrencyWrapper);
5807                             break;
5808                         case DispatchWrapperType.BStr:
5809                             wrapperType = typeof(BStrWrapper);
5810                             isString = true;
5811                             break;
5812                         default:
5813                             Contract.Assert(false, "[RuntimeType.WrapArgsForInvokeCall]Invalid safe array wrapper type specified.");
5814                             break;
5815                     }
5816
5817                     // Allocate the new array of wrappers.
5818                     Array oldArray = (Array)aArgs[i];
5819                     int numElems = oldArray.Length;
5820                     Object[] newArray = (Object[])Array.UnsafeCreateInstance(wrapperType, numElems);
5821
5822                     // Retrieve the ConstructorInfo for the wrapper type.
5823                     ConstructorInfo wrapperCons;
5824                     if(isString)
5825                     {
5826                          wrapperCons = wrapperType.GetConstructor(new Type[] {typeof(String)});
5827                     }
5828                     else
5829                     {
5830                          wrapperCons = wrapperType.GetConstructor(new Type[] {typeof(Object)});
5831                     }
5832                 
5833                     // Wrap each of the elements of the array.
5834                     for (int currElem = 0; currElem < numElems; currElem++)
5835                     {
5836                         if(isString)
5837                         {
5838                             newArray[currElem] = wrapperCons.Invoke(new Object[] {(String)oldArray.GetValue(currElem)});
5839                         }
5840                         else
5841                         {
5842                             newArray[currElem] = wrapperCons.Invoke(new Object[] {oldArray.GetValue(currElem)});
5843                         }
5844                     }
5845
5846                     // Update the argument.
5847                     aArgs[i] = newArray;
5848                 }
5849                 else
5850                 {                           
5851                     // Determine the wrapper to use and then wrap the argument.
5852                     switch ((DispatchWrapperType)aWrapperTypes[i])
5853                     {
5854                         case DispatchWrapperType.Unknown:
5855                             aArgs[i] = new UnknownWrapper(aArgs[i]);
5856                             break;
5857                         case DispatchWrapperType.Dispatch:
5858                             aArgs[i] = new DispatchWrapper(aArgs[i]);
5859                             break;
5860                         case DispatchWrapperType.Error:   
5861                             aArgs[i] = new ErrorWrapper(aArgs[i]);
5862                             break;
5863                         case DispatchWrapperType.Currency:
5864                             aArgs[i] = new CurrencyWrapper(aArgs[i]);
5865                             break;
5866                         case DispatchWrapperType.BStr:
5867                             aArgs[i] = new BStrWrapper((String)aArgs[i]);
5868                             break;
5869                         default:
5870                             Contract.Assert(false, "[RuntimeType.WrapArgsForInvokeCall]Invalid wrapper type specified.");
5871                             break;
5872                     }
5873                 }
5874             }
5875         }
5876
5877         private OleAutBinder ForwardCallBinder 
5878         {
5879             get 
5880             {
5881                 // Synchronization is not required.
5882                 if (s_ForwardCallBinder == null)
5883                     s_ForwardCallBinder = new OleAutBinder();
5884
5885                 return s_ForwardCallBinder;
5886             }
5887         }
5888
5889         [Flags]
5890         private enum DispatchWrapperType : int
5891         {
5892             // This enum must stay in [....] with the DispatchWrapperType enum defined in MLInfo.h
5893             Unknown         = 0x00000001,
5894             Dispatch        = 0x00000002,
5895             Record          = 0x00000004,
5896             Error           = 0x00000008,
5897             Currency        = 0x00000010,
5898             BStr            = 0x00000020,
5899             SafeArray       = 0x00010000
5900         }
5901
5902         private static volatile OleAutBinder s_ForwardCallBinder;
5903 #endif // FEATURE_COMINTEROP && FEATURE_REMOTING
5904         #endregion
5905     }
5906
5907     // this is the introspection only type. This type overrides all the functions with runtime semantics
5908     // and throws an exception.
5909     // The idea behind this type is that it relieves RuntimeType from doing honerous checks about ReflectionOnly
5910     // context.
5911     // This type should not derive from RuntimeType but it's doing so for convinience.
5912     // That should not present a security threat though it is risky as a direct call to one of the base method
5913     // method (RuntimeType) and an instance of this type will work around the reason to have this type in the 
5914     // first place. However given RuntimeType is not public all its methods are protected and require full trust
5915     // to be accessed
5916     [Serializable]
5917     internal class ReflectionOnlyType : RuntimeType {
5918
5919         private ReflectionOnlyType() {}
5920
5921         // always throw
5922         public override RuntimeTypeHandle TypeHandle 
5923         {
5924             get 
5925             {
5926                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInReflectionOnly"));
5927             }
5928         }
5929
5930     }
5931 #if !MONO
5932     #region Library
5933     internal unsafe struct Utf8String
5934     {
5935         [System.Security.SecurityCritical]  // auto-generated
5936         [ResourceExposure(ResourceScope.None)]
5937         [MethodImplAttribute(MethodImplOptions.InternalCall)]
5938         private static extern unsafe bool EqualsCaseSensitive(void* szLhs, void* szRhs, int cSz);
5939
5940         [System.Security.SecurityCritical]  // auto-generated
5941         [ResourceExposure(ResourceScope.None)]
5942         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
5943         [SuppressUnmanagedCodeSecurity]
5944         private static extern unsafe bool EqualsCaseInsensitive(void* szLhs, void* szRhs, int cSz);
5945
5946         [System.Security.SecurityCritical]  // auto-generated
5947         [ResourceExposure(ResourceScope.None)]
5948         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
5949         [SuppressUnmanagedCodeSecurity]
5950         private static extern unsafe uint HashCaseInsensitive(void* sz, int cSz);
5951
5952         [System.Security.SecurityCritical]  // auto-generated
5953         private static int GetUtf8StringByteLength(void* pUtf8String)
5954         {
5955             int len = 0;
5956
5957             unsafe
5958             {
5959                 byte* pItr = (byte*)pUtf8String;
5960
5961                 while (*pItr != 0)
5962                 {
5963                     len++;
5964                     pItr++;
5965                 }
5966             }
5967
5968             return len;
5969         }
5970
5971         [SecurityCritical]
5972         private void* m_pStringHeap;        // This is the raw UTF8 string.
5973         private int m_StringHeapByteLength;
5974
5975         [System.Security.SecurityCritical]  // auto-generated
5976         internal Utf8String(void* pStringHeap)
5977         {
5978             m_pStringHeap = pStringHeap;
5979             if (pStringHeap != null)
5980             {
5981                 m_StringHeapByteLength = GetUtf8StringByteLength(pStringHeap);
5982             }
5983             else
5984             {
5985                 m_StringHeapByteLength = 0;
5986             }
5987         }
5988
5989         [System.Security.SecurityCritical]  // auto-generated
5990         internal unsafe Utf8String(void* pUtf8String, int cUtf8String)
5991         {
5992             m_pStringHeap = pUtf8String;
5993             m_StringHeapByteLength = cUtf8String;
5994         }
5995
5996         [System.Security.SecuritySafeCritical]  // auto-generated
5997         internal unsafe bool Equals(Utf8String s)
5998         {
5999             if (m_pStringHeap == null)
6000             {
6001                 return s.m_StringHeapByteLength == 0;
6002             }
6003             if ((s.m_StringHeapByteLength == m_StringHeapByteLength) && (m_StringHeapByteLength != 0))
6004             {
6005                 return Utf8String.EqualsCaseSensitive(s.m_pStringHeap, m_pStringHeap, m_StringHeapByteLength);
6006             }
6007             return false;
6008         }
6009
6010         [System.Security.SecuritySafeCritical]  // auto-generated
6011         internal unsafe bool EqualsCaseInsensitive(Utf8String s)
6012         {
6013             if (m_pStringHeap == null)
6014             {
6015                 return s.m_StringHeapByteLength == 0;
6016             }
6017             if ((s.m_StringHeapByteLength == m_StringHeapByteLength) && (m_StringHeapByteLength != 0))
6018             {
6019                 return Utf8String.EqualsCaseInsensitive(s.m_pStringHeap, m_pStringHeap, m_StringHeapByteLength);
6020             }
6021             return false;
6022         }
6023
6024         [System.Security.SecuritySafeCritical]  // auto-generated
6025         internal unsafe uint HashCaseInsensitive()
6026         {
6027             return Utf8String.HashCaseInsensitive(m_pStringHeap, m_StringHeapByteLength);
6028         }
6029
6030         [System.Security.SecuritySafeCritical]  // auto-generated
6031         public override string ToString()
6032         {
6033             unsafe
6034             {
6035                 byte* buf = stackalloc byte[m_StringHeapByteLength];
6036                 byte* pItr = (byte*)m_pStringHeap;
6037
6038                 for (int currentPos = 0; currentPos < m_StringHeapByteLength; currentPos++)
6039                 {
6040                     buf[currentPos] = *pItr;
6041                     pItr++;
6042                 }
6043
6044                 if (m_StringHeapByteLength == 0)
6045                     return "";
6046
6047                 int cResult = Encoding.UTF8.GetCharCount(buf, m_StringHeapByteLength);
6048                 char* result = stackalloc char[cResult];
6049                 Encoding.UTF8.GetChars(buf, m_StringHeapByteLength, result, cResult);
6050                 return new string(result, 0, cResult);
6051             }
6052         }
6053     }
6054     #endregion
6055 #endif
6056 }
6057 #if !MONO
6058 namespace System.Reflection
6059 {
6060     // Reliable hashtable thread safe for multiple readers and single writer. Note that the reliability goes together with thread
6061     // safety. Thread safety for multiple readers requires atomic update of the state that also makes makes the table
6062     // reliable in the presence of asynchronous exceptions.
6063     internal struct CerHashtable<K, V> where K : class
6064     {
6065         private class Table
6066         {
6067             // Note that m_keys and m_values arrays are immutable to allow lock-free reads. A new instance 
6068             // of CerHashtable has to be allocated to grow the size of the hashtable.
6069             internal K[] m_keys;
6070             internal V[] m_values;
6071             internal int m_count;
6072
6073             internal Table(int size)
6074             {
6075                 size = HashHelpers.GetPrime(size);
6076                 m_keys = new K[size];
6077                 m_values = new V[size];
6078             }
6079
6080             internal void Insert(K key, V value)
6081             {
6082
6083                 int hashcode = GetHashCodeHelper(key);
6084                 if (hashcode < 0)
6085                     hashcode = ~hashcode;
6086
6087                 K[] keys = m_keys;
6088                 int index = hashcode % keys.Length;
6089
6090                 while (true)
6091                 {
6092                     K hit = keys[index];
6093
6094                     if (hit == null)
6095                     {
6096                         m_count++;
6097                         m_values[index] = value;
6098
6099                         // This volatile write has to be last. It is going to publish the result atomically.
6100                         //
6101                         // Note that incrementing the count or setting the value does not do any harm without setting the key. The inconsistency will be ignored 
6102                         // and it will go away completely during next rehash.
6103                         Volatile.Write(ref keys[index], key);
6104
6105                         break;
6106                     }
6107                     else
6108                     {
6109                         Contract.Assert(!hit.Equals(key), "Key was already in CerHashtable!  Potential ---- (or bug) in the Reflection cache?");
6110
6111                         index++;
6112                         if (index >= keys.Length)
6113                             index -= keys.Length;
6114                     }
6115                 }
6116             }
6117         }
6118
6119         private Table m_Table;
6120
6121         private const int MinSize = 7;
6122
6123         private static int GetHashCodeHelper(K key)
6124         {
6125             string sKey = key as string;
6126
6127             // For strings we don't want the key to differ across domains as CerHashtable might be shared.
6128             if(sKey == null)
6129             {
6130                 return key.GetHashCode(); 
6131
6132             }
6133             else
6134             {
6135                 return sKey.GetLegacyNonRandomizedHashCode();
6136             }               
6137         }
6138
6139         private void Rehash(int newSize)
6140         {
6141             Table newTable = new Table(newSize);
6142
6143             Table oldTable = m_Table;
6144             if (oldTable != null)
6145             {
6146                 K[] keys = oldTable.m_keys;
6147                 V[] values = oldTable.m_values;
6148
6149                 for (int i = 0; i < keys.Length; i++)
6150                 {
6151                     K key = keys[i];
6152
6153                     if (key != null)
6154                     {
6155                         newTable.Insert(key, values[i]);
6156                     }
6157                 }
6158             }
6159
6160             // Publish the new table atomically
6161             Volatile.Write(ref m_Table, newTable);
6162         }
6163
6164         internal V this[K key]
6165         {
6166             set
6167             {
6168                 Table table = m_Table;
6169
6170                 if (table != null)
6171                 {
6172                     int requiredSize = 2 * (table.m_count + 1);
6173                     if (requiredSize >= table.m_keys.Length)
6174                         Rehash(requiredSize);
6175                 }
6176                 else
6177                 {
6178                     Rehash(MinSize);
6179                 }
6180
6181                 m_Table.Insert(key, value);
6182             }
6183             get
6184             {
6185                 Table table = Volatile.Read(ref m_Table);
6186                 if (table == null)
6187                     return default(V);
6188
6189                 int hashcode = GetHashCodeHelper(key);
6190                 if (hashcode < 0)
6191                     hashcode = ~hashcode;
6192
6193                 K[] keys = table.m_keys;
6194                 int index = hashcode % keys.Length;
6195
6196                 while (true)
6197                 {
6198                     // This volatile read has to be first. It is reading the atomically published result.
6199                     K hit = Volatile.Read(ref keys[index]);
6200
6201                     if (hit != null)
6202                     {
6203                         if (hit.Equals(key))
6204                             return table.m_values[index];
6205
6206                         index++;
6207                         if (index >= keys.Length)
6208                             index -= keys.Length;
6209                     }
6210                     else
6211                     {
6212                         return default(V);
6213                     }
6214                 }
6215             }
6216         }
6217     }
6218 }
6219 #endif