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