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