Enable reflection load ComImport assembly and Type.IsComObjectType (#16943)
[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     CONTRACTL {
1016         FCALL_CHECK;
1017     }
1018     CONTRACTL_END;
1019     
1020     BOOL ret = FALSE;
1021
1022     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1023
1024     if (refType == NULL)
1025         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1026
1027     TypeHandle typeHandle = refType->GetType();
1028
1029     HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
1030     {
1031         if (isGenericCOM) 
1032             ret = IsComObjectClass(typeHandle);
1033         else
1034             ret = IsComWrapperClass(typeHandle);
1035     }
1036     HELPER_METHOD_FRAME_END();
1037
1038     FC_RETURN_BOOL(ret);
1039 }
1040 FCIMPLEND
1041
1042 FCIMPL1(LPCUTF8, RuntimeTypeHandle::GetUtf8Name, ReflectClassBaseObject* pTypeUNSAFE) {
1043     CONTRACTL {
1044         FCALL_CHECK;
1045     }
1046     CONTRACTL_END;
1047     
1048     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1049
1050     if (refType == NULL)
1051         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1052
1053     TypeHandle typeHandle = refType->GetType();
1054     INT32 tkTypeDef = mdTypeDefNil;
1055     LPCUTF8 szName = NULL;
1056
1057     if (typeHandle.IsGenericVariable())
1058         FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1059         
1060     if (typeHandle.IsTypeDesc()) 
1061         FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1062
1063     MethodTable* pMT= typeHandle.GetMethodTable();
1064     
1065     if (pMT == NULL)
1066         FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1067
1068     tkTypeDef = (INT32)pMT->GetCl();
1069     
1070     if (IsNilToken(tkTypeDef))
1071         FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1072     
1073     if (FAILED(pMT->GetMDImport()->GetNameOfTypeDef(tkTypeDef, &szName, NULL)))
1074     {
1075         FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1076     }
1077     
1078     _ASSERTE(CheckPointer(szName, NULL_OK));
1079     
1080     return szName;
1081 }
1082 FCIMPLEND
1083
1084 FCIMPL1(INT32, RuntimeTypeHandle::GetToken, ReflectClassBaseObject *pTypeUNSAFE) {
1085     CONTRACTL {
1086         FCALL_CHECK;
1087     }
1088     CONTRACTL_END;
1089
1090     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1091
1092     if (refType == NULL)
1093         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1094
1095     TypeHandle typeHandle = refType->GetType();
1096
1097     if (typeHandle.IsTypeDesc()) 
1098     {
1099         if (typeHandle.IsGenericVariable())
1100         {
1101             INT32 tkTypeDef = typeHandle.AsGenericVariable()->GetToken();
1102         
1103             _ASSERTE(!IsNilToken(tkTypeDef) && TypeFromToken(tkTypeDef) == mdtGenericParam);
1104
1105             return tkTypeDef;
1106         }
1107         
1108         return mdTypeDefNil;
1109     }
1110
1111     return  (INT32)typeHandle.AsMethodTable()->GetCl();
1112 }
1113 FCIMPLEND
1114
1115 PVOID QCALLTYPE RuntimeTypeHandle::GetGCHandle(EnregisteredTypeHandle pTypeHandle, INT32 handleType)
1116 {
1117     QCALL_CONTRACT;
1118     
1119     OBJECTHANDLE objHandle = NULL;
1120
1121     BEGIN_QCALL;
1122     
1123     GCX_COOP();
1124
1125     TypeHandle th = TypeHandle::FromPtr(pTypeHandle);
1126     assert(handleType >= HNDTYPE_WEAK_SHORT && handleType <= HNDTYPE_WEAK_WINRT);
1127     objHandle = th.GetDomain()->CreateTypedHandle(NULL, static_cast<HandleType>(handleType));
1128     th.GetLoaderAllocator()->RegisterHandleForCleanup(objHandle);
1129
1130     END_QCALL;
1131
1132     return objHandle;
1133 }
1134
1135 void QCALLTYPE RuntimeTypeHandle::VerifyInterfaceIsImplemented(EnregisteredTypeHandle pTypeHandle, EnregisteredTypeHandle pIFaceHandle)
1136 {
1137     QCALL_CONTRACT;
1138
1139     BEGIN_QCALL;
1140
1141     TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
1142     TypeHandle ifaceHandle = TypeHandle::FromPtr(pIFaceHandle);
1143
1144     if (typeHandle.IsGenericVariable())
1145         COMPlusThrow(kArgumentException, W("Arg_InvalidHandle"));
1146     
1147     if (typeHandle.IsTypeDesc()) {
1148         if (!typeHandle.IsArray())
1149             COMPlusThrow(kArgumentException, W("Arg_NotFoundIFace"));
1150     }
1151
1152     if (typeHandle.IsInterface())
1153         COMPlusThrow(kArgumentException, W("Argument_InterfaceMap"));
1154
1155     if (!ifaceHandle.IsInterface())
1156         COMPlusThrow(kArgumentException, W("Arg_MustBeInterface"));
1157
1158     // First try the cheap check, which amounts to iterating the interface map looking for
1159     // the ifaceHandle MethodTable.
1160     if (!typeHandle.GetMethodTable()->ImplementsInterface(ifaceHandle.AsMethodTable()))
1161     {   // If the cheap check fails, try the more expensive but complete check.
1162         if (!typeHandle.CanCastTo(ifaceHandle))
1163         {   // If the complete check fails, we're certain that this type
1164             // does not implement the interface specified.
1165         COMPlusThrow(kArgumentException, W("Arg_NotFoundIFace"));
1166         }
1167     }
1168
1169     END_QCALL;
1170 }
1171
1172 MethodDesc* QCALLTYPE RuntimeTypeHandle::GetInterfaceMethodImplementation(EnregisteredTypeHandle pTypeHandle, EnregisteredTypeHandle pOwner, MethodDesc * pMD)
1173 {
1174     QCALL_CONTRACT;
1175
1176     MethodDesc* pResult = nullptr;
1177
1178     BEGIN_QCALL;
1179
1180     TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
1181     TypeHandle thOwnerOfMD = TypeHandle::FromPtr(pOwner);
1182
1183         // Ok to have INVALID_SLOT in the case where abstract class does not implement an interface method.
1184         // This case can not be reproed using C# "implements" all interface methods
1185         // with at least an abstract method. b19897_GetInterfaceMap_Abstract.exe tests this case.
1186         //@TODO:STUBDISPATCH: Don't need to track down the implementation, just the declaration, and this can
1187         //@TODO:              be done faster - just need to make a function FindDispatchDecl.
1188         DispatchSlot slot(typeHandle.GetMethodTable()->FindDispatchSlotForInterfaceMD(thOwnerOfMD, pMD));
1189     if (!slot.IsNull())
1190             pResult = slot.GetMethodDesc();
1191
1192     END_QCALL;
1193     
1194     return pResult;
1195     }
1196     
1197 void QCALLTYPE RuntimeTypeHandle::GetDefaultConstructor(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retMethod)
1198 {
1199     QCALL_CONTRACT;
1200
1201     BEGIN_QCALL;
1202     
1203     MethodDesc* pCtor = NULL;
1204     
1205     TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
1206
1207     if (!typeHandle.IsTypeDesc())
1208     {
1209         MethodTable* pMethodTable = typeHandle.AsMethodTable();
1210         if (pMethodTable->HasDefaultConstructor())
1211             pCtor = pMethodTable->GetDefaultConstructor();
1212     }
1213
1214     if (pCtor != NULL)
1215     {
1216         GCX_COOP();
1217         retMethod.Set(pCtor->GetStubMethodInfo());
1218     }
1219     END_QCALL;
1220
1221     return;
1222 }
1223
1224 FCIMPL1(ReflectMethodObject*, RuntimeTypeHandle::GetDeclaringMethod, ReflectClassBaseObject *pTypeUNSAFE) {
1225     CONTRACTL {
1226         FCALL_CHECK;
1227     }
1228     CONTRACTL_END;
1229     
1230     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1231
1232     if (refType == NULL)
1233         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1234
1235     TypeHandle typeHandle = refType->GetType();;
1236
1237     if (!typeHandle.IsTypeDesc())
1238         return NULL;
1239     
1240     TypeVarTypeDesc* pGenericVariable = typeHandle.AsGenericVariable();
1241     mdToken defToken = pGenericVariable->GetTypeOrMethodDef();
1242     if (TypeFromToken(defToken) != mdtMethodDef)
1243         return NULL;
1244
1245     REFLECTMETHODREF pRet = NULL;
1246     HELPER_METHOD_FRAME_BEGIN_RET_0();
1247     MethodDesc * pMD = pGenericVariable->LoadOwnerMethod();
1248     pMD->CheckRestore();
1249     pRet = pMD->GetStubMethodInfo();
1250     HELPER_METHOD_FRAME_END();
1251
1252     return (ReflectMethodObject*)OBJECTREFToObject(pRet);
1253 }
1254 FCIMPLEND
1255
1256 FCIMPL1(ReflectClassBaseObject*, RuntimeTypeHandle::GetDeclaringType, ReflectClassBaseObject *pTypeUNSAFE) {
1257     CONTRACTL {
1258         FCALL_CHECK;
1259     }
1260     CONTRACTL_END;
1261     
1262     TypeHandle retTypeHandle;
1263
1264     BOOL fThrowException = FALSE;
1265     LPCWSTR argName = W("Arg_InvalidHandle");
1266     RuntimeExceptionKind reKind = kArgumentNullException;
1267
1268     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1269
1270     if (refType == NULL)
1271         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1272
1273     TypeHandle typeHandle = refType->GetType();
1274
1275     MethodTable* pMT = NULL;
1276     mdTypeDef tkTypeDef = mdTokenNil;
1277
1278     BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
1279     if (typeHandle.IsTypeDesc()) {
1280
1281         if (typeHandle.IsGenericVariable()) {
1282             TypeVarTypeDesc* pGenericVariable = typeHandle.AsGenericVariable();
1283             mdToken defToken = pGenericVariable->GetTypeOrMethodDef();
1284             
1285             // Try the fast way first (if the declaring type has been loaded already).
1286             if (TypeFromToken(defToken) == mdtMethodDef)
1287             {
1288                 MethodDesc * retMethod = pGenericVariable->GetModule()->LookupMethodDef(defToken);
1289                 if (retMethod != NULL)
1290                     retTypeHandle = retMethod->GetMethodTable();
1291             }
1292             else
1293             {
1294                 retTypeHandle = pGenericVariable->GetModule()->LookupTypeDef(defToken);
1295             }
1296
1297             if (!retTypeHandle.IsNull() && retTypeHandle.IsFullyLoaded())
1298                 goto Exit;
1299
1300             // OK, need to go the slow way and load the type first.
1301             HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
1302             {
1303                 if (TypeFromToken(defToken) == mdtMethodDef)
1304                 {
1305                     retTypeHandle = pGenericVariable->LoadOwnerMethod()->GetMethodTable();
1306                 }
1307                 else
1308                 {
1309                     retTypeHandle = pGenericVariable->LoadOwnerType();
1310                 }
1311                 retTypeHandle.CheckRestore();
1312             }
1313             HELPER_METHOD_FRAME_END();
1314             goto Exit;
1315         }
1316         if (!typeHandle.IsArray())
1317         {
1318             retTypeHandle = TypeHandle();
1319             goto Exit;
1320         }
1321     }
1322     
1323     pMT = typeHandle.GetMethodTable();
1324
1325     if (pMT == NULL) 
1326     {
1327         fThrowException = TRUE;
1328         goto Exit;
1329     }
1330
1331     if(!pMT->GetClass()->IsNested())
1332     {
1333         retTypeHandle = TypeHandle();
1334         goto Exit;
1335     }
1336
1337     tkTypeDef = pMT->GetCl();
1338     
1339     if (FAILED(typeHandle.GetModule()->GetMDImport()->GetNestedClassProps(tkTypeDef, &tkTypeDef)))
1340     {
1341         fThrowException = TRUE;
1342         reKind = kBadImageFormatException;
1343         argName = NULL;
1344         goto Exit;
1345     }
1346     
1347     // Try the fast way first (if the declaring type has been loaded already).
1348     retTypeHandle = typeHandle.GetModule()->LookupTypeDef(tkTypeDef);
1349     if (retTypeHandle.IsNull())
1350     { 
1351          // OK, need to go the slow way and load the type first.
1352         HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
1353         {
1354             retTypeHandle = ClassLoader::LoadTypeDefThrowing(typeHandle.GetModule(), tkTypeDef, 
1355                                                              ClassLoader::ThrowIfNotFound, 
1356                                                              ClassLoader::PermitUninstDefOrRef);
1357         }
1358         HELPER_METHOD_FRAME_END();
1359     }
1360 Exit:
1361
1362     END_SO_INTOLERANT_CODE;
1363
1364     if (fThrowException)
1365     {
1366         FCThrowRes(reKind, argName);
1367     }
1368
1369     RETURN_CLASS_OBJECT(retTypeHandle, refType);
1370   }
1371 FCIMPLEND
1372
1373 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::CanCastTo, ReflectClassBaseObject *pTypeUNSAFE, ReflectClassBaseObject *pTargetUNSAFE) {
1374     CONTRACTL {
1375         FCALL_CHECK;
1376     }
1377     CONTRACTL_END;
1378     
1379     
1380     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1381     REFLECTCLASSBASEREF refTarget = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTargetUNSAFE);
1382
1383     if ((refType == NULL) || (refTarget == NULL)) 
1384         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1385
1386     TypeHandle fromHandle = refType->GetType();
1387     TypeHandle toHandle = refTarget->GetType();
1388
1389     BOOL iRetVal = 0;
1390
1391     TypeHandle::CastResult r = fromHandle.CanCastToNoGC(toHandle);
1392     if (r == TypeHandle::MaybeCast)
1393     {
1394         HELPER_METHOD_FRAME_BEGIN_RET_2(refType, refTarget);
1395         iRetVal = fromHandle.CanCastTo(toHandle);
1396         HELPER_METHOD_FRAME_END();
1397     }
1398     else
1399     {
1400         iRetVal = (r == TypeHandle::CanCast);
1401     }
1402
1403     // We allow T to be cast to Nullable<T>
1404     if (!iRetVal && Nullable::IsNullableType(toHandle) && !fromHandle.IsTypeDesc())
1405     {
1406         HELPER_METHOD_FRAME_BEGIN_RET_2(refType, refTarget);
1407         if (Nullable::IsNullableForType(toHandle, fromHandle.AsMethodTable())) 
1408         {
1409             iRetVal = TRUE;
1410         }
1411         HELPER_METHOD_FRAME_END();
1412     }
1413         
1414     FC_RETURN_BOOL(iRetVal);
1415 }
1416 FCIMPLEND
1417
1418 void QCALLTYPE RuntimeTypeHandle::GetTypeByNameUsingCARules(LPCWSTR pwzClassName, QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retType)
1419 {
1420     QCALL_CONTRACT;
1421     
1422     TypeHandle typeHandle;
1423
1424     BEGIN_QCALL;
1425         
1426     if (!pwzClassName)
1427         COMPlusThrowArgumentNull(W("className"),W("ArgumentNull_String"));
1428
1429     typeHandle = TypeName::GetTypeUsingCASearchRules(pwzClassName, pModule->GetAssembly());
1430
1431     GCX_COOP();
1432     retType.Set(typeHandle.GetManagedClassObject());
1433
1434     END_QCALL;
1435
1436     return;
1437 }
1438
1439 void QCALLTYPE RuntimeTypeHandle::GetTypeByName(LPCWSTR pwzClassName, BOOL bThrowOnError, BOOL bIgnoreCase, BOOL bReflectionOnly,
1440                                                 QCall::StackCrawlMarkHandle pStackMark, 
1441                                                 ICLRPrivBinder * pPrivHostBinder,
1442                                                 BOOL bLoadTypeFromPartialNameHack, QCall::ObjectHandleOnStack retType,
1443                                                 QCall::ObjectHandleOnStack keepAlive)
1444 {
1445     QCALL_CONTRACT;
1446     
1447     TypeHandle typeHandle;
1448     
1449     BEGIN_QCALL;
1450
1451     if (!pwzClassName)
1452             COMPlusThrowArgumentNull(W("className"),W("ArgumentNull_String"));
1453
1454     {
1455         typeHandle = TypeName::GetTypeManaged(pwzClassName, NULL, bThrowOnError, bIgnoreCase, bReflectionOnly, /*bProhibitAsmQualifiedName =*/ FALSE, pStackMark,
1456                                               bLoadTypeFromPartialNameHack, (OBJECTREF*)keepAlive.m_ppObject,
1457                                               pPrivHostBinder);
1458     }
1459
1460     if (!typeHandle.IsNull())
1461     {
1462         GCX_COOP();
1463         retType.Set(typeHandle.GetManagedClassObject());
1464     }
1465
1466     END_QCALL;
1467
1468     return;
1469 }
1470
1471 FCIMPL6(FC_BOOL_RET, RuntimeTypeHandle::SatisfiesConstraints, PTR_ReflectClassBaseObject pParamTypeUNSAFE, TypeHandle *typeContextArgs, INT32 typeContextCount, TypeHandle *methodContextArgs, INT32 methodContextCount, PTR_ReflectClassBaseObject pArgumentTypeUNSAFE);
1472 {
1473     CONTRACTL {
1474         FCALL_CHECK;
1475         PRECONDITION(CheckPointer(typeContextArgs, NULL_OK));
1476         PRECONDITION(CheckPointer(methodContextArgs, NULL_OK));
1477     }
1478     CONTRACTL_END;
1479     
1480     REFLECTCLASSBASEREF refParamType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pParamTypeUNSAFE);
1481     REFLECTCLASSBASEREF refArgumentType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pArgumentTypeUNSAFE);
1482
1483     TypeHandle thGenericParameter = refParamType->GetType();
1484     TypeHandle thGenericArgument = refArgumentType->GetType();
1485     BOOL bResult = FALSE; 
1486     SigTypeContext typeContext;
1487
1488     Instantiation classInst;
1489     Instantiation methodInst;
1490
1491     if (typeContextArgs != NULL)
1492     {
1493         classInst = Instantiation(typeContextArgs, typeContextCount);
1494     }
1495     
1496     if (methodContextArgs != NULL)
1497     {
1498         methodInst = Instantiation(methodContextArgs, methodContextCount);
1499     }
1500
1501     SigTypeContext::InitTypeContext(classInst, methodInst, &typeContext);
1502
1503     HELPER_METHOD_FRAME_BEGIN_RET_2(refParamType, refArgumentType);
1504     {
1505         bResult = thGenericParameter.AsGenericVariable()->SatisfiesConstraints(&typeContext, thGenericArgument);
1506     }
1507     HELPER_METHOD_FRAME_END();
1508
1509     FC_RETURN_BOOL(bResult);      
1510 }
1511 FCIMPLEND
1512
1513 void QCALLTYPE RuntimeTypeHandle::GetInstantiation(EnregisteredTypeHandle pType, QCall::ObjectHandleOnStack retTypes, BOOL fAsRuntimeTypeArray)
1514 {
1515     QCALL_CONTRACT;
1516
1517     BEGIN_QCALL;
1518
1519     TypeHandle typeHandle = TypeHandle::FromPtr(pType);
1520     Instantiation inst = typeHandle.GetInstantiation();
1521     GCX_COOP();
1522     retTypes.Set(CopyRuntimeTypeHandles(NULL, inst.GetRawArgs(), inst.GetNumArgs(), fAsRuntimeTypeArray ? CLASS__CLASS : CLASS__TYPE));
1523     END_QCALL;
1524
1525     return;
1526 }
1527
1528 void QCALLTYPE RuntimeTypeHandle::MakeArray(EnregisteredTypeHandle pTypeHandle, INT32 rank, QCall::ObjectHandleOnStack retType)
1529 {
1530     QCALL_CONTRACT;
1531
1532     TypeHandle arrayHandle;
1533     
1534     BEGIN_QCALL;
1535     arrayHandle = TypeHandle::FromPtr(pTypeHandle).MakeArray(rank);
1536     GCX_COOP();
1537     retType.Set(arrayHandle.GetManagedClassObject());
1538     END_QCALL;
1539     
1540     return;
1541 }
1542
1543 void QCALLTYPE RuntimeTypeHandle::MakeSZArray(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType)
1544 {
1545     QCALL_CONTRACT;
1546     
1547     TypeHandle arrayHandle;
1548     
1549     BEGIN_QCALL;
1550     arrayHandle = TypeHandle::FromPtr(pTypeHandle).MakeSZArray();
1551     GCX_COOP();
1552     retType.Set(arrayHandle.GetManagedClassObject());
1553     END_QCALL;
1554
1555     return;
1556 }
1557
1558 void QCALLTYPE RuntimeTypeHandle::MakePointer(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType)
1559 {
1560     QCALL_CONTRACT;
1561     
1562     TypeHandle pointerHandle;
1563     
1564     BEGIN_QCALL;
1565     pointerHandle = TypeHandle::FromPtr(pTypeHandle).MakePointer();
1566     GCX_COOP();
1567     retType.Set(pointerHandle.GetManagedClassObject());
1568     END_QCALL;
1569     
1570     return;
1571 }
1572
1573 void QCALLTYPE RuntimeTypeHandle::MakeByRef(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType)
1574 {
1575     QCALL_CONTRACT;
1576     
1577     TypeHandle byRefHandle;
1578     
1579     BEGIN_QCALL;
1580     byRefHandle = TypeHandle::FromPtr(pTypeHandle).MakeByRef();
1581     GCX_COOP();
1582     retType.Set(byRefHandle.GetManagedClassObject());
1583     END_QCALL;
1584     
1585     return;
1586 }
1587
1588 BOOL QCALLTYPE RuntimeTypeHandle::IsCollectible(EnregisteredTypeHandle pTypeHandle)
1589 {
1590     QCALL_CONTRACT;
1591
1592     BOOL retVal = FALSE;
1593
1594     BEGIN_QCALL;
1595     retVal = TypeHandle::FromPtr(pTypeHandle).GetLoaderAllocator()->IsCollectible();
1596     END_QCALL;
1597
1598     return retVal;
1599 }
1600     
1601 void QCALLTYPE RuntimeTypeHandle::Instantiate(EnregisteredTypeHandle pTypeHandle, TypeHandle * pInstArray, INT32 cInstArray, QCall::ObjectHandleOnStack retType)
1602 {
1603     QCALL_CONTRACT;
1604     
1605     TypeHandle type;
1606
1607     BEGIN_QCALL;
1608     type = TypeHandle::FromPtr(pTypeHandle).Instantiate(Instantiation(pInstArray, cInstArray));
1609     GCX_COOP();
1610     retType.Set(type.GetManagedClassObject());
1611     END_QCALL;
1612
1613     return;
1614 }
1615
1616 void QCALLTYPE RuntimeTypeHandle::GetGenericTypeDefinition(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType)
1617 {
1618     QCALL_CONTRACT;
1619     
1620     TypeHandle typeDef;
1621     
1622     BEGIN_QCALL;
1623     
1624     TypeHandle genericType = TypeHandle::FromPtr(pTypeHandle);
1625
1626     typeDef = ClassLoader::LoadTypeDefThrowing(genericType.GetModule(), 
1627                                                        genericType.GetMethodTable()->GetCl(),
1628                                                        ClassLoader::ThrowIfNotFound,
1629                                                        ClassLoader::PermitUninstDefOrRef);
1630
1631     GCX_COOP();
1632     retType.Set(typeDef.GetManagedClassObject());
1633
1634     END_QCALL;
1635     
1636     return;
1637 }
1638
1639 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::CompareCanonicalHandles, ReflectClassBaseObject *pLeftUNSAFE, ReflectClassBaseObject *pRightUNSAFE)
1640 {
1641     FCALL_CONTRACT;
1642     
1643     REFLECTCLASSBASEREF refLeft = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pLeftUNSAFE);
1644     REFLECTCLASSBASEREF refRight = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pRightUNSAFE);
1645
1646     if ((refLeft == NULL) || (refRight == NULL))
1647         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1648
1649     FC_RETURN_BOOL(refLeft->GetType().GetCanonicalMethodTable() == refRight->GetType().GetCanonicalMethodTable());
1650 }
1651 FCIMPLEND
1652
1653 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::HasInstantiation, PTR_ReflectClassBaseObject pTypeUNSAFE)
1654 {
1655     FCALL_CONTRACT;       
1656     
1657     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1658
1659     if (refType == NULL)
1660         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1661
1662     FC_RETURN_BOOL(refType->GetType().HasInstantiation());
1663 }
1664 FCIMPLEND
1665
1666 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsGenericTypeDefinition, PTR_ReflectClassBaseObject pTypeUNSAFE)
1667 {
1668     FCALL_CONTRACT;
1669     
1670     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1671
1672     if (refType == NULL)
1673         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1674
1675     FC_RETURN_BOOL(refType->GetType().IsGenericTypeDefinition());
1676 }
1677 FCIMPLEND
1678
1679 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsGenericVariable, PTR_ReflectClassBaseObject pTypeUNSAFE)
1680 {
1681     FCALL_CONTRACT;
1682     
1683     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1684
1685     if (refType == NULL)
1686         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1687
1688     FC_RETURN_BOOL(refType->GetType().IsGenericVariable());
1689 }
1690 FCIMPLEND
1691
1692 FCIMPL1(INT32, RuntimeTypeHandle::GetGenericVariableIndex, PTR_ReflectClassBaseObject pTypeUNSAFE)
1693 {
1694     FCALL_CONTRACT;
1695     
1696     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1697
1698     if (refType == NULL)
1699         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1700
1701     return (INT32)refType->GetType().AsGenericVariable()->GetIndex();
1702 }
1703 FCIMPLEND
1704
1705 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::ContainsGenericVariables, PTR_ReflectClassBaseObject pTypeUNSAFE)
1706 {
1707     FCALL_CONTRACT;
1708
1709     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1710
1711     if (refType == NULL)
1712         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1713
1714     FC_RETURN_BOOL(refType->GetType().ContainsGenericVariables());
1715 }
1716 FCIMPLEND
1717
1718 FCIMPL1(IMDInternalImport*, RuntimeTypeHandle::GetMetadataImport, ReflectClassBaseObject * pTypeUNSAFE)
1719 {
1720     FCALL_CONTRACT;
1721
1722     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1723
1724     if (refType == NULL)
1725         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1726
1727     Module *pModule = refType->GetType().GetModule();
1728
1729     return pModule->GetMDImport();
1730 }
1731 FCIMPLEND
1732
1733
1734 //***********************************************************************************
1735 //***********************************************************************************
1736 //***********************************************************************************
1737
1738 void * QCALLTYPE RuntimeMethodHandle::GetFunctionPointer(MethodDesc * pMethod)
1739 {
1740     QCALL_CONTRACT;
1741         
1742     void* funcPtr = 0;
1743     
1744     BEGIN_QCALL;
1745
1746     funcPtr = (void*)pMethod->GetMultiCallableAddrOfCode();
1747
1748     END_QCALL;
1749
1750     return funcPtr;
1751 }
1752     
1753 FCIMPL1(LPCUTF8, RuntimeMethodHandle::GetUtf8Name, MethodDesc *pMethod) {
1754     CONTRACTL {
1755         FCALL_CHECK;
1756     }
1757     CONTRACTL_END;
1758     
1759     LPCUTF8 szName = NULL;
1760     
1761     if (!pMethod)
1762         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1763            
1764     szName = pMethod->GetName();
1765
1766     _ASSERTE(CheckPointer(szName, NULL_OK));
1767     
1768     return szName;
1769 }
1770 FCIMPLEND
1771
1772 FCIMPL2(FC_BOOL_RET, RuntimeMethodHandle::MatchesNameHash, MethodDesc * pMethod, ULONG hash)
1773 {
1774     FCALL_CONTRACT;
1775
1776     FC_RETURN_BOOL(pMethod->MightHaveName(hash));
1777 }
1778 FCIMPLEND
1779
1780 FCIMPL1(StringObject*, RuntimeMethodHandle::GetName, MethodDesc *pMethod) {
1781     CONTRACTL {
1782         FCALL_CHECK;
1783     }
1784     CONTRACTL_END;
1785         
1786     if (!pMethod)
1787         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1788         
1789     STRINGREF refName = NULL;
1790
1791     HELPER_METHOD_FRAME_BEGIN_RET_0();
1792     refName = StringObject::NewString(pMethod->GetName());
1793     HELPER_METHOD_FRAME_END();            
1794     
1795     return (StringObject*)OBJECTREFToObject(refName);
1796 }
1797 FCIMPLEND
1798
1799 FCIMPL1(INT32, RuntimeMethodHandle::GetAttributes, MethodDesc *pMethod) {
1800     CONTRACTL {
1801         FCALL_CHECK;
1802     }
1803     CONTRACTL_END;
1804     
1805     if (!pMethod)
1806         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1807
1808     INT32 retVal = 0;        
1809     BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
1810     retVal = (INT32)pMethod->GetAttrs();
1811     END_SO_INTOLERANT_CODE;
1812     return retVal;
1813 }
1814 FCIMPLEND
1815
1816 FCIMPL1(INT32, RuntimeMethodHandle::GetImplAttributes, ReflectMethodObject *pMethodUNSAFE) {
1817     CONTRACTL {
1818         FCALL_CHECK;
1819     }
1820     CONTRACTL_END;
1821     
1822     if (!pMethodUNSAFE)
1823         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1824
1825     MethodDesc* pMethod = pMethodUNSAFE->GetMethod();
1826     INT32 attributes = 0;
1827
1828     if (IsNilToken(pMethod->GetMemberDef()))
1829         return attributes;
1830     
1831     BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
1832     {
1833         attributes = (INT32)pMethod->GetImplAttrs();
1834     }
1835     END_SO_INTOLERANT_CODE;
1836
1837     return attributes;
1838 }
1839 FCIMPLEND
1840     
1841
1842 FCIMPL1(ReflectClassBaseObject*, RuntimeMethodHandle::GetDeclaringType, MethodDesc *pMethod) {
1843     CONTRACTL {
1844         FCALL_CHECK;
1845         PRECONDITION(CheckPointer(pMethod));
1846     }
1847     CONTRACTL_END;
1848     
1849     if (!pMethod)
1850         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1851         
1852     MethodTable *pMT = pMethod->GetMethodTable();
1853     TypeHandle declType(pMT);
1854     if (pMT->IsArray()) 
1855     {
1856         HELPER_METHOD_FRAME_BEGIN_RET_0();   
1857         
1858         // Load the TypeDesc for the array type.  Note the returned type is approximate, i.e.
1859         // if shared between reference array types then we will get object[] back.
1860         DWORD rank = pMT->GetRank();
1861         TypeHandle elemType = pMT->GetApproxArrayElementTypeHandle();
1862         declType = ClassLoader::LoadArrayTypeThrowing(elemType, pMT->GetInternalCorElementType(), rank);
1863         HELPER_METHOD_FRAME_END();            
1864     }
1865     RETURN_CLASS_OBJECT(declType, NULL);
1866 }
1867 FCIMPLEND
1868
1869 FCIMPL1(INT32, RuntimeMethodHandle::GetSlot, MethodDesc *pMethod) {
1870     CONTRACTL {
1871         FCALL_CHECK;
1872     }
1873     CONTRACTL_END;
1874     
1875     if (!pMethod)
1876         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1877         
1878     return (INT32)pMethod->GetSlot();
1879 }
1880 FCIMPLEND
1881
1882 FCIMPL3(Object *, SignatureNative::GetCustomModifiers, SignatureNative* pSignatureUNSAFE, 
1883     INT32 parameter, CLR_BOOL fRequired)
1884 {   
1885     CONTRACTL {
1886         FCALL_CHECK;
1887     }
1888     CONTRACTL_END;
1889
1890     struct 
1891     {
1892         SIGNATURENATIVEREF pSig;
1893         PTRARRAYREF retVal;
1894     } gc;
1895
1896     gc.pSig = (SIGNATURENATIVEREF)pSignatureUNSAFE;
1897     gc.retVal = NULL;
1898
1899     HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
1900     {
1901         
1902         BYTE callConv = *(BYTE*)gc.pSig->GetCorSig();
1903         SigTypeContext typeContext;
1904         gc.pSig->GetTypeContext(&typeContext);
1905         MetaSig sig(gc.pSig->GetCorSig(), 
1906                     gc.pSig->GetCorSigSize(),
1907                     gc.pSig->GetModule(), 
1908                     &typeContext,
1909                     (callConv & IMAGE_CEE_CS_CALLCONV_MASK) == IMAGE_CEE_CS_CALLCONV_FIELD ? MetaSig::sigField : MetaSig::sigMember);
1910         _ASSERTE(callConv == sig.GetCallingConventionInfo());                 
1911
1912         SigPointer argument(NULL, 0);
1913
1914         PRECONDITION(sig.GetCallingConvention() != IMAGE_CEE_CS_CALLCONV_FIELD || parameter == 1);
1915
1916         if (parameter == 0) 
1917         {
1918             argument = sig.GetReturnProps();
1919         }
1920         else
1921         {
1922             for(INT32 i = 0; i < parameter; i++)
1923                 sig.NextArg();
1924
1925             argument = sig.GetArgProps();
1926         }
1927         
1928         //if (parameter < 0 || parameter > (INT32)sig.NumFixedArgs())
1929         //    FCThrowResVoid(kArgumentNullException, W("Arg_ArgumentOutOfRangeException")); 
1930         
1931         SigPointer sp = argument;
1932         Module* pModule = sig.GetModule();
1933         INT32 cMods = 0;
1934         CorElementType cmodType;
1935
1936         CorElementType cmodTypeExpected = fRequired ? ELEMENT_TYPE_CMOD_REQD : ELEMENT_TYPE_CMOD_OPT;
1937         
1938         // Discover the number of required and optional custom modifiers.   
1939         while(TRUE)
1940         {
1941             BYTE data;
1942             IfFailThrow(sp.GetByte(&data));
1943             cmodType = (CorElementType)data;
1944             
1945             if (cmodType == ELEMENT_TYPE_CMOD_REQD || cmodType == ELEMENT_TYPE_CMOD_OPT)
1946             {
1947                 if (cmodType == cmodTypeExpected)
1948                 {
1949                     cMods ++;
1950                 }
1951             }        
1952             else if (cmodType != ELEMENT_TYPE_SENTINEL) 
1953             {
1954                 break;        
1955             }
1956             
1957             IfFailThrow(sp.GetToken(NULL));
1958         }
1959
1960         // Reset sp and populate the arrays for the required and optional custom 
1961         // modifiers now that we know how long they should be. 
1962         sp = argument;
1963
1964         MethodTable *pMT = MscorlibBinder::GetClass(CLASS__TYPE);
1965         TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pMT), ELEMENT_TYPE_SZARRAY);
1966
1967         gc.retVal = (PTRARRAYREF) AllocateArrayEx(arrayHandle, &cMods, 1);
1968
1969         while(cMods != 0)
1970         {
1971             BYTE data;
1972             IfFailThrow(sp.GetByte(&data));
1973             cmodType = (CorElementType)data;
1974
1975             mdToken token;
1976             IfFailThrow(sp.GetToken(&token));
1977
1978             if (cmodType == cmodTypeExpected)
1979             {
1980                 TypeHandle th = ClassLoader::LoadTypeDefOrRefOrSpecThrowing(pModule, token, 
1981                                                                             &typeContext,
1982                                                                             ClassLoader::ThrowIfNotFound, 
1983                                                                             ClassLoader::FailIfUninstDefOrRef);        
1984         
1985                 OBJECTREF refType = th.GetManagedClassObject();
1986                 gc.retVal->SetAt(--cMods, refType);
1987             }
1988         }    
1989     }  
1990     HELPER_METHOD_FRAME_END();
1991
1992     return OBJECTREFToObject(gc.retVal);
1993 }
1994 FCIMPLEND
1995
1996 FCIMPL1(INT32, RuntimeMethodHandle::GetMethodDef, ReflectMethodObject *pMethodUNSAFE) {
1997     CONTRACTL {
1998         FCALL_CHECK;
1999     }
2000     CONTRACTL_END;
2001     
2002     if (!pMethodUNSAFE)
2003         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2004
2005     MethodDesc* pMethod = pMethodUNSAFE->GetMethod();
2006
2007     if (pMethod->HasMethodInstantiation())
2008     {
2009         HELPER_METHOD_FRAME_BEGIN_RET_1(pMethodUNSAFE);
2010         {         
2011             pMethod = pMethod->StripMethodInstantiation();
2012         }
2013         HELPER_METHOD_FRAME_END();
2014     }
2015
2016     INT32 tkMethodDef = (INT32)pMethod->GetMemberDef();
2017     _ASSERTE(TypeFromToken(tkMethodDef) == mdtMethodDef);
2018     
2019     if (IsNilToken(tkMethodDef) || TypeFromToken(tkMethodDef) != mdtMethodDef)
2020         return mdMethodDefNil;
2021     
2022     return tkMethodDef;
2023 }
2024 FCIMPLEND
2025
2026 FCIMPL6(void, SignatureNative::GetSignature,
2027     SignatureNative* pSignatureNativeUNSAFE, 
2028     PCCOR_SIGNATURE pCorSig, DWORD cCorSig,
2029     FieldDesc *pFieldDesc, ReflectMethodObject *pMethodUNSAFE, ReflectClassBaseObject *pDeclaringTypeUNSAFE) {
2030     CONTRACTL {
2031         FCALL_CHECK;
2032         PRECONDITION(pDeclaringTypeUNSAFE || pMethodUNSAFE->GetMethod()->IsDynamicMethod());
2033         PRECONDITION(CheckPointer(pCorSig, NULL_OK));
2034         PRECONDITION(CheckPointer(pMethodUNSAFE, NULL_OK));
2035         PRECONDITION(CheckPointer(pFieldDesc, NULL_OK));
2036     }
2037     CONTRACTL_END;
2038
2039     struct
2040     {
2041         REFLECTCLASSBASEREF refDeclaringType;
2042         REFLECTMETHODREF refMethod;
2043         SIGNATURENATIVEREF pSig;
2044     } gc;
2045
2046     gc.refDeclaringType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pDeclaringTypeUNSAFE);
2047     gc.refMethod = (REFLECTMETHODREF)ObjectToOBJECTREF(pMethodUNSAFE);
2048     gc.pSig = (SIGNATURENATIVEREF)pSignatureNativeUNSAFE;
2049
2050     MethodDesc *pMethod;
2051     TypeHandle declType;
2052
2053     if (gc.refDeclaringType == NULL)
2054     {
2055         // for dynamic method, see precondition
2056         pMethod = gc.refMethod->GetMethod();
2057         declType = pMethod->GetMethodTable();
2058     }
2059     else
2060     {
2061         pMethod = gc.refMethod != NULL ? gc.refMethod->GetMethod() : NULL;
2062         declType = gc.refDeclaringType->GetType();
2063     }
2064
2065     HELPER_METHOD_FRAME_BEGIN_PROTECT(gc);
2066     {        
2067         Module* pModule = declType.GetModule();
2068         
2069         if (pMethod)
2070         {
2071             pMethod->GetSig(&pCorSig, &cCorSig);
2072             if (pMethod->GetClassification() == mcInstantiated)
2073             {
2074                 LoaderAllocator *pLoaderAllocator = pMethod->GetLoaderAllocator();
2075                 if (pLoaderAllocator->IsCollectible())
2076                     gc.pSig->SetKeepAlive(pLoaderAllocator->GetExposedObject());
2077             }
2078         }
2079         else if (pFieldDesc)
2080             pFieldDesc->GetSig(&pCorSig, &cCorSig);
2081         
2082         gc.pSig->m_sig = pCorSig;    
2083         gc.pSig->m_cSig = cCorSig;    
2084         gc.pSig->m_pMethod = pMethod;    
2085
2086         REFLECTCLASSBASEREF refDeclType = (REFLECTCLASSBASEREF)declType.GetManagedClassObject();
2087         gc.pSig->SetDeclaringType(refDeclType);
2088
2089         PREFIX_ASSUME(pCorSig!= NULL);
2090         BYTE callConv = *(BYTE*)pCorSig;
2091         SigTypeContext typeContext;
2092         if (pMethod)
2093             SigTypeContext::InitTypeContext(
2094                 pMethod, declType.GetClassOrArrayInstantiation(), pMethod->LoadMethodInstantiation(), &typeContext);
2095         else
2096             SigTypeContext::InitTypeContext(declType, &typeContext);
2097         MetaSig msig(pCorSig, cCorSig, pModule, &typeContext,
2098             (callConv & IMAGE_CEE_CS_CALLCONV_MASK) == IMAGE_CEE_CS_CALLCONV_FIELD ? MetaSig::sigField : MetaSig::sigMember);
2099
2100         if (callConv == IMAGE_CEE_CS_CALLCONV_FIELD)
2101         {            
2102             msig.NextArgNormalized();
2103
2104             OBJECTREF refRetType = msig.GetLastTypeHandleThrowing().GetManagedClassObject();
2105             gc.pSig->SetReturnType(refRetType);
2106         }
2107         else
2108         {
2109             gc.pSig->SetCallingConvention(msig.GetCallingConventionInfo());
2110
2111             OBJECTREF refRetType = msig.GetRetTypeHandleThrowing().GetManagedClassObject();
2112             gc.pSig->SetReturnType(refRetType);
2113
2114             INT32 nArgs = msig.NumFixedArgs();
2115             TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(g_pRuntimeTypeClass), ELEMENT_TYPE_SZARRAY);
2116
2117             PTRARRAYREF ptrArrayarguments = (PTRARRAYREF) AllocateArrayEx(arrayHandle, &nArgs, 1);
2118             gc.pSig->SetArgumentArray(ptrArrayarguments);
2119
2120             for (INT32 i = 0; i < nArgs; i++) 
2121             {
2122                 msig.NextArg();
2123
2124                 OBJECTREF refArgType = msig.GetLastTypeHandleThrowing().GetManagedClassObject();
2125                 gc.pSig->SetArgument(i, refArgType);
2126             }
2127
2128             _ASSERTE(gc.pSig->m_returnType != NULL);
2129         }
2130     }
2131     HELPER_METHOD_FRAME_END();
2132 }
2133 FCIMPLEND
2134
2135 FCIMPL2(FC_BOOL_RET, SignatureNative::CompareSig, SignatureNative* pLhsUNSAFE, SignatureNative* pRhsUNSAFE)
2136 {
2137     FCALL_CONTRACT;
2138     
2139     INT32 ret = 0;
2140
2141     struct
2142     {
2143         SIGNATURENATIVEREF pLhs;
2144         SIGNATURENATIVEREF pRhs;
2145     } gc;
2146
2147     gc.pLhs = (SIGNATURENATIVEREF)pLhsUNSAFE;
2148     gc.pRhs = (SIGNATURENATIVEREF)pRhsUNSAFE;
2149
2150     HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
2151     {
2152         ret = MetaSig::CompareMethodSigs(
2153             gc.pLhs->GetCorSig(), gc.pLhs->GetCorSigSize(), gc.pLhs->GetModule(), NULL, 
2154             gc.pRhs->GetCorSig(), gc.pRhs->GetCorSigSize(), gc.pRhs->GetModule(), NULL);    
2155     }
2156     HELPER_METHOD_FRAME_END();
2157     FC_RETURN_BOOL(ret);
2158 }
2159 FCIMPLEND
2160
2161 void QCALLTYPE RuntimeMethodHandle::GetMethodInstantiation(MethodDesc * pMethod, QCall::ObjectHandleOnStack retTypes, BOOL fAsRuntimeTypeArray)
2162 {
2163     QCALL_CONTRACT;
2164             
2165     BEGIN_QCALL;
2166     Instantiation inst = pMethod->LoadMethodInstantiation();
2167
2168     GCX_COOP();
2169     retTypes.Set(CopyRuntimeTypeHandles(NULL, inst.GetRawArgs(), inst.GetNumArgs(), fAsRuntimeTypeArray ? CLASS__CLASS : CLASS__TYPE));
2170     END_QCALL;
2171
2172     return;
2173 }
2174     
2175 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::HasMethodInstantiation, MethodDesc * pMethod)
2176 {
2177     FCALL_CONTRACT;
2178
2179     FC_RETURN_BOOL(pMethod->HasMethodInstantiation());
2180 }
2181 FCIMPLEND
2182
2183 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsGenericMethodDefinition, MethodDesc * pMethod)
2184 {
2185     FCALL_CONTRACT;
2186
2187     FC_RETURN_BOOL(pMethod->IsGenericMethodDefinition());
2188 }
2189 FCIMPLEND
2190
2191 FCIMPL1(INT32, RuntimeMethodHandle::GetGenericParameterCount, MethodDesc * pMethod)
2192 {
2193     FCALL_CONTRACT;
2194
2195     return pMethod->GetNumGenericMethodArgs();
2196 }
2197 FCIMPLEND
2198
2199 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsDynamicMethod, MethodDesc * pMethod)
2200 {
2201     FCALL_CONTRACT;
2202
2203     FC_RETURN_BOOL(pMethod->IsNoMetadata());
2204 }
2205 FCIMPLEND
2206
2207 FCIMPL1(Object*, RuntimeMethodHandle::GetResolver, MethodDesc * pMethod)
2208 {
2209     FCALL_CONTRACT;
2210
2211     if (!pMethod)
2212         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2213
2214     OBJECTREF resolver = NULL;
2215     if (pMethod->IsLCGMethod())
2216     {
2217         resolver = pMethod->AsDynamicMethodDesc()->GetLCGMethodResolver()->GetManagedResolver();
2218     }
2219     return OBJECTREFToObject(resolver);
2220 }
2221 FCIMPLEND
2222
2223 void QCALLTYPE RuntimeMethodHandle::Destroy(MethodDesc * pMethod)
2224 {
2225     QCALL_CONTRACT;
2226
2227     BEGIN_QCALL;
2228
2229     if (pMethod == NULL)
2230         COMPlusThrowArgumentNull(NULL, W("Arg_InvalidHandle"));
2231     
2232     DynamicMethodDesc* pDynamicMethodDesc = pMethod->AsDynamicMethodDesc();
2233
2234     GCX_COOP();
2235
2236     // Destroy should be called only if the managed part is gone.
2237     _ASSERTE(OBJECTREFToObject(pDynamicMethodDesc->GetLCGMethodResolver()->GetManagedResolver()) == NULL);
2238
2239     // Fire Unload Dynamic Method Event here
2240     ETW::MethodLog::DynamicMethodDestroyed(pMethod);
2241
2242     BEGIN_PIN_PROFILER(CORProfilerIsMonitoringDynamicFunctionUnloads());
2243     g_profControlBlock.pProfInterface->DynamicMethodUnloaded((FunctionID)pMethod);
2244     END_PIN_PROFILER();
2245
2246     pDynamicMethodDesc->Destroy();
2247
2248     END_QCALL;
2249     }
2250     
2251 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsTypicalMethodDefinition, ReflectMethodObject *pMethodUNSAFE)
2252 {
2253     FCALL_CONTRACT;
2254
2255     if (!pMethodUNSAFE)
2256         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2257
2258     MethodDesc* pMethod = pMethodUNSAFE->GetMethod();
2259
2260     FC_RETURN_BOOL(pMethod->IsTypicalMethodDefinition());
2261 }
2262 FCIMPLEND
2263     
2264 void QCALLTYPE RuntimeMethodHandle::GetTypicalMethodDefinition(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod)
2265     {            
2266     QCALL_CONTRACT;
2267
2268     BEGIN_QCALL;
2269 #ifdef _DEBUG
2270     {
2271         GCX_COOP();
2272         _ASSERTE(((ReflectMethodObject *)(*refMethod.m_ppObject))->GetMethod() == pMethod);
2273     }
2274 #endif
2275     MethodDesc *pMethodTypical = pMethod->LoadTypicalMethodDefinition();
2276     if (pMethodTypical != pMethod)
2277     {
2278         GCX_COOP();
2279         refMethod.Set(pMethodTypical->GetStubMethodInfo());
2280     }
2281     END_QCALL;
2282     
2283     return;
2284 }
2285
2286 void QCALLTYPE RuntimeMethodHandle::StripMethodInstantiation(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod)
2287     {            
2288     QCALL_CONTRACT;
2289
2290     BEGIN_QCALL;
2291
2292     if (!pMethod)
2293         COMPlusThrowArgumentNull(NULL, W("Arg_InvalidHandle"));
2294
2295 #ifdef _DEBUG
2296     {
2297         GCX_COOP();
2298         _ASSERTE(((ReflectMethodObject *)(*refMethod.m_ppObject))->GetMethod() == pMethod);
2299     }
2300 #endif
2301     MethodDesc *pMethodStripped = pMethod->StripMethodInstantiation();
2302     if (pMethodStripped != pMethod)
2303     {
2304         GCX_COOP();
2305         refMethod.Set(pMethodStripped->GetStubMethodInfo());
2306     }
2307     END_QCALL;
2308
2309     return;
2310 }
2311
2312 // In the VM there might be more than one MethodDescs for a "method"
2313 // examples are methods on generic types which may have additional instantiating stubs
2314 //          and methods on value types which may have additional unboxing stubs.
2315 //
2316 // For generic methods we always hand out an instantiating stub except for a generic method definition
2317 // For non-generic methods on generic types we need an instantiating stub if it's one of the following
2318 //  - static method on a generic class
2319 //  - static or instance method on a generic interface
2320 //  - static or instance method on a generic value type
2321 // The Reflection policy is to always hand out instantiating stubs in these cases
2322 //
2323 // For methods on non-generic value types we can use either the cannonical method or the unboxing stub
2324 // The Reflection policy is to always hand out unboxing stubs if the methods are virtual methods
2325 // The reason for this is that in the current implementation of the class loader, the v-table slots for 
2326 // those methods point to unboxing stubs already. Note that this is just a implementation choice
2327 // that might change in the future. But we should always keep this Reflection policy an invariant.
2328 // 
2329 // For virtual methods on generic value types (intersection of the two cases), reflection will hand
2330 // out an unboxing instantiating stub
2331 // 
2332 // GetInstantiatingStub is called to: 
2333 // 1. create an InstantiatedMethodDesc for a generic method when calling BindGenericArguments() on a generic
2334 //    method. In this case instArray will not be null.
2335 // 2. create an InstantiatedMethodDesc for a method in a generic class. In this case instArray will be null.
2336 // 3. create an UnboxingStub for a method in a value type. In this case instArray will be null.
2337 // For case 2 and 3, an instantiating stub or unboxing stub might not be needed in which case the original 
2338 // MethodDesc is returned.
2339 FCIMPL3(MethodDesc*, RuntimeMethodHandle::GetStubIfNeeded,
2340     MethodDesc *pMethod,
2341     ReflectClassBaseObject *pTypeUNSAFE,
2342     PtrArray* instArrayUNSAFE)
2343 {
2344     CONTRACTL {
2345         FCALL_CHECK;
2346     }
2347     CONTRACTL_END;
2348
2349     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
2350     PTRARRAYREF instArray = (PTRARRAYREF)ObjectToOBJECTREF(instArrayUNSAFE);
2351
2352     if (refType == NULL)
2353         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2354
2355     TypeHandle instType = refType->GetType();
2356     MethodDesc *pNewMethod = pMethod;
2357
2358     // error conditions
2359     if (!pMethod)
2360         FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
2361
2362     if (instType.IsNull())
2363         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2364     
2365     // Perf optimization: this logic is actually duplicated in FindOrCreateAssociatedMethodDescForReflection, but since it
2366     // is the more common case it's worth the duplicate check here to avoid the helper method frame
2367     if ( instArray == NULL &&
2368          ( pMethod->HasMethodInstantiation() || 
2369            ( !instType.IsValueType() && 
2370              ( !instType.HasInstantiation() || instType.IsGenericTypeDefinition() ) ) ) )
2371     {
2372         return pNewMethod;
2373     }
2374
2375     HELPER_METHOD_FRAME_BEGIN_RET_2(refType, instArray);
2376     {
2377         TypeHandle *inst = NULL;
2378         DWORD ntypars = 0;
2379
2380         if (instArray != NULL) 
2381         {
2382             ntypars = instArray->GetNumComponents();    
2383
2384             size_t size = ntypars * sizeof(TypeHandle);
2385             if ((size / sizeof(TypeHandle)) != ntypars) // uint over/underflow
2386                 COMPlusThrow(kArgumentException);
2387             inst = (TypeHandle*) _alloca(size);        
2388
2389             for (DWORD i = 0; i < ntypars; i++) 
2390             {
2391                 REFLECTCLASSBASEREF instRef = (REFLECTCLASSBASEREF)instArray->GetAt(i);
2392
2393                 if (instRef == NULL)
2394                     COMPlusThrowArgumentNull(W("inst"), W("ArgumentNull_ArrayElement"));
2395
2396                 inst[i] = instRef->GetType();
2397             }
2398         }
2399
2400         pNewMethod = MethodDesc::FindOrCreateAssociatedMethodDescForReflection(pMethod, instType, Instantiation(inst, ntypars));
2401     }
2402     HELPER_METHOD_FRAME_END();
2403
2404     return pNewMethod;
2405 }
2406 FCIMPLEND
2407
2408         
2409 FCIMPL2(MethodDesc*, RuntimeMethodHandle::GetMethodFromCanonical, MethodDesc *pMethod, ReflectClassBaseObject *pTypeUNSAFE)
2410 {
2411     CONTRACTL {
2412         FCALL_CHECK;
2413         PRECONDITION(CheckPointer(pMethod));
2414     }
2415     CONTRACTL_END;
2416     
2417     REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
2418
2419     TypeHandle instType = refType->GetType();
2420     MethodDesc* pMDescInCanonMT = instType.GetMethodTable()->GetParallelMethodDesc(pMethod);
2421
2422     return pMDescInCanonMT;
2423 }
2424 FCIMPLEND
2425
2426
2427 FCIMPL2(MethodBody *, RuntimeMethodHandle::GetMethodBody, ReflectMethodObject *pMethodUNSAFE, ReflectClassBaseObject *pDeclaringTypeUNSAFE)
2428 {      
2429     CONTRACTL 
2430     {
2431         FCALL_CHECK;
2432     }
2433     CONTRACTL_END;
2434
2435     struct _gc
2436     {
2437         METHODBODYREF MethodBodyObj;
2438         EXCEPTIONHANDLINGCLAUSEREF EHClauseObj;
2439         LOCALVARIABLEINFOREF LocalVariableInfoObj;
2440         U1ARRAYREF                  U1Array;
2441         BASEARRAYREF                TempArray;
2442         REFLECTCLASSBASEREF         declaringType;
2443         REFLECTMETHODREF            refMethod;
2444     } gc;
2445
2446     gc.MethodBodyObj = NULL;
2447     gc.EHClauseObj = NULL;
2448     gc.LocalVariableInfoObj = NULL;
2449     gc.U1Array              = NULL;
2450     gc.TempArray            = NULL;
2451     gc.declaringType        = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pDeclaringTypeUNSAFE);
2452     gc.refMethod = (REFLECTMETHODREF)ObjectToOBJECTREF(pMethodUNSAFE);
2453
2454
2455     if (!gc.refMethod)
2456         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2457
2458     MethodDesc* pMethod = gc.refMethod->GetMethod();
2459
2460     TypeHandle declaringType = gc.declaringType == NULL ? TypeHandle() : gc.declaringType->GetType();
2461
2462     if (!pMethod->IsIL())
2463         return NULL;
2464
2465     HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
2466     {
2467         MethodDesc *pMethodIL = pMethod;
2468         if (pMethod->IsWrapperStub())
2469             pMethodIL = pMethod->GetWrappedMethodDesc();
2470         
2471         COR_ILMETHOD* pILHeader = pMethodIL->GetILHeader();
2472         
2473         if (pILHeader)
2474         {
2475             MethodTable * pExceptionHandlingClauseMT = MscorlibBinder::GetClass(CLASS__EH_CLAUSE);
2476             TypeHandle thEHClauseArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pExceptionHandlingClauseMT), ELEMENT_TYPE_SZARRAY);
2477
2478             MethodTable * pLocalVariableMT = MscorlibBinder::GetClass(CLASS__LOCAL_VARIABLE_INFO);
2479             TypeHandle thLocalVariableArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pLocalVariableMT), ELEMENT_TYPE_SZARRAY);
2480
2481             Module* pModule = pMethod->GetModule();
2482             COR_ILMETHOD_DECODER::DecoderStatus status;
2483             COR_ILMETHOD_DECODER header(pILHeader, pModule->GetMDImport(), &status);
2484
2485             if (status != COR_ILMETHOD_DECODER::SUCCESS)
2486             {
2487                 if (status == COR_ILMETHOD_DECODER::VERIFICATION_ERROR)
2488                 {
2489                     // Throw a verification HR
2490                     COMPlusThrowHR(COR_E_VERIFICATION);
2491                 }
2492                 else
2493                 {
2494                     COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
2495                 }
2496             }
2497
2498             gc.MethodBodyObj = (METHODBODYREF)AllocateObject(MscorlibBinder::GetClass(CLASS__METHOD_BODY));
2499             
2500             gc.MethodBodyObj->m_maxStackSize = header.GetMaxStack();
2501             gc.MethodBodyObj->m_initLocals = !!(header.GetFlags() & CorILMethod_InitLocals);
2502
2503             if (header.IsFat())
2504                 gc.MethodBodyObj->m_localVarSigToken = header.GetLocalVarSigTok();
2505             else
2506                 gc.MethodBodyObj->m_localVarSigToken = 0;
2507
2508             // Allocate the array of IL and fill it in from the method header.
2509             BYTE* pIL = const_cast<BYTE*>(header.Code);
2510             COUNT_T cIL = header.GetCodeSize();
2511             gc.U1Array  = (U1ARRAYREF) AllocatePrimitiveArray(ELEMENT_TYPE_U1, cIL);
2512
2513             SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->m_IL, gc.U1Array, GetAppDomain());
2514             memcpyNoGCRefs(gc.MethodBodyObj->m_IL->GetDataPtr(), pIL, cIL);
2515
2516             // Allocate the array of exception clauses.
2517             INT32 cEh = (INT32)header.EHCount();
2518             const COR_ILMETHOD_SECT_EH* ehInfo = header.EH;
2519             gc.TempArray = (BASEARRAYREF) AllocateArrayEx(thEHClauseArray, &cEh, 1);
2520
2521             SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->m_exceptionClauses, gc.TempArray, GetAppDomain());
2522             
2523             for (INT32 i = 0; i < cEh; i++)
2524             {                    
2525                 COR_ILMETHOD_SECT_EH_CLAUSE_FAT ehBuff; 
2526                 const COR_ILMETHOD_SECT_EH_CLAUSE_FAT* ehClause = 
2527                     (const COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)ehInfo->EHClause(i, &ehBuff); 
2528
2529                 gc.EHClauseObj = (EXCEPTIONHANDLINGCLAUSEREF) AllocateObject(pExceptionHandlingClauseMT);
2530
2531                 gc.EHClauseObj->m_flags = ehClause->GetFlags();  
2532                 gc.EHClauseObj->m_tryOffset = ehClause->GetTryOffset();
2533                 gc.EHClauseObj->m_tryLength = ehClause->GetTryLength();
2534                 gc.EHClauseObj->m_handlerOffset = ehClause->GetHandlerOffset();
2535                 gc.EHClauseObj->m_handlerLength = ehClause->GetHandlerLength();
2536                 
2537                 if ((ehClause->GetFlags() & COR_ILEXCEPTION_CLAUSE_FILTER) == 0)
2538                     gc.EHClauseObj->m_catchToken = ehClause->GetClassToken();
2539                 else
2540                     gc.EHClauseObj->m_filterOffset = ehClause->GetFilterOffset();
2541                 
2542                 gc.MethodBodyObj->m_exceptionClauses->SetAt(i, (OBJECTREF) gc.EHClauseObj);
2543                 SetObjectReference((OBJECTREF*)&(gc.EHClauseObj->m_methodBody), (OBJECTREF)gc.MethodBodyObj, GetAppDomain());
2544             }     
2545            
2546             if (header.LocalVarSig != NULL)
2547             {
2548                 SigTypeContext sigTypeContext(pMethod, declaringType, pMethod->LoadMethodInstantiation());
2549                 MetaSig metaSig(header.LocalVarSig, 
2550                                 header.cbLocalVarSig, 
2551                                 pModule, 
2552                                 &sigTypeContext, 
2553                                 MetaSig::sigLocalVars);
2554                 INT32 cLocals = metaSig.NumFixedArgs();
2555                 gc.TempArray  = (BASEARRAYREF) AllocateArrayEx(thLocalVariableArray, &cLocals, 1);
2556                 SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->m_localVariables, gc.TempArray, GetAppDomain());
2557
2558                 for (INT32 i = 0; i < cLocals; i ++)
2559                 {
2560                     gc.LocalVariableInfoObj = (LOCALVARIABLEINFOREF)AllocateObject(pLocalVariableMT);
2561
2562                     gc.LocalVariableInfoObj->m_localIndex = i;
2563                     
2564                     metaSig.NextArg();
2565
2566                     CorElementType eType;
2567                     IfFailThrow(metaSig.GetArgProps().PeekElemType(&eType));
2568                     if (ELEMENT_TYPE_PINNED == eType)
2569                         gc.LocalVariableInfoObj->m_bIsPinned = TRUE;
2570
2571                     TypeHandle  tempType= metaSig.GetArgProps().GetTypeHandleThrowing(pModule, &sigTypeContext);       
2572                     OBJECTREF refLocalType = tempType.GetManagedClassObject();
2573                     gc.LocalVariableInfoObj->SetType(refLocalType);
2574                     gc.MethodBodyObj->m_localVariables->SetAt(i, (OBJECTREF) gc.LocalVariableInfoObj);
2575                 }        
2576             }
2577             else
2578             {
2579                 INT32 cLocals = 0;
2580                 gc.TempArray  = (BASEARRAYREF) AllocateArrayEx(thLocalVariableArray, &cLocals, 1);
2581                 SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->m_localVariables, gc.TempArray, GetAppDomain());
2582             }
2583         }
2584     }
2585     HELPER_METHOD_FRAME_END();
2586
2587     return (MethodBody*)OBJECTREFToObject(gc.MethodBodyObj);
2588 }
2589 FCIMPLEND
2590
2591 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsConstructor, MethodDesc *pMethod)
2592 {
2593     CONTRACTL {
2594         FCALL_CHECK;
2595         PRECONDITION(CheckPointer(pMethod));
2596     }
2597     CONTRACTL_END;
2598
2599     BOOL ret = FALSE;
2600     BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
2601     ret = (BOOL)pMethod->IsClassConstructorOrCtor();
2602     END_SO_INTOLERANT_CODE;
2603     FC_RETURN_BOOL(ret);
2604 }
2605 FCIMPLEND
2606
2607 FCIMPL1(Object*, RuntimeMethodHandle::GetLoaderAllocator, MethodDesc *pMethod)
2608 {
2609     CONTRACTL {
2610         FCALL_CHECK;
2611     }
2612     CONTRACTL_END;
2613
2614     OBJECTREF loaderAllocator = NULL;
2615
2616     if (!pMethod)
2617         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2618
2619     HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(loaderAllocator);
2620
2621     LoaderAllocator *pLoaderAllocator = pMethod->GetLoaderAllocator();
2622     loaderAllocator = pLoaderAllocator->GetExposedObject();
2623
2624     HELPER_METHOD_FRAME_END();
2625
2626     return OBJECTREFToObject(loaderAllocator);
2627 }
2628 FCIMPLEND
2629
2630 //*********************************************************************************************
2631 //*********************************************************************************************
2632 //*********************************************************************************************
2633
2634 FCIMPL1(StringObject*, RuntimeFieldHandle::GetName, ReflectFieldObject *pFieldUNSAFE) {
2635     CONTRACTL {
2636         FCALL_CHECK;
2637     }
2638     CONTRACTL_END;
2639     
2640     REFLECTFIELDREF refField = (REFLECTFIELDREF)ObjectToOBJECTREF(pFieldUNSAFE);
2641     if (!refField)
2642         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2643         
2644     FieldDesc *pField = refField->GetField();
2645     
2646     STRINGREF refString = NULL;
2647     HELPER_METHOD_FRAME_BEGIN_RET_1(refField);
2648     {
2649         refString = StringObject::NewString(pField->GetName());
2650     }
2651     HELPER_METHOD_FRAME_END();
2652     return (StringObject*)OBJECTREFToObject(refString);
2653 }
2654 FCIMPLEND
2655     
2656 FCIMPL1(LPCUTF8, RuntimeFieldHandle::GetUtf8Name, FieldDesc *pField) {
2657     CONTRACTL {
2658         FCALL_CHECK;
2659         PRECONDITION(CheckPointer(pField));
2660     }
2661     CONTRACTL_END;
2662     
2663     LPCUTF8    szFieldName;
2664     
2665     if (FAILED(pField->GetName_NoThrow(&szFieldName)))
2666     {
2667         FCThrow(kBadImageFormatException);
2668     }
2669     return szFieldName;
2670 }
2671 FCIMPLEND
2672
2673 FCIMPL2(FC_BOOL_RET, RuntimeFieldHandle::MatchesNameHash, FieldDesc * pField, ULONG hash)
2674 {
2675     FCALL_CONTRACT;
2676
2677     FC_RETURN_BOOL(pField->MightHaveName(hash));
2678 }
2679 FCIMPLEND
2680
2681 FCIMPL1(INT32, RuntimeFieldHandle::GetAttributes, FieldDesc *pField) {
2682     CONTRACTL {
2683         FCALL_CHECK;
2684     }
2685     CONTRACTL_END;
2686     
2687     if (!pField)
2688         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2689
2690     INT32 ret = 0;
2691     BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
2692     ret = (INT32)pField->GetAttributes();
2693     END_SO_INTOLERANT_CODE;
2694     return ret;
2695 }
2696 FCIMPLEND
2697     
2698 FCIMPL1(ReflectClassBaseObject*, RuntimeFieldHandle::GetApproxDeclaringType, FieldDesc *pField) {
2699     CONTRACTL {
2700         FCALL_CHECK;
2701     }
2702     CONTRACTL_END;
2703     
2704     if (!pField)
2705         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2706         
2707     TypeHandle th = TypeHandle(pField->GetApproxEnclosingMethodTable());  // <REVISIT_TODO> this needs to be checked - see bug 184355 </REVISIT_TODO>
2708     RETURN_CLASS_OBJECT(th, NULL);
2709 }
2710 FCIMPLEND
2711
2712 FCIMPL1(INT32, RuntimeFieldHandle::GetToken, ReflectFieldObject *pFieldUNSAFE) {
2713     CONTRACTL {
2714         FCALL_CHECK;
2715     }
2716     CONTRACTL_END;
2717
2718     REFLECTFIELDREF refField = (REFLECTFIELDREF)ObjectToOBJECTREF(pFieldUNSAFE);
2719     if (!refField)
2720         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2721         
2722     FieldDesc *pField = refField->GetField();
2723
2724     INT32 tkFieldDef = (INT32)pField->GetMemberDef();
2725     _ASSERTE(!IsNilToken(tkFieldDef) || tkFieldDef == mdFieldDefNil);
2726     return tkFieldDef;
2727 }
2728 FCIMPLEND
2729
2730 FCIMPL2(FieldDesc*, RuntimeFieldHandle::GetStaticFieldForGenericType, FieldDesc *pField, ReflectClassBaseObject *pDeclaringTypeUNSAFE)
2731 {
2732     CONTRACTL {
2733         FCALL_CHECK;
2734     }
2735     CONTRACTL_END;
2736
2737     REFLECTCLASSBASEREF refDeclaringType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pDeclaringTypeUNSAFE);
2738
2739     if ((refDeclaringType == NULL) || (pField == NULL))
2740         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2741
2742     TypeHandle declaringType = refDeclaringType->GetType();
2743     
2744     if (!pField)
2745         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2746     if (declaringType.IsTypeDesc())
2747         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2748     MethodTable *pMT = declaringType.AsMethodTable();
2749
2750     _ASSERTE(pField->IsStatic());
2751     if (pMT->HasGenericsStaticsInfo())
2752         pField = pMT->GetFieldDescByIndex(pField->GetApproxEnclosingMethodTable()->GetIndexForFieldDesc(pField));
2753     _ASSERTE(!pField->IsSharedByGenericInstantiations());
2754     _ASSERTE(pField->GetEnclosingMethodTable() == pMT);
2755
2756     return pField;
2757 }
2758 FCIMPLEND
2759
2760 FCIMPL1(ReflectModuleBaseObject*, AssemblyHandle::GetManifestModule, AssemblyBaseObject* pAssemblyUNSAFE) {
2761     FCALL_CONTRACT;
2762
2763     ASSEMBLYREF refAssembly = (ASSEMBLYREF)ObjectToOBJECTREF(pAssemblyUNSAFE);
2764     
2765     if (refAssembly == NULL)
2766         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2767
2768     DomainAssembly *pAssembly = refAssembly->GetDomainAssembly();
2769     Assembly* currentAssembly = pAssembly->GetCurrentAssembly();
2770
2771     if (currentAssembly == NULL)
2772         return NULL;
2773
2774     Module *pModule = currentAssembly->GetManifestModule();
2775     DomainFile * pDomainFile = pModule->FindDomainFile(GetAppDomain());
2776
2777 #ifdef _DEBUG
2778     OBJECTREF orModule;
2779     
2780     HELPER_METHOD_FRAME_BEGIN_RET_1(refAssembly);
2781     orModule = (pDomainFile != NULL) ? pDomainFile->GetExposedModuleObjectIfExists() : NULL;
2782     if (orModule == NULL)
2783         orModule = pModule->GetExposedObject();
2784 #else
2785     OBJECTREF orModule = (pDomainFile != NULL) ? pDomainFile->GetExposedModuleObjectIfExists() : NULL;
2786     if (orModule != NULL)
2787         return (ReflectModuleBaseObject*)OBJECTREFToObject(orModule);
2788
2789     HELPER_METHOD_FRAME_BEGIN_RET_1(refAssembly);
2790     orModule = pModule->GetExposedObject();
2791 #endif
2792
2793     HELPER_METHOD_FRAME_END();
2794     return (ReflectModuleBaseObject*)OBJECTREFToObject(orModule);
2795
2796 }
2797 FCIMPLEND
2798
2799 FCIMPL1(INT32, AssemblyHandle::GetToken, AssemblyBaseObject* pAssemblyUNSAFE) {
2800     FCALL_CONTRACT;
2801     
2802     ASSEMBLYREF refAssembly = (ASSEMBLYREF)ObjectToOBJECTREF(pAssemblyUNSAFE);
2803     
2804     if (refAssembly == NULL)
2805         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2806
2807     DomainAssembly *pAssembly = refAssembly->GetDomainAssembly();
2808     mdAssembly token = mdAssemblyNil;
2809     
2810     IMDInternalImport *mdImport = pAssembly->GetCurrentAssembly()->GetManifestImport();
2811     
2812     if (mdImport != 0)
2813     {
2814         if (FAILED(mdImport->GetAssemblyFromScope(&token)))
2815         {
2816             FCThrow(kBadImageFormatException);
2817         }
2818     }
2819     
2820     return token;
2821 }
2822 FCIMPLEND
2823
2824     
2825 void QCALLTYPE ModuleHandle::GetPEKind(QCall::ModuleHandle pModule, DWORD* pdwPEKind, DWORD* pdwMachine)
2826 {
2827     QCALL_CONTRACT;
2828
2829     BEGIN_QCALL;
2830     pModule->GetFile()->GetPEKindAndMachine(pdwPEKind, pdwMachine);
2831     END_QCALL;
2832 }
2833
2834 FCIMPL1(INT32, ModuleHandle::GetMDStreamVersion, ReflectModuleBaseObject * pModuleUNSAFE)
2835 {
2836     FCALL_CONTRACT;
2837
2838     REFLECTMODULEBASEREF refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
2839
2840     if (refModule == NULL)
2841         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2842
2843     Module *pModule = refModule->GetModule();
2844     
2845     if (pModule->IsResource())
2846         return 0;
2847     
2848     return pModule->GetMDImport()->GetMetadataStreamVersion();   
2849 }
2850 FCIMPLEND
2851
2852 void QCALLTYPE ModuleHandle::GetModuleType(QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retType)
2853 {
2854     QCALL_CONTRACT;
2855
2856     TypeHandle globalTypeHandle = TypeHandle();
2857     
2858     BEGIN_QCALL;
2859     
2860         EX_TRY
2861         {          
2862             globalTypeHandle = TypeHandle(pModule->GetGlobalMethodTable());
2863         }
2864         EX_SWALLOW_NONTRANSIENT;
2865
2866         if (!globalTypeHandle.IsNull())
2867         {
2868             GCX_COOP();
2869             retType.Set(globalTypeHandle.GetManagedClassObject());
2870         }
2871
2872     END_QCALL;
2873
2874     return;
2875 }
2876
2877 FCIMPL1(INT32, ModuleHandle::GetToken, ReflectModuleBaseObject * pModuleUNSAFE) {
2878     CONTRACTL {
2879         FCALL_CHECK;
2880     }
2881     CONTRACTL_END;
2882
2883     REFLECTMODULEBASEREF refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
2884
2885     if (refModule == NULL)
2886         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2887
2888     Module *pModule = refModule->GetModule();
2889     
2890     if (pModule->IsResource())
2891         return mdModuleNil;
2892     
2893     return pModule->GetMDImport()->GetModuleFromScope();
2894 }
2895 FCIMPLEND
2896
2897 FCIMPL1(IMDInternalImport*, ModuleHandle::GetMetadataImport, ReflectModuleBaseObject * pModuleUNSAFE)
2898 {
2899     FCALL_CONTRACT;
2900
2901     REFLECTMODULEBASEREF refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
2902
2903     if (refModule == NULL)
2904         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2905
2906     Module *pModule = refModule->GetModule();
2907
2908     if (pModule->IsResource())
2909         return NULL;
2910
2911     return pModule->GetMDImport();
2912 }
2913 FCIMPLEND
2914
2915 BOOL QCALLTYPE ModuleHandle::ContainsPropertyMatchingHash(QCall::ModuleHandle pModule, INT32 tkProperty, ULONG hash)
2916 {
2917     QCALL_CONTRACT;
2918
2919     BOOL fContains = TRUE;
2920
2921     BEGIN_QCALL;
2922
2923     fContains = pModule->MightContainMatchingProperty(tkProperty, hash);
2924
2925     END_QCALL;
2926
2927     return fContains;
2928 }
2929
2930 void QCALLTYPE ModuleHandle::ResolveType(QCall::ModuleHandle pModule, INT32 tkType, TypeHandle *typeArgs, INT32 typeArgsCount, TypeHandle *methodArgs, INT32 methodArgsCount, QCall::ObjectHandleOnStack retType)
2931 {
2932     QCALL_CONTRACT;
2933
2934     TypeHandle typeHandle;
2935     
2936     BEGIN_QCALL;
2937     
2938     _ASSERTE(!IsNilToken(tkType));
2939
2940     SigTypeContext typeContext(Instantiation(typeArgs, typeArgsCount), Instantiation(methodArgs, methodArgsCount));
2941         typeHandle = ClassLoader::LoadTypeDefOrRefOrSpecThrowing(pModule, tkType, &typeContext, 
2942                                                           ClassLoader::ThrowIfNotFound, 
2943                                                           ClassLoader::PermitUninstDefOrRef);
2944
2945     GCX_COOP();
2946     retType.Set(typeHandle.GetManagedClassObject());
2947
2948     END_QCALL;
2949
2950     return;
2951 }
2952
2953 MethodDesc *QCALLTYPE ModuleHandle::ResolveMethod(QCall::ModuleHandle pModule, INT32 tkMemberRef, TypeHandle *typeArgs, INT32 typeArgsCount, TypeHandle *methodArgs, INT32 methodArgsCount)
2954 {
2955     QCALL_CONTRACT;
2956
2957     MethodDesc* pMD = NULL;
2958     
2959     BEGIN_QCALL;
2960
2961     _ASSERTE(!IsNilToken(tkMemberRef));
2962
2963     BOOL strictMetadataChecks = (TypeFromToken(tkMemberRef) == mdtMethodSpec);
2964
2965     SigTypeContext typeContext(Instantiation(typeArgs, typeArgsCount), Instantiation(methodArgs, methodArgsCount));
2966     pMD = MemberLoader::GetMethodDescFromMemberDefOrRefOrSpec(pModule, tkMemberRef, &typeContext, strictMetadataChecks, FALSE);
2967
2968     // This will get us the instantiating or unboxing stub if needed
2969     pMD = MethodDesc::FindOrCreateAssociatedMethodDescForReflection(pMD, pMD->GetMethodTable(), pMD->GetMethodInstantiation());
2970
2971     END_QCALL;
2972
2973     return pMD;
2974 }
2975
2976 void QCALLTYPE ModuleHandle::ResolveField(QCall::ModuleHandle pModule, INT32 tkMemberRef, TypeHandle *typeArgs, INT32 typeArgsCount, TypeHandle *methodArgs, INT32 methodArgsCount, QCall::ObjectHandleOnStack retField)
2977 {
2978     QCALL_CONTRACT;
2979
2980     FieldDesc* pField = NULL;
2981     
2982     BEGIN_QCALL;
2983
2984     _ASSERTE(!IsNilToken(tkMemberRef));
2985
2986     SigTypeContext typeContext(Instantiation(typeArgs, typeArgsCount), Instantiation(methodArgs, methodArgsCount));
2987     pField = MemberLoader::GetFieldDescFromMemberDefOrRef(pModule, tkMemberRef, &typeContext, FALSE);
2988     GCX_COOP();
2989     retField.Set(pField->GetStubFieldInfo());
2990
2991     END_QCALL;
2992
2993     return;
2994 }
2995
2996 void QCALLTYPE ModuleHandle::GetAssembly(QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retAssembly)
2997 {
2998     QCALL_CONTRACT;
2999
3000     DomainAssembly *pAssembly = NULL;
3001
3002     BEGIN_QCALL;
3003     pAssembly = pModule->GetDomainAssembly();
3004
3005     GCX_COOP();
3006     retAssembly.Set(pAssembly->GetExposedAssemblyObject());
3007     END_QCALL;
3008
3009     return;
3010 }
3011
3012 FCIMPL5(ReflectMethodObject*, ModuleHandle::GetDynamicMethod, ReflectMethodObject *pMethodUNSAFE, ReflectModuleBaseObject *pModuleUNSAFE, StringObject *name, U1Array *sig,  Object *resolver) {
3013     CONTRACTL {
3014         FCALL_CHECK;
3015         PRECONDITION(CheckPointer(name));
3016         PRECONDITION(CheckPointer(sig));
3017     }
3018     CONTRACTL_END;
3019     
3020     DynamicMethodDesc *pNewMD = NULL;
3021
3022     struct
3023     {
3024         STRINGREF nameRef;
3025         OBJECTREF resolverRef;
3026         OBJECTREF methodRef;
3027         REFLECTMETHODREF retMethod;
3028         REFLECTMODULEBASEREF refModule;
3029     } gc;
3030     gc.nameRef = (STRINGREF)name;
3031     gc.resolverRef = (OBJECTREF)resolver;
3032     gc.methodRef = ObjectToOBJECTREF(pMethodUNSAFE);
3033     gc.retMethod = NULL;
3034     gc.refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
3035
3036     if (gc.refModule == NULL)
3037         FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
3038
3039     Module *pModule = gc.refModule->GetModule();
3040
3041     HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
3042     
3043     DomainFile *pDomainModule = pModule->GetDomainFile();
3044
3045     U1ARRAYREF dataArray = (U1ARRAYREF)sig;
3046     DWORD sigSize = dataArray->GetNumComponents();
3047     NewHolder<BYTE> pSig(new BYTE[sigSize]);
3048     memcpy(pSig, dataArray->GetDataPtr(), sigSize);
3049
3050     DWORD length = gc.nameRef->GetStringLength();
3051     NewArrayHolder<char> pName(new char[(length + 1) * 2]);
3052     pName[0] = '\0';
3053     length = WszWideCharToMultiByte(CP_UTF8, 0, gc.nameRef->GetBuffer(), length, pName, (length + 1) * 2 - sizeof(char), NULL, NULL);
3054     if (length)
3055         pName[length / sizeof(char)] = '\0';
3056
3057     DynamicMethodTable *pMTForDynamicMethods = pDomainModule->GetDynamicMethodTable();
3058     pNewMD = pMTForDynamicMethods->GetDynamicMethod(pSig, sigSize, pName);
3059     _ASSERTE(pNewMD != NULL);
3060     // pNewMD now owns pSig and pName.
3061     pSig.SuppressRelease();
3062     pName.SuppressRelease();
3063
3064     // create a handle to hold the resolver objectref
3065     OBJECTHANDLE resolverHandle = pDomainModule->GetAppDomain()->CreateLongWeakHandle(gc.resolverRef);
3066     pNewMD->GetLCGMethodResolver()->SetManagedResolver(resolverHandle);
3067     gc.retMethod = pNewMD->GetStubMethodInfo();
3068     gc.retMethod->SetKeepAlive(gc.resolverRef);
3069
3070     LoaderAllocator *pLoaderAllocator = pModule->GetLoaderAllocator();
3071
3072     if (pLoaderAllocator->IsCollectible())
3073         pLoaderAllocator->AddReference();
3074    
3075     HELPER_METHOD_FRAME_END();
3076
3077     return (ReflectMethodObject*)OBJECTREFToObject(gc.retMethod);
3078 }
3079 FCIMPLEND
3080
3081 void QCALLTYPE RuntimeMethodHandle::GetCallerType(QCall::StackCrawlMarkHandle pStackMark, QCall::ObjectHandleOnStack retType)
3082
3083     QCALL_CONTRACT;
3084
3085     BEGIN_QCALL;
3086     GCX_COOP();
3087     MethodTable *pMT = NULL;
3088
3089     pMT = SystemDomain::GetCallersType(pStackMark);
3090
3091     if (pMT != NULL)
3092         retType.Set(pMT->GetManagedClassObject());
3093
3094     END_QCALL;
3095
3096     return;
3097 }
3098