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