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