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