Add IsCollectible property to Memberinfo and MethodInfo (#21155)
[platform/upstream/coreclr.git] / src / System.Private.CoreLib / src / System / RuntimeHandles.cs
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4
5 using System.Diagnostics;
6 using System.Reflection;
7 using System.Runtime.CompilerServices;
8 using System.Runtime.InteropServices;
9 using System.Runtime.Serialization;
10 using System.Threading;
11
12 namespace System
13 {
14     public unsafe struct RuntimeTypeHandle : ISerializable
15     {
16         // Returns handle for interop with EE. The handle is guaranteed to be non-null.
17         internal RuntimeTypeHandle GetNativeHandle()
18         {
19             // Create local copy to avoid a race condition
20             RuntimeType type = m_type;
21             if (type == null)
22                 throw new ArgumentNullException(null, SR.Arg_InvalidHandle);
23             return new RuntimeTypeHandle(type);
24         }
25
26         // Returns type for interop with EE. The type is guaranteed to be non-null.
27         internal RuntimeType GetTypeChecked()
28         {
29             // Create local copy to avoid a race condition
30             RuntimeType type = m_type;
31             if (type == null)
32                 throw new ArgumentNullException(null, SR.Arg_InvalidHandle);
33             return type;
34         }
35
36         [MethodImplAttribute(MethodImplOptions.InternalCall)]
37         internal static extern bool IsInstanceOfType(RuntimeType type, object o);
38
39         internal static unsafe Type GetTypeHelper(Type typeStart, Type[] genericArgs, IntPtr pModifiers, int cModifiers)
40         {
41             Type type = typeStart;
42
43             if (genericArgs != null)
44             {
45                 type = type.MakeGenericType(genericArgs);
46             }
47
48             if (cModifiers > 0)
49             {
50                 int* arModifiers = (int*)pModifiers.ToPointer();
51                 for (int i = 0; i < cModifiers; i++)
52                 {
53                     if ((CorElementType)Marshal.ReadInt32((IntPtr)arModifiers, i * sizeof(int)) == CorElementType.Ptr)
54                         type = type.MakePointerType();
55
56                     else if ((CorElementType)Marshal.ReadInt32((IntPtr)arModifiers, i * sizeof(int)) == CorElementType.ByRef)
57                         type = type.MakeByRefType();
58
59                     else if ((CorElementType)Marshal.ReadInt32((IntPtr)arModifiers, i * sizeof(int)) == CorElementType.SzArray)
60                         type = type.MakeArrayType();
61
62                     else
63                         type = type.MakeArrayType(Marshal.ReadInt32((IntPtr)arModifiers, ++i * sizeof(int)));
64                 }
65             }
66
67             return type;
68         }
69
70         public static bool operator ==(RuntimeTypeHandle left, object right) { return left.Equals(right); }
71
72         public static bool operator ==(object left, RuntimeTypeHandle right) { return right.Equals(left); }
73
74         public static bool operator !=(RuntimeTypeHandle left, object right) { return !left.Equals(right); }
75
76         public static bool operator !=(object left, RuntimeTypeHandle right) { return !right.Equals(left); }
77
78
79         // This is the RuntimeType for the type
80         private RuntimeType m_type;
81
82         public override int GetHashCode()
83         {
84             return m_type != null ? m_type.GetHashCode() : 0;
85         }
86
87         public override bool Equals(object obj)
88         {
89             if (!(obj is RuntimeTypeHandle))
90                 return false;
91
92             RuntimeTypeHandle handle = (RuntimeTypeHandle)obj;
93             return handle.m_type == m_type;
94         }
95
96         public bool Equals(RuntimeTypeHandle handle)
97         {
98             return handle.m_type == m_type;
99         }
100
101         public IntPtr Value
102         {
103             get
104             {
105                 return m_type != null ? m_type.m_handle : IntPtr.Zero;
106             }
107         }
108
109         [MethodImpl(MethodImplOptions.InternalCall)]
110         internal static extern IntPtr GetValueInternal(RuntimeTypeHandle handle);
111
112         internal RuntimeTypeHandle(RuntimeType type)
113         {
114             m_type = type;
115         }
116
117         internal static bool IsTypeDefinition(RuntimeType type)
118         {
119             CorElementType corElemType = GetCorElementType(type);
120             if (!((corElemType >= CorElementType.Void && corElemType < CorElementType.Ptr) ||
121                     corElemType == CorElementType.ValueType ||
122                     corElemType == CorElementType.Class ||
123                     corElemType == CorElementType.TypedByRef ||
124                     corElemType == CorElementType.I ||
125                     corElemType == CorElementType.U ||
126                     corElemType == CorElementType.Object))
127                 return false;
128
129             if (HasInstantiation(type) && !IsGenericTypeDefinition(type))
130                 return false;
131
132             return true;
133         }
134
135         internal static bool IsPrimitive(RuntimeType type)
136         {
137             CorElementType corElemType = GetCorElementType(type);
138             return (corElemType >= CorElementType.Boolean && corElemType <= CorElementType.R8) ||
139                     corElemType == CorElementType.I ||
140                     corElemType == CorElementType.U;
141         }
142
143         internal static bool IsByRef(RuntimeType type)
144         {
145             CorElementType corElemType = GetCorElementType(type);
146             return (corElemType == CorElementType.ByRef);
147         }
148
149         internal static bool IsPointer(RuntimeType type)
150         {
151             CorElementType corElemType = GetCorElementType(type);
152             return (corElemType == CorElementType.Ptr);
153         }
154
155         internal static bool IsArray(RuntimeType type)
156         {
157             CorElementType corElemType = GetCorElementType(type);
158             return (corElemType == CorElementType.Array || corElemType == CorElementType.SzArray);
159         }
160
161         internal static bool IsSZArray(RuntimeType type)
162         {
163             CorElementType corElemType = GetCorElementType(type);
164             return (corElemType == CorElementType.SzArray);
165         }
166
167         internal static bool HasElementType(RuntimeType type)
168         {
169             CorElementType corElemType = GetCorElementType(type);
170
171             return ((corElemType == CorElementType.Array || corElemType == CorElementType.SzArray) // IsArray
172                    || (corElemType == CorElementType.Ptr)                                          // IsPointer
173                    || (corElemType == CorElementType.ByRef));                                      // IsByRef
174         }
175
176         internal static IntPtr[] CopyRuntimeTypeHandles(RuntimeTypeHandle[] inHandles, out int length)
177         {
178             if (inHandles == null || inHandles.Length == 0)
179             {
180                 length = 0;
181                 return null;
182             }
183
184             IntPtr[] outHandles = new IntPtr[inHandles.Length];
185             for (int i = 0; i < inHandles.Length; i++)
186             {
187                 outHandles[i] = inHandles[i].Value;
188             }
189             length = outHandles.Length;
190             return outHandles;
191         }
192
193         internal static IntPtr[] CopyRuntimeTypeHandles(Type[] inHandles, out int length)
194         {
195             if (inHandles == null || inHandles.Length == 0)
196             {
197                 length = 0;
198                 return null;
199             }
200
201             IntPtr[] outHandles = new IntPtr[inHandles.Length];
202             for (int i = 0; i < inHandles.Length; i++)
203             {
204                 outHandles[i] = inHandles[i].GetTypeHandleInternal().Value;
205             }
206             length = outHandles.Length;
207             return outHandles;
208         }
209
210         [MethodImplAttribute(MethodImplOptions.InternalCall)]
211         internal static extern object CreateInstance(RuntimeType type, bool publicOnly, bool wrapExceptions, ref bool canBeCached, ref RuntimeMethodHandleInternal ctor, ref bool hasNoDefaultCtor);
212
213         [MethodImplAttribute(MethodImplOptions.InternalCall)]
214         internal static extern object CreateCaInstance(RuntimeType type, IRuntimeMethodInfo ctor);
215
216         [MethodImplAttribute(MethodImplOptions.InternalCall)]
217         internal static extern object Allocate(RuntimeType type);
218
219         [MethodImplAttribute(MethodImplOptions.InternalCall)]
220         internal static extern object CreateInstanceForAnotherGenericParameter(RuntimeType type, RuntimeType genericParameter);
221
222         internal RuntimeType GetRuntimeType()
223         {
224             return m_type;
225         }
226
227         [MethodImplAttribute(MethodImplOptions.InternalCall)]
228         internal static extern CorElementType GetCorElementType(RuntimeType type);
229
230         [MethodImplAttribute(MethodImplOptions.InternalCall)]
231         internal static extern RuntimeAssembly GetAssembly(RuntimeType type);
232
233         [MethodImplAttribute(MethodImplOptions.InternalCall)]
234         internal static extern RuntimeModule GetModule(RuntimeType type);
235
236         public ModuleHandle GetModuleHandle()
237         {
238             return new ModuleHandle(RuntimeTypeHandle.GetModule(m_type));
239         }
240
241         [MethodImplAttribute(MethodImplOptions.InternalCall)]
242         internal static extern RuntimeType GetBaseType(RuntimeType type);
243
244         [MethodImplAttribute(MethodImplOptions.InternalCall)]
245         internal static extern TypeAttributes GetAttributes(RuntimeType type);
246
247         [MethodImplAttribute(MethodImplOptions.InternalCall)]
248         internal static extern RuntimeType GetElementType(RuntimeType type);
249
250         [MethodImplAttribute(MethodImplOptions.InternalCall)]
251         internal static extern bool CompareCanonicalHandles(RuntimeType left, RuntimeType right);
252
253         [MethodImplAttribute(MethodImplOptions.InternalCall)]
254         internal static extern int GetArrayRank(RuntimeType type);
255
256         [MethodImplAttribute(MethodImplOptions.InternalCall)]
257         internal static extern int GetToken(RuntimeType type);
258
259         [MethodImplAttribute(MethodImplOptions.InternalCall)]
260         internal static extern RuntimeMethodHandleInternal GetMethodAt(RuntimeType type, int slot);
261
262         // This is managed wrapper for MethodTable::IntroducedMethodIterator
263         internal struct IntroducedMethodEnumerator
264         {
265             private bool _firstCall;
266             private RuntimeMethodHandleInternal _handle;
267
268             internal IntroducedMethodEnumerator(RuntimeType type)
269             {
270                 _handle = RuntimeTypeHandle.GetFirstIntroducedMethod(type);
271                 _firstCall = true;
272             }
273
274             public bool MoveNext()
275             {
276                 if (_firstCall)
277                 {
278                     _firstCall = false;
279                 }
280                 else if (_handle.Value != IntPtr.Zero)
281                 {
282                     RuntimeTypeHandle.GetNextIntroducedMethod(ref _handle);
283                 }
284                 return !(_handle.Value == IntPtr.Zero);
285             }
286
287             public RuntimeMethodHandleInternal Current
288             {
289                 get
290                 {
291                     return _handle;
292                 }
293             }
294
295             // Glue to make this work nicely with C# foreach statement
296             public IntroducedMethodEnumerator GetEnumerator()
297             {
298                 return this;
299             }
300         }
301
302         internal static IntroducedMethodEnumerator GetIntroducedMethods(RuntimeType type)
303         {
304             return new IntroducedMethodEnumerator(type);
305         }
306
307         [MethodImplAttribute(MethodImplOptions.InternalCall)]
308         private static extern RuntimeMethodHandleInternal GetFirstIntroducedMethod(RuntimeType type);
309
310         [MethodImplAttribute(MethodImplOptions.InternalCall)]
311         private static extern void GetNextIntroducedMethod(ref RuntimeMethodHandleInternal method);
312
313         [MethodImplAttribute(MethodImplOptions.InternalCall)]
314         internal static extern bool GetFields(RuntimeType type, IntPtr* result, int* count);
315
316         [MethodImplAttribute(MethodImplOptions.InternalCall)]
317         internal static extern Type[] GetInterfaces(RuntimeType type);
318
319         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
320         private static extern void GetConstraints(RuntimeTypeHandle handle, ObjectHandleOnStack types);
321
322         internal Type[] GetConstraints()
323         {
324             Type[] types = null;
325             GetConstraints(GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref types));
326
327             return types;
328         }
329
330         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
331         private static extern IntPtr GetGCHandle(RuntimeTypeHandle handle, GCHandleType type);
332
333         internal IntPtr GetGCHandle(GCHandleType type)
334         {
335             return GetGCHandle(GetNativeHandle(), type);
336         }
337
338         [MethodImplAttribute(MethodImplOptions.InternalCall)]
339         internal static extern int GetNumVirtuals(RuntimeType type);
340
341         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
342         private static extern void VerifyInterfaceIsImplemented(RuntimeTypeHandle handle, RuntimeTypeHandle interfaceHandle);
343
344         internal void VerifyInterfaceIsImplemented(RuntimeTypeHandle interfaceHandle)
345         {
346             VerifyInterfaceIsImplemented(GetNativeHandle(), interfaceHandle.GetNativeHandle());
347         }
348
349         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
350         private static extern RuntimeMethodHandleInternal GetInterfaceMethodImplementation(RuntimeTypeHandle handle, RuntimeTypeHandle interfaceHandle, RuntimeMethodHandleInternal interfaceMethodHandle);
351
352         internal RuntimeMethodHandleInternal GetInterfaceMethodImplementation(RuntimeTypeHandle interfaceHandle, RuntimeMethodHandleInternal interfaceMethodHandle)
353         {
354             return GetInterfaceMethodImplementation(GetNativeHandle(), interfaceHandle.GetNativeHandle(), interfaceMethodHandle);
355         }
356
357         [MethodImplAttribute(MethodImplOptions.InternalCall)]
358         internal static extern bool IsComObject(RuntimeType type, bool isGenericCOM);
359
360         [MethodImplAttribute(MethodImplOptions.InternalCall)]
361         internal static extern bool IsInterface(RuntimeType type);
362
363         [MethodImplAttribute(MethodImplOptions.InternalCall)]
364         internal static extern bool IsByRefLike(RuntimeType type);
365
366         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
367         [return: MarshalAs(UnmanagedType.Bool)]
368         private static extern bool _IsVisible(RuntimeTypeHandle typeHandle);
369
370         internal static bool IsVisible(RuntimeType type)
371         {
372             return _IsVisible(new RuntimeTypeHandle(type));
373         }
374
375         [MethodImplAttribute(MethodImplOptions.InternalCall)]
376         internal static extern bool IsValueType(RuntimeType type);
377
378         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
379         private static extern void ConstructName(RuntimeTypeHandle handle, TypeNameFormatFlags formatFlags, StringHandleOnStack retString);
380
381         internal string ConstructName(TypeNameFormatFlags formatFlags)
382         {
383             string name = null;
384             ConstructName(GetNativeHandle(), formatFlags, JitHelpers.GetStringHandleOnStack(ref name));
385             return name;
386         }
387
388         [MethodImplAttribute(MethodImplOptions.InternalCall)]
389         private static extern void* _GetUtf8Name(RuntimeType type);
390
391         internal static MdUtf8String GetUtf8Name(RuntimeType type)
392         {
393             return new MdUtf8String(_GetUtf8Name(type));
394         }
395
396         [MethodImplAttribute(MethodImplOptions.InternalCall)]
397         internal static extern bool CanCastTo(RuntimeType type, RuntimeType target);
398
399         [MethodImplAttribute(MethodImplOptions.InternalCall)]
400         internal static extern RuntimeType GetDeclaringType(RuntimeType type);
401
402         [MethodImplAttribute(MethodImplOptions.InternalCall)]
403         internal static extern IRuntimeMethodInfo GetDeclaringMethod(RuntimeType type);
404
405         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
406         private static extern void GetDefaultConstructor(RuntimeTypeHandle handle, ObjectHandleOnStack method);
407
408         internal IRuntimeMethodInfo GetDefaultConstructor()
409         {
410             IRuntimeMethodInfo ctor = null;
411             GetDefaultConstructor(GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref ctor));
412             return ctor;
413         }
414
415         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
416         private static extern void GetTypeByName(string name, bool throwOnError, bool ignoreCase, StackCrawlMarkHandle stackMark,
417             IntPtr pPrivHostBinder,
418             bool loadTypeFromPartialName, ObjectHandleOnStack type, ObjectHandleOnStack keepalive);
419
420         // Wrapper function to reduce the need for ifdefs.
421         internal static RuntimeType GetTypeByName(string name, bool throwOnError, bool ignoreCase, ref StackCrawlMark stackMark, bool loadTypeFromPartialName)
422         {
423             return GetTypeByName(name, throwOnError, ignoreCase, ref stackMark, IntPtr.Zero, loadTypeFromPartialName);
424         }
425
426         internal static RuntimeType GetTypeByName(string name, bool throwOnError, bool ignoreCase, ref StackCrawlMark stackMark,
427                                                   IntPtr pPrivHostBinder,
428                                                   bool loadTypeFromPartialName)
429         {
430             if (name == null || name.Length == 0)
431             {
432                 if (throwOnError)
433                     throw new TypeLoadException(SR.Arg_TypeLoadNullStr);
434
435                 return null;
436             }
437
438             RuntimeType type = null;
439
440             object keepAlive = null;
441             GetTypeByName(name, throwOnError, ignoreCase,
442                 JitHelpers.GetStackCrawlMarkHandle(ref stackMark),
443                 pPrivHostBinder,
444                 loadTypeFromPartialName, JitHelpers.GetObjectHandleOnStack(ref type), JitHelpers.GetObjectHandleOnStack(ref keepAlive));
445             GC.KeepAlive(keepAlive);
446
447             return type;
448         }
449
450         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
451         private static extern void GetTypeByNameUsingCARules(string name, RuntimeModule scope, ObjectHandleOnStack type);
452
453         internal static RuntimeType GetTypeByNameUsingCARules(string name, RuntimeModule scope)
454         {
455             if (name == null || name.Length == 0)
456                 throw new ArgumentException(null, nameof(name));
457
458             RuntimeType type = null;
459             GetTypeByNameUsingCARules(name, scope.GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref type));
460
461             return type;
462         }
463
464         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
465         internal static extern void GetInstantiation(RuntimeTypeHandle type, ObjectHandleOnStack types, bool fAsRuntimeTypeArray);
466
467         internal RuntimeType[] GetInstantiationInternal()
468         {
469             RuntimeType[] types = null;
470             GetInstantiation(GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref types), true);
471             return types;
472         }
473
474         internal Type[] GetInstantiationPublic()
475         {
476             Type[] types = null;
477             GetInstantiation(GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref types), false);
478             return types;
479         }
480
481         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
482         private static extern void Instantiate(RuntimeTypeHandle handle, IntPtr* pInst, int numGenericArgs, ObjectHandleOnStack type);
483
484         internal RuntimeType Instantiate(Type[] inst)
485         {
486             // defensive copy to be sure array is not mutated from the outside during processing
487             int instCount;
488             IntPtr[] instHandles = CopyRuntimeTypeHandles(inst, out instCount);
489
490             fixed (IntPtr* pInst = instHandles)
491             {
492                 RuntimeType type = null;
493                 Instantiate(GetNativeHandle(), pInst, instCount, JitHelpers.GetObjectHandleOnStack(ref type));
494                 GC.KeepAlive(inst);
495                 return type;
496             }
497         }
498
499         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
500         private static extern void MakeArray(RuntimeTypeHandle handle, int rank, ObjectHandleOnStack type);
501
502         internal RuntimeType MakeArray(int rank)
503         {
504             RuntimeType type = null;
505             MakeArray(GetNativeHandle(), rank, JitHelpers.GetObjectHandleOnStack(ref type));
506             return type;
507         }
508
509         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
510         private static extern void MakeSZArray(RuntimeTypeHandle handle, ObjectHandleOnStack type);
511
512         internal RuntimeType MakeSZArray()
513         {
514             RuntimeType type = null;
515             MakeSZArray(GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref type));
516             return type;
517         }
518
519         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
520         private static extern void MakeByRef(RuntimeTypeHandle handle, ObjectHandleOnStack type);
521
522         internal RuntimeType MakeByRef()
523         {
524             RuntimeType type = null;
525             MakeByRef(GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref type));
526             return type;
527         }
528
529         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
530         private static extern void MakePointer(RuntimeTypeHandle handle, ObjectHandleOnStack type);
531
532         internal RuntimeType MakePointer()
533         {
534             RuntimeType type = null;
535             MakePointer(GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref type));
536             return type;
537         }
538
539         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
540         internal static extern bool IsCollectible(RuntimeTypeHandle handle);
541
542         [MethodImplAttribute(MethodImplOptions.InternalCall)]
543         internal static extern bool HasInstantiation(RuntimeType type);
544
545         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
546         private static extern void GetGenericTypeDefinition(RuntimeTypeHandle type, ObjectHandleOnStack retType);
547
548         internal static RuntimeType GetGenericTypeDefinition(RuntimeType type)
549         {
550             RuntimeType retType = type;
551
552             if (HasInstantiation(retType) && !IsGenericTypeDefinition(retType))
553                 GetGenericTypeDefinition(retType.GetTypeHandleInternal(), JitHelpers.GetObjectHandleOnStack(ref retType));
554
555             return retType;
556         }
557
558         [MethodImplAttribute(MethodImplOptions.InternalCall)]
559         internal static extern bool IsGenericTypeDefinition(RuntimeType type);
560
561         [MethodImplAttribute(MethodImplOptions.InternalCall)]
562         internal static extern bool IsGenericVariable(RuntimeType type);
563
564         [MethodImplAttribute(MethodImplOptions.InternalCall)]
565         private static extern int GetGenericVariableIndex(RuntimeType type);
566
567         internal int GetGenericVariableIndex()
568         {
569             RuntimeType type = GetTypeChecked();
570
571             if (!IsGenericVariable(type))
572                 throw new InvalidOperationException(SR.Arg_NotGenericParameter);
573
574             return GetGenericVariableIndex(type);
575         }
576
577         [MethodImplAttribute(MethodImplOptions.InternalCall)]
578         internal static extern bool ContainsGenericVariables(RuntimeType handle);
579
580         internal bool ContainsGenericVariables()
581         {
582             return ContainsGenericVariables(GetTypeChecked());
583         }
584
585         [MethodImplAttribute(MethodImplOptions.InternalCall)]
586         private static extern bool SatisfiesConstraints(RuntimeType paramType, IntPtr* pTypeContext, int typeContextLength, IntPtr* pMethodContext, int methodContextLength, RuntimeType toType);
587
588         internal static bool SatisfiesConstraints(RuntimeType paramType, RuntimeType[] typeContext, RuntimeType[] methodContext, RuntimeType toType)
589         {
590             int typeContextLength;
591             int methodContextLength;
592             IntPtr[] typeContextHandles = CopyRuntimeTypeHandles(typeContext, out typeContextLength);
593             IntPtr[] methodContextHandles = CopyRuntimeTypeHandles(methodContext, out methodContextLength);
594
595             fixed (IntPtr* pTypeContextHandles = typeContextHandles, pMethodContextHandles = methodContextHandles)
596             {
597                 bool result = SatisfiesConstraints(paramType, pTypeContextHandles, typeContextLength, pMethodContextHandles, methodContextLength, toType);
598
599                 GC.KeepAlive(typeContext);
600                 GC.KeepAlive(methodContext);
601
602                 return result;
603             }
604         }
605
606         [MethodImplAttribute(MethodImplOptions.InternalCall)]
607         private static extern IntPtr _GetMetadataImport(RuntimeType type);
608
609         internal static MetadataImport GetMetadataImport(RuntimeType type)
610         {
611             return new MetadataImport(_GetMetadataImport(type), type);
612         }
613
614         public void GetObjectData(SerializationInfo info, StreamingContext context)
615         {
616             throw new PlatformNotSupportedException();
617         }
618     }
619
620     // This type is used to remove the expense of having a managed reference object that is dynamically 
621     // created when we can prove that we don't need that object. Use of this type requires code to ensure
622     // that the underlying native resource is not freed. 
623     // Cases in which this may be used:
624     //  1. When native code calls managed code passing one of these as a parameter
625     //  2. When managed code acquires one of these from an IRuntimeMethodInfo, and ensure that the IRuntimeMethodInfo is preserved
626     //     across the lifetime of the RuntimeMethodHandleInternal instance
627     //  3. When another object is used to keep the RuntimeMethodHandleInternal alive. See delegates, CreateInstance cache, Signature structure
628     // When in doubt, do not use. 
629     internal struct RuntimeMethodHandleInternal
630     {
631         internal static RuntimeMethodHandleInternal EmptyHandle
632         {
633             get
634             {
635                 return new RuntimeMethodHandleInternal();
636             }
637         }
638
639         internal bool IsNullHandle()
640         {
641             return m_handle == IntPtr.Zero;
642         }
643
644         internal IntPtr Value
645         {
646             get
647             {
648                 return m_handle;
649             }
650         }
651
652         internal RuntimeMethodHandleInternal(IntPtr value)
653         {
654             m_handle = value;
655         }
656
657         internal IntPtr m_handle;
658     }
659
660     internal class RuntimeMethodInfoStub : IRuntimeMethodInfo
661     {
662         public RuntimeMethodInfoStub(RuntimeMethodHandleInternal methodHandleValue, object keepalive)
663         {
664             m_keepalive = keepalive;
665             m_value = methodHandleValue;
666         }
667
668         public RuntimeMethodInfoStub(IntPtr methodHandleValue, object keepalive)
669         {
670             m_keepalive = keepalive;
671             m_value = new RuntimeMethodHandleInternal(methodHandleValue);
672         }
673
674         private object m_keepalive;
675
676         // These unused variables are used to ensure that this class has the same layout as RuntimeMethodInfo
677 #pragma warning disable 169
678         private object m_a;
679         private object m_b;
680         private object m_c;
681         private object m_d;
682         private object m_e;
683         private object m_f;
684         private object m_g;
685 #pragma warning restore 169
686
687         public RuntimeMethodHandleInternal m_value;
688
689         RuntimeMethodHandleInternal IRuntimeMethodInfo.Value
690         {
691             get
692             {
693                 return m_value;
694             }
695         }
696     }
697
698     internal interface IRuntimeMethodInfo
699     {
700         RuntimeMethodHandleInternal Value
701         {
702             get;
703         }
704     }
705
706     public unsafe struct RuntimeMethodHandle : ISerializable
707     {
708         // Returns handle for interop with EE. The handle is guaranteed to be non-null.
709         internal static IRuntimeMethodInfo EnsureNonNullMethodInfo(IRuntimeMethodInfo method)
710         {
711             if (method == null)
712                 throw new ArgumentNullException(null, SR.Arg_InvalidHandle);
713             return method;
714         }
715
716         private IRuntimeMethodInfo m_value;
717
718         internal RuntimeMethodHandle(IRuntimeMethodInfo method)
719         {
720             m_value = method;
721         }
722
723         internal IRuntimeMethodInfo GetMethodInfo()
724         {
725             return m_value;
726         }
727
728         // Used by EE
729         private static IntPtr GetValueInternal(RuntimeMethodHandle rmh)
730         {
731             return rmh.Value;
732         }
733
734         // ISerializable interface
735         public void GetObjectData(SerializationInfo info, StreamingContext context)
736         {
737             throw new PlatformNotSupportedException();
738         }
739
740         public IntPtr Value
741         {
742             get
743             {
744                 return m_value != null ? m_value.Value.Value : IntPtr.Zero;
745             }
746         }
747
748         public override int GetHashCode()
749         {
750             return ValueType.GetHashCodeOfPtr(Value);
751         }
752
753         public override bool Equals(object obj)
754         {
755             if (!(obj is RuntimeMethodHandle))
756                 return false;
757
758             RuntimeMethodHandle handle = (RuntimeMethodHandle)obj;
759
760             return handle.Value == Value;
761         }
762
763         public static bool operator ==(RuntimeMethodHandle left, RuntimeMethodHandle right)
764         {
765             return left.Equals(right);
766         }
767
768         public static bool operator !=(RuntimeMethodHandle left, RuntimeMethodHandle right)
769         {
770             return !left.Equals(right);
771         }
772
773         public bool Equals(RuntimeMethodHandle handle)
774         {
775             return handle.Value == Value;
776         }
777
778         internal bool IsNullHandle()
779         {
780             return m_value == null;
781         }
782
783         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
784         internal static extern IntPtr GetFunctionPointer(RuntimeMethodHandleInternal handle);
785
786         public IntPtr GetFunctionPointer()
787         {
788             IntPtr ptr = GetFunctionPointer(EnsureNonNullMethodInfo(m_value).Value);
789             GC.KeepAlive(m_value);
790             return ptr;
791         }
792
793         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
794         [return: MarshalAs(UnmanagedType.Bool)]
795         internal static extern bool GetIsCollectible(RuntimeMethodHandleInternal handle);
796
797         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
798         internal static extern bool IsCAVisibleFromDecoratedType(
799             RuntimeTypeHandle attrTypeHandle,
800             IRuntimeMethodInfo attrCtor,
801             RuntimeTypeHandle sourceTypeHandle,
802             RuntimeModule sourceModule);
803
804         [MethodImplAttribute(MethodImplOptions.InternalCall)]
805         private static extern IRuntimeMethodInfo _GetCurrentMethod(ref StackCrawlMark stackMark);
806         internal static IRuntimeMethodInfo GetCurrentMethod(ref StackCrawlMark stackMark)
807         {
808             return _GetCurrentMethod(ref stackMark);
809         }
810
811         [MethodImplAttribute(MethodImplOptions.InternalCall)]
812         internal static extern MethodAttributes GetAttributes(RuntimeMethodHandleInternal method);
813
814         internal static MethodAttributes GetAttributes(IRuntimeMethodInfo method)
815         {
816             MethodAttributes retVal = RuntimeMethodHandle.GetAttributes(method.Value);
817             GC.KeepAlive(method);
818             return retVal;
819         }
820
821         [MethodImplAttribute(MethodImplOptions.InternalCall)]
822         internal static extern MethodImplAttributes GetImplAttributes(IRuntimeMethodInfo method);
823
824         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
825         private static extern void ConstructInstantiation(IRuntimeMethodInfo method, TypeNameFormatFlags format, StringHandleOnStack retString);
826
827         internal static string ConstructInstantiation(IRuntimeMethodInfo method, TypeNameFormatFlags format)
828         {
829             string name = null;
830             ConstructInstantiation(EnsureNonNullMethodInfo(method), format, JitHelpers.GetStringHandleOnStack(ref name));
831             return name;
832         }
833
834         [MethodImplAttribute(MethodImplOptions.InternalCall)]
835         internal static extern RuntimeType GetDeclaringType(RuntimeMethodHandleInternal method);
836
837         internal static RuntimeType GetDeclaringType(IRuntimeMethodInfo method)
838         {
839             RuntimeType type = RuntimeMethodHandle.GetDeclaringType(method.Value);
840             GC.KeepAlive(method);
841             return type;
842         }
843
844         [MethodImplAttribute(MethodImplOptions.InternalCall)]
845         internal static extern int GetSlot(RuntimeMethodHandleInternal method);
846
847         internal static int GetSlot(IRuntimeMethodInfo method)
848         {
849             Debug.Assert(method != null);
850
851             int slot = RuntimeMethodHandle.GetSlot(method.Value);
852             GC.KeepAlive(method);
853             return slot;
854         }
855
856         [MethodImplAttribute(MethodImplOptions.InternalCall)]
857         internal static extern int GetMethodDef(IRuntimeMethodInfo method);
858
859         [MethodImplAttribute(MethodImplOptions.InternalCall)]
860         internal static extern string GetName(RuntimeMethodHandleInternal method);
861
862         internal static string GetName(IRuntimeMethodInfo method)
863         {
864             string name = RuntimeMethodHandle.GetName(method.Value);
865             GC.KeepAlive(method);
866             return name;
867         }
868
869         [MethodImplAttribute(MethodImplOptions.InternalCall)]
870         private static extern void* _GetUtf8Name(RuntimeMethodHandleInternal method);
871
872         internal static MdUtf8String GetUtf8Name(RuntimeMethodHandleInternal method)
873         {
874             return new MdUtf8String(_GetUtf8Name(method));
875         }
876
877         [MethodImplAttribute(MethodImplOptions.InternalCall)]
878         internal static extern bool MatchesNameHash(RuntimeMethodHandleInternal method, uint hash);
879
880         [DebuggerStepThroughAttribute]
881         [Diagnostics.DebuggerHidden]
882         [MethodImplAttribute(MethodImplOptions.InternalCall)]
883         internal static extern object InvokeMethod(object target, object[] arguments, Signature sig, bool constructor, bool wrapExceptions);
884
885         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
886         private static extern void GetMethodInstantiation(RuntimeMethodHandleInternal method, ObjectHandleOnStack types, bool fAsRuntimeTypeArray);
887
888         internal static RuntimeType[] GetMethodInstantiationInternal(IRuntimeMethodInfo method)
889         {
890             RuntimeType[] types = null;
891             GetMethodInstantiation(EnsureNonNullMethodInfo(method).Value, JitHelpers.GetObjectHandleOnStack(ref types), true);
892             GC.KeepAlive(method);
893             return types;
894         }
895
896         internal static RuntimeType[] GetMethodInstantiationInternal(RuntimeMethodHandleInternal method)
897         {
898             RuntimeType[] types = null;
899             GetMethodInstantiation(method, JitHelpers.GetObjectHandleOnStack(ref types), true);
900             return types;
901         }
902
903         internal static Type[] GetMethodInstantiationPublic(IRuntimeMethodInfo method)
904         {
905             RuntimeType[] types = null;
906             GetMethodInstantiation(EnsureNonNullMethodInfo(method).Value, JitHelpers.GetObjectHandleOnStack(ref types), false);
907             GC.KeepAlive(method);
908             return types;
909         }
910
911         [MethodImplAttribute(MethodImplOptions.InternalCall)]
912         internal static extern bool HasMethodInstantiation(RuntimeMethodHandleInternal method);
913
914         internal static bool HasMethodInstantiation(IRuntimeMethodInfo method)
915         {
916             bool fRet = RuntimeMethodHandle.HasMethodInstantiation(method.Value);
917             GC.KeepAlive(method);
918             return fRet;
919         }
920
921         [MethodImplAttribute(MethodImplOptions.InternalCall)]
922         internal static extern RuntimeMethodHandleInternal GetStubIfNeeded(RuntimeMethodHandleInternal method, RuntimeType declaringType, RuntimeType[] methodInstantiation);
923
924         [MethodImplAttribute(MethodImplOptions.InternalCall)]
925         internal static extern RuntimeMethodHandleInternal GetMethodFromCanonical(RuntimeMethodHandleInternal method, RuntimeType declaringType);
926
927         [MethodImplAttribute(MethodImplOptions.InternalCall)]
928         internal static extern bool IsGenericMethodDefinition(RuntimeMethodHandleInternal method);
929
930         internal static bool IsGenericMethodDefinition(IRuntimeMethodInfo method)
931         {
932             bool fRet = RuntimeMethodHandle.IsGenericMethodDefinition(method.Value);
933             GC.KeepAlive(method);
934             return fRet;
935         }
936
937         [MethodImplAttribute(MethodImplOptions.InternalCall)]
938         internal static extern bool IsTypicalMethodDefinition(IRuntimeMethodInfo method);
939
940         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
941         private static extern void GetTypicalMethodDefinition(IRuntimeMethodInfo method, ObjectHandleOnStack outMethod);
942
943         internal static IRuntimeMethodInfo GetTypicalMethodDefinition(IRuntimeMethodInfo method)
944         {
945             if (!IsTypicalMethodDefinition(method))
946                 GetTypicalMethodDefinition(method, JitHelpers.GetObjectHandleOnStack(ref method));
947
948             return method;
949         }
950
951         [MethodImplAttribute(MethodImplOptions.InternalCall)]
952         private static extern int GetGenericParameterCount(RuntimeMethodHandleInternal method);
953
954         internal static int GetGenericParameterCount(IRuntimeMethodInfo method) => GetGenericParameterCount(method.Value);
955
956         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
957         private static extern void StripMethodInstantiation(IRuntimeMethodInfo method, ObjectHandleOnStack outMethod);
958
959         internal static IRuntimeMethodInfo StripMethodInstantiation(IRuntimeMethodInfo method)
960         {
961             IRuntimeMethodInfo strippedMethod = method;
962
963             StripMethodInstantiation(method, JitHelpers.GetObjectHandleOnStack(ref strippedMethod));
964
965             return strippedMethod;
966         }
967
968         [MethodImplAttribute(MethodImplOptions.InternalCall)]
969         internal static extern bool IsDynamicMethod(RuntimeMethodHandleInternal method);
970
971         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
972         internal static extern void Destroy(RuntimeMethodHandleInternal method);
973
974         [MethodImplAttribute(MethodImplOptions.InternalCall)]
975         internal static extern Resolver GetResolver(RuntimeMethodHandleInternal method);
976
977         [MethodImpl(MethodImplOptions.InternalCall)]
978         internal static extern RuntimeMethodBody GetMethodBody(IRuntimeMethodInfo method, RuntimeType declaringType);
979
980         [MethodImpl(MethodImplOptions.InternalCall)]
981         internal static extern bool IsConstructor(RuntimeMethodHandleInternal method);
982
983         [MethodImpl(MethodImplOptions.InternalCall)]
984         internal static extern LoaderAllocator GetLoaderAllocator(RuntimeMethodHandleInternal method);
985     }
986
987     // This type is used to remove the expense of having a managed reference object that is dynamically 
988     // created when we can prove that we don't need that object. Use of this type requires code to ensure
989     // that the underlying native resource is not freed. 
990     // Cases in which this may be used:
991     //  1. When native code calls managed code passing one of these as a parameter
992     //  2. When managed code acquires one of these from an RtFieldInfo, and ensure that the RtFieldInfo is preserved
993     //     across the lifetime of the RuntimeFieldHandleInternal instance
994     //  3. When another object is used to keep the RuntimeFieldHandleInternal alive.
995     // When in doubt, do not use. 
996     internal struct RuntimeFieldHandleInternal
997     {
998         internal bool IsNullHandle()
999         {
1000             return m_handle == IntPtr.Zero;
1001         }
1002
1003         internal IntPtr Value
1004         {
1005             get
1006             {
1007                 return m_handle;
1008             }
1009         }
1010
1011         internal RuntimeFieldHandleInternal(IntPtr value)
1012         {
1013             m_handle = value;
1014         }
1015
1016         internal IntPtr m_handle;
1017     }
1018
1019     internal interface IRuntimeFieldInfo
1020     {
1021         RuntimeFieldHandleInternal Value
1022         {
1023             get;
1024         }
1025     }
1026
1027     [StructLayout(LayoutKind.Sequential)]
1028     internal class RuntimeFieldInfoStub : IRuntimeFieldInfo
1029     {
1030         // These unused variables are used to ensure that this class has the same layout as RuntimeFieldInfo
1031 #pragma warning disable 169
1032         private object m_keepalive;
1033         private object m_c;
1034         private object m_d;
1035         private int m_b;
1036         private object m_e;
1037         private RuntimeFieldHandleInternal m_fieldHandle;
1038 #pragma warning restore 169
1039
1040         RuntimeFieldHandleInternal IRuntimeFieldInfo.Value
1041         {
1042             get
1043             {
1044                 return m_fieldHandle;
1045             }
1046         }
1047     }
1048
1049     public unsafe struct RuntimeFieldHandle : ISerializable
1050     {
1051         // Returns handle for interop with EE. The handle is guaranteed to be non-null.
1052         internal RuntimeFieldHandle GetNativeHandle()
1053         {
1054             // Create local copy to avoid a race condition
1055             IRuntimeFieldInfo field = m_ptr;
1056             if (field == null)
1057                 throw new ArgumentNullException(null, SR.Arg_InvalidHandle);
1058             return new RuntimeFieldHandle(field);
1059         }
1060
1061         private IRuntimeFieldInfo m_ptr;
1062
1063         internal RuntimeFieldHandle(IRuntimeFieldInfo fieldInfo)
1064         {
1065             m_ptr = fieldInfo;
1066         }
1067
1068         internal IRuntimeFieldInfo GetRuntimeFieldInfo()
1069         {
1070             return m_ptr;
1071         }
1072
1073         public IntPtr Value
1074         {
1075             get
1076             {
1077                 return m_ptr != null ? m_ptr.Value.Value : IntPtr.Zero;
1078             }
1079         }
1080
1081         internal bool IsNullHandle()
1082         {
1083             return m_ptr == null;
1084         }
1085
1086         public override int GetHashCode()
1087         {
1088             return ValueType.GetHashCodeOfPtr(Value);
1089         }
1090
1091         public override bool Equals(object obj)
1092         {
1093             if (!(obj is RuntimeFieldHandle))
1094                 return false;
1095
1096             RuntimeFieldHandle handle = (RuntimeFieldHandle)obj;
1097
1098             return handle.Value == Value;
1099         }
1100
1101         public unsafe bool Equals(RuntimeFieldHandle handle)
1102         {
1103             return handle.Value == Value;
1104         }
1105
1106         public static bool operator ==(RuntimeFieldHandle left, RuntimeFieldHandle right)
1107         {
1108             return left.Equals(right);
1109         }
1110
1111         public static bool operator !=(RuntimeFieldHandle left, RuntimeFieldHandle right)
1112         {
1113             return !left.Equals(right);
1114         }
1115
1116         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1117         internal static extern string GetName(RtFieldInfo field);
1118
1119         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1120         private static extern unsafe void* _GetUtf8Name(RuntimeFieldHandleInternal field);
1121
1122         internal static unsafe MdUtf8String GetUtf8Name(RuntimeFieldHandleInternal field) { return new MdUtf8String(_GetUtf8Name(field)); }
1123
1124         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1125         internal static extern bool MatchesNameHash(RuntimeFieldHandleInternal handle, uint hash);
1126
1127         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1128         internal static extern FieldAttributes GetAttributes(RuntimeFieldHandleInternal field);
1129
1130         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1131         internal static extern RuntimeType GetApproxDeclaringType(RuntimeFieldHandleInternal field);
1132
1133         internal static RuntimeType GetApproxDeclaringType(IRuntimeFieldInfo field)
1134         {
1135             RuntimeType type = GetApproxDeclaringType(field.Value);
1136             GC.KeepAlive(field);
1137             return type;
1138         }
1139
1140         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1141         internal static extern int GetToken(RtFieldInfo field);
1142
1143         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1144         internal static extern object GetValue(RtFieldInfo field, object instance, RuntimeType fieldType, RuntimeType declaringType, ref bool domainInitialized);
1145
1146         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1147         internal static extern object GetValueDirect(RtFieldInfo field, RuntimeType fieldType, void* pTypedRef, RuntimeType contextType);
1148
1149         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1150         internal static extern void SetValue(RtFieldInfo field, object obj, object value, RuntimeType fieldType, FieldAttributes fieldAttr, RuntimeType declaringType, ref bool domainInitialized);
1151
1152         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1153         internal static extern void SetValueDirect(RtFieldInfo field, RuntimeType fieldType, void* pTypedRef, object value, RuntimeType contextType);
1154
1155         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1156         internal static extern RuntimeFieldHandleInternal GetStaticFieldForGenericType(RuntimeFieldHandleInternal field, RuntimeType declaringType);
1157
1158         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1159         internal static extern bool AcquiresContextFromThis(RuntimeFieldHandleInternal field);
1160
1161         // ISerializable interface
1162         public void GetObjectData(SerializationInfo info, StreamingContext context)
1163         {
1164             throw new PlatformNotSupportedException();
1165         }
1166     }
1167
1168     public unsafe struct ModuleHandle
1169     {
1170         // Returns handle for interop with EE. The handle is guaranteed to be non-null.
1171         #region Public Static Members
1172         public static readonly ModuleHandle EmptyHandle = GetEmptyMH();
1173         #endregion
1174
1175         unsafe private static ModuleHandle GetEmptyMH()
1176         {
1177             return new ModuleHandle();
1178         }
1179
1180         #region Private Data Members
1181         private RuntimeModule m_ptr;
1182         #endregion
1183
1184         #region Constructor
1185         internal ModuleHandle(RuntimeModule module)
1186         {
1187             m_ptr = module;
1188         }
1189         #endregion
1190
1191         #region Internal FCalls
1192
1193         internal RuntimeModule GetRuntimeModule()
1194         {
1195             return m_ptr;
1196         }
1197
1198         public override int GetHashCode()
1199         {
1200             return m_ptr != null ? m_ptr.GetHashCode() : 0;
1201         }
1202
1203         public override bool Equals(object obj)
1204         {
1205             if (!(obj is ModuleHandle))
1206                 return false;
1207
1208             ModuleHandle handle = (ModuleHandle)obj;
1209
1210             return handle.m_ptr == m_ptr;
1211         }
1212
1213         public unsafe bool Equals(ModuleHandle handle)
1214         {
1215             return handle.m_ptr == m_ptr;
1216         }
1217
1218         public static bool operator ==(ModuleHandle left, ModuleHandle right)
1219         {
1220             return left.Equals(right);
1221         }
1222
1223         public static bool operator !=(ModuleHandle left, ModuleHandle right)
1224         {
1225             return !left.Equals(right);
1226         }
1227
1228         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1229         internal static extern IRuntimeMethodInfo GetDynamicMethod(System.Reflection.Emit.DynamicMethod method, RuntimeModule module, string name, byte[] sig, Resolver resolver);
1230
1231         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1232         internal static extern int GetToken(RuntimeModule module);
1233
1234         private static void ValidateModulePointer(RuntimeModule module)
1235         {
1236             // Make sure we have a valid Module to resolve against.
1237             if (module == null)
1238                 throw new InvalidOperationException(SR.InvalidOperation_NullModuleHandle);
1239         }
1240
1241         // SQL-CLR LKG9 Compiler dependency
1242         public RuntimeTypeHandle GetRuntimeTypeHandleFromMetadataToken(int typeToken) { return ResolveTypeHandle(typeToken); }
1243         public RuntimeTypeHandle ResolveTypeHandle(int typeToken)
1244         {
1245             return new RuntimeTypeHandle(ResolveTypeHandleInternal(GetRuntimeModule(), typeToken, null, null));
1246         }
1247         public RuntimeTypeHandle ResolveTypeHandle(int typeToken, RuntimeTypeHandle[] typeInstantiationContext, RuntimeTypeHandle[] methodInstantiationContext)
1248         {
1249             return new RuntimeTypeHandle(ModuleHandle.ResolveTypeHandleInternal(GetRuntimeModule(), typeToken, typeInstantiationContext, methodInstantiationContext));
1250         }
1251
1252         internal static RuntimeType ResolveTypeHandleInternal(RuntimeModule module, int typeToken, RuntimeTypeHandle[] typeInstantiationContext, RuntimeTypeHandle[] methodInstantiationContext)
1253         {
1254             ValidateModulePointer(module);
1255             if (!ModuleHandle.GetMetadataImport(module).IsValidToken(typeToken))
1256                 throw new ArgumentOutOfRangeException(nameof(typeToken),
1257                     SR.Format(SR.Argument_InvalidToken, typeToken, new ModuleHandle(module)));
1258
1259             int typeInstCount, methodInstCount;
1260             IntPtr[] typeInstantiationContextHandles = RuntimeTypeHandle.CopyRuntimeTypeHandles(typeInstantiationContext, out typeInstCount);
1261             IntPtr[] methodInstantiationContextHandles = RuntimeTypeHandle.CopyRuntimeTypeHandles(methodInstantiationContext, out methodInstCount);
1262
1263             fixed (IntPtr* typeInstArgs = typeInstantiationContextHandles, methodInstArgs = methodInstantiationContextHandles)
1264             {
1265                 RuntimeType type = null;
1266                 ResolveType(module, typeToken, typeInstArgs, typeInstCount, methodInstArgs, methodInstCount, JitHelpers.GetObjectHandleOnStack(ref type));
1267                 GC.KeepAlive(typeInstantiationContext);
1268                 GC.KeepAlive(methodInstantiationContext);
1269                 return type;
1270             }
1271         }
1272
1273         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
1274         private static extern void ResolveType(RuntimeModule module,
1275                                                             int typeToken,
1276                                                             IntPtr* typeInstArgs,
1277                                                             int typeInstCount,
1278                                                             IntPtr* methodInstArgs,
1279                                                             int methodInstCount,
1280                                                             ObjectHandleOnStack type);
1281
1282         // SQL-CLR LKG9 Compiler dependency
1283         public RuntimeMethodHandle GetRuntimeMethodHandleFromMetadataToken(int methodToken) { return ResolveMethodHandle(methodToken); }
1284         public RuntimeMethodHandle ResolveMethodHandle(int methodToken) { return ResolveMethodHandle(methodToken, null, null); }
1285         internal static IRuntimeMethodInfo ResolveMethodHandleInternal(RuntimeModule module, int methodToken) { return ModuleHandle.ResolveMethodHandleInternal(module, methodToken, null, null); }
1286         public RuntimeMethodHandle ResolveMethodHandle(int methodToken, RuntimeTypeHandle[] typeInstantiationContext, RuntimeTypeHandle[] methodInstantiationContext)
1287         {
1288             return new RuntimeMethodHandle(ResolveMethodHandleInternal(GetRuntimeModule(), methodToken, typeInstantiationContext, methodInstantiationContext));
1289         }
1290
1291         internal static IRuntimeMethodInfo ResolveMethodHandleInternal(RuntimeModule module, int methodToken, RuntimeTypeHandle[] typeInstantiationContext, RuntimeTypeHandle[] methodInstantiationContext)
1292         {
1293             int typeInstCount, methodInstCount;
1294
1295             IntPtr[] typeInstantiationContextHandles = RuntimeTypeHandle.CopyRuntimeTypeHandles(typeInstantiationContext, out typeInstCount);
1296             IntPtr[] methodInstantiationContextHandles = RuntimeTypeHandle.CopyRuntimeTypeHandles(methodInstantiationContext, out methodInstCount);
1297
1298             RuntimeMethodHandleInternal handle = ResolveMethodHandleInternalCore(module, methodToken, typeInstantiationContextHandles, typeInstCount, methodInstantiationContextHandles, methodInstCount);
1299             IRuntimeMethodInfo retVal = new RuntimeMethodInfoStub(handle, RuntimeMethodHandle.GetLoaderAllocator(handle));
1300             GC.KeepAlive(typeInstantiationContext);
1301             GC.KeepAlive(methodInstantiationContext);
1302             return retVal;
1303         }
1304
1305         internal static RuntimeMethodHandleInternal ResolveMethodHandleInternalCore(RuntimeModule module, int methodToken, IntPtr[] typeInstantiationContext, int typeInstCount, IntPtr[] methodInstantiationContext, int methodInstCount)
1306         {
1307             ValidateModulePointer(module);
1308             if (!ModuleHandle.GetMetadataImport(module.GetNativeHandle()).IsValidToken(methodToken))
1309                 throw new ArgumentOutOfRangeException(nameof(methodToken),
1310                     SR.Format(SR.Argument_InvalidToken, methodToken, new ModuleHandle(module)));
1311
1312             fixed (IntPtr* typeInstArgs = typeInstantiationContext, methodInstArgs = methodInstantiationContext)
1313             {
1314                 return ResolveMethod(module.GetNativeHandle(), methodToken, typeInstArgs, typeInstCount, methodInstArgs, methodInstCount);
1315             }
1316         }
1317
1318         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
1319         private static extern RuntimeMethodHandleInternal ResolveMethod(RuntimeModule module,
1320                                                         int methodToken,
1321                                                         IntPtr* typeInstArgs,
1322                                                         int typeInstCount,
1323                                                         IntPtr* methodInstArgs,
1324                                                         int methodInstCount);
1325
1326         // SQL-CLR LKG9 Compiler dependency
1327         public RuntimeFieldHandle GetRuntimeFieldHandleFromMetadataToken(int fieldToken) { return ResolveFieldHandle(fieldToken); }
1328         public RuntimeFieldHandle ResolveFieldHandle(int fieldToken) { return new RuntimeFieldHandle(ResolveFieldHandleInternal(GetRuntimeModule(), fieldToken, null, null)); }
1329         public RuntimeFieldHandle ResolveFieldHandle(int fieldToken, RuntimeTypeHandle[] typeInstantiationContext, RuntimeTypeHandle[] methodInstantiationContext)
1330         { return new RuntimeFieldHandle(ResolveFieldHandleInternal(GetRuntimeModule(), fieldToken, typeInstantiationContext, methodInstantiationContext)); }
1331
1332         internal static IRuntimeFieldInfo ResolveFieldHandleInternal(RuntimeModule module, int fieldToken, RuntimeTypeHandle[] typeInstantiationContext, RuntimeTypeHandle[] methodInstantiationContext)
1333         {
1334             ValidateModulePointer(module);
1335             if (!ModuleHandle.GetMetadataImport(module.GetNativeHandle()).IsValidToken(fieldToken))
1336                 throw new ArgumentOutOfRangeException(nameof(fieldToken),
1337                     SR.Format(SR.Argument_InvalidToken, fieldToken, new ModuleHandle(module)));
1338
1339             // defensive copy to be sure array is not mutated from the outside during processing
1340             int typeInstCount, methodInstCount;
1341             IntPtr[] typeInstantiationContextHandles = RuntimeTypeHandle.CopyRuntimeTypeHandles(typeInstantiationContext, out typeInstCount);
1342             IntPtr[] methodInstantiationContextHandles = RuntimeTypeHandle.CopyRuntimeTypeHandles(methodInstantiationContext, out methodInstCount);
1343
1344             fixed (IntPtr* typeInstArgs = typeInstantiationContextHandles, methodInstArgs = methodInstantiationContextHandles)
1345             {
1346                 IRuntimeFieldInfo field = null;
1347                 ResolveField(module.GetNativeHandle(), fieldToken, typeInstArgs, typeInstCount, methodInstArgs, methodInstCount, JitHelpers.GetObjectHandleOnStack(ref field));
1348                 GC.KeepAlive(typeInstantiationContext);
1349                 GC.KeepAlive(methodInstantiationContext);
1350                 return field;
1351             }
1352         }
1353
1354         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
1355         private static extern void ResolveField(RuntimeModule module,
1356                                                       int fieldToken,
1357                                                       IntPtr* typeInstArgs,
1358                                                       int typeInstCount,
1359                                                       IntPtr* methodInstArgs,
1360                                                       int methodInstCount,
1361                                                       ObjectHandleOnStack retField);
1362
1363         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
1364         private static extern bool _ContainsPropertyMatchingHash(RuntimeModule module, int propertyToken, uint hash);
1365
1366         internal static bool ContainsPropertyMatchingHash(RuntimeModule module, int propertyToken, uint hash)
1367         {
1368             return _ContainsPropertyMatchingHash(module.GetNativeHandle(), propertyToken, hash);
1369         }
1370
1371         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
1372         internal static extern void GetModuleType(RuntimeModule handle, ObjectHandleOnStack type);
1373
1374         internal static RuntimeType GetModuleType(RuntimeModule module)
1375         {
1376             RuntimeType type = null;
1377             GetModuleType(module.GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref type));
1378             return type;
1379         }
1380
1381         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
1382         private static extern void GetPEKind(RuntimeModule handle, out int peKind, out int machine);
1383
1384         // making this internal, used by Module.GetPEKind
1385         internal static void GetPEKind(RuntimeModule module, out PortableExecutableKinds peKind, out ImageFileMachine machine)
1386         {
1387             int lKind, lMachine;
1388             GetPEKind(module.GetNativeHandle(), out lKind, out lMachine);
1389             peKind = (PortableExecutableKinds)lKind;
1390             machine = (ImageFileMachine)lMachine;
1391         }
1392
1393         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1394         internal static extern int GetMDStreamVersion(RuntimeModule module);
1395
1396         public int MDStreamVersion
1397         {
1398             get { return GetMDStreamVersion(GetRuntimeModule().GetNativeHandle()); }
1399         }
1400
1401         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1402         private static extern IntPtr _GetMetadataImport(RuntimeModule module);
1403
1404         internal static MetadataImport GetMetadataImport(RuntimeModule module)
1405         {
1406             return new MetadataImport(_GetMetadataImport(module.GetNativeHandle()), module);
1407         }
1408         #endregion
1409     }
1410
1411     internal unsafe class Signature
1412     {
1413         #region Definitions
1414         internal enum MdSigCallingConvention : byte
1415         {
1416             Generics = 0x10,
1417             HasThis = 0x20,
1418             ExplicitThis = 0x40,
1419             CallConvMask = 0x0F,
1420             Default = 0x00,
1421             C = 0x01,
1422             StdCall = 0x02,
1423             ThisCall = 0x03,
1424             FastCall = 0x04,
1425             Vararg = 0x05,
1426             Field = 0x06,
1427             LocalSig = 0x07,
1428             Property = 0x08,
1429             Unmgd = 0x09,
1430             GenericInst = 0x0A,
1431             Max = 0x0B,
1432         }
1433         #endregion
1434
1435         #region FCalls
1436         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1437         private extern void GetSignature(
1438             void* pCorSig, int cCorSig,
1439             RuntimeFieldHandleInternal fieldHandle, IRuntimeMethodInfo methodHandle, RuntimeType declaringType);
1440
1441         #endregion
1442
1443         #region Private Data Members
1444         //
1445         // Keep the layout in sync with SignatureNative in the VM
1446         //
1447         internal RuntimeType[] m_arguments;
1448         internal RuntimeType m_declaringType;
1449         internal RuntimeType m_returnTypeORfieldType;
1450         internal object m_keepalive;
1451         internal void* m_sig;
1452         internal int m_managedCallingConventionAndArgIteratorFlags; // lowest byte is CallingConvention, upper 3 bytes are ArgIterator flags
1453         internal int m_nSizeOfArgStack;
1454         internal int m_csig;
1455         internal RuntimeMethodHandleInternal m_pMethod;
1456         #endregion
1457
1458         #region Constructors
1459         public Signature(
1460             IRuntimeMethodInfo method,
1461             RuntimeType[] arguments,
1462             RuntimeType returnType,
1463             CallingConventions callingConvention)
1464         {
1465             m_pMethod = method.Value;
1466             m_arguments = arguments;
1467             m_returnTypeORfieldType = returnType;
1468             m_managedCallingConventionAndArgIteratorFlags = (byte)callingConvention;
1469
1470             GetSignature(null, 0, new RuntimeFieldHandleInternal(), method, null);
1471         }
1472
1473         public Signature(IRuntimeMethodInfo methodHandle, RuntimeType declaringType)
1474         {
1475             GetSignature(null, 0, new RuntimeFieldHandleInternal(), methodHandle, declaringType);
1476         }
1477
1478         public Signature(IRuntimeFieldInfo fieldHandle, RuntimeType declaringType)
1479         {
1480             GetSignature(null, 0, fieldHandle.Value, null, declaringType);
1481             GC.KeepAlive(fieldHandle);
1482         }
1483
1484         public Signature(void* pCorSig, int cCorSig, RuntimeType declaringType)
1485         {
1486             GetSignature(pCorSig, cCorSig, new RuntimeFieldHandleInternal(), null, declaringType);
1487         }
1488         #endregion
1489
1490         #region Internal Members
1491         internal CallingConventions CallingConvention { get { return (CallingConventions)(byte)m_managedCallingConventionAndArgIteratorFlags; } }
1492         internal RuntimeType[] Arguments { get { return m_arguments; } }
1493         internal RuntimeType ReturnType { get { return m_returnTypeORfieldType; } }
1494         internal RuntimeType FieldType { get { return m_returnTypeORfieldType; } }
1495
1496         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1497         internal static extern bool CompareSig(Signature sig1, Signature sig2);
1498
1499         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1500         internal extern Type[] GetCustomModifiers(int position, bool required);
1501         #endregion
1502     }
1503
1504
1505     internal abstract class Resolver
1506     {
1507         internal struct CORINFO_EH_CLAUSE
1508         {
1509             internal int Flags;
1510             internal int TryOffset;
1511             internal int TryLength;
1512             internal int HandlerOffset;
1513             internal int HandlerLength;
1514             internal int ClassTokenOrFilterOffset;
1515         }
1516
1517         // ILHeader info
1518         internal abstract RuntimeType GetJitContext(ref int securityControlFlags);
1519         internal abstract byte[] GetCodeInfo(ref int stackSize, ref int initLocals, ref int EHCount);
1520         internal abstract byte[] GetLocalsSignature();
1521         internal abstract unsafe void GetEHInfo(int EHNumber, void* exception);
1522         internal abstract unsafe byte[] GetRawEHInfo();
1523         // token resolution
1524         internal abstract string GetStringLiteral(int token);
1525         internal abstract void ResolveToken(int token, out IntPtr typeHandle, out IntPtr methodHandle, out IntPtr fieldHandle);
1526         internal abstract byte[] ResolveSignature(int token, int fromMethod);
1527         // 
1528         internal abstract MethodInfo GetDynamicMethod();
1529     }
1530 }