[Local GC] Remove a number of inclusions of handle table private headers from the...
[platform/upstream/coreclr.git] / src / vm / runtimehandles.cpp
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 #include "common.h"
7 #include "corhdr.h"
8 #include "runtimehandles.h"
9 #include "object.h"
10 #include "class.h"
11 #include "method.hpp"
12 #include "typehandle.h"
13 #include "field.h"
14 #include "siginfo.hpp"
15 #include "clsload.hpp"
16 #include "typestring.h"
17 #include "typeparse.h"
18 #include "holder.h"
19 #include "codeman.h"
20 #include "corhlpr.h"
21 #include "jitinterface.h"
22 #include "stackprobe.h"
23 #include "eeconfig.h"
24 #include "eehash.h"
25 #include "interoputil.h"
26 #include "typedesc.h"
27 #include "virtualcallstub.h"
28 #include "contractimpl.h"
29 #include "dynamicmethod.h"
30 #include "peimagelayout.inl"
31 #include "security.h"
32 #include "eventtrace.h"
33 #include "invokeutil.h"
34
35
36 FCIMPL3(FC_BOOL_RET, Utf8String::EqualsCaseSensitive, LPCUTF8 szLhs, LPCUTF8 szRhs, INT32 stringNumBytes)
37 {
38     CONTRACTL {
39         FCALL_CHECK;
40         PRECONDITION(CheckPointer(szLhs));
41         PRECONDITION(CheckPointer(szRhs));
42     }
43     CONTRACTL_END;
44
45     // Important: the string in pSsz isn't null terminated so the length must be used
46     // when performing operations on the string.
47
48     // At this point, both the left and right strings are guaranteed to have the
49     // same length.
50     FC_RETURN_BOOL(strncmp(szLhs, szRhs, stringNumBytes) == 0);
51 }
52 FCIMPLEND
53
54 BOOL QCALLTYPE Utf8String::EqualsCaseInsensitive(LPCUTF8 szLhs, LPCUTF8 szRhs, INT32 stringNumBytes)
55 {
56     QCALL_CONTRACT;
57
58     // Important: the string in pSsz isn't null terminated so the length must be used
59     // when performing operations on the string.
60     
61     BOOL fStringsEqual = FALSE;
62     
63     BEGIN_QCALL;
64
65     _ASSERTE(CheckPointer(szLhs));
66     _ASSERTE(CheckPointer(szRhs));
67
68     // At this point, both the left and right strings are guaranteed to have the
69     // same length. 
70     StackSString lhs(SString::Utf8, szLhs, stringNumBytes);
71     StackSString rhs(SString::Utf8, szRhs, stringNumBytes);
72
73     // We can use SString for simple case insensitive compares
74     fStringsEqual = lhs.EqualsCaseInsensitive(rhs);
75
76     END_QCALL;
77
78     return fStringsEqual;
79 }
80
81 ULONG QCALLTYPE Utf8String::HashCaseInsensitive(LPCUTF8 sz, INT32 stringNumBytes)
82 {
83     QCALL_CONTRACT;
84
85     // Important: the string in pSsz isn't null terminated so the length must be used
86     // when performing operations on the string.
87
88     ULONG hashValue = 0;
89     
90     BEGIN_QCALL;
91
92     StackSString str(SString::Utf8, sz, stringNumBytes);
93     hashValue = str.HashCaseInsensitive();
94
95     END_QCALL;
96
97     return hashValue;
98 }
99
100 static BOOL CheckCAVisibilityFromDecoratedType(MethodTable* pCAMT, MethodDesc* pCACtor, MethodTable* pDecoratedMT, Module* pDecoratedModule)
101 {
102     CONTRACTL
103     {
104         THROWS;
105         GC_TRIGGERS;
106         MODE_ANY;
107         PRECONDITION(CheckPointer(pCAMT));
108         PRECONDITION(CheckPointer(pCACtor, NULL_OK));
109         PRECONDITION(CheckPointer(pDecoratedMT, NULL_OK));
110         PRECONDITION(CheckPointer(pDecoratedModule));
111     }
112     CONTRACTL_END;
113
114     DWORD dwAttr = mdPublic;
115
116     if (pCACtor != NULL)
117     {
118         // Allowing a dangerous method to be called in custom attribute instantiation is, well, dangerous.
119         // E.g. a malicious user can craft a custom attribute record that fools us into creating a DynamicMethod
120         // object attached to typeof(System.Reflection.CustomAttribute) and thus gain access to mscorlib internals.
121         if (InvokeUtil::IsDangerousMethod(pCACtor))
122             return FALSE;
123
124         _ASSERTE(pCACtor->IsCtor());
125
126         dwAttr = pCACtor->GetAttrs();
127     }
128     
129     StaticAccessCheckContext accessContext(NULL, pDecoratedMT, pDecoratedModule->GetAssembly());
130
131     return ClassLoader::CanAccess(
132         &accessContext, 
133         pCAMT,
134         pCAMT->GetAssembly(), 
135         dwAttr,
136         pCACtor,
137         NULL,
138         *AccessCheckOptions::s_pNormalAccessChecks,
139         FALSE,
140         FALSE);
141 }
142
143 BOOL QCALLTYPE RuntimeMethodHandle::IsCAVisibleFromDecoratedType(
144     EnregisteredTypeHandle  targetTypeHandle,
145     MethodDesc *            pTargetCtor,
146     EnregisteredTypeHandle  sourceTypeHandle,
147     QCall::ModuleHandle     sourceModuleHandle)
148 {
149     QCALL_CONTRACT;
150
151     BOOL bResult = TRUE;
152
153     BEGIN_QCALL;
154     TypeHandle sourceHandle = TypeHandle::FromPtr(sourceTypeHandle);
155     TypeHandle targetHandle = TypeHandle::FromPtr(targetTypeHandle);
156
157     _ASSERTE((sourceHandle.IsNull() || !sourceHandle.IsTypeDesc()) &&
158              !targetHandle.IsNull() &&
159              !targetHandle.IsTypeDesc());
160
161     if (sourceHandle.IsTypeDesc() ||
162         targetHandle.IsNull() || 
163         targetHandle.IsTypeDesc())
164         COMPlusThrowArgumentNull(NULL, W("Arg_InvalidHandle"));
165
166     bResult = CheckCAVisibilityFromDecoratedType(targetHandle.AsMethodTable(), pTargetCtor, sourceHandle.AsMethodTable(), sourceModuleHandle);
167     END_QCALL;
168
169     return bResult;
170 }
171
172 // static
173 NOINLINE static ReflectClassBaseObject* GetRuntimeTypeHelper(LPVOID __me, TypeHandle typeHandle, OBJECTREF keepAlive)
174 {
175     FC_INNER_PROLOG_NO_ME_SETUP();
176     if (typeHandle.AsPtr() == NULL)
177         return NULL;
178     
179     // RuntimeTypeHandle::GetRuntimeType has picked off the most common case, but does not cover array types.
180     // Before we do the really heavy weight option of setting up a helper method frame, check if we have to. 
181     OBJECTREF refType = typeHandle.GetManagedClassObjectFast();
182     if (refType != NULL)
183         return (ReflectClassBaseObject*)OBJECTREFToObject(refType);
184
185     HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_1(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, keepAlive);
186     refType = typeHandle.GetManagedClassObject();
187     HELPER_METHOD_FRAME_END();
188
189     FC_INNER_EPILOG();
190     return (ReflectClassBaseObject*)OBJECTREFToObject(refType);
191 }
192
193 #define RETURN_CLASS_OBJECT(typeHandle, keepAlive) FC_INNER_RETURN(ReflectClassBaseObject*, GetRuntimeTypeHelper(__me, typeHandle, keepAlive))
194
195 NOINLINE ReflectModuleBaseObject* GetRuntimeModuleHelper(LPVOID __me, Module *pModule, OBJECTREF keepAlive)
196 {
197     FC_INNER_PROLOG_NO_ME_SETUP();
198     if (pModule == NULL)
199         return NULL;
200     
201     DomainFile * pDomainFile = pModule->FindDomainFile(GetAppDomain());
202
203     OBJECTREF refModule = (pDomainFile != NULL) ? pDomainFile->GetExposedModuleObjectIfExists() : NULL;
204
205     if(refModule != NULL)
206         return (ReflectModuleBaseObject*)OBJECTREFToObject(refModule);
207
208     HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_1(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, keepAlive);
209     refModule = pModule->GetExposedObject();
210     HELPER_METHOD_FRAME_END();
211
212     FC_INNER_EPILOG();
213     return (ReflectModuleBaseObject*)OBJECTREFToObject(refModule);
214 }
215
216 NOINLINE AssemblyBaseObject* GetRuntimeAssemblyHelper(LPVOID __me, DomainAssembly *pAssembly, OBJECTREF keepAlive)
217 {
218     FC_INNER_PROLOG_NO_ME_SETUP();
219     if (pAssembly == NULL)
220         return NULL;
221     
222     OBJECTREF refAssembly = (pAssembly != NULL) ? pAssembly->GetExposedAssemblyObjectIfExists() : NULL;
223
224     if(refAssembly != NULL)
225         return (AssemblyBaseObject*)OBJECTREFToObject(refAssembly);
226
227     HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_1(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, keepAlive);
228     refAssembly = pAssembly->GetExposedAssemblyObject();
229     HELPER_METHOD_FRAME_END();
230
231     FC_INNER_EPILOG();
232     return (AssemblyBaseObject*)OBJECTREFToObject(refAssembly);
233 }
234
235
236 // This is the routine that is called by the 'typeof()' operator in C#.  It is one of the most commonly used
237 // reflection operations. This call should be optimized away in nearly all situations
238 FCIMPL1_V(ReflectClassBaseObject*, RuntimeTypeHandle::GetTypeFromHandle, FCALLRuntimeTypeHandle th)
239 {
240     FCALL_CONTRACT;
241     
242     FCUnique(0x31);
243     return FCALL_RTH_TO_REFLECTCLASS(th);
244 }
245 FCIMPLEND
246
247 FCIMPL1(ReflectClassBaseObject*, RuntimeTypeHandle::GetRuntimeType, EnregisteredTypeHandle th)
248 {
249     FCALL_CONTRACT;
250     
251     TypeHandle typeHandle = TypeHandle::FromPtr(th);
252     _ASSERTE(CheckPointer(typeHandle.AsPtr(), NULL_OK));
253     if (typeHandle.AsPtr()!= NULL)
254     {
255         if (!typeHandle.IsTypeDesc())
256         {
257             OBJECTREF typePtr = typeHandle.AsMethodTable()->GetManagedClassObjectIfExists();
258             if (typePtr != NULL)
259             {
260                 return (ReflectClassBaseObject*)OBJECTREFToObject(typePtr);
261             }
262         }
263     }
264     else 
265         return NULL;
266
267     RETURN_CLASS_OBJECT(typeHandle, NULL);
268 }
269 FCIMPLEND
270
271 FCIMPL1_V(EnregisteredTypeHandle, RuntimeTypeHandle::GetValueInternal, FCALLRuntimeTypeHandle RTH)
272 {
273     FCALL_CONTRACT;
274
275     if (FCALL_RTH_TO_REFLECTCLASS(RTH) == NULL)
276         return 0;
277
278     return FCALL_RTH_TO_REFLECTCLASS(RTH) ->GetType().AsPtr();
279 }
280 FCIMPLEND
281
282 // TypeEqualsHelper and TypeNotEqualsHelper are almost identical.
283 // Unfortunately we cannot combime them because they need to hardcode the caller's name
284 NOINLINE static BOOL TypeEqualSlow(OBJECTREF refL, OBJECTREF refR, LPVOID __me)
285 {
286     BOOL ret = FALSE;
287
288     FC_INNER_PROLOG_NO_ME_SETUP();
289
290     _ASSERTE(refL != NULL && refR != NULL);
291
292     HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_2(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, refL, refR);
293
294     MethodDescCallSite TypeEqualsMethod(METHOD__OBJECT__EQUALS, &refL);
295
296     ARG_SLOT args[] = 
297     {
298         ObjToArgSlot(refL),
299         ObjToArgSlot(refR)
300     };
301
302     ret = TypeEqualsMethod.Call_RetBool(args);
303
304     HELPER_METHOD_FRAME_END();
305
306     FC_INNER_EPILOG();
307
308     return ret;
309 }
310
311
312
313 #include <optsmallperfcritical.h>
314
315 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::TypeEQ, Object* left, Object* right)
316 {
317     FCALL_CONTRACT;
318
319     OBJECTREF refL = (OBJECTREF)left;
320     OBJECTREF refR = (OBJECTREF)right;
321
322     if (refL == refR)
323     {
324         FC_RETURN_BOOL(TRUE);
325     }
326
327     if (!refL || !refR)
328     {
329         FC_RETURN_BOOL(FALSE);
330     }
331
332     if ((refL->GetMethodTable() == g_pRuntimeTypeClass || refR->GetMethodTable() == g_pRuntimeTypeClass))
333     {
334         // Quick path for negative common case
335         FC_RETURN_BOOL(FALSE);
336     }
337
338     // The fast path didn't get us the result
339     // Let's try the slow path: refL.Equals(refR);
340     FC_INNER_RETURN(FC_BOOL_RET, (FC_BOOL_RET)(!!TypeEqualSlow(refL, refR, __me)));
341 }
342 FCIMPLEND
343
344 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::TypeNEQ, Object* left, Object* right)
345 {
346     FCALL_CONTRACT;
347
348     OBJECTREF refL = (OBJECTREF)left;
349     OBJECTREF refR = (OBJECTREF)right;
350
351     if (refL == refR)
352     {
353         FC_RETURN_BOOL(FALSE);
354     }
355
356     if (!refL || !refR)
357     {
358         FC_RETURN_BOOL(TRUE);
359     }
360
361     if ((refL->GetMethodTable() == g_pRuntimeTypeClass || refR->GetMethodTable() == g_pRuntimeTypeClass))
362     {
363         // Quick path for negative common case
364         FC_RETURN_BOOL(TRUE);
365     }
366
367     // The fast path didn't get us the result
368     // Let's try the slow path: refL.Equals(refR);
369     FC_INNER_RETURN(FC_BOOL_RET, (FC_BOOL_RET)(!TypeEqualSlow(refL, refR, __me)));
370 }
371 FCIMPLEND
372
373 #include <optdefault.h>
374
375
376
377
378 #ifdef FEATURE_COMINTEROP
379 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsWindowsRuntimeObjectType, ReflectClassBaseObject *rtTypeUNSAFE)
380 {
381     FCALL_CONTRACT;
382
383     BOOL isWindowsRuntimeType = FALSE;
384
385     TypeHandle typeHandle = rtTypeUNSAFE->GetType();
386     MethodTable *pMT = typeHandle.GetMethodTable();
387
388     if (pMT != NULL)
389     {
390         isWindowsRuntimeType = pMT->IsWinRTObjectType();
391     }
392
393     FC_RETURN_BOOL(isWindowsRuntimeType);
394 }
395 FCIMPLEND
396
397 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsTypeExportedToWindowsRuntime, ReflectClassBaseObject *rtTypeUNSAFE)
398 {
399     FCALL_CONTRACT;
400
401     BOOL isExportedToWinRT = FALSE;
402
403     TypeHandle typeHandle = rtTypeUNSAFE->GetType();
404     MethodTable *pMT = typeHandle.GetMethodTable();
405
406     if (pMT != NULL)
407     {
408         isExportedToWinRT = pMT->IsExportedToWinRT();
409     }
410
411     FC_RETURN_BOOL(isExportedToWinRT);
412 }
413 FCIMPLEND
414 #endif // FEATURE_COMINTEROP
415
416 NOINLINE static MethodDesc * RestoreMethodHelper(MethodDesc * pMethod, LPVOID __me)
417 {
418     FC_INNER_PROLOG_NO_ME_SETUP();
419
420     HELPER_METHOD_FRAME_BEGIN_RET_0();
421     pMethod->CheckRestore();
422     HELPER_METHOD_FRAME_END();
423
424     FC_INNER_EPILOG();
425
426     return pMethod;
427 }
428
429 FCIMPL1(MethodDesc *, RuntimeTypeHandle::GetFirstIntroducedMethod, ReflectClassBaseObject *pTypeUNSAFE) {
430     CONTRACTL {
431         FCALL_CHECK;
432         PRECONDITION(CheckPointer(pTypeUNSAFE));
433     }
434     CONTRACTL_END;
435
436     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
437     TypeHandle typeHandle = refType->GetType();
438     
439     if (typeHandle.IsGenericVariable())
440         FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
441         
442     if (typeHandle.IsTypeDesc()) {
443         if (!typeHandle.IsArray()) 
444             return NULL;
445     }
446
447     MethodTable* pMT = typeHandle.GetMethodTable();
448     if (pMT == NULL)
449         return NULL;
450
451     MethodDesc* pMethod = MethodTable::IntroducedMethodIterator::GetFirst(pMT);
452
453     // The only method that can show up here unrestored is instantiated methods. Check for it before performing the expensive IsRestored() check.
454     if (pMethod != NULL && pMethod->GetClassification() == mcInstantiated && !pMethod->IsRestored()) {
455         FC_INNER_RETURN(MethodDesc *, RestoreMethodHelper(pMethod, __me));
456     }
457
458     _ASSERTE(pMethod == NULL || pMethod->IsRestored());
459     return pMethod;
460 }
461 FCIMPLEND
462
463 #include <optsmallperfcritical.h>
464 FCIMPL1(void, RuntimeTypeHandle::GetNextIntroducedMethod, MethodDesc ** ppMethod) {
465     CONTRACTL {
466         FCALL_CHECK;
467         PRECONDITION(CheckPointer(ppMethod));
468         PRECONDITION(CheckPointer(*ppMethod));
469     }
470     CONTRACTL_END;
471
472     MethodDesc *pMethod = MethodTable::IntroducedMethodIterator::GetNext(*ppMethod);
473
474     *ppMethod = pMethod;
475
476     if (pMethod != NULL && pMethod->GetClassification() == mcInstantiated && !pMethod->IsRestored()) {
477         FC_INNER_RETURN_VOID(RestoreMethodHelper(pMethod, __me));
478     }
479
480     _ASSERTE(pMethod == NULL || pMethod->IsRestored());
481 }
482 FCIMPLEND
483 #include <optdefault.h>
484
485 FCIMPL1(INT32, RuntimeTypeHandle::GetCorElementType, ReflectClassBaseObject *pTypeUNSAFE) {
486     CONTRACTL {
487         FCALL_CHECK;
488     }
489     CONTRACTL_END;
490
491     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
492
493     if (refType == NULL)
494         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
495
496     return refType->GetType().GetSignatureCorElementType();
497 }
498 FCIMPLEND
499
500 FCIMPL1(AssemblyBaseObject*, RuntimeTypeHandle::GetAssembly, ReflectClassBaseObject *pTypeUNSAFE) {
501     CONTRACTL {
502         FCALL_CHECK;
503     }
504     CONTRACTL_END;
505
506     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
507
508     if (refType == NULL)
509         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
510
511     DomainFile *pDomainFile = NULL;
512     
513         Module *pModule = refType->GetType().GetAssembly()->GetManifestModule();
514
515             pDomainFile = pModule->FindDomainFile(GetAppDomain());
516 #ifdef FEATURE_LOADER_OPTIMIZATION        
517         if (pDomainFile == NULL)
518         {
519             HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
520             
521             pDomainFile = GetAppDomain()->LoadDomainNeutralModuleDependency(pModule, FILE_LOADED);
522
523             HELPER_METHOD_FRAME_END();
524         }
525 #endif // FEATURE_LOADER_OPTIMIZATION        
526
527
528     FC_RETURN_ASSEMBLY_OBJECT((DomainAssembly *)pDomainFile, refType);
529 }
530 FCIMPLEND
531
532
533 FCIMPL1(FC_BOOL_RET, RuntimeFieldHandle::AcquiresContextFromThis, FieldDesc *pField)
534 {
535     CONTRACTL {
536         FCALL_CHECK;
537         PRECONDITION(CheckPointer(pField));
538     }
539     CONTRACTL_END;
540
541     FC_RETURN_BOOL(pField->IsSharedByGenericInstantiations());
542
543 }
544 FCIMPLEND
545
546 FCIMPL1(ReflectModuleBaseObject*, RuntimeTypeHandle::GetModule, ReflectClassBaseObject *pTypeUNSAFE) {
547     CONTRACTL {
548         FCALL_CHECK;
549     }
550     CONTRACTL_END;
551     
552     Module *result;
553
554     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
555
556     if (refType == NULL)
557         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
558
559     BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
560
561     result = refType->GetType().GetModule();
562
563     END_SO_INTOLERANT_CODE;
564
565     FC_RETURN_MODULE_OBJECT(result, refType);
566 }
567 FCIMPLEND
568
569 FCIMPL1(ReflectClassBaseObject *, RuntimeTypeHandle::GetBaseType, ReflectClassBaseObject *pTypeUNSAFE) {
570     CONTRACTL {
571         FCALL_CHECK;
572     }
573     CONTRACTL_END;
574
575     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
576
577     if (refType == NULL)
578         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
579
580     TypeHandle typeHandle = refType->GetType();
581     
582     if (typeHandle.IsGenericVariable())
583         FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
584         
585     if (typeHandle.IsTypeDesc()) {
586         if (!typeHandle.IsArray()) 
587             return NULL;
588     }
589     
590     RETURN_CLASS_OBJECT(typeHandle.GetParent(), refType);
591 }
592 FCIMPLEND
593      
594 FCIMPL1(ReflectClassBaseObject *, RuntimeTypeHandle::GetElementType, ReflectClassBaseObject *pTypeUNSAFE) {
595     CONTRACTL {
596         FCALL_CHECK;
597     }
598     CONTRACTL_END;
599     
600     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
601
602     if (refType == NULL)
603         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
604
605     TypeHandle typeHandle = refType->GetType();
606
607     if (!typeHandle.IsTypeDesc())
608         return 0;   
609
610     if (typeHandle.IsGenericVariable())
611         return 0;
612
613     TypeHandle typeReturn;
614
615     if (typeHandle.IsArray()) 
616         typeReturn = typeHandle.AsArray()->GetArrayElementTypeHandle();
617     else
618         typeReturn = typeHandle.AsTypeDesc()->GetTypeParam();
619
620     RETURN_CLASS_OBJECT(typeReturn, refType);
621 }
622 FCIMPLEND
623             
624 FCIMPL1(INT32, RuntimeTypeHandle::GetArrayRank, ReflectClassBaseObject *pTypeUNSAFE) {
625     CONTRACTL {
626         FCALL_CHECK;
627         PRECONDITION(CheckPointer(pTypeUNSAFE));
628         PRECONDITION(pTypeUNSAFE->GetType().IsArray());
629     }
630     CONTRACTL_END;
631
632     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
633
634     return (INT32)refType->GetType().AsArray()->GetRank();   
635 }
636 FCIMPLEND
637
638 FCIMPL1(INT32, RuntimeTypeHandle::GetNumVirtuals, ReflectClassBaseObject *pTypeUNSAFE) {
639     CONTRACTL {
640         FCALL_CHECK;
641     }
642     CONTRACTL_END;
643     
644     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
645
646     if (refType == NULL)
647         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
648
649     TypeHandle typeHandle = refType->GetType();
650
651     if (typeHandle.IsGenericVariable())
652         FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
653     
654     MethodTable *pMT = typeHandle.GetMethodTable();
655
656     if (pMT) 
657         return (INT32)pMT->GetNumVirtuals();
658     else
659         return 0; //REVIEW: should this return the number of methods in Object?
660 }
661 FCIMPLEND
662
663 FCIMPL2(MethodDesc *, RuntimeTypeHandle::GetMethodAt, ReflectClassBaseObject *pTypeUNSAFE, INT32 slot) {
664     CONTRACTL {
665         FCALL_CHECK;
666     }
667     CONTRACTL_END;
668     
669     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
670
671     if (refType == NULL)
672         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
673
674     TypeHandle typeHandle = refType->GetType();
675
676     MethodDesc* pRetMethod = NULL;
677
678     if (typeHandle.IsGenericVariable())
679         FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
680
681     if (slot < 0 || slot >= (INT32)typeHandle.GetMethodTable()->GetNumVirtuals())
682         FCThrowRes(kArgumentException, W("Arg_ArgumentOutOfRangeException"));      
683
684     HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
685     pRetMethod = typeHandle.GetMethodTable()->GetMethodDescForSlot((DWORD)slot);
686     HELPER_METHOD_FRAME_END();
687
688     return pRetMethod;
689 }
690
691 FCIMPLEND
692
693 FCIMPL3(FC_BOOL_RET, RuntimeTypeHandle::GetFields, ReflectClassBaseObject *pTypeUNSAFE, INT32 **result, INT32 *pCount) {
694     CONTRACTL {
695         FCALL_CHECK;
696     }
697     CONTRACTL_END;
698     
699     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
700     if (refType == NULL)
701         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
702
703     TypeHandle typeHandle = refType->GetType();
704     
705     if (!pCount || !result)
706         FCThrow(kArgumentNullException);
707
708     if (typeHandle.IsGenericVariable())
709         FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
710     
711     if (typeHandle.IsTypeDesc()) {
712         *pCount = 0;
713         FC_RETURN_BOOL(TRUE);
714     }
715
716     MethodTable *pMT= typeHandle.GetMethodTable();
717     if (!pMT)
718         FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
719
720     BOOL retVal = FALSE;
721     HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
722     // <TODO>Check this approximation - we may be losing exact type information </TODO>
723     ApproxFieldDescIterator fdIterator(pMT, ApproxFieldDescIterator::ALL_FIELDS);
724     INT32 count = (INT32)fdIterator.Count();
725
726     if (count > *pCount) 
727     {
728         *pCount = count;
729     } 
730     else 
731     {
732         for(INT32 i = 0; i < count; i ++)
733             result[i] = (INT32*)fdIterator.Next();
734         
735         *pCount = count;
736         retVal = TRUE;
737     }
738     HELPER_METHOD_FRAME_END();
739     FC_RETURN_BOOL(retVal);
740 }
741 FCIMPLEND
742
743 void QCALLTYPE RuntimeMethodHandle::ConstructInstantiation(MethodDesc * pMethod, DWORD format, QCall::StringHandleOnStack retString)
744 {
745     QCALL_CONTRACT;
746
747     BEGIN_QCALL;
748
749     StackSString ss;
750     TypeString::AppendInst(ss, pMethod->LoadMethodInstantiation(), format);
751     retString.Set(ss);
752     
753     END_QCALL;
754 }
755
756 void QCALLTYPE RuntimeTypeHandle::ConstructName(EnregisteredTypeHandle pTypeHandle, DWORD format, QCall::StringHandleOnStack retString)
757 {
758     QCALL_CONTRACT;
759       
760     BEGIN_QCALL;
761
762     StackSString ss;    
763     TypeString::AppendType(ss, TypeHandle::FromPtr(pTypeHandle), format);
764     retString.Set(ss);
765
766     END_QCALL;
767 }
768
769 PTRARRAYREF CopyRuntimeTypeHandles(TypeHandle * prgTH, FixupPointer<TypeHandle> * prgTH2, INT32 numTypeHandles, BinderClassID arrayElemType)
770 {
771     CONTRACTL {
772         THROWS;
773         GC_TRIGGERS;
774         MODE_COOPERATIVE;
775     }
776     CONTRACTL_END;
777
778     PTRARRAYREF refReturn = NULL;
779     PTRARRAYREF refArray  = NULL;
780
781     if (numTypeHandles == 0)
782         return NULL;
783
784     _ASSERTE((prgTH != NULL) || (prgTH2 != NULL));
785     if (prgTH != NULL)
786     {
787         _ASSERTE(prgTH2 == NULL);
788     }
789
790     GCPROTECT_BEGIN(refArray);
791     TypeHandle thRuntimeType = TypeHandle(MscorlibBinder::GetClass(arrayElemType));
792     TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(thRuntimeType, ELEMENT_TYPE_SZARRAY);
793     refArray = (PTRARRAYREF)AllocateArrayEx(arrayHandle, &numTypeHandles, 1);
794
795     for (INT32 i = 0; i < numTypeHandles; i++)
796     {
797         TypeHandle th;
798
799         if (prgTH != NULL)
800             th = prgTH[i];
801         else
802             th = prgTH2[i].GetValue();
803
804         OBJECTREF refType = th.GetManagedClassObject();
805         refArray->SetAt(i, refType);
806     }
807
808     refReturn = refArray;
809     GCPROTECT_END();
810
811     return refReturn;
812 }
813
814 void QCALLTYPE RuntimeTypeHandle::GetConstraints(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retTypeArray)
815 {
816     QCALL_CONTRACT;
817
818     TypeHandle* constraints = NULL;
819     
820     BEGIN_QCALL;
821     
822     TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
823     
824     if (!typeHandle.IsGenericVariable())
825         COMPlusThrow(kArgumentException, W("Arg_InvalidHandle"));
826
827         TypeVarTypeDesc* pGenericVariable = typeHandle.AsGenericVariable();              
828     
829     DWORD dwCount;
830     constraints = pGenericVariable->GetConstraints(&dwCount);
831
832     GCX_COOP();
833     retTypeArray.Set(CopyRuntimeTypeHandles(constraints, NULL, dwCount, CLASS__TYPE));
834
835     END_QCALL;
836
837     return;
838 }
839
840 FCIMPL1(PtrArray*, RuntimeTypeHandle::GetInterfaces, ReflectClassBaseObject *pTypeUNSAFE) {
841     CONTRACTL {
842         FCALL_CHECK;
843     }
844     CONTRACTL_END;
845     
846     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
847
848     if (refType == NULL)
849         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
850
851     TypeHandle typeHandle = refType->GetType();
852     
853   if (typeHandle.IsGenericVariable())
854         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
855     
856     INT32 ifaceCount = 0; 
857   
858     PTRARRAYREF refRetVal  = NULL;
859     HELPER_METHOD_FRAME_BEGIN_RET_2(refRetVal, refType);
860     {
861         if (typeHandle.IsTypeDesc())
862         {
863             if (typeHandle.IsArray())
864             {
865                 ifaceCount = typeHandle.GetMethodTable()->GetNumInterfaces();            
866             }
867             else
868             {
869                 ifaceCount = 0;
870             }
871         }
872         else
873         {
874             ifaceCount = typeHandle.GetMethodTable()->GetNumInterfaces();
875         }
876
877         // Allocate the array
878         if (ifaceCount > 0)
879         {            
880             TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(g_pRuntimeTypeClass), ELEMENT_TYPE_SZARRAY);
881             refRetVal = (PTRARRAYREF)AllocateArrayEx(arrayHandle, &ifaceCount, 1);
882         
883             // populate type array
884             UINT i = 0;
885             
886             MethodTable::InterfaceMapIterator it = typeHandle.GetMethodTable()->IterateInterfaceMap();
887             while (it.Next())
888             {
889                 OBJECTREF refInterface = it.GetInterface()->GetManagedClassObject();
890                 refRetVal->SetAt(i, refInterface);
891                 _ASSERTE(refRetVal->GetAt(i) != NULL);
892                 i++;
893             }
894         }
895     }
896     HELPER_METHOD_FRAME_END();
897
898     return (PtrArray*)OBJECTREFToObject(refRetVal);
899 }
900 FCIMPLEND
901
902 FCIMPL1(INT32, RuntimeTypeHandle::GetAttributes, ReflectClassBaseObject *pTypeUNSAFE) {
903     CONTRACTL {
904         FCALL_CHECK;
905     }
906     CONTRACTL_END;
907     
908     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
909
910     if (refType == NULL)
911         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
912
913     TypeHandle typeHandle = refType->GetType();
914       
915     if (typeHandle.IsTypeDesc()) {
916
917         if (typeHandle.IsGenericVariable()) {
918             return tdPublic;        
919         }
920     
921         if (!typeHandle.IsArray()) 
922             return 0;
923     }
924
925 #ifdef FEATURE_COMINTEROP
926     // __ComObject types are always public.
927     if (IsComObjectClass(typeHandle))
928         return (typeHandle.GetMethodTable()->GetAttrClass() & tdVisibilityMask) | tdPublic;
929 #endif // FEATURE_COMINTEROP
930
931     INT32 ret = 0;
932     
933     ret = (INT32)typeHandle.GetMethodTable()->GetAttrClass();
934     return ret;
935 }
936 FCIMPLEND
937
938
939 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsValueType, ReflectClassBaseObject *pTypeUNSAFE)
940 {
941     CONTRACTL {
942         FCALL_CHECK;
943     }
944     CONTRACTL_END;
945     
946     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
947
948     _ASSERTE(refType != NULL);
949
950     TypeHandle typeHandle = refType->GetType();
951
952     FC_RETURN_BOOL(typeHandle.IsValueType());
953 }
954 FCIMPLEND;
955
956 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsInterface, ReflectClassBaseObject *pTypeUNSAFE)
957 {
958     CONTRACTL {
959         FCALL_CHECK;
960     }
961     CONTRACTL_END;
962     
963     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
964
965     _ASSERTE(refType != NULL);
966
967     TypeHandle typeHandle = refType->GetType();
968
969     FC_RETURN_BOOL(typeHandle.IsInterface());
970 }
971 FCIMPLEND;
972
973 BOOL 
974 QCALLTYPE 
975 RuntimeTypeHandle::IsVisible(
976     EnregisteredTypeHandle pTypeHandle)
977 {
978     CONTRACTL
979     {
980         QCALL_CHECK;
981     }
982     CONTRACTL_END;
983     
984     BOOL fIsExternallyVisible = FALSE;
985     
986     BEGIN_QCALL;
987     
988     TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
989
990     _ASSERTE(!typeHandle.IsNull());
991     
992     fIsExternallyVisible = typeHandle.IsExternallyVisible();
993     
994     END_QCALL;
995     
996     return fIsExternallyVisible;
997 } // RuntimeTypeHandle::IsVisible
998
999 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::HasProxyAttribute, ReflectClassBaseObject *pTypeUNSAFE) {
1000     CONTRACTL {
1001         FCALL_CHECK;
1002     }
1003     CONTRACTL_END;
1004
1005     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1006
1007     if (refType == NULL)
1008         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1009
1010     TypeHandle typeHandle = refType->GetType();
1011     
1012     // TODO: Justify this
1013     if (typeHandle.IsGenericVariable())
1014         FC_RETURN_BOOL(FALSE);
1015         
1016     if (typeHandle.IsTypeDesc()) {
1017         if (!typeHandle.IsArray()) 
1018             FC_RETURN_BOOL(FALSE);
1019     }  
1020     
1021     MethodTable* pMT= typeHandle.GetMethodTable();
1022     
1023     if (!pMT) 
1024         FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1025
1026     FC_RETURN_BOOL(pMT->GetClass()->HasRemotingProxyAttribute());
1027 }
1028 FCIMPLEND
1029
1030 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::IsComObject, ReflectClassBaseObject *pTypeUNSAFE, CLR_BOOL isGenericCOM) {
1031 #ifdef FEATURE_COMINTEROP
1032     CONTRACTL {
1033         FCALL_CHECK;
1034     }
1035     CONTRACTL_END;
1036     
1037     BOOL ret = FALSE;
1038
1039     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1040
1041     if (refType == NULL)
1042         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1043
1044     TypeHandle typeHandle = refType->GetType();
1045
1046     HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
1047     {
1048         if (isGenericCOM) 
1049             ret = IsComObjectClass(typeHandle);
1050         else
1051             ret = IsComWrapperClass(typeHandle);
1052     }
1053     HELPER_METHOD_FRAME_END();
1054
1055     FC_RETURN_BOOL(ret);
1056 #else
1057     CONTRACTL {
1058         DISABLED(NOTHROW);
1059         GC_NOTRIGGER;
1060         MODE_COOPERATIVE;
1061         PRECONDITION(CheckPointer(pTypeUNSAFE));
1062     }
1063     CONTRACTL_END;
1064     FCUnique(0x37);
1065     FC_RETURN_BOOL(FALSE);
1066 #endif
1067 }
1068 FCIMPLEND
1069
1070 FCIMPL1(LPCUTF8, RuntimeTypeHandle::GetUtf8Name, ReflectClassBaseObject* pTypeUNSAFE) {
1071     CONTRACTL {
1072         FCALL_CHECK;
1073     }
1074     CONTRACTL_END;
1075     
1076     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1077
1078     if (refType == NULL)
1079         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1080
1081     TypeHandle typeHandle = refType->GetType();
1082     INT32 tkTypeDef = mdTypeDefNil;
1083     LPCUTF8 szName = NULL;
1084
1085     if (typeHandle.IsGenericVariable())
1086         FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1087         
1088     if (typeHandle.IsTypeDesc()) 
1089         FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1090
1091     MethodTable* pMT= typeHandle.GetMethodTable();
1092     
1093     if (pMT == NULL)
1094         FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1095
1096     tkTypeDef = (INT32)pMT->GetCl();
1097     
1098     if (IsNilToken(tkTypeDef))
1099         FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1100     
1101     if (FAILED(pMT->GetMDImport()->GetNameOfTypeDef(tkTypeDef, &szName, NULL)))
1102     {
1103         FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1104     }
1105     
1106     _ASSERTE(CheckPointer(szName, NULL_OK));
1107     
1108     return szName;
1109 }
1110 FCIMPLEND
1111
1112 FCIMPL1(INT32, RuntimeTypeHandle::GetToken, ReflectClassBaseObject *pTypeUNSAFE) {
1113     CONTRACTL {
1114         FCALL_CHECK;
1115     }
1116     CONTRACTL_END;
1117
1118     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1119
1120     if (refType == NULL)
1121         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1122
1123     TypeHandle typeHandle = refType->GetType();
1124
1125     if (typeHandle.IsTypeDesc()) 
1126     {
1127         if (typeHandle.IsGenericVariable())
1128         {
1129             INT32 tkTypeDef = typeHandle.AsGenericVariable()->GetToken();
1130         
1131             _ASSERTE(!IsNilToken(tkTypeDef) && TypeFromToken(tkTypeDef) == mdtGenericParam);
1132
1133             return tkTypeDef;
1134         }
1135         
1136         return mdTypeDefNil;
1137     }
1138
1139     return  (INT32)typeHandle.AsMethodTable()->GetCl();
1140 }
1141 FCIMPLEND
1142
1143 PVOID QCALLTYPE RuntimeTypeHandle::GetGCHandle(EnregisteredTypeHandle pTypeHandle, INT32 handleType)
1144 {
1145     QCALL_CONTRACT;
1146     
1147     OBJECTHANDLE objHandle = NULL;
1148
1149     BEGIN_QCALL;
1150     
1151     GCX_COOP();
1152
1153     TypeHandle th = TypeHandle::FromPtr(pTypeHandle);
1154     assert(handleType >= HNDTYPE_WEAK_SHORT && handleType <= HNDTYPE_WEAK_WINRT);
1155     objHandle = th.GetDomain()->CreateTypedHandle(NULL, static_cast<HandleType>(handleType));
1156     th.GetLoaderAllocator()->RegisterHandleForCleanup(objHandle);
1157
1158     END_QCALL;
1159
1160     return objHandle;
1161 }
1162
1163 void QCALLTYPE RuntimeTypeHandle::VerifyInterfaceIsImplemented(EnregisteredTypeHandle pTypeHandle, EnregisteredTypeHandle pIFaceHandle)
1164 {
1165     QCALL_CONTRACT;
1166
1167     BEGIN_QCALL;
1168
1169     TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
1170     TypeHandle ifaceHandle = TypeHandle::FromPtr(pIFaceHandle);
1171
1172     if (typeHandle.IsGenericVariable())
1173         COMPlusThrow(kArgumentException, W("Arg_InvalidHandle"));
1174     
1175     if (typeHandle.IsTypeDesc()) {
1176         if (!typeHandle.IsArray())
1177             COMPlusThrow(kArgumentException, W("Arg_NotFoundIFace"));
1178     }
1179
1180     if (typeHandle.IsInterface())
1181         COMPlusThrow(kArgumentException, W("Argument_InterfaceMap"));
1182
1183     if (!ifaceHandle.IsInterface())
1184         COMPlusThrow(kArgumentException, W("Arg_MustBeInterface"));
1185
1186     // First try the cheap check, which amounts to iterating the interface map looking for
1187     // the ifaceHandle MethodTable.
1188     if (!typeHandle.GetMethodTable()->ImplementsInterface(ifaceHandle.AsMethodTable()))
1189     {   // If the cheap check fails, try the more expensive but complete check.
1190         if (!typeHandle.CanCastTo(ifaceHandle))
1191         {   // If the complete check fails, we're certain that this type
1192             // does not implement the interface specified.
1193         COMPlusThrow(kArgumentException, W("Arg_NotFoundIFace"));
1194         }
1195     }
1196
1197     END_QCALL;
1198 }
1199
1200 INT32 QCALLTYPE RuntimeTypeHandle::GetInterfaceMethodImplementationSlot(EnregisteredTypeHandle pTypeHandle, EnregisteredTypeHandle pOwner, MethodDesc * pMD)
1201 {
1202     QCALL_CONTRACT;
1203
1204     INT32 slotNumber = -1;
1205
1206     BEGIN_QCALL;
1207
1208     TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
1209     TypeHandle thOwnerOfMD = TypeHandle::FromPtr(pOwner);
1210
1211         // Ok to have INVALID_SLOT in the case where abstract class does not implement an interface method.
1212         // This case can not be reproed using C# "implements" all interface methods
1213         // with at least an abstract method. b19897_GetInterfaceMap_Abstract.exe tests this case.
1214         //@TODO:STUBDISPATCH: Don't need to track down the implementation, just the declaration, and this can
1215         //@TODO:              be done faster - just need to make a function FindDispatchDecl.
1216         DispatchSlot slot(typeHandle.GetMethodTable()->FindDispatchSlotForInterfaceMD(thOwnerOfMD, pMD));
1217     if (!slot.IsNull())
1218             slotNumber = slot.GetMethodDesc()->GetSlot();
1219
1220     END_QCALL;
1221     
1222     return slotNumber;
1223     }
1224     
1225 void QCALLTYPE RuntimeTypeHandle::GetDefaultConstructor(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retMethod)
1226 {
1227     QCALL_CONTRACT;
1228
1229     BEGIN_QCALL;
1230     
1231     MethodDesc* pCtor = NULL;
1232     
1233     TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
1234
1235     if (!typeHandle.IsTypeDesc())
1236     {
1237         MethodTable* pMethodTable = typeHandle.AsMethodTable();
1238         if (pMethodTable->HasDefaultConstructor())
1239             pCtor = pMethodTable->GetDefaultConstructor();
1240     }
1241
1242     if (pCtor != NULL)
1243     {
1244         GCX_COOP();
1245         retMethod.Set(pCtor->GetStubMethodInfo());
1246     }
1247     END_QCALL;
1248
1249     return;
1250 }
1251
1252 FCIMPL1(ReflectMethodObject*, RuntimeTypeHandle::GetDeclaringMethod, ReflectClassBaseObject *pTypeUNSAFE) {
1253     CONTRACTL {
1254         FCALL_CHECK;
1255     }
1256     CONTRACTL_END;
1257     
1258     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1259
1260     if (refType == NULL)
1261         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1262
1263     TypeHandle typeHandle = refType->GetType();;
1264
1265     if (!typeHandle.IsTypeDesc())
1266         return NULL;
1267     
1268     TypeVarTypeDesc* pGenericVariable = typeHandle.AsGenericVariable();
1269     mdToken defToken = pGenericVariable->GetTypeOrMethodDef();
1270     if (TypeFromToken(defToken) != mdtMethodDef)
1271         return NULL;
1272
1273     REFLECTMETHODREF pRet = NULL;
1274     HELPER_METHOD_FRAME_BEGIN_RET_0();
1275     MethodDesc * pMD = pGenericVariable->LoadOwnerMethod();
1276     pMD->CheckRestore();
1277     pRet = pMD->GetStubMethodInfo();
1278     HELPER_METHOD_FRAME_END();
1279
1280     return (ReflectMethodObject*)OBJECTREFToObject(pRet);
1281 }
1282 FCIMPLEND
1283
1284 FCIMPL1(ReflectClassBaseObject*, RuntimeTypeHandle::GetDeclaringType, ReflectClassBaseObject *pTypeUNSAFE) {
1285     CONTRACTL {
1286         FCALL_CHECK;
1287     }
1288     CONTRACTL_END;
1289     
1290     TypeHandle retTypeHandle;
1291
1292     BOOL fThrowException = FALSE;
1293     LPCWSTR argName = W("Arg_InvalidHandle");
1294     RuntimeExceptionKind reKind = kArgumentNullException;
1295
1296     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1297
1298     if (refType == NULL)
1299         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1300
1301     TypeHandle typeHandle = refType->GetType();
1302
1303     MethodTable* pMT = NULL;
1304     mdTypeDef tkTypeDef = mdTokenNil;
1305
1306     BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
1307     if (typeHandle.IsTypeDesc()) {
1308
1309         if (typeHandle.IsGenericVariable()) {
1310             TypeVarTypeDesc* pGenericVariable = typeHandle.AsGenericVariable();
1311             mdToken defToken = pGenericVariable->GetTypeOrMethodDef();
1312             
1313             // Try the fast way first (if the declaring type has been loaded already).
1314             if (TypeFromToken(defToken) == mdtMethodDef)
1315             {
1316                 MethodDesc * retMethod = pGenericVariable->GetModule()->LookupMethodDef(defToken);
1317                 if (retMethod != NULL)
1318                     retTypeHandle = retMethod->GetMethodTable();
1319             }
1320             else
1321             {
1322                 retTypeHandle = pGenericVariable->GetModule()->LookupTypeDef(defToken);
1323             }
1324
1325             if (!retTypeHandle.IsNull() && retTypeHandle.IsFullyLoaded())
1326                 goto Exit;
1327
1328             // OK, need to go the slow way and load the type first.
1329             HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
1330             {
1331                 if (TypeFromToken(defToken) == mdtMethodDef)
1332                 {
1333                     retTypeHandle = pGenericVariable->LoadOwnerMethod()->GetMethodTable();
1334                 }
1335                 else
1336                 {
1337                     retTypeHandle = pGenericVariable->LoadOwnerType();
1338                 }
1339                 retTypeHandle.CheckRestore();
1340             }
1341             HELPER_METHOD_FRAME_END();
1342             goto Exit;
1343         }
1344         if (!typeHandle.IsArray())
1345         {
1346             retTypeHandle = TypeHandle();
1347             goto Exit;
1348         }
1349     }
1350     
1351     pMT = typeHandle.GetMethodTable();
1352
1353     if (pMT == NULL) 
1354     {
1355         fThrowException = TRUE;
1356         goto Exit;
1357     }
1358
1359     if(!pMT->GetClass()->IsNested())
1360     {
1361         retTypeHandle = TypeHandle();
1362         goto Exit;
1363     }
1364
1365     tkTypeDef = pMT->GetCl();
1366     
1367     if (FAILED(typeHandle.GetModule()->GetMDImport()->GetNestedClassProps(tkTypeDef, &tkTypeDef)))
1368     {
1369         fThrowException = TRUE;
1370         reKind = kBadImageFormatException;
1371         argName = NULL;
1372         goto Exit;
1373     }
1374     
1375     // Try the fast way first (if the declaring type has been loaded already).
1376     retTypeHandle = typeHandle.GetModule()->LookupTypeDef(tkTypeDef);
1377     if (retTypeHandle.IsNull())
1378     { 
1379          // OK, need to go the slow way and load the type first.
1380         HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
1381         {
1382             retTypeHandle = ClassLoader::LoadTypeDefThrowing(typeHandle.GetModule(), tkTypeDef, 
1383                                                              ClassLoader::ThrowIfNotFound, 
1384                                                              ClassLoader::PermitUninstDefOrRef);
1385         }
1386         HELPER_METHOD_FRAME_END();
1387     }
1388 Exit:
1389
1390     END_SO_INTOLERANT_CODE;
1391
1392     if (fThrowException)
1393     {
1394         FCThrowRes(reKind, argName);
1395     }
1396
1397     RETURN_CLASS_OBJECT(retTypeHandle, refType);
1398   }
1399 FCIMPLEND
1400
1401 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::CanCastTo, ReflectClassBaseObject *pTypeUNSAFE, ReflectClassBaseObject *pTargetUNSAFE) {
1402     CONTRACTL {
1403         FCALL_CHECK;
1404     }
1405     CONTRACTL_END;
1406     
1407     
1408     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1409     REFLECTCLASSBASEREF refTarget = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTargetUNSAFE);
1410
1411     if ((refType == NULL) || (refTarget == NULL)) 
1412         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1413
1414     TypeHandle fromHandle = refType->GetType();
1415     TypeHandle toHandle = refTarget->GetType();
1416
1417     BOOL iRetVal = 0;
1418
1419     TypeHandle::CastResult r = fromHandle.CanCastToNoGC(toHandle);
1420     if (r == TypeHandle::MaybeCast)
1421     {
1422         HELPER_METHOD_FRAME_BEGIN_RET_2(refType, refTarget);
1423         iRetVal = fromHandle.CanCastTo(toHandle);
1424         HELPER_METHOD_FRAME_END();
1425     }
1426     else
1427     {
1428         iRetVal = (r == TypeHandle::CanCast);
1429     }
1430
1431     // We allow T to be cast to Nullable<T>
1432     if (!iRetVal && Nullable::IsNullableType(toHandle) && !fromHandle.IsTypeDesc())
1433     {
1434         HELPER_METHOD_FRAME_BEGIN_RET_2(refType, refTarget);
1435         if (Nullable::IsNullableForType(toHandle, fromHandle.AsMethodTable())) 
1436         {
1437             iRetVal = TRUE;
1438         }
1439         HELPER_METHOD_FRAME_END();
1440     }
1441         
1442     FC_RETURN_BOOL(iRetVal);
1443 }
1444 FCIMPLEND
1445
1446 void QCALLTYPE RuntimeTypeHandle::GetTypeByNameUsingCARules(LPCWSTR pwzClassName, QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retType)
1447 {
1448     QCALL_CONTRACT;
1449     
1450     TypeHandle typeHandle;
1451
1452     BEGIN_QCALL;
1453         
1454     if (!pwzClassName)
1455         COMPlusThrowArgumentNull(W("className"),W("ArgumentNull_String"));
1456
1457     typeHandle = TypeName::GetTypeUsingCASearchRules(pwzClassName, pModule->GetAssembly());
1458
1459     GCX_COOP();
1460     retType.Set(typeHandle.GetManagedClassObject());
1461
1462     END_QCALL;
1463
1464     return;
1465 }
1466
1467 void QCALLTYPE RuntimeTypeHandle::GetTypeByName(LPCWSTR pwzClassName, BOOL bThrowOnError, BOOL bIgnoreCase, BOOL bReflectionOnly,
1468                                                 QCall::StackCrawlMarkHandle pStackMark, 
1469                                                 ICLRPrivBinder * pPrivHostBinder,
1470                                                 BOOL bLoadTypeFromPartialNameHack, QCall::ObjectHandleOnStack retType,
1471                                                 QCall::ObjectHandleOnStack keepAlive)
1472 {
1473     QCALL_CONTRACT;
1474     
1475     TypeHandle typeHandle;
1476     
1477     BEGIN_QCALL;
1478
1479     if (!pwzClassName)
1480             COMPlusThrowArgumentNull(W("className"),W("ArgumentNull_String"));
1481
1482     {
1483         typeHandle = TypeName::GetTypeManaged(pwzClassName, NULL, bThrowOnError, bIgnoreCase, bReflectionOnly, /*bProhibitAsmQualifiedName =*/ FALSE, pStackMark,
1484                                               bLoadTypeFromPartialNameHack, (OBJECTREF*)keepAlive.m_ppObject,
1485                                               pPrivHostBinder);
1486     }
1487
1488     if (!typeHandle.IsNull())
1489     {
1490         GCX_COOP();
1491         retType.Set(typeHandle.GetManagedClassObject());
1492     }
1493
1494     END_QCALL;
1495
1496     return;
1497 }
1498
1499 FCIMPL6(FC_BOOL_RET, RuntimeTypeHandle::SatisfiesConstraints, PTR_ReflectClassBaseObject pParamTypeUNSAFE, TypeHandle *typeContextArgs, INT32 typeContextCount, TypeHandle *methodContextArgs, INT32 methodContextCount, PTR_ReflectClassBaseObject pArgumentTypeUNSAFE);
1500 {
1501     CONTRACTL {
1502         FCALL_CHECK;
1503         PRECONDITION(CheckPointer(typeContextArgs, NULL_OK));
1504         PRECONDITION(CheckPointer(methodContextArgs, NULL_OK));
1505     }
1506     CONTRACTL_END;
1507     
1508     REFLECTCLASSBASEREF refParamType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pParamTypeUNSAFE);
1509     REFLECTCLASSBASEREF refArgumentType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pArgumentTypeUNSAFE);
1510
1511     TypeHandle thGenericParameter = refParamType->GetType();
1512     TypeHandle thGenericArgument = refArgumentType->GetType();
1513     BOOL bResult = FALSE; 
1514     SigTypeContext typeContext;
1515
1516     Instantiation classInst;
1517     Instantiation methodInst;
1518
1519     if (typeContextArgs != NULL)
1520     {
1521         classInst = Instantiation(typeContextArgs, typeContextCount);
1522     }
1523     
1524     if (methodContextArgs != NULL)
1525     {
1526         methodInst = Instantiation(methodContextArgs, methodContextCount);
1527     }
1528
1529     SigTypeContext::InitTypeContext(classInst, methodInst, &typeContext);
1530
1531     HELPER_METHOD_FRAME_BEGIN_RET_2(refParamType, refArgumentType);
1532     {
1533         bResult = thGenericParameter.AsGenericVariable()->SatisfiesConstraints(&typeContext, thGenericArgument);
1534     }
1535     HELPER_METHOD_FRAME_END();
1536
1537     FC_RETURN_BOOL(bResult);      
1538 }
1539 FCIMPLEND
1540
1541 void QCALLTYPE RuntimeTypeHandle::GetInstantiation(EnregisteredTypeHandle pType, QCall::ObjectHandleOnStack retTypes, BOOL fAsRuntimeTypeArray)
1542 {
1543     QCALL_CONTRACT;
1544
1545     BEGIN_QCALL;
1546
1547     TypeHandle typeHandle = TypeHandle::FromPtr(pType);
1548     Instantiation inst = typeHandle.GetInstantiation();
1549     GCX_COOP();
1550     retTypes.Set(CopyRuntimeTypeHandles(NULL, inst.GetRawArgs(), inst.GetNumArgs(), fAsRuntimeTypeArray ? CLASS__CLASS : CLASS__TYPE));
1551     END_QCALL;
1552
1553     return;
1554 }
1555
1556 void QCALLTYPE RuntimeTypeHandle::MakeArray(EnregisteredTypeHandle pTypeHandle, INT32 rank, QCall::ObjectHandleOnStack retType)
1557 {
1558     QCALL_CONTRACT;
1559
1560     TypeHandle arrayHandle;
1561     
1562     BEGIN_QCALL;
1563     arrayHandle = TypeHandle::FromPtr(pTypeHandle).MakeArray(rank);
1564     GCX_COOP();
1565     retType.Set(arrayHandle.GetManagedClassObject());
1566     END_QCALL;
1567     
1568     return;
1569 }
1570
1571 void QCALLTYPE RuntimeTypeHandle::MakeSZArray(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType)
1572 {
1573     QCALL_CONTRACT;
1574     
1575     TypeHandle arrayHandle;
1576     
1577     BEGIN_QCALL;
1578     arrayHandle = TypeHandle::FromPtr(pTypeHandle).MakeSZArray();
1579     GCX_COOP();
1580     retType.Set(arrayHandle.GetManagedClassObject());
1581     END_QCALL;
1582
1583     return;
1584 }
1585
1586 void QCALLTYPE RuntimeTypeHandle::MakePointer(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType)
1587 {
1588     QCALL_CONTRACT;
1589     
1590     TypeHandle pointerHandle;
1591     
1592     BEGIN_QCALL;
1593     pointerHandle = TypeHandle::FromPtr(pTypeHandle).MakePointer();
1594     GCX_COOP();
1595     retType.Set(pointerHandle.GetManagedClassObject());
1596     END_QCALL;
1597     
1598     return;
1599 }
1600
1601 void QCALLTYPE RuntimeTypeHandle::MakeByRef(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType)
1602 {
1603     QCALL_CONTRACT;
1604     
1605     TypeHandle byRefHandle;
1606     
1607     BEGIN_QCALL;
1608     byRefHandle = TypeHandle::FromPtr(pTypeHandle).MakeByRef();
1609     GCX_COOP();
1610     retType.Set(byRefHandle.GetManagedClassObject());
1611     END_QCALL;
1612     
1613     return;
1614 }
1615
1616 BOOL QCALLTYPE RuntimeTypeHandle::IsCollectible(EnregisteredTypeHandle pTypeHandle)
1617 {
1618     QCALL_CONTRACT;
1619
1620     BOOL retVal = FALSE;
1621
1622     BEGIN_QCALL;
1623     retVal = TypeHandle::FromPtr(pTypeHandle).GetLoaderAllocator()->IsCollectible();
1624     END_QCALL;
1625
1626     return retVal;
1627 }
1628     
1629 void QCALLTYPE RuntimeTypeHandle::Instantiate(EnregisteredTypeHandle pTypeHandle, TypeHandle * pInstArray, INT32 cInstArray, QCall::ObjectHandleOnStack retType)
1630 {
1631     QCALL_CONTRACT;
1632     
1633     TypeHandle type;
1634
1635     BEGIN_QCALL;
1636     type = TypeHandle::FromPtr(pTypeHandle).Instantiate(Instantiation(pInstArray, cInstArray));
1637     GCX_COOP();
1638     retType.Set(type.GetManagedClassObject());
1639     END_QCALL;
1640
1641     return;
1642 }
1643
1644 void QCALLTYPE RuntimeTypeHandle::GetGenericTypeDefinition(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType)
1645 {
1646     QCALL_CONTRACT;
1647     
1648     TypeHandle typeDef;
1649     
1650     BEGIN_QCALL;
1651     
1652     TypeHandle genericType = TypeHandle::FromPtr(pTypeHandle);
1653
1654     typeDef = ClassLoader::LoadTypeDefThrowing(genericType.GetModule(), 
1655                                                        genericType.GetMethodTable()->GetCl(),
1656                                                        ClassLoader::ThrowIfNotFound,
1657                                                        ClassLoader::PermitUninstDefOrRef);
1658
1659     GCX_COOP();
1660     retType.Set(typeDef.GetManagedClassObject());
1661
1662     END_QCALL;
1663     
1664     return;
1665 }
1666
1667 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::CompareCanonicalHandles, ReflectClassBaseObject *pLeftUNSAFE, ReflectClassBaseObject *pRightUNSAFE)
1668 {
1669     FCALL_CONTRACT;
1670     
1671     REFLECTCLASSBASEREF refLeft = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pLeftUNSAFE);
1672     REFLECTCLASSBASEREF refRight = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pRightUNSAFE);
1673
1674     if ((refLeft == NULL) || (refRight == NULL))
1675         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1676
1677     FC_RETURN_BOOL(refLeft->GetType().GetCanonicalMethodTable() == refRight->GetType().GetCanonicalMethodTable());
1678 }
1679 FCIMPLEND
1680
1681 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::HasInstantiation, PTR_ReflectClassBaseObject pTypeUNSAFE)
1682 {
1683     FCALL_CONTRACT;       
1684     
1685     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1686
1687     if (refType == NULL)
1688         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1689
1690     FC_RETURN_BOOL(refType->GetType().HasInstantiation());
1691 }
1692 FCIMPLEND
1693
1694 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsGenericTypeDefinition, PTR_ReflectClassBaseObject pTypeUNSAFE)
1695 {
1696     FCALL_CONTRACT;
1697     
1698     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1699
1700     if (refType == NULL)
1701         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1702
1703     FC_RETURN_BOOL(refType->GetType().IsGenericTypeDefinition());
1704 }
1705 FCIMPLEND
1706
1707 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsGenericVariable, PTR_ReflectClassBaseObject pTypeUNSAFE)
1708 {
1709     FCALL_CONTRACT;
1710     
1711     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1712
1713     if (refType == NULL)
1714         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1715
1716     FC_RETURN_BOOL(refType->GetType().IsGenericVariable());
1717 }
1718 FCIMPLEND
1719
1720 FCIMPL1(INT32, RuntimeTypeHandle::GetGenericVariableIndex, PTR_ReflectClassBaseObject pTypeUNSAFE)
1721 {
1722     FCALL_CONTRACT;
1723     
1724     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1725
1726     if (refType == NULL)
1727         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1728
1729     return (INT32)refType->GetType().AsGenericVariable()->GetIndex();
1730 }
1731 FCIMPLEND
1732
1733 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::ContainsGenericVariables, PTR_ReflectClassBaseObject pTypeUNSAFE)
1734 {
1735     FCALL_CONTRACT;
1736
1737     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1738
1739     if (refType == NULL)
1740         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1741
1742     FC_RETURN_BOOL(refType->GetType().ContainsGenericVariables());
1743 }
1744 FCIMPLEND
1745
1746 FCIMPL1(IMDInternalImport*, RuntimeTypeHandle::GetMetadataImport, ReflectClassBaseObject * pTypeUNSAFE)
1747 {
1748     FCALL_CONTRACT;
1749
1750     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1751
1752     if (refType == NULL)
1753         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1754
1755     Module *pModule = refType->GetType().GetModule();
1756
1757     return pModule->GetMDImport();
1758 }
1759 FCIMPLEND
1760
1761
1762 //***********************************************************************************
1763 //***********************************************************************************
1764 //***********************************************************************************
1765
1766 void * QCALLTYPE RuntimeMethodHandle::GetFunctionPointer(MethodDesc * pMethod)
1767 {
1768     QCALL_CONTRACT;
1769         
1770     void* funcPtr = 0;
1771     
1772     BEGIN_QCALL;
1773
1774     funcPtr = (void*)pMethod->GetMultiCallableAddrOfCode();
1775
1776     END_QCALL;
1777
1778     return funcPtr;
1779 }
1780     
1781 FCIMPL1(LPCUTF8, RuntimeMethodHandle::GetUtf8Name, MethodDesc *pMethod) {
1782     CONTRACTL {
1783         FCALL_CHECK;
1784     }
1785     CONTRACTL_END;
1786     
1787     LPCUTF8 szName = NULL;
1788     
1789     if (!pMethod)
1790         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1791            
1792     szName = pMethod->GetName();
1793
1794     _ASSERTE(CheckPointer(szName, NULL_OK));
1795     
1796     return szName;
1797 }
1798 FCIMPLEND
1799
1800 FCIMPL2(FC_BOOL_RET, RuntimeMethodHandle::MatchesNameHash, MethodDesc * pMethod, ULONG hash)
1801 {
1802     FCALL_CONTRACT;
1803
1804     FC_RETURN_BOOL(pMethod->MightHaveName(hash));
1805 }
1806 FCIMPLEND
1807
1808 FCIMPL1(StringObject*, RuntimeMethodHandle::GetName, MethodDesc *pMethod) {
1809     CONTRACTL {
1810         FCALL_CHECK;
1811     }
1812     CONTRACTL_END;
1813         
1814     if (!pMethod)
1815         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1816         
1817     STRINGREF refName = NULL;
1818
1819     HELPER_METHOD_FRAME_BEGIN_RET_0();
1820     refName = StringObject::NewString(pMethod->GetName());
1821     HELPER_METHOD_FRAME_END();            
1822     
1823     return (StringObject*)OBJECTREFToObject(refName);
1824 }
1825 FCIMPLEND
1826
1827 FCIMPL1(INT32, RuntimeMethodHandle::GetAttributes, MethodDesc *pMethod) {
1828     CONTRACTL {
1829         FCALL_CHECK;
1830     }
1831     CONTRACTL_END;
1832     
1833     if (!pMethod)
1834         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1835
1836     INT32 retVal = 0;        
1837     BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
1838     retVal = (INT32)pMethod->GetAttrs();
1839     END_SO_INTOLERANT_CODE;
1840     return retVal;
1841 }
1842 FCIMPLEND
1843
1844 FCIMPL1(INT32, RuntimeMethodHandle::GetImplAttributes, ReflectMethodObject *pMethodUNSAFE) {
1845     CONTRACTL {
1846         FCALL_CHECK;
1847     }
1848     CONTRACTL_END;
1849     
1850     if (!pMethodUNSAFE)
1851         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1852
1853     MethodDesc* pMethod = pMethodUNSAFE->GetMethod();
1854     INT32 attributes = 0;
1855
1856     if (IsNilToken(pMethod->GetMemberDef()))
1857         return attributes;
1858     
1859     BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
1860     {
1861         attributes = (INT32)pMethod->GetImplAttrs();
1862     }
1863     END_SO_INTOLERANT_CODE;
1864
1865     return attributes;
1866 }
1867 FCIMPLEND
1868     
1869
1870 FCIMPL1(ReflectClassBaseObject*, RuntimeMethodHandle::GetDeclaringType, MethodDesc *pMethod) {
1871     CONTRACTL {
1872         FCALL_CHECK;
1873         PRECONDITION(CheckPointer(pMethod));
1874     }
1875     CONTRACTL_END;
1876     
1877     if (!pMethod)
1878         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1879         
1880     MethodTable *pMT = pMethod->GetMethodTable();
1881     TypeHandle declType(pMT);
1882     if (pMT->IsArray()) 
1883     {
1884         HELPER_METHOD_FRAME_BEGIN_RET_0();   
1885         
1886         // Load the TypeDesc for the array type.  Note the returned type is approximate, i.e.
1887         // if shared between reference array types then we will get object[] back.
1888         DWORD rank = pMT->GetRank();
1889         TypeHandle elemType = pMT->GetApproxArrayElementTypeHandle();
1890         declType = ClassLoader::LoadArrayTypeThrowing(elemType, pMT->GetInternalCorElementType(), rank);
1891         HELPER_METHOD_FRAME_END();            
1892     }
1893     RETURN_CLASS_OBJECT(declType, NULL);
1894 }
1895 FCIMPLEND
1896
1897 FCIMPL1(INT32, RuntimeMethodHandle::GetSlot, MethodDesc *pMethod) {
1898     CONTRACTL {
1899         FCALL_CHECK;
1900     }
1901     CONTRACTL_END;
1902     
1903     if (!pMethod)
1904         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1905         
1906     return (INT32)pMethod->GetSlot();
1907 }
1908 FCIMPLEND
1909
1910 FCIMPL3(Object *, SignatureNative::GetCustomModifiers, SignatureNative* pSignatureUNSAFE, 
1911     INT32 parameter, CLR_BOOL fRequired)
1912 {   
1913     CONTRACTL {
1914         FCALL_CHECK;
1915     }
1916     CONTRACTL_END;
1917
1918     struct 
1919     {
1920         SIGNATURENATIVEREF pSig;
1921         PTRARRAYREF retVal;
1922     } gc;
1923
1924     gc.pSig = (SIGNATURENATIVEREF)pSignatureUNSAFE;
1925     gc.retVal = NULL;
1926
1927     HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
1928     {
1929         
1930         BYTE callConv = *(BYTE*)gc.pSig->GetCorSig();
1931         SigTypeContext typeContext;
1932         gc.pSig->GetTypeContext(&typeContext);
1933         MetaSig sig(gc.pSig->GetCorSig(), 
1934                     gc.pSig->GetCorSigSize(),
1935                     gc.pSig->GetModule(), 
1936                     &typeContext,
1937                     (callConv & IMAGE_CEE_CS_CALLCONV_MASK) == IMAGE_CEE_CS_CALLCONV_FIELD ? MetaSig::sigField : MetaSig::sigMember);
1938         _ASSERTE(callConv == sig.GetCallingConventionInfo());                 
1939
1940         SigPointer argument(NULL, 0);
1941
1942         PRECONDITION(sig.GetCallingConvention() != IMAGE_CEE_CS_CALLCONV_FIELD || parameter == 1);
1943
1944         if (parameter == 0) 
1945         {
1946             argument = sig.GetReturnProps();
1947         }
1948         else
1949         {
1950             for(INT32 i = 0; i < parameter; i++)
1951                 sig.NextArg();
1952
1953             argument = sig.GetArgProps();
1954         }
1955         
1956         //if (parameter < 0 || parameter > (INT32)sig.NumFixedArgs())
1957         //    FCThrowResVoid(kArgumentNullException, W("Arg_ArgumentOutOfRangeException")); 
1958         
1959         SigPointer sp = argument;
1960         Module* pModule = sig.GetModule();
1961         INT32 cMods = 0;
1962         CorElementType cmodType;
1963
1964         CorElementType cmodTypeExpected = fRequired ? ELEMENT_TYPE_CMOD_REQD : ELEMENT_TYPE_CMOD_OPT;
1965         
1966         // Discover the number of required and optional custom modifiers.   
1967         while(TRUE)
1968         {
1969             BYTE data;
1970             IfFailThrow(sp.GetByte(&data));
1971             cmodType = (CorElementType)data;
1972             
1973             if (cmodType == ELEMENT_TYPE_CMOD_REQD || cmodType == ELEMENT_TYPE_CMOD_OPT)
1974             {
1975                 if (cmodType == cmodTypeExpected)
1976                 {
1977                     cMods ++;
1978                 }
1979             }        
1980             else if (cmodType != ELEMENT_TYPE_SENTINEL) 
1981             {
1982                 break;        
1983             }
1984             
1985             IfFailThrow(sp.GetToken(NULL));
1986         }
1987
1988         // Reset sp and populate the arrays for the required and optional custom 
1989         // modifiers now that we know how long they should be. 
1990         sp = argument;
1991
1992         MethodTable *pMT = MscorlibBinder::GetClass(CLASS__TYPE);
1993         TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pMT), ELEMENT_TYPE_SZARRAY);
1994
1995         gc.retVal = (PTRARRAYREF) AllocateArrayEx(arrayHandle, &cMods, 1);
1996
1997         while(cMods != 0)
1998         {
1999             BYTE data;
2000             IfFailThrow(sp.GetByte(&data));
2001             cmodType = (CorElementType)data;
2002
2003             mdToken token;
2004             IfFailThrow(sp.GetToken(&token));
2005
2006             if (cmodType == cmodTypeExpected)
2007             {
2008                 TypeHandle th = ClassLoader::LoadTypeDefOrRefOrSpecThrowing(pModule, token, 
2009                                                                             &typeContext,
2010                                                                             ClassLoader::ThrowIfNotFound, 
2011                                                                             ClassLoader::FailIfUninstDefOrRef);        
2012         
2013                 OBJECTREF refType = th.GetManagedClassObject();
2014                 gc.retVal->SetAt(--cMods, refType);
2015             }
2016         }    
2017     }  
2018     HELPER_METHOD_FRAME_END();
2019
2020     return OBJECTREFToObject(gc.retVal);
2021 }
2022 FCIMPLEND
2023
2024 FCIMPL1(INT32, RuntimeMethodHandle::GetMethodDef, ReflectMethodObject *pMethodUNSAFE) {
2025     CONTRACTL {
2026         FCALL_CHECK;
2027     }
2028     CONTRACTL_END;
2029     
2030     if (!pMethodUNSAFE)
2031         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2032
2033     MethodDesc* pMethod = pMethodUNSAFE->GetMethod();
2034
2035     if (pMethod->HasMethodInstantiation())
2036     {
2037         HELPER_METHOD_FRAME_BEGIN_RET_1(pMethodUNSAFE);
2038         {         
2039             pMethod = pMethod->StripMethodInstantiation();
2040         }
2041         HELPER_METHOD_FRAME_END();
2042     }
2043
2044     INT32 tkMethodDef = (INT32)pMethod->GetMemberDef();
2045     _ASSERTE(TypeFromToken(tkMethodDef) == mdtMethodDef);
2046     
2047     if (IsNilToken(tkMethodDef) || TypeFromToken(tkMethodDef) != mdtMethodDef)
2048         return mdMethodDefNil;
2049     
2050     return tkMethodDef;
2051 }
2052 FCIMPLEND
2053
2054 FCIMPL6(void, SignatureNative::GetSignature,
2055     SignatureNative* pSignatureNativeUNSAFE, 
2056     PCCOR_SIGNATURE pCorSig, DWORD cCorSig,
2057     FieldDesc *pFieldDesc, ReflectMethodObject *pMethodUNSAFE, ReflectClassBaseObject *pDeclaringTypeUNSAFE) {
2058     CONTRACTL {
2059         FCALL_CHECK;
2060         PRECONDITION(pDeclaringTypeUNSAFE || pMethodUNSAFE->GetMethod()->IsDynamicMethod());
2061         PRECONDITION(CheckPointer(pCorSig, NULL_OK));
2062         PRECONDITION(CheckPointer(pMethodUNSAFE, NULL_OK));
2063         PRECONDITION(CheckPointer(pFieldDesc, NULL_OK));
2064     }
2065     CONTRACTL_END;
2066
2067     struct
2068     {
2069         REFLECTCLASSBASEREF refDeclaringType;
2070         REFLECTMETHODREF refMethod;
2071         SIGNATURENATIVEREF pSig;
2072     } gc;
2073
2074     gc.refDeclaringType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pDeclaringTypeUNSAFE);
2075     gc.refMethod = (REFLECTMETHODREF)ObjectToOBJECTREF(pMethodUNSAFE);
2076     gc.pSig = (SIGNATURENATIVEREF)pSignatureNativeUNSAFE;
2077
2078     MethodDesc *pMethod;
2079     TypeHandle declType;
2080
2081     if (gc.refDeclaringType == NULL)
2082     {
2083         // for dynamic method, see precondition
2084         pMethod = gc.refMethod->GetMethod();
2085         declType = pMethod->GetMethodTable();
2086     }
2087     else
2088     {
2089         pMethod = gc.refMethod != NULL ? gc.refMethod->GetMethod() : NULL;
2090         declType = gc.refDeclaringType->GetType();
2091     }
2092
2093     HELPER_METHOD_FRAME_BEGIN_PROTECT(gc);
2094     {        
2095         Module* pModule = declType.GetModule();
2096         
2097         if (pMethod)
2098         {
2099             pMethod->GetSig(&pCorSig, &cCorSig);
2100             if (pMethod->GetClassification() == mcInstantiated)
2101             {
2102                 LoaderAllocator *pLoaderAllocator = pMethod->GetLoaderAllocator();
2103                 if (pLoaderAllocator->IsCollectible())
2104                     gc.pSig->SetKeepAlive(pLoaderAllocator->GetExposedObject());
2105             }
2106         }
2107         else if (pFieldDesc)
2108             pFieldDesc->GetSig(&pCorSig, &cCorSig);
2109         
2110         gc.pSig->m_sig = pCorSig;    
2111         gc.pSig->m_cSig = cCorSig;    
2112         gc.pSig->m_pMethod = pMethod;    
2113
2114         REFLECTCLASSBASEREF refDeclType = (REFLECTCLASSBASEREF)declType.GetManagedClassObject();
2115         gc.pSig->SetDeclaringType(refDeclType);
2116
2117         PREFIX_ASSUME(pCorSig!= NULL);
2118         BYTE callConv = *(BYTE*)pCorSig;
2119         SigTypeContext typeContext;
2120         if (pMethod)
2121             SigTypeContext::InitTypeContext(
2122                 pMethod, declType.GetClassOrArrayInstantiation(), pMethod->LoadMethodInstantiation(), &typeContext);
2123         else
2124             SigTypeContext::InitTypeContext(declType, &typeContext);
2125         MetaSig msig(pCorSig, cCorSig, pModule, &typeContext,
2126             (callConv & IMAGE_CEE_CS_CALLCONV_MASK) == IMAGE_CEE_CS_CALLCONV_FIELD ? MetaSig::sigField : MetaSig::sigMember);
2127
2128         if (callConv == IMAGE_CEE_CS_CALLCONV_FIELD)
2129         {            
2130             msig.NextArgNormalized();
2131
2132             OBJECTREF refRetType = msig.GetLastTypeHandleThrowing().GetManagedClassObject();
2133             gc.pSig->SetReturnType(refRetType);
2134         }
2135         else
2136         {
2137             gc.pSig->SetCallingConvention(msig.GetCallingConventionInfo());
2138
2139             OBJECTREF refRetType = msig.GetRetTypeHandleThrowing().GetManagedClassObject();
2140             gc.pSig->SetReturnType(refRetType);
2141
2142             INT32 nArgs = msig.NumFixedArgs();
2143             TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(g_pRuntimeTypeClass), ELEMENT_TYPE_SZARRAY);
2144
2145             PTRARRAYREF ptrArrayarguments = (PTRARRAYREF) AllocateArrayEx(arrayHandle, &nArgs, 1);
2146             gc.pSig->SetArgumentArray(ptrArrayarguments);
2147
2148             for (INT32 i = 0; i < nArgs; i++) 
2149             {
2150                 msig.NextArg();
2151
2152                 OBJECTREF refArgType = msig.GetLastTypeHandleThrowing().GetManagedClassObject();
2153                 gc.pSig->SetArgument(i, refArgType);
2154             }
2155
2156             _ASSERTE(gc.pSig->m_returnType != NULL);
2157         }
2158     }
2159     HELPER_METHOD_FRAME_END();
2160 }
2161 FCIMPLEND
2162
2163 FCIMPL2(FC_BOOL_RET, SignatureNative::CompareSig, SignatureNative* pLhsUNSAFE, SignatureNative* pRhsUNSAFE)
2164 {
2165     FCALL_CONTRACT;
2166     
2167     INT32 ret = 0;
2168
2169     struct
2170     {
2171         SIGNATURENATIVEREF pLhs;
2172         SIGNATURENATIVEREF pRhs;
2173     } gc;
2174
2175     gc.pLhs = (SIGNATURENATIVEREF)pLhsUNSAFE;
2176     gc.pRhs = (SIGNATURENATIVEREF)pRhsUNSAFE;
2177
2178     HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
2179     {
2180         ret = MetaSig::CompareMethodSigs(
2181             gc.pLhs->GetCorSig(), gc.pLhs->GetCorSigSize(), gc.pLhs->GetModule(), NULL, 
2182             gc.pRhs->GetCorSig(), gc.pRhs->GetCorSigSize(), gc.pRhs->GetModule(), NULL);    
2183     }
2184     HELPER_METHOD_FRAME_END();
2185     FC_RETURN_BOOL(ret);
2186 }
2187 FCIMPLEND
2188
2189 void QCALLTYPE RuntimeMethodHandle::GetMethodInstantiation(MethodDesc * pMethod, QCall::ObjectHandleOnStack retTypes, BOOL fAsRuntimeTypeArray)
2190 {
2191     QCALL_CONTRACT;
2192             
2193     BEGIN_QCALL;
2194     Instantiation inst = pMethod->LoadMethodInstantiation();
2195
2196     GCX_COOP();
2197     retTypes.Set(CopyRuntimeTypeHandles(NULL, inst.GetRawArgs(), inst.GetNumArgs(), fAsRuntimeTypeArray ? CLASS__CLASS : CLASS__TYPE));
2198     END_QCALL;
2199
2200     return;
2201 }
2202     
2203 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::HasMethodInstantiation, MethodDesc * pMethod)
2204 {
2205     FCALL_CONTRACT;
2206
2207     FC_RETURN_BOOL(pMethod->HasMethodInstantiation());
2208 }
2209 FCIMPLEND
2210
2211 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsGenericMethodDefinition, MethodDesc * pMethod)
2212 {
2213     FCALL_CONTRACT;
2214
2215     FC_RETURN_BOOL(pMethod->IsGenericMethodDefinition());
2216 }
2217 FCIMPLEND
2218
2219 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsDynamicMethod, MethodDesc * pMethod)
2220 {
2221     FCALL_CONTRACT;
2222
2223     FC_RETURN_BOOL(pMethod->IsNoMetadata());
2224 }
2225 FCIMPLEND
2226
2227 FCIMPL1(Object*, RuntimeMethodHandle::GetResolver, MethodDesc * pMethod)
2228 {
2229     FCALL_CONTRACT;
2230
2231     if (!pMethod)
2232         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2233
2234     OBJECTREF resolver = NULL;
2235     if (pMethod->IsLCGMethod())
2236     {
2237         resolver = pMethod->AsDynamicMethodDesc()->GetLCGMethodResolver()->GetManagedResolver();
2238     }
2239     return OBJECTREFToObject(resolver);
2240 }
2241 FCIMPLEND
2242
2243 void QCALLTYPE RuntimeMethodHandle::Destroy(MethodDesc * pMethod)
2244 {
2245     QCALL_CONTRACT;
2246
2247     BEGIN_QCALL;
2248
2249     if (pMethod == NULL)
2250         COMPlusThrowArgumentNull(NULL, W("Arg_InvalidHandle"));
2251     
2252     DynamicMethodDesc* pDynamicMethodDesc = pMethod->AsDynamicMethodDesc();
2253
2254     GCX_COOP();
2255
2256     // Destroy should be called only if the managed part is gone.
2257     _ASSERTE(OBJECTREFToObject(pDynamicMethodDesc->GetLCGMethodResolver()->GetManagedResolver()) == NULL);
2258
2259     // Fire Unload Dynamic Method Event here
2260     ETW::MethodLog::DynamicMethodDestroyed(pMethod);
2261
2262     BEGIN_PIN_PROFILER(CORProfilerIsMonitoringDynamicFunctionUnloads());
2263     g_profControlBlock.pProfInterface->DynamicMethodUnloaded((FunctionID)pMethod);
2264     END_PIN_PROFILER();
2265
2266     pDynamicMethodDesc->Destroy();
2267
2268     END_QCALL;
2269     }
2270     
2271 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsTypicalMethodDefinition, ReflectMethodObject *pMethodUNSAFE)
2272 {
2273     FCALL_CONTRACT;
2274
2275     if (!pMethodUNSAFE)
2276         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2277
2278     MethodDesc* pMethod = pMethodUNSAFE->GetMethod();
2279
2280     FC_RETURN_BOOL(pMethod->IsTypicalMethodDefinition());
2281 }
2282 FCIMPLEND
2283     
2284 void QCALLTYPE RuntimeMethodHandle::GetTypicalMethodDefinition(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod)
2285     {            
2286     QCALL_CONTRACT;
2287
2288     BEGIN_QCALL;
2289 #ifdef _DEBUG
2290     {
2291         GCX_COOP();
2292         _ASSERTE(((ReflectMethodObject *)(*refMethod.m_ppObject))->GetMethod() == pMethod);
2293     }
2294 #endif
2295     MethodDesc *pMethodTypical = pMethod->LoadTypicalMethodDefinition();
2296     if (pMethodTypical != pMethod)
2297     {
2298         GCX_COOP();
2299         refMethod.Set(pMethodTypical->GetStubMethodInfo());
2300     }
2301     END_QCALL;
2302     
2303     return;
2304 }
2305
2306 void QCALLTYPE RuntimeMethodHandle::StripMethodInstantiation(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod)
2307     {            
2308     QCALL_CONTRACT;
2309
2310     BEGIN_QCALL;
2311
2312     if (!pMethod)
2313         COMPlusThrowArgumentNull(NULL, W("Arg_InvalidHandle"));
2314
2315 #ifdef _DEBUG
2316     {
2317         GCX_COOP();
2318         _ASSERTE(((ReflectMethodObject *)(*refMethod.m_ppObject))->GetMethod() == pMethod);
2319     }
2320 #endif
2321     MethodDesc *pMethodStripped = pMethod->StripMethodInstantiation();
2322     if (pMethodStripped != pMethod)
2323     {
2324         GCX_COOP();
2325         refMethod.Set(pMethodStripped->GetStubMethodInfo());
2326     }
2327     END_QCALL;
2328
2329     return;
2330 }
2331
2332 // In the VM there might be more than one MethodDescs for a "method"
2333 // examples are methods on generic types which may have additional instantiating stubs
2334 //          and methods on value types which may have additional unboxing stubs.
2335 //
2336 // For generic methods we always hand out an instantiating stub except for a generic method definition
2337 // For non-generic methods on generic types we need an instantiating stub if it's one of the following
2338 //  - static method on a generic class
2339 //  - static or instance method on a generic interface
2340 //  - static or instance method on a generic value type
2341 // The Reflection policy is to always hand out instantiating stubs in these cases
2342 //
2343 // For methods on non-generic value types we can use either the cannonical method or the unboxing stub
2344 // The Reflection policy is to always hand out unboxing stubs if the methods are virtual methods
2345 // The reason for this is that in the current implementation of the class loader, the v-table slots for 
2346 // those methods point to unboxing stubs already. Note that this is just a implementation choice
2347 // that might change in the future. But we should always keep this Reflection policy an invariant.
2348 // 
2349 // For virtual methods on generic value types (intersection of the two cases), reflection will hand
2350 // out an unboxing instantiating stub
2351 // 
2352 // GetInstantiatingStub is called to: 
2353 // 1. create an InstantiatedMethodDesc for a generic method when calling BindGenericArguments() on a generic
2354 //    method. In this case instArray will not be null.
2355 // 2. create an InstantiatedMethodDesc for a method in a generic class. In this case instArray will be null.
2356 // 3. create an UnboxingStub for a method in a value type. In this case instArray will be null.
2357 // For case 2 and 3, an instantiating stub or unboxing stub might not be needed in which case the original 
2358 // MethodDesc is returned.
2359 FCIMPL3(MethodDesc*, RuntimeMethodHandle::GetStubIfNeeded,
2360     MethodDesc *pMethod,
2361     ReflectClassBaseObject *pTypeUNSAFE,
2362     PtrArray* instArrayUNSAFE)
2363 {
2364     CONTRACTL {
2365         FCALL_CHECK;
2366     }
2367     CONTRACTL_END;
2368
2369     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
2370     PTRARRAYREF instArray = (PTRARRAYREF)ObjectToOBJECTREF(instArrayUNSAFE);
2371
2372     if (refType == NULL)
2373         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2374
2375     TypeHandle instType = refType->GetType();
2376     MethodDesc *pNewMethod = pMethod;
2377
2378     // error conditions
2379     if (!pMethod)
2380         FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
2381
2382     if (instType.IsNull())
2383         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2384     
2385     // Perf optimization: this logic is actually duplicated in FindOrCreateAssociatedMethodDescForReflection, but since it
2386     // is the more common case it's worth the duplicate check here to avoid the helper method frame
2387     if ( instArray == NULL &&
2388          ( pMethod->HasMethodInstantiation() || 
2389            ( !instType.IsValueType() && 
2390              ( !instType.HasInstantiation() || instType.IsGenericTypeDefinition() ) ) ) )
2391     {
2392         return pNewMethod;
2393     }
2394
2395     HELPER_METHOD_FRAME_BEGIN_RET_2(refType, instArray);
2396     {
2397         TypeHandle *inst = NULL;
2398         DWORD ntypars = 0;
2399
2400         if (instArray != NULL) 
2401         {
2402             ntypars = instArray->GetNumComponents();    
2403
2404             size_t size = ntypars * sizeof(TypeHandle);
2405             if ((size / sizeof(TypeHandle)) != ntypars) // uint over/underflow
2406                 COMPlusThrow(kArgumentException);
2407             inst = (TypeHandle*) _alloca(size);        
2408
2409             for (DWORD i = 0; i < ntypars; i++) 
2410             {
2411                 REFLECTCLASSBASEREF instRef = (REFLECTCLASSBASEREF)instArray->GetAt(i);
2412
2413                 if (instRef == NULL)
2414                     COMPlusThrowArgumentNull(W("inst"), W("ArgumentNull_ArrayElement"));
2415
2416                 inst[i] = instRef->GetType();
2417             }
2418         }
2419
2420         pNewMethod = MethodDesc::FindOrCreateAssociatedMethodDescForReflection(pMethod, instType, Instantiation(inst, ntypars));
2421     }
2422     HELPER_METHOD_FRAME_END();
2423
2424     return pNewMethod;
2425 }
2426 FCIMPLEND
2427
2428         
2429 FCIMPL2(MethodDesc*, RuntimeMethodHandle::GetMethodFromCanonical, MethodDesc *pMethod, ReflectClassBaseObject *pTypeUNSAFE)
2430 {
2431     CONTRACTL {
2432         FCALL_CHECK;
2433         PRECONDITION(CheckPointer(pMethod));
2434     }
2435     CONTRACTL_END;
2436     
2437     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
2438
2439     TypeHandle instType = refType->GetType();
2440     MethodDesc* pMDescInCanonMT = instType.GetMethodTable()->GetParallelMethodDesc(pMethod);
2441
2442     return pMDescInCanonMT;
2443 }
2444 FCIMPLEND
2445
2446
2447 FCIMPL2(MethodBody *, RuntimeMethodHandle::GetMethodBody, ReflectMethodObject *pMethodUNSAFE, ReflectClassBaseObject *pDeclaringTypeUNSAFE)
2448 {      
2449     CONTRACTL 
2450     {
2451         FCALL_CHECK;
2452     }
2453     CONTRACTL_END;
2454
2455     struct _gc
2456     {
2457         METHODBODYREF MethodBodyObj;
2458         EXCEPTIONHANDLINGCLAUSEREF EHClauseObj;
2459         LOCALVARIABLEINFOREF LocalVariableInfoObj;
2460         U1ARRAYREF                  U1Array;
2461         BASEARRAYREF                TempArray;
2462         REFLECTCLASSBASEREF         declaringType;
2463         REFLECTMETHODREF            refMethod;
2464     } gc;
2465
2466     gc.MethodBodyObj = NULL;
2467     gc.EHClauseObj = NULL;
2468     gc.LocalVariableInfoObj = NULL;
2469     gc.U1Array              = NULL;
2470     gc.TempArray            = NULL;
2471     gc.declaringType        = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pDeclaringTypeUNSAFE);
2472     gc.refMethod = (REFLECTMETHODREF)ObjectToOBJECTREF(pMethodUNSAFE);
2473
2474
2475     if (!gc.refMethod)
2476         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2477
2478     MethodDesc* pMethod = gc.refMethod->GetMethod();
2479
2480     TypeHandle declaringType = gc.declaringType == NULL ? TypeHandle() : gc.declaringType->GetType();
2481
2482     if (!pMethod->IsIL())
2483         return NULL;
2484
2485     HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
2486     {
2487         MethodDesc *pMethodIL = pMethod;
2488         if (pMethod->IsWrapperStub())
2489             pMethodIL = pMethod->GetWrappedMethodDesc();
2490         
2491         COR_ILMETHOD* pILHeader = pMethodIL->GetILHeader();
2492         
2493         if (pILHeader)
2494         {
2495             MethodTable * pExceptionHandlingClauseMT = MscorlibBinder::GetClass(CLASS__EH_CLAUSE);
2496             TypeHandle thEHClauseArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pExceptionHandlingClauseMT), ELEMENT_TYPE_SZARRAY);
2497
2498             MethodTable * pLocalVariableMT = MscorlibBinder::GetClass(CLASS__LOCAL_VARIABLE_INFO);
2499             TypeHandle thLocalVariableArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pLocalVariableMT), ELEMENT_TYPE_SZARRAY);
2500
2501             Module* pModule = pMethod->GetModule();
2502             COR_ILMETHOD_DECODER::DecoderStatus status;
2503             COR_ILMETHOD_DECODER header(pILHeader, pModule->GetMDImport(), &status);
2504
2505             if (status != COR_ILMETHOD_DECODER::SUCCESS)
2506             {
2507                 if (status == COR_ILMETHOD_DECODER::VERIFICATION_ERROR)
2508                 {
2509                     // Throw a verification HR
2510                     COMPlusThrowHR(COR_E_VERIFICATION);
2511                 }
2512                 else
2513                 {
2514                     COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
2515                 }
2516             }
2517
2518             gc.MethodBodyObj = (METHODBODYREF)AllocateObject(MscorlibBinder::GetClass(CLASS__METHOD_BODY));
2519             
2520             gc.MethodBodyObj->m_maxStackSize = header.GetMaxStack();
2521             gc.MethodBodyObj->m_initLocals = !!(header.GetFlags() & CorILMethod_InitLocals);
2522
2523             if (header.IsFat())
2524                 gc.MethodBodyObj->m_localVarSigToken = header.GetLocalVarSigTok();
2525             else
2526                 gc.MethodBodyObj->m_localVarSigToken = 0;
2527
2528             // Allocate the array of IL and fill it in from the method header.
2529             BYTE* pIL = const_cast<BYTE*>(header.Code);
2530             COUNT_T cIL = header.GetCodeSize();
2531             gc.U1Array  = (U1ARRAYREF) AllocatePrimitiveArray(ELEMENT_TYPE_U1, cIL);
2532
2533             SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->m_IL, gc.U1Array, GetAppDomain());
2534             memcpyNoGCRefs(gc.MethodBodyObj->m_IL->GetDataPtr(), pIL, cIL);
2535
2536             // Allocate the array of exception clauses.
2537             INT32 cEh = (INT32)header.EHCount();
2538             const COR_ILMETHOD_SECT_EH* ehInfo = header.EH;
2539             gc.TempArray = (BASEARRAYREF) AllocateArrayEx(thEHClauseArray, &cEh, 1);
2540
2541             SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->m_exceptionClauses, gc.TempArray, GetAppDomain());
2542             
2543             for (INT32 i = 0; i < cEh; i++)
2544             {                    
2545                 COR_ILMETHOD_SECT_EH_CLAUSE_FAT ehBuff; 
2546                 const COR_ILMETHOD_SECT_EH_CLAUSE_FAT* ehClause = 
2547                     (const COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)ehInfo->EHClause(i, &ehBuff); 
2548
2549                 gc.EHClauseObj = (EXCEPTIONHANDLINGCLAUSEREF) AllocateObject(pExceptionHandlingClauseMT);
2550
2551                 gc.EHClauseObj->m_flags = ehClause->GetFlags();  
2552                 gc.EHClauseObj->m_tryOffset = ehClause->GetTryOffset();
2553                 gc.EHClauseObj->m_tryLength = ehClause->GetTryLength();
2554                 gc.EHClauseObj->m_handlerOffset = ehClause->GetHandlerOffset();
2555                 gc.EHClauseObj->m_handlerLength = ehClause->GetHandlerLength();
2556                 
2557                 if ((ehClause->GetFlags() & COR_ILEXCEPTION_CLAUSE_FILTER) == 0)
2558                     gc.EHClauseObj->m_catchToken = ehClause->GetClassToken();
2559                 else
2560                     gc.EHClauseObj->m_filterOffset = ehClause->GetFilterOffset();
2561                 
2562                 gc.MethodBodyObj->m_exceptionClauses->SetAt(i, (OBJECTREF) gc.EHClauseObj);
2563                 SetObjectReference((OBJECTREF*)&(gc.EHClauseObj->m_methodBody), (OBJECTREF)gc.MethodBodyObj, GetAppDomain());
2564             }     
2565            
2566             if (header.LocalVarSig != NULL)
2567             {
2568                 SigTypeContext sigTypeContext(pMethod, declaringType, pMethod->LoadMethodInstantiation());
2569                 MetaSig metaSig(header.LocalVarSig, 
2570                                 header.cbLocalVarSig, 
2571                                 pModule, 
2572                                 &sigTypeContext, 
2573                                 MetaSig::sigLocalVars);
2574                 INT32 cLocals = metaSig.NumFixedArgs();
2575                 gc.TempArray  = (BASEARRAYREF) AllocateArrayEx(thLocalVariableArray, &cLocals, 1);
2576                 SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->m_localVariables, gc.TempArray, GetAppDomain());
2577
2578                 for (INT32 i = 0; i < cLocals; i ++)
2579                 {
2580                     gc.LocalVariableInfoObj = (LOCALVARIABLEINFOREF)AllocateObject(pLocalVariableMT);
2581
2582                     gc.LocalVariableInfoObj->m_localIndex = i;
2583                     
2584                     metaSig.NextArg();
2585
2586                     CorElementType eType;
2587                     IfFailThrow(metaSig.GetArgProps().PeekElemType(&eType));
2588                     if (ELEMENT_TYPE_PINNED == eType)
2589                         gc.LocalVariableInfoObj->m_bIsPinned = TRUE;
2590
2591                     TypeHandle  tempType= metaSig.GetArgProps().GetTypeHandleThrowing(pModule, &sigTypeContext);       
2592                     OBJECTREF refLocalType = tempType.GetManagedClassObject();
2593                     gc.LocalVariableInfoObj->SetType(refLocalType);
2594                     gc.MethodBodyObj->m_localVariables->SetAt(i, (OBJECTREF) gc.LocalVariableInfoObj);
2595                 }        
2596             }
2597             else
2598             {
2599                 INT32 cLocals = 0;
2600                 gc.TempArray  = (BASEARRAYREF) AllocateArrayEx(thLocalVariableArray, &cLocals, 1);
2601                 SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->m_localVariables, gc.TempArray, GetAppDomain());
2602             }
2603         }
2604     }
2605     HELPER_METHOD_FRAME_END();
2606
2607     return (MethodBody*)OBJECTREFToObject(gc.MethodBodyObj);
2608 }
2609 FCIMPLEND
2610
2611 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsConstructor, MethodDesc *pMethod)
2612 {
2613     CONTRACTL {
2614         FCALL_CHECK;
2615         PRECONDITION(CheckPointer(pMethod));
2616     }
2617     CONTRACTL_END;
2618
2619     BOOL ret = FALSE;
2620     BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
2621     ret = (BOOL)pMethod->IsClassConstructorOrCtor();
2622     END_SO_INTOLERANT_CODE;
2623     FC_RETURN_BOOL(ret);
2624 }
2625 FCIMPLEND
2626
2627 FCIMPL1(Object*, RuntimeMethodHandle::GetLoaderAllocator, MethodDesc *pMethod)
2628 {
2629     CONTRACTL {
2630         FCALL_CHECK;
2631     }
2632     CONTRACTL_END;
2633
2634     OBJECTREF loaderAllocator = NULL;
2635
2636     if (!pMethod)
2637         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2638
2639     HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(loaderAllocator);
2640
2641     LoaderAllocator *pLoaderAllocator = pMethod->GetLoaderAllocator();
2642     loaderAllocator = pLoaderAllocator->GetExposedObject();
2643
2644     HELPER_METHOD_FRAME_END();
2645
2646     return OBJECTREFToObject(loaderAllocator);
2647 }
2648 FCIMPLEND
2649
2650 //*********************************************************************************************
2651 //*********************************************************************************************
2652 //*********************************************************************************************
2653
2654 FCIMPL1(StringObject*, RuntimeFieldHandle::GetName, ReflectFieldObject *pFieldUNSAFE) {
2655     CONTRACTL {
2656         FCALL_CHECK;
2657     }
2658     CONTRACTL_END;
2659     
2660     REFLECTFIELDREF refField = (REFLECTFIELDREF)ObjectToOBJECTREF(pFieldUNSAFE);
2661     if (!refField)
2662         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2663         
2664     FieldDesc *pField = refField->GetField();
2665     
2666     STRINGREF refString = NULL;
2667     HELPER_METHOD_FRAME_BEGIN_RET_1(refField);
2668     {
2669         refString = StringObject::NewString(pField->GetName());
2670     }
2671     HELPER_METHOD_FRAME_END();
2672     return (StringObject*)OBJECTREFToObject(refString);
2673 }
2674 FCIMPLEND
2675     
2676 FCIMPL1(LPCUTF8, RuntimeFieldHandle::GetUtf8Name, FieldDesc *pField) {
2677     CONTRACTL {
2678         FCALL_CHECK;
2679         PRECONDITION(CheckPointer(pField));
2680     }
2681     CONTRACTL_END;
2682     
2683     LPCUTF8    szFieldName;
2684     
2685     if (FAILED(pField->GetName_NoThrow(&szFieldName)))
2686     {
2687         FCThrow(kBadImageFormatException);
2688     }
2689     return szFieldName;
2690 }
2691 FCIMPLEND
2692
2693 FCIMPL2(FC_BOOL_RET, RuntimeFieldHandle::MatchesNameHash, FieldDesc * pField, ULONG hash)
2694 {
2695     FCALL_CONTRACT;
2696
2697     FC_RETURN_BOOL(pField->MightHaveName(hash));
2698 }
2699 FCIMPLEND
2700
2701 FCIMPL1(INT32, RuntimeFieldHandle::GetAttributes, FieldDesc *pField) {
2702     CONTRACTL {
2703         FCALL_CHECK;
2704     }
2705     CONTRACTL_END;
2706     
2707     if (!pField)
2708         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2709
2710     INT32 ret = 0;
2711     BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
2712     ret = (INT32)pField->GetAttributes();
2713     END_SO_INTOLERANT_CODE;
2714     return ret;
2715 }
2716 FCIMPLEND
2717     
2718 FCIMPL1(ReflectClassBaseObject*, RuntimeFieldHandle::GetApproxDeclaringType, FieldDesc *pField) {
2719     CONTRACTL {
2720         FCALL_CHECK;
2721     }
2722     CONTRACTL_END;
2723     
2724     if (!pField)
2725         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2726         
2727     TypeHandle th = TypeHandle(pField->GetApproxEnclosingMethodTable());  // <REVISIT_TODO> this needs to be checked - see bug 184355 </REVISIT_TODO>
2728     RETURN_CLASS_OBJECT(th, NULL);
2729 }
2730 FCIMPLEND
2731
2732 FCIMPL1(INT32, RuntimeFieldHandle::GetToken, ReflectFieldObject *pFieldUNSAFE) {
2733     CONTRACTL {
2734         FCALL_CHECK;
2735     }
2736     CONTRACTL_END;
2737
2738     REFLECTFIELDREF refField = (REFLECTFIELDREF)ObjectToOBJECTREF(pFieldUNSAFE);
2739     if (!refField)
2740         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2741         
2742     FieldDesc *pField = refField->GetField();
2743
2744     INT32 tkFieldDef = (INT32)pField->GetMemberDef();
2745     _ASSERTE(!IsNilToken(tkFieldDef) || tkFieldDef == mdFieldDefNil);
2746     return tkFieldDef;
2747 }
2748 FCIMPLEND
2749
2750 FCIMPL2(FieldDesc*, RuntimeFieldHandle::GetStaticFieldForGenericType, FieldDesc *pField, ReflectClassBaseObject *pDeclaringTypeUNSAFE)
2751 {
2752     CONTRACTL {
2753         FCALL_CHECK;
2754     }
2755     CONTRACTL_END;
2756
2757     REFLECTCLASSBASEREF refDeclaringType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pDeclaringTypeUNSAFE);
2758
2759     if ((refDeclaringType == NULL) || (pField == NULL))
2760         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2761
2762     TypeHandle declaringType = refDeclaringType->GetType();
2763     
2764     if (!pField)
2765         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2766     if (declaringType.IsTypeDesc())
2767         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2768     MethodTable *pMT = declaringType.AsMethodTable();
2769
2770     _ASSERTE(pField->IsStatic());
2771     if (pMT->HasGenericsStaticsInfo())
2772         pField = pMT->GetFieldDescByIndex(pField->GetApproxEnclosingMethodTable()->GetIndexForFieldDesc(pField));
2773     _ASSERTE(!pField->IsSharedByGenericInstantiations());
2774     _ASSERTE(pField->GetEnclosingMethodTable() == pMT);
2775
2776     return pField;
2777 }
2778 FCIMPLEND
2779
2780 FCIMPL1(ReflectModuleBaseObject*, AssemblyHandle::GetManifestModule, AssemblyBaseObject* pAssemblyUNSAFE) {
2781     FCALL_CONTRACT;
2782
2783     ASSEMBLYREF refAssembly = (ASSEMBLYREF)ObjectToOBJECTREF(pAssemblyUNSAFE);
2784     
2785     if (refAssembly == NULL)
2786         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2787
2788     DomainAssembly *pAssembly = refAssembly->GetDomainAssembly();
2789     Assembly* currentAssembly = pAssembly->GetCurrentAssembly();
2790
2791     if (currentAssembly == NULL)
2792         return NULL;
2793
2794     Module *pModule = currentAssembly->GetManifestModule();
2795     DomainFile * pDomainFile = pModule->FindDomainFile(GetAppDomain());
2796
2797 #ifdef _DEBUG
2798     OBJECTREF orModule;
2799     
2800     HELPER_METHOD_FRAME_BEGIN_RET_1(refAssembly);
2801     orModule = (pDomainFile != NULL) ? pDomainFile->GetExposedModuleObjectIfExists() : NULL;
2802     if (orModule == NULL)
2803         orModule = pModule->GetExposedObject();
2804 #else
2805     OBJECTREF orModule = (pDomainFile != NULL) ? pDomainFile->GetExposedModuleObjectIfExists() : NULL;
2806     if (orModule != NULL)
2807         return (ReflectModuleBaseObject*)OBJECTREFToObject(orModule);
2808
2809     HELPER_METHOD_FRAME_BEGIN_RET_1(refAssembly);
2810     orModule = pModule->GetExposedObject();
2811 #endif
2812
2813     HELPER_METHOD_FRAME_END();
2814     return (ReflectModuleBaseObject*)OBJECTREFToObject(orModule);
2815
2816 }
2817 FCIMPLEND
2818
2819 FCIMPL1(INT32, AssemblyHandle::GetToken, AssemblyBaseObject* pAssemblyUNSAFE) {
2820     FCALL_CONTRACT;
2821     
2822     ASSEMBLYREF refAssembly = (ASSEMBLYREF)ObjectToOBJECTREF(pAssemblyUNSAFE);
2823     
2824     if (refAssembly == NULL)
2825         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2826
2827     DomainAssembly *pAssembly = refAssembly->GetDomainAssembly();
2828     mdAssembly token = mdAssemblyNil;
2829     
2830     IMDInternalImport *mdImport = pAssembly->GetCurrentAssembly()->GetManifestImport();
2831     
2832     if (mdImport != 0)
2833     {
2834         if (FAILED(mdImport->GetAssemblyFromScope(&token)))
2835         {
2836             FCThrow(kBadImageFormatException);
2837         }
2838     }
2839     
2840     return token;
2841 }
2842 FCIMPLEND
2843
2844     
2845 void QCALLTYPE ModuleHandle::GetPEKind(QCall::ModuleHandle pModule, DWORD* pdwPEKind, DWORD* pdwMachine)
2846 {
2847     QCALL_CONTRACT;
2848
2849     BEGIN_QCALL;
2850     pModule->GetFile()->GetPEKindAndMachine(pdwPEKind, pdwMachine);
2851     END_QCALL;
2852 }
2853
2854 FCIMPL1(INT32, ModuleHandle::GetMDStreamVersion, ReflectModuleBaseObject * pModuleUNSAFE)
2855 {
2856     FCALL_CONTRACT;
2857
2858     REFLECTMODULEBASEREF refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
2859
2860     if (refModule == NULL)
2861         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2862
2863     Module *pModule = refModule->GetModule();
2864     
2865     if (pModule->IsResource())
2866         return 0;
2867     
2868     return pModule->GetMDImport()->GetMetadataStreamVersion();   
2869 }
2870 FCIMPLEND
2871
2872 void QCALLTYPE ModuleHandle::GetModuleType(QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retType)
2873 {
2874     QCALL_CONTRACT;
2875
2876     TypeHandle globalTypeHandle = TypeHandle();
2877     
2878     BEGIN_QCALL;
2879     
2880         EX_TRY
2881         {          
2882             globalTypeHandle = TypeHandle(pModule->GetGlobalMethodTable());
2883         }
2884         EX_SWALLOW_NONTRANSIENT;
2885
2886         if (!globalTypeHandle.IsNull())
2887         {
2888             GCX_COOP();
2889             retType.Set(globalTypeHandle.GetManagedClassObject());
2890         }
2891
2892     END_QCALL;
2893
2894     return;
2895 }
2896
2897 FCIMPL1(INT32, ModuleHandle::GetToken, ReflectModuleBaseObject * pModuleUNSAFE) {
2898     CONTRACTL {
2899         FCALL_CHECK;
2900     }
2901     CONTRACTL_END;
2902
2903     REFLECTMODULEBASEREF refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
2904
2905     if (refModule == NULL)
2906         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2907
2908     Module *pModule = refModule->GetModule();
2909     
2910     if (pModule->IsResource())
2911         return mdModuleNil;
2912     
2913     return pModule->GetMDImport()->GetModuleFromScope();
2914 }
2915 FCIMPLEND
2916
2917 FCIMPL1(IMDInternalImport*, ModuleHandle::GetMetadataImport, ReflectModuleBaseObject * pModuleUNSAFE)
2918 {
2919     FCALL_CONTRACT;
2920
2921     REFLECTMODULEBASEREF refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
2922
2923     if (refModule == NULL)
2924         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2925
2926     Module *pModule = refModule->GetModule();
2927
2928     if (pModule->IsResource())
2929         return NULL;
2930
2931     return pModule->GetMDImport();
2932 }
2933 FCIMPLEND
2934
2935 BOOL QCALLTYPE ModuleHandle::ContainsPropertyMatchingHash(QCall::ModuleHandle pModule, INT32 tkProperty, ULONG hash)
2936 {
2937     QCALL_CONTRACT;
2938
2939     BOOL fContains = TRUE;
2940
2941     BEGIN_QCALL;
2942
2943     fContains = pModule->MightContainMatchingProperty(tkProperty, hash);
2944
2945     END_QCALL;
2946
2947     return fContains;
2948 }
2949
2950 void QCALLTYPE ModuleHandle::ResolveType(QCall::ModuleHandle pModule, INT32 tkType, TypeHandle *typeArgs, INT32 typeArgsCount, TypeHandle *methodArgs, INT32 methodArgsCount, QCall::ObjectHandleOnStack retType)
2951 {
2952     QCALL_CONTRACT;
2953
2954     TypeHandle typeHandle;
2955     
2956     BEGIN_QCALL;
2957     
2958     _ASSERTE(!IsNilToken(tkType));
2959
2960     SigTypeContext typeContext(Instantiation(typeArgs, typeArgsCount), Instantiation(methodArgs, methodArgsCount));
2961         typeHandle = ClassLoader::LoadTypeDefOrRefOrSpecThrowing(pModule, tkType, &typeContext, 
2962                                                           ClassLoader::ThrowIfNotFound, 
2963                                                           ClassLoader::PermitUninstDefOrRef);
2964
2965     GCX_COOP();
2966     retType.Set(typeHandle.GetManagedClassObject());
2967
2968     END_QCALL;
2969
2970     return;
2971 }
2972
2973 MethodDesc *QCALLTYPE ModuleHandle::ResolveMethod(QCall::ModuleHandle pModule, INT32 tkMemberRef, TypeHandle *typeArgs, INT32 typeArgsCount, TypeHandle *methodArgs, INT32 methodArgsCount)
2974 {
2975     QCALL_CONTRACT;
2976
2977     MethodDesc* pMD = NULL;
2978     
2979     BEGIN_QCALL;
2980
2981     _ASSERTE(!IsNilToken(tkMemberRef));
2982
2983     BOOL strictMetadataChecks = (TypeFromToken(tkMemberRef) == mdtMethodSpec);
2984
2985     SigTypeContext typeContext(Instantiation(typeArgs, typeArgsCount), Instantiation(methodArgs, methodArgsCount));
2986     pMD = MemberLoader::GetMethodDescFromMemberDefOrRefOrSpec(pModule, tkMemberRef, &typeContext, strictMetadataChecks, FALSE);
2987
2988     // This will get us the instantiating or unboxing stub if needed
2989     pMD = MethodDesc::FindOrCreateAssociatedMethodDescForReflection(pMD, pMD->GetMethodTable(), pMD->GetMethodInstantiation());
2990
2991     END_QCALL;
2992
2993     return pMD;
2994 }
2995
2996 void QCALLTYPE ModuleHandle::ResolveField(QCall::ModuleHandle pModule, INT32 tkMemberRef, TypeHandle *typeArgs, INT32 typeArgsCount, TypeHandle *methodArgs, INT32 methodArgsCount, QCall::ObjectHandleOnStack retField)
2997 {
2998     QCALL_CONTRACT;
2999
3000     FieldDesc* pField = NULL;
3001     
3002     BEGIN_QCALL;
3003
3004     _ASSERTE(!IsNilToken(tkMemberRef));
3005
3006     SigTypeContext typeContext(Instantiation(typeArgs, typeArgsCount), Instantiation(methodArgs, methodArgsCount));
3007     pField = MemberLoader::GetFieldDescFromMemberDefOrRef(pModule, tkMemberRef, &typeContext, FALSE);
3008     GCX_COOP();
3009     retField.Set(pField->GetStubFieldInfo());
3010
3011     END_QCALL;
3012
3013     return;
3014 }
3015
3016 void QCALLTYPE ModuleHandle::GetAssembly(QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retAssembly)
3017 {
3018     QCALL_CONTRACT;
3019
3020     DomainAssembly *pAssembly = NULL;
3021
3022     BEGIN_QCALL;
3023     pAssembly = pModule->GetDomainAssembly();
3024
3025     GCX_COOP();
3026     retAssembly.Set(pAssembly->GetExposedAssemblyObject());
3027     END_QCALL;
3028
3029     return;
3030 }
3031
3032 FCIMPL5(ReflectMethodObject*, ModuleHandle::GetDynamicMethod, ReflectMethodObject *pMethodUNSAFE, ReflectModuleBaseObject *pModuleUNSAFE, StringObject *name, U1Array *sig,  Object *resolver) {
3033     CONTRACTL {
3034         FCALL_CHECK;
3035         PRECONDITION(CheckPointer(name));
3036         PRECONDITION(CheckPointer(sig));
3037     }
3038     CONTRACTL_END;
3039     
3040     DynamicMethodDesc *pNewMD = NULL;
3041
3042     struct
3043     {
3044         STRINGREF nameRef;
3045         OBJECTREF resolverRef;
3046         OBJECTREF methodRef;
3047         REFLECTMETHODREF retMethod;
3048         REFLECTMODULEBASEREF refModule;
3049     } gc;
3050     gc.nameRef = (STRINGREF)name;
3051     gc.resolverRef = (OBJECTREF)resolver;
3052     gc.methodRef = ObjectToOBJECTREF(pMethodUNSAFE);
3053     gc.retMethod = NULL;
3054     gc.refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
3055
3056     if (gc.refModule == NULL)
3057         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
3058
3059     Module *pModule = gc.refModule->GetModule();
3060
3061     HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
3062     
3063     DomainFile *pDomainModule = pModule->GetDomainFile();
3064
3065     U1ARRAYREF dataArray = (U1ARRAYREF)sig;
3066     DWORD sigSize = dataArray->GetNumComponents();
3067     NewHolder<BYTE> pSig(new BYTE[sigSize]);
3068     memcpy(pSig, dataArray->GetDataPtr(), sigSize);
3069
3070     DWORD length = gc.nameRef->GetStringLength();
3071     NewArrayHolder<char> pName(new char[(length + 1) * 2]);
3072     pName[0] = '\0';
3073     length = WszWideCharToMultiByte(CP_UTF8, 0, gc.nameRef->GetBuffer(), length, pName, (length + 1) * 2 - sizeof(char), NULL, NULL);
3074     if (length)
3075         pName[length / sizeof(char)] = '\0';
3076
3077     DynamicMethodTable *pMTForDynamicMethods = pDomainModule->GetDynamicMethodTable();
3078     pNewMD = pMTForDynamicMethods->GetDynamicMethod(pSig, sigSize, pName);
3079     _ASSERTE(pNewMD != NULL);
3080     // pNewMD now owns pSig and pName.
3081     pSig.SuppressRelease();
3082     pName.SuppressRelease();
3083
3084     // create a handle to hold the resolver objectref
3085     OBJECTHANDLE resolverHandle = pDomainModule->GetAppDomain()->CreateLongWeakHandle(gc.resolverRef);
3086     pNewMD->GetLCGMethodResolver()->SetManagedResolver(resolverHandle);
3087     gc.retMethod = pNewMD->GetStubMethodInfo();
3088     gc.retMethod->SetKeepAlive(gc.resolverRef);
3089
3090     LoaderAllocator *pLoaderAllocator = pModule->GetLoaderAllocator();
3091
3092     if (pLoaderAllocator->IsCollectible())
3093         pLoaderAllocator->AddReference();
3094    
3095     HELPER_METHOD_FRAME_END();
3096
3097     return (ReflectMethodObject*)OBJECTREFToObject(gc.retMethod);
3098 }
3099 FCIMPLEND
3100
3101 void QCALLTYPE RuntimeMethodHandle::GetCallerType(QCall::StackCrawlMarkHandle pStackMark, QCall::ObjectHandleOnStack retType)
3102
3103     QCALL_CONTRACT;
3104
3105     BEGIN_QCALL;
3106     GCX_COOP();
3107     MethodTable *pMT = NULL;
3108
3109     pMT = SystemDomain::GetCallersType(pStackMark);
3110
3111     if (pMT != NULL)
3112         retType.Set(pMT->GetManagedClassObject());
3113
3114     END_QCALL;
3115
3116     return;
3117 }