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.
8 #include "runtimehandles.h"
12 #include "typehandle.h"
14 #include "siginfo.hpp"
15 #include "clsload.hpp"
16 #include "typestring.h"
17 #include "typeparse.h"
21 #include "jitinterface.h"
22 #include "stackprobe.h"
25 #include "objecthandle.h"
26 #include "interoputil.h"
28 #include "virtualcallstub.h"
29 #include "contractimpl.h"
30 #include "dynamicmethod.h"
31 #include "peimagelayout.inl"
33 #include "eventtrace.h"
34 #include "invokeutil.h"
37 FCIMPL3(FC_BOOL_RET, Utf8String::EqualsCaseSensitive, LPCUTF8 szLhs, LPCUTF8 szRhs, INT32 stringNumBytes)
41 PRECONDITION(CheckPointer(szLhs));
42 PRECONDITION(CheckPointer(szRhs));
46 // Important: the string in pSsz isn't null terminated so the length must be used
47 // when performing operations on the string.
49 // At this point, both the left and right strings are guaranteed to have the
51 FC_RETURN_BOOL(strncmp(szLhs, szRhs, stringNumBytes) == 0);
55 BOOL QCALLTYPE Utf8String::EqualsCaseInsensitive(LPCUTF8 szLhs, LPCUTF8 szRhs, INT32 stringNumBytes)
59 // Important: the string in pSsz isn't null terminated so the length must be used
60 // when performing operations on the string.
62 BOOL fStringsEqual = FALSE;
66 _ASSERTE(CheckPointer(szLhs));
67 _ASSERTE(CheckPointer(szRhs));
69 // At this point, both the left and right strings are guaranteed to have the
71 StackSString lhs(SString::Utf8, szLhs, stringNumBytes);
72 StackSString rhs(SString::Utf8, szRhs, stringNumBytes);
74 // We can use SString for simple case insensitive compares
75 fStringsEqual = lhs.EqualsCaseInsensitive(rhs);
82 ULONG QCALLTYPE Utf8String::HashCaseInsensitive(LPCUTF8 sz, INT32 stringNumBytes)
86 // Important: the string in pSsz isn't null terminated so the length must be used
87 // when performing operations on the string.
93 StackSString str(SString::Utf8, sz, stringNumBytes);
94 hashValue = str.HashCaseInsensitive();
101 static BOOL CheckCAVisibilityFromDecoratedType(MethodTable* pCAMT, MethodDesc* pCACtor, MethodTable* pDecoratedMT, Module* pDecoratedModule)
108 PRECONDITION(CheckPointer(pCAMT));
109 PRECONDITION(CheckPointer(pCACtor, NULL_OK));
110 PRECONDITION(CheckPointer(pDecoratedMT, NULL_OK));
111 PRECONDITION(CheckPointer(pDecoratedModule));
115 DWORD dwAttr = mdPublic;
119 // Allowing a dangerous method to be called in custom attribute instantiation is, well, dangerous.
120 // E.g. a malicious user can craft a custom attribute record that fools us into creating a DynamicMethod
121 // object attached to typeof(System.Reflection.CustomAttribute) and thus gain access to mscorlib internals.
122 if (InvokeUtil::IsDangerousMethod(pCACtor))
125 _ASSERTE(pCACtor->IsCtor());
127 dwAttr = pCACtor->GetAttrs();
130 StaticAccessCheckContext accessContext(NULL, pDecoratedMT, pDecoratedModule->GetAssembly());
132 // Don't do transparency check here. Custom attributes have different transparency rules.
133 // The checks are done by AllowCriticalCustomAttributes and CheckLinktimeDemands in CustomAttribute.cs.
134 return ClassLoader::CanAccess(
137 pCAMT->GetAssembly(),
141 *AccessCheckOptions::s_pNormalAccessChecks,
146 BOOL QCALLTYPE RuntimeMethodHandle::IsCAVisibleFromDecoratedType(
147 EnregisteredTypeHandle targetTypeHandle,
148 MethodDesc * pTargetCtor,
149 EnregisteredTypeHandle sourceTypeHandle,
150 QCall::ModuleHandle sourceModuleHandle)
157 TypeHandle sourceHandle = TypeHandle::FromPtr(sourceTypeHandle);
158 TypeHandle targetHandle = TypeHandle::FromPtr(targetTypeHandle);
160 _ASSERTE((sourceHandle.IsNull() || !sourceHandle.IsTypeDesc()) &&
161 !targetHandle.IsNull() &&
162 !targetHandle.IsTypeDesc());
164 if (sourceHandle.IsTypeDesc() ||
165 targetHandle.IsNull() ||
166 targetHandle.IsTypeDesc())
167 COMPlusThrowArgumentNull(NULL, W("Arg_InvalidHandle"));
169 bResult = CheckCAVisibilityFromDecoratedType(targetHandle.AsMethodTable(), pTargetCtor, sourceHandle.AsMethodTable(), sourceModuleHandle);
176 BOOL QCALLTYPE RuntimeMethodHandle::IsSecurityCritical(MethodDesc *pMD)
181 PRECONDITION(CheckPointer(pMD));
185 BOOL fIsCritical = TRUE;
190 COMPlusThrowArgumentNull(NULL, W("Arg_InvalidHandle"));
192 fIsCritical = Security::IsMethodCritical(pMD);
200 BOOL QCALLTYPE RuntimeMethodHandle::IsSecuritySafeCritical(MethodDesc *pMD)
205 PRECONDITION(CheckPointer(pMD));
209 BOOL fIsSafeCritical = TRUE;
214 COMPlusThrowArgumentNull(NULL, W("Arg_InvalidHandle"));
216 fIsSafeCritical = Security::IsMethodSafeCritical(pMD);
220 return fIsSafeCritical;
224 BOOL QCALLTYPE RuntimeMethodHandle::IsSecurityTransparent(MethodDesc *pMD)
229 PRECONDITION(CheckPointer(pMD));
233 BOOL fIsTransparent = TRUE;
238 COMPlusThrowArgumentNull(NULL, W("Arg_InvalidHandle"));
240 fIsTransparent = Security::IsMethodTransparent(pMD);
244 return fIsTransparent;
247 FCIMPL2(FC_BOOL_RET, RuntimeMethodHandle::IsTokenSecurityTransparent, ReflectModuleBaseObject *pModuleUNSAFE, INT32 tkToken) {
253 REFLECTMODULEBASEREF refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
255 if(refModule == NULL)
256 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
258 Module *pModule = refModule->GetModule();
260 BOOL bIsSecurityTransparent = TRUE;
262 HELPER_METHOD_FRAME_BEGIN_RET_1(refModule);
264 bIsSecurityTransparent = Security::IsTokenTransparent(pModule, tkToken);
266 HELPER_METHOD_FRAME_END();
268 FC_RETURN_BOOL(bIsSecurityTransparent );
273 static bool DoAttributeTransparencyChecks(Assembly *pAttributeAssembly, Assembly *pDecoratedAssembly)
280 PRECONDITION(CheckPointer(pAttributeAssembly));
281 PRECONDITION(CheckPointer(pDecoratedAssembly));
285 // Do transparency checks - if both the decorated assembly and attribute use the v4 security model,
286 // then we can do a direct transparency check. However, if the decorated assembly uses the v2
287 // security model, then we need to convert the security critical attribute to looking as though it
288 // has a LinkDemand for full trust.
289 const SecurityTransparencyBehavior *pTargetTransparency = pDecoratedAssembly->GetSecurityTransparencyBehavior();
290 const SecurityTransparencyBehavior *pAttributeTransparency = pAttributeAssembly->GetSecurityTransparencyBehavior();
292 // v2 transparency did not impose checks for using its custom attributes, so if the attribute is
293 // defined in an assembly using the v2 transparency model then we don't need to do any
294 // additional checks.
295 if (pAttributeTransparency->DoAttributesRequireTransparencyChecks())
297 if (pTargetTransparency->CanTransparentCodeCallLinkDemandMethods() &&
298 pAttributeTransparency->CanCriticalMembersBeConvertedToLinkDemand())
300 // We have a v4 critical attribute being applied to a v2 transparent target. Since v2
301 // transparency doesn't understand externally visible critical attributes, we convert the
302 // attribute to a LinkDemand for full trust. v2 transparency did not convert
303 // LinkDemands on its attributes into full demands so we do not do that second level of
304 // conversion here either.
305 Security::FullTrustLinkDemand(pDecoratedAssembly);
310 // If we are here either the target of the attribute uses the v4 security model, or the
311 // attribute itself uses the v2 model. In these cases, we cannot perform a conversion of
312 // the critical attribute into a LinkDemand, and we have an error condition.
320 FCIMPL3(void, RuntimeMethodHandle::CheckLinktimeDemands, ReflectMethodObject *pMethodUNSAFE, ReflectModuleBaseObject *pModuleUNSAFE, CLR_BOOL isDecoratedTargetSecurityTransparent)
325 PRECONDITION(CheckPointer(pModuleUNSAFE));
326 PRECONDITION(CheckPointer(pMethodUNSAFE));
330 if(!Security::IsTransparencyEnforcementEnabled())
336 REFLECTMETHODREF refMethod = (REFLECTMETHODREF)ObjectToOBJECTREF(pMethodUNSAFE);
337 REFLECTMODULEBASEREF refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
339 HELPER_METHOD_FRAME_BEGIN_2(refMethod, refModule);
341 MethodDesc *pCallee = refMethod->GetMethod(); // pCallee is the CA ctor or CA setter method
342 Module *pDecoratedModule = refModule->GetModule();
344 bool isAttributeSecurityCritical = Security::IsMethodCritical(pCallee) &&
345 !Security::IsMethodSafeCritical(pCallee);
347 if (isDecoratedTargetSecurityTransparent && isAttributeSecurityCritical)
349 if (!DoAttributeTransparencyChecks(pCallee->GetAssembly(), pDecoratedModule->GetAssembly()))
351 SecurityTransparent::ThrowMethodAccessException(pCallee);
356 HELPER_METHOD_FRAME_END();
360 NOINLINE static ReflectClassBaseObject* GetRuntimeTypeHelper(LPVOID __me, TypeHandle typeHandle, OBJECTREF keepAlive)
362 FC_INNER_PROLOG_NO_ME_SETUP();
363 if (typeHandle.AsPtr() == NULL)
366 // RuntimeTypeHandle::GetRuntimeType has picked off the most common case, but does not cover array types.
367 // Before we do the really heavy weight option of setting up a helper method frame, check if we have to.
368 OBJECTREF refType = typeHandle.GetManagedClassObjectFast();
370 return (ReflectClassBaseObject*)OBJECTREFToObject(refType);
372 HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_1(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, keepAlive);
373 refType = typeHandle.GetManagedClassObject();
374 HELPER_METHOD_FRAME_END();
377 return (ReflectClassBaseObject*)OBJECTREFToObject(refType);
380 #define RETURN_CLASS_OBJECT(typeHandle, keepAlive) FC_INNER_RETURN(ReflectClassBaseObject*, GetRuntimeTypeHelper(__me, typeHandle, keepAlive))
382 NOINLINE ReflectModuleBaseObject* GetRuntimeModuleHelper(LPVOID __me, Module *pModule, OBJECTREF keepAlive)
384 FC_INNER_PROLOG_NO_ME_SETUP();
388 DomainFile * pDomainFile = pModule->FindDomainFile(GetAppDomain());
390 OBJECTREF refModule = (pDomainFile != NULL) ? pDomainFile->GetExposedModuleObjectIfExists() : NULL;
392 if(refModule != NULL)
393 return (ReflectModuleBaseObject*)OBJECTREFToObject(refModule);
395 HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_1(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, keepAlive);
396 refModule = pModule->GetExposedObject();
397 HELPER_METHOD_FRAME_END();
400 return (ReflectModuleBaseObject*)OBJECTREFToObject(refModule);
403 NOINLINE AssemblyBaseObject* GetRuntimeAssemblyHelper(LPVOID __me, DomainAssembly *pAssembly, OBJECTREF keepAlive)
405 FC_INNER_PROLOG_NO_ME_SETUP();
406 if (pAssembly == NULL)
409 OBJECTREF refAssembly = (pAssembly != NULL) ? pAssembly->GetExposedAssemblyObjectIfExists() : NULL;
411 if(refAssembly != NULL)
412 return (AssemblyBaseObject*)OBJECTREFToObject(refAssembly);
414 HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_1(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, keepAlive);
415 refAssembly = pAssembly->GetExposedAssemblyObject();
416 HELPER_METHOD_FRAME_END();
419 return (AssemblyBaseObject*)OBJECTREFToObject(refAssembly);
423 // This is the routine that is called by the 'typeof()' operator in C#. It is one of the most commonly used
424 // reflection operations. This call should be optimized away in nearly all situations
425 FCIMPL1_V(ReflectClassBaseObject*, RuntimeTypeHandle::GetTypeFromHandle, FCALLRuntimeTypeHandle th)
430 return FCALL_RTH_TO_REFLECTCLASS(th);
434 FCIMPL1(ReflectClassBaseObject*, RuntimeTypeHandle::GetRuntimeType, EnregisteredTypeHandle th)
438 TypeHandle typeHandle = TypeHandle::FromPtr(th);
439 _ASSERTE(CheckPointer(typeHandle.AsPtr(), NULL_OK));
440 if (typeHandle.AsPtr()!= NULL)
442 if (!typeHandle.IsTypeDesc())
444 OBJECTREF typePtr = typeHandle.AsMethodTable()->GetManagedClassObjectIfExists();
447 return (ReflectClassBaseObject*)OBJECTREFToObject(typePtr);
454 RETURN_CLASS_OBJECT(typeHandle, NULL);
458 FCIMPL1_V(EnregisteredTypeHandle, RuntimeTypeHandle::GetValueInternal, FCALLRuntimeTypeHandle RTH)
462 if (FCALL_RTH_TO_REFLECTCLASS(RTH) == NULL)
465 return FCALL_RTH_TO_REFLECTCLASS(RTH) ->GetType().AsPtr();
469 // TypeEqualsHelper and TypeNotEqualsHelper are almost identical.
470 // Unfortunately we cannot combime them because they need to hardcode the caller's name
471 NOINLINE static BOOL TypeEqualSlow(OBJECTREF refL, OBJECTREF refR, LPVOID __me)
475 FC_INNER_PROLOG_NO_ME_SETUP();
477 _ASSERTE(refL != NULL && refR != NULL);
479 HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_2(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, refL, refR);
481 MethodDescCallSite TypeEqualsMethod(METHOD__OBJECT__EQUALS, &refL);
489 ret = TypeEqualsMethod.Call_RetBool(args);
491 HELPER_METHOD_FRAME_END();
500 #include <optsmallperfcritical.h>
502 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::TypeEQ, Object* left, Object* right)
506 OBJECTREF refL = (OBJECTREF)left;
507 OBJECTREF refR = (OBJECTREF)right;
511 FC_RETURN_BOOL(TRUE);
516 FC_RETURN_BOOL(FALSE);
519 if ((refL->GetMethodTable() == g_pRuntimeTypeClass || refR->GetMethodTable() == g_pRuntimeTypeClass))
521 // Quick path for negative common case
522 FC_RETURN_BOOL(FALSE);
525 // The fast path didn't get us the result
526 // Let's try the slow path: refL.Equals(refR);
527 FC_INNER_RETURN(FC_BOOL_RET, (FC_BOOL_RET)(!!TypeEqualSlow(refL, refR, __me)));
531 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::TypeNEQ, Object* left, Object* right)
535 OBJECTREF refL = (OBJECTREF)left;
536 OBJECTREF refR = (OBJECTREF)right;
540 FC_RETURN_BOOL(FALSE);
545 FC_RETURN_BOOL(TRUE);
548 if ((refL->GetMethodTable() == g_pRuntimeTypeClass || refR->GetMethodTable() == g_pRuntimeTypeClass))
550 // Quick path for negative common case
551 FC_RETURN_BOOL(TRUE);
554 // The fast path didn't get us the result
555 // Let's try the slow path: refL.Equals(refR);
556 FC_INNER_RETURN(FC_BOOL_RET, (FC_BOOL_RET)(!TypeEqualSlow(refL, refR, __me)));
560 #include <optdefault.h>
565 #ifdef FEATURE_COMINTEROP
566 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsWindowsRuntimeObjectType, ReflectClassBaseObject *rtTypeUNSAFE)
570 BOOL isWindowsRuntimeType = FALSE;
572 TypeHandle typeHandle = rtTypeUNSAFE->GetType();
573 MethodTable *pMT = typeHandle.GetMethodTable();
577 isWindowsRuntimeType = pMT->IsWinRTObjectType();
580 FC_RETURN_BOOL(isWindowsRuntimeType);
584 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsTypeExportedToWindowsRuntime, ReflectClassBaseObject *rtTypeUNSAFE)
588 BOOL isExportedToWinRT = FALSE;
590 TypeHandle typeHandle = rtTypeUNSAFE->GetType();
591 MethodTable *pMT = typeHandle.GetMethodTable();
595 isExportedToWinRT = pMT->IsExportedToWinRT();
598 FC_RETURN_BOOL(isExportedToWinRT);
601 #endif // FEATURE_COMINTEROP
603 NOINLINE static MethodDesc * RestoreMethodHelper(MethodDesc * pMethod, LPVOID __me)
605 FC_INNER_PROLOG_NO_ME_SETUP();
607 HELPER_METHOD_FRAME_BEGIN_RET_0();
608 pMethod->CheckRestore();
609 HELPER_METHOD_FRAME_END();
616 FCIMPL1(MethodDesc *, RuntimeTypeHandle::GetFirstIntroducedMethod, ReflectClassBaseObject *pTypeUNSAFE) {
619 PRECONDITION(CheckPointer(pTypeUNSAFE));
623 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
624 TypeHandle typeHandle = refType->GetType();
626 if (typeHandle.IsGenericVariable())
627 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
629 if (typeHandle.IsTypeDesc()) {
630 if (!typeHandle.IsArray())
634 MethodTable* pMT = typeHandle.GetMethodTable();
638 MethodDesc* pMethod = MethodTable::IntroducedMethodIterator::GetFirst(pMT);
640 // The only method that can show up here unrestored is instantiated methods. Check for it before performing the expensive IsRestored() check.
641 if (pMethod != NULL && pMethod->GetClassification() == mcInstantiated && !pMethod->IsRestored()) {
642 FC_INNER_RETURN(MethodDesc *, RestoreMethodHelper(pMethod, __me));
645 _ASSERTE(pMethod == NULL || pMethod->IsRestored());
650 #include <optsmallperfcritical.h>
651 FCIMPL1(void, RuntimeTypeHandle::GetNextIntroducedMethod, MethodDesc ** ppMethod) {
654 PRECONDITION(CheckPointer(ppMethod));
655 PRECONDITION(CheckPointer(*ppMethod));
659 MethodDesc *pMethod = MethodTable::IntroducedMethodIterator::GetNext(*ppMethod);
663 if (pMethod != NULL && pMethod->GetClassification() == mcInstantiated && !pMethod->IsRestored()) {
664 FC_INNER_RETURN_VOID(RestoreMethodHelper(pMethod, __me));
667 _ASSERTE(pMethod == NULL || pMethod->IsRestored());
670 #include <optdefault.h>
672 FCIMPL1(INT32, RuntimeTypeHandle::GetCorElementType, ReflectClassBaseObject *pTypeUNSAFE) {
678 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
681 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
683 return refType->GetType().GetSignatureCorElementType();
687 FCIMPL1(AssemblyBaseObject*, RuntimeTypeHandle::GetAssembly, ReflectClassBaseObject *pTypeUNSAFE) {
693 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
696 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
698 DomainFile *pDomainFile = NULL;
700 Module *pModule = refType->GetType().GetAssembly()->GetManifestModule();
702 pDomainFile = pModule->FindDomainFile(GetAppDomain());
703 #ifdef FEATURE_LOADER_OPTIMIZATION
704 if (pDomainFile == NULL)
706 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
708 pDomainFile = GetAppDomain()->LoadDomainNeutralModuleDependency(pModule, FILE_LOADED);
710 HELPER_METHOD_FRAME_END();
712 #endif // FEATURE_LOADER_OPTIMIZATION
715 FC_RETURN_ASSEMBLY_OBJECT((DomainAssembly *)pDomainFile, refType);
720 FCIMPL1(FC_BOOL_RET, RuntimeFieldHandle::AcquiresContextFromThis, FieldDesc *pField)
724 PRECONDITION(CheckPointer(pField));
728 FC_RETURN_BOOL(pField->IsSharedByGenericInstantiations());
734 BOOL QCALLTYPE RuntimeFieldHandle::IsSecurityCritical(FieldDesc *pFD)
739 PRECONDITION(CheckPointer(pFD));
743 BOOL fIsCritical = FALSE;
747 fIsCritical = Security::IsFieldCritical(pFD);
755 BOOL QCALLTYPE RuntimeFieldHandle::IsSecuritySafeCritical(FieldDesc *pFD)
760 PRECONDITION(CheckPointer(pFD));
764 BOOL fIsSafeCritical = FALSE;
768 fIsSafeCritical = Security::IsFieldSafeCritical(pFD);
772 return fIsSafeCritical;
776 BOOL QCALLTYPE RuntimeFieldHandle::IsSecurityTransparent(FieldDesc *pFD)
781 PRECONDITION(CheckPointer(pFD));
785 BOOL fIsTransparent = FALSE;
789 fIsTransparent = Security::IsFieldTransparent(pFD);
793 return fIsTransparent;
797 void QCALLTYPE RuntimeFieldHandle::CheckAttributeAccess(FieldDesc *pFD, QCall::ModuleHandle pModule)
802 PRECONDITION(CheckPointer(pFD));
803 PRECONDITION(CheckPointer(pModule.m_pModule));
807 if(!Security::IsTransparencyEnforcementEnabled())
815 if (Security::IsFieldCritical(pFD) && !Security::IsFieldSafeCritical(pFD))
819 if (!DoAttributeTransparencyChecks(pFD->GetModule()->GetAssembly(), pModule->GetAssembly()))
821 ThrowFieldAccessException(NULL, pFD, TRUE, IDS_E_CRITICAL_FIELD_ACCESS_DENIED);
828 FCIMPL1(ReflectModuleBaseObject*, RuntimeTypeHandle::GetModule, ReflectClassBaseObject *pTypeUNSAFE) {
836 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
839 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
841 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
843 result = refType->GetType().GetModule();
845 END_SO_INTOLERANT_CODE;
847 FC_RETURN_MODULE_OBJECT(result, refType);
851 FCIMPL1(ReflectClassBaseObject *, RuntimeTypeHandle::GetBaseType, ReflectClassBaseObject *pTypeUNSAFE) {
857 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
860 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
862 TypeHandle typeHandle = refType->GetType();
864 if (typeHandle.IsGenericVariable())
865 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
867 if (typeHandle.IsTypeDesc()) {
868 if (!typeHandle.IsArray())
872 RETURN_CLASS_OBJECT(typeHandle.GetParent(), refType);
876 FCIMPL1(ReflectClassBaseObject *, RuntimeTypeHandle::GetElementType, ReflectClassBaseObject *pTypeUNSAFE) {
882 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
885 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
887 TypeHandle typeHandle = refType->GetType();
889 if (!typeHandle.IsTypeDesc())
892 if (typeHandle.IsGenericVariable())
895 TypeHandle typeReturn;
897 if (typeHandle.IsArray())
898 typeReturn = typeHandle.AsArray()->GetArrayElementTypeHandle();
900 typeReturn = typeHandle.AsTypeDesc()->GetTypeParam();
902 RETURN_CLASS_OBJECT(typeReturn, refType);
906 FCIMPL1(INT32, RuntimeTypeHandle::GetArrayRank, ReflectClassBaseObject *pTypeUNSAFE) {
909 PRECONDITION(CheckPointer(pTypeUNSAFE));
910 PRECONDITION(pTypeUNSAFE->GetType().IsArray());
914 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
916 return (INT32)refType->GetType().AsArray()->GetRank();
920 FCIMPL1(INT32, RuntimeTypeHandle::GetNumVirtuals, ReflectClassBaseObject *pTypeUNSAFE) {
926 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
929 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
931 TypeHandle typeHandle = refType->GetType();
933 if (typeHandle.IsGenericVariable())
934 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
936 MethodTable *pMT = typeHandle.GetMethodTable();
939 return (INT32)pMT->GetNumVirtuals();
941 return 0; //REVIEW: should this return the number of methods in Object?
945 FCIMPL2(MethodDesc *, RuntimeTypeHandle::GetMethodAt, ReflectClassBaseObject *pTypeUNSAFE, INT32 slot) {
951 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
954 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
956 TypeHandle typeHandle = refType->GetType();
958 MethodDesc* pRetMethod = NULL;
960 if (typeHandle.IsGenericVariable())
961 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
963 if (slot < 0 || slot >= (INT32)typeHandle.GetMethodTable()->GetNumVirtuals())
964 FCThrowRes(kArgumentException, W("Arg_ArgumentOutOfRangeException"));
966 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
967 pRetMethod = typeHandle.GetMethodTable()->GetMethodDescForSlot((DWORD)slot);
968 HELPER_METHOD_FRAME_END();
975 FCIMPL3(FC_BOOL_RET, RuntimeTypeHandle::GetFields, ReflectClassBaseObject *pTypeUNSAFE, INT32 **result, INT32 *pCount) {
981 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
983 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
985 TypeHandle typeHandle = refType->GetType();
987 if (!pCount || !result)
988 FCThrow(kArgumentNullException);
990 if (typeHandle.IsGenericVariable())
991 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
993 if (typeHandle.IsTypeDesc()) {
995 FC_RETURN_BOOL(TRUE);
998 MethodTable *pMT= typeHandle.GetMethodTable();
1000 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1002 BOOL retVal = FALSE;
1003 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
1004 // <TODO>Check this approximation - we may be losing exact type information </TODO>
1005 ApproxFieldDescIterator fdIterator(pMT, ApproxFieldDescIterator::ALL_FIELDS);
1006 INT32 count = (INT32)fdIterator.Count();
1008 if (count > *pCount)
1014 for(INT32 i = 0; i < count; i ++)
1015 result[i] = (INT32*)fdIterator.Next();
1020 HELPER_METHOD_FRAME_END();
1021 FC_RETURN_BOOL(retVal);
1025 void QCALLTYPE RuntimeMethodHandle::ConstructInstantiation(MethodDesc * pMethod, DWORD format, QCall::StringHandleOnStack retString)
1032 TypeString::AppendInst(ss, pMethod->LoadMethodInstantiation(), format);
1038 void QCALLTYPE RuntimeTypeHandle::ConstructName(EnregisteredTypeHandle pTypeHandle, DWORD format, QCall::StringHandleOnStack retString)
1045 TypeString::AppendType(ss, TypeHandle::FromPtr(pTypeHandle), format);
1051 PTRARRAYREF CopyRuntimeTypeHandles(TypeHandle * prgTH, FixupPointer<TypeHandle> * prgTH2, INT32 numTypeHandles, BinderClassID arrayElemType)
1060 PTRARRAYREF refReturn = NULL;
1061 PTRARRAYREF refArray = NULL;
1063 if (numTypeHandles == 0)
1066 _ASSERTE((prgTH != NULL) || (prgTH2 != NULL));
1069 _ASSERTE(prgTH2 == NULL);
1072 GCPROTECT_BEGIN(refArray);
1073 TypeHandle thRuntimeType = TypeHandle(MscorlibBinder::GetClass(arrayElemType));
1074 TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(thRuntimeType, ELEMENT_TYPE_SZARRAY);
1075 refArray = (PTRARRAYREF)AllocateArrayEx(arrayHandle, &numTypeHandles, 1);
1077 for (INT32 i = 0; i < numTypeHandles; i++)
1084 th = prgTH2[i].GetValue();
1086 OBJECTREF refType = th.GetManagedClassObject();
1087 refArray->SetAt(i, refType);
1090 refReturn = refArray;
1096 void QCALLTYPE RuntimeTypeHandle::GetConstraints(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retTypeArray)
1100 TypeHandle* constraints = NULL;
1104 TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
1106 if (!typeHandle.IsGenericVariable())
1107 COMPlusThrow(kArgumentException, W("Arg_InvalidHandle"));
1109 TypeVarTypeDesc* pGenericVariable = typeHandle.AsGenericVariable();
1112 constraints = pGenericVariable->GetConstraints(&dwCount);
1115 retTypeArray.Set(CopyRuntimeTypeHandles(constraints, NULL, dwCount, CLASS__TYPE));
1122 FCIMPL1(PtrArray*, RuntimeTypeHandle::GetInterfaces, ReflectClassBaseObject *pTypeUNSAFE) {
1128 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1130 if (refType == NULL)
1131 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1133 TypeHandle typeHandle = refType->GetType();
1135 if (typeHandle.IsGenericVariable())
1136 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1138 INT32 ifaceCount = 0;
1140 PTRARRAYREF refRetVal = NULL;
1141 HELPER_METHOD_FRAME_BEGIN_RET_2(refRetVal, refType);
1143 if (typeHandle.IsTypeDesc())
1145 if (typeHandle.IsArray())
1147 ifaceCount = typeHandle.GetMethodTable()->GetNumInterfaces();
1156 ifaceCount = typeHandle.GetMethodTable()->GetNumInterfaces();
1159 // Allocate the array
1162 TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(g_pRuntimeTypeClass), ELEMENT_TYPE_SZARRAY);
1163 refRetVal = (PTRARRAYREF)AllocateArrayEx(arrayHandle, &ifaceCount, 1);
1165 // populate type array
1168 MethodTable::InterfaceMapIterator it = typeHandle.GetMethodTable()->IterateInterfaceMap();
1171 OBJECTREF refInterface = it.GetInterface()->GetManagedClassObject();
1172 refRetVal->SetAt(i, refInterface);
1173 _ASSERTE(refRetVal->GetAt(i) != NULL);
1178 HELPER_METHOD_FRAME_END();
1180 return (PtrArray*)OBJECTREFToObject(refRetVal);
1184 FCIMPL1(INT32, RuntimeTypeHandle::GetAttributes, ReflectClassBaseObject *pTypeUNSAFE) {
1190 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1192 if (refType == NULL)
1193 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1195 TypeHandle typeHandle = refType->GetType();
1197 if (typeHandle.IsTypeDesc()) {
1199 if (typeHandle.IsGenericVariable()) {
1203 if (!typeHandle.IsArray())
1207 #ifdef FEATURE_COMINTEROP
1208 // __ComObject types are always public.
1209 if (IsComObjectClass(typeHandle))
1210 return (typeHandle.GetMethodTable()->GetAttrClass() & tdVisibilityMask) | tdPublic;
1211 #endif // FEATURE_COMINTEROP
1215 ret = (INT32)typeHandle.GetMethodTable()->GetAttrClass();
1221 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsValueType, ReflectClassBaseObject *pTypeUNSAFE)
1228 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1230 _ASSERTE(refType != NULL);
1232 TypeHandle typeHandle = refType->GetType();
1234 FC_RETURN_BOOL(typeHandle.IsValueType());
1238 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsInterface, ReflectClassBaseObject *pTypeUNSAFE)
1245 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1247 _ASSERTE(refType != NULL);
1249 TypeHandle typeHandle = refType->GetType();
1251 FC_RETURN_BOOL(typeHandle.IsInterface());
1257 RuntimeTypeHandle::IsVisible(
1258 EnregisteredTypeHandle pTypeHandle)
1266 BOOL fIsExternallyVisible = FALSE;
1270 TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
1272 _ASSERTE(!typeHandle.IsNull());
1274 fIsExternallyVisible = typeHandle.IsExternallyVisible();
1278 return fIsExternallyVisible;
1279 } // RuntimeTypeHandle::IsVisible
1282 BOOL QCALLTYPE RuntimeTypeHandle::IsSecurityCritical(EnregisteredTypeHandle pTypeHandle)
1287 PRECONDITION(CheckPointer(pTypeHandle));
1291 BOOL fIsCritical = FALSE;
1295 MethodTable *pMT = TypeHandle::FromPtr(pTypeHandle).GetMethodTable();
1298 fIsCritical = Security::IsTypeCritical(pMT);
1307 BOOL QCALLTYPE RuntimeTypeHandle::IsSecuritySafeCritical(EnregisteredTypeHandle pTypeHandle)
1312 PRECONDITION(CheckPointer(pTypeHandle));
1316 BOOL fIsSafeCritical = FALSE;
1320 MethodTable *pMT = TypeHandle::FromPtr(pTypeHandle).GetMethodTable();
1323 fIsSafeCritical = Security::IsTypeSafeCritical(pMT);
1328 return fIsSafeCritical;
1332 BOOL QCALLTYPE RuntimeTypeHandle::IsSecurityTransparent(EnregisteredTypeHandle pTypeHandle)
1337 PRECONDITION(CheckPointer(pTypeHandle));
1341 BOOL fIsTransparent = TRUE;
1345 MethodTable * pMT = TypeHandle::FromPtr(pTypeHandle).GetMethodTable();
1348 fIsTransparent = Security::IsTypeTransparent(pMT);
1353 return fIsTransparent;
1356 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::HasProxyAttribute, ReflectClassBaseObject *pTypeUNSAFE) {
1362 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1364 if (refType == NULL)
1365 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1367 TypeHandle typeHandle = refType->GetType();
1369 // TODO: Justify this
1370 if (typeHandle.IsGenericVariable())
1371 FC_RETURN_BOOL(FALSE);
1373 if (typeHandle.IsTypeDesc()) {
1374 if (!typeHandle.IsArray())
1375 FC_RETURN_BOOL(FALSE);
1378 MethodTable* pMT= typeHandle.GetMethodTable();
1381 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1383 FC_RETURN_BOOL(pMT->GetClass()->HasRemotingProxyAttribute());
1387 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::IsComObject, ReflectClassBaseObject *pTypeUNSAFE, CLR_BOOL isGenericCOM) {
1388 #ifdef FEATURE_COMINTEROP
1396 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1398 if (refType == NULL)
1399 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1401 TypeHandle typeHandle = refType->GetType();
1403 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
1406 ret = IsComObjectClass(typeHandle);
1408 ret = IsComWrapperClass(typeHandle);
1410 HELPER_METHOD_FRAME_END();
1412 FC_RETURN_BOOL(ret);
1418 PRECONDITION(CheckPointer(pTypeUNSAFE));
1422 FC_RETURN_BOOL(FALSE);
1427 FCIMPL1(LPCUTF8, RuntimeTypeHandle::GetUtf8Name, ReflectClassBaseObject* pTypeUNSAFE) {
1433 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1435 if (refType == NULL)
1436 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1438 TypeHandle typeHandle = refType->GetType();
1439 INT32 tkTypeDef = mdTypeDefNil;
1440 LPCUTF8 szName = NULL;
1442 if (typeHandle.IsGenericVariable())
1443 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1445 if (typeHandle.IsTypeDesc())
1446 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1448 MethodTable* pMT= typeHandle.GetMethodTable();
1451 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1453 tkTypeDef = (INT32)pMT->GetCl();
1455 if (IsNilToken(tkTypeDef))
1456 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1458 if (FAILED(pMT->GetMDImport()->GetNameOfTypeDef(tkTypeDef, &szName, NULL)))
1460 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1463 _ASSERTE(CheckPointer(szName, NULL_OK));
1469 FCIMPL1(INT32, RuntimeTypeHandle::GetToken, ReflectClassBaseObject *pTypeUNSAFE) {
1475 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1477 if (refType == NULL)
1478 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1480 TypeHandle typeHandle = refType->GetType();
1482 if (typeHandle.IsTypeDesc())
1484 if (typeHandle.IsGenericVariable())
1486 INT32 tkTypeDef = typeHandle.AsGenericVariable()->GetToken();
1488 _ASSERTE(!IsNilToken(tkTypeDef) && TypeFromToken(tkTypeDef) == mdtGenericParam);
1493 return mdTypeDefNil;
1496 return (INT32)typeHandle.AsMethodTable()->GetCl();
1500 PVOID QCALLTYPE RuntimeTypeHandle::GetGCHandle(EnregisteredTypeHandle pTypeHandle, INT32 handleType)
1504 OBJECTHANDLE objHandle = NULL;
1510 TypeHandle th = TypeHandle::FromPtr(pTypeHandle);
1511 objHandle = th.GetDomain()->CreateTypedHandle(NULL, handleType);
1512 th.GetLoaderAllocator()->RegisterHandleForCleanup(objHandle);
1519 void QCALLTYPE RuntimeTypeHandle::VerifyInterfaceIsImplemented(EnregisteredTypeHandle pTypeHandle, EnregisteredTypeHandle pIFaceHandle)
1525 TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
1526 TypeHandle ifaceHandle = TypeHandle::FromPtr(pIFaceHandle);
1528 if (typeHandle.IsGenericVariable())
1529 COMPlusThrow(kArgumentException, W("Arg_InvalidHandle"));
1531 if (typeHandle.IsTypeDesc()) {
1532 if (!typeHandle.IsArray())
1533 COMPlusThrow(kArgumentException, W("Arg_NotFoundIFace"));
1536 if (typeHandle.IsInterface())
1537 COMPlusThrow(kArgumentException, W("Argument_InterfaceMap"));
1539 if (!ifaceHandle.IsInterface())
1540 COMPlusThrow(kArgumentException, W("Arg_MustBeInterface"));
1542 // First try the cheap check, which amounts to iterating the interface map looking for
1543 // the ifaceHandle MethodTable.
1544 if (!typeHandle.GetMethodTable()->ImplementsInterface(ifaceHandle.AsMethodTable()))
1545 { // If the cheap check fails, try the more expensive but complete check.
1546 if (!typeHandle.CanCastTo(ifaceHandle))
1547 { // If the complete check fails, we're certain that this type
1548 // does not implement the interface specified.
1549 COMPlusThrow(kArgumentException, W("Arg_NotFoundIFace"));
1556 INT32 QCALLTYPE RuntimeTypeHandle::GetInterfaceMethodImplementationSlot(EnregisteredTypeHandle pTypeHandle, EnregisteredTypeHandle pOwner, MethodDesc * pMD)
1560 INT32 slotNumber = -1;
1564 TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
1565 TypeHandle thOwnerOfMD = TypeHandle::FromPtr(pOwner);
1567 // Ok to have INVALID_SLOT in the case where abstract class does not implement an interface method.
1568 // This case can not be reproed using C# "implements" all interface methods
1569 // with at least an abstract method. b19897_GetInterfaceMap_Abstract.exe tests this case.
1570 //@TODO:STUBDISPATCH: Don't need to track down the implementation, just the declaration, and this can
1571 //@TODO: be done faster - just need to make a function FindDispatchDecl.
1572 DispatchSlot slot(typeHandle.GetMethodTable()->FindDispatchSlotForInterfaceMD(thOwnerOfMD, pMD));
1574 slotNumber = slot.GetMethodDesc()->GetSlot();
1581 void QCALLTYPE RuntimeTypeHandle::GetDefaultConstructor(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retMethod)
1587 MethodDesc* pCtor = NULL;
1589 TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
1591 if (!typeHandle.IsTypeDesc())
1593 MethodTable* pMethodTable = typeHandle.AsMethodTable();
1594 if (pMethodTable->HasDefaultConstructor())
1595 pCtor = pMethodTable->GetDefaultConstructor();
1601 retMethod.Set(pCtor->GetStubMethodInfo());
1608 FCIMPL1(ReflectMethodObject*, RuntimeTypeHandle::GetDeclaringMethod, ReflectClassBaseObject *pTypeUNSAFE) {
1614 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1616 if (refType == NULL)
1617 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1619 TypeHandle typeHandle = refType->GetType();;
1621 if (!typeHandle.IsTypeDesc())
1624 TypeVarTypeDesc* pGenericVariable = typeHandle.AsGenericVariable();
1625 mdToken defToken = pGenericVariable->GetTypeOrMethodDef();
1626 if (TypeFromToken(defToken) != mdtMethodDef)
1629 REFLECTMETHODREF pRet = NULL;
1630 HELPER_METHOD_FRAME_BEGIN_RET_0();
1631 MethodDesc * pMD = pGenericVariable->LoadOwnerMethod();
1632 pMD->CheckRestore();
1633 pRet = pMD->GetStubMethodInfo();
1634 HELPER_METHOD_FRAME_END();
1636 return (ReflectMethodObject*)OBJECTREFToObject(pRet);
1640 FCIMPL1(ReflectClassBaseObject*, RuntimeTypeHandle::GetDeclaringType, ReflectClassBaseObject *pTypeUNSAFE) {
1646 TypeHandle retTypeHandle;
1648 BOOL fThrowException = FALSE;
1649 LPCWSTR argName = W("Arg_InvalidHandle");
1650 RuntimeExceptionKind reKind = kArgumentNullException;
1652 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1654 if (refType == NULL)
1655 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1657 TypeHandle typeHandle = refType->GetType();
1659 MethodTable* pMT = NULL;
1660 mdTypeDef tkTypeDef = mdTokenNil;
1662 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
1663 if (typeHandle.IsTypeDesc()) {
1665 if (typeHandle.IsGenericVariable()) {
1666 TypeVarTypeDesc* pGenericVariable = typeHandle.AsGenericVariable();
1667 mdToken defToken = pGenericVariable->GetTypeOrMethodDef();
1669 // Try the fast way first (if the declaring type has been loaded already).
1670 if (TypeFromToken(defToken) == mdtMethodDef)
1672 MethodDesc * retMethod = pGenericVariable->GetModule()->LookupMethodDef(defToken);
1673 if (retMethod != NULL)
1674 retTypeHandle = retMethod->GetMethodTable();
1678 retTypeHandle = pGenericVariable->GetModule()->LookupTypeDef(defToken);
1681 if (!retTypeHandle.IsNull() && retTypeHandle.IsFullyLoaded())
1684 // OK, need to go the slow way and load the type first.
1685 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
1687 if (TypeFromToken(defToken) == mdtMethodDef)
1689 retTypeHandle = pGenericVariable->LoadOwnerMethod()->GetMethodTable();
1693 retTypeHandle = pGenericVariable->LoadOwnerType();
1695 retTypeHandle.CheckRestore();
1697 HELPER_METHOD_FRAME_END();
1700 if (!typeHandle.IsArray())
1702 retTypeHandle = TypeHandle();
1707 pMT = typeHandle.GetMethodTable();
1711 fThrowException = TRUE;
1715 if(!pMT->GetClass()->IsNested())
1717 retTypeHandle = TypeHandle();
1721 tkTypeDef = pMT->GetCl();
1723 if (FAILED(typeHandle.GetModule()->GetMDImport()->GetNestedClassProps(tkTypeDef, &tkTypeDef)))
1725 fThrowException = TRUE;
1726 reKind = kBadImageFormatException;
1731 // Try the fast way first (if the declaring type has been loaded already).
1732 retTypeHandle = typeHandle.GetModule()->LookupTypeDef(tkTypeDef);
1733 if (retTypeHandle.IsNull())
1735 // OK, need to go the slow way and load the type first.
1736 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
1738 retTypeHandle = ClassLoader::LoadTypeDefThrowing(typeHandle.GetModule(), tkTypeDef,
1739 ClassLoader::ThrowIfNotFound,
1740 ClassLoader::PermitUninstDefOrRef);
1742 HELPER_METHOD_FRAME_END();
1746 END_SO_INTOLERANT_CODE;
1748 if (fThrowException)
1750 FCThrowRes(reKind, argName);
1753 RETURN_CLASS_OBJECT(retTypeHandle, refType);
1757 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::CanCastTo, ReflectClassBaseObject *pTypeUNSAFE, ReflectClassBaseObject *pTargetUNSAFE) {
1764 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1765 REFLECTCLASSBASEREF refTarget = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTargetUNSAFE);
1767 if ((refType == NULL) || (refTarget == NULL))
1768 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1770 TypeHandle fromHandle = refType->GetType();
1771 TypeHandle toHandle = refTarget->GetType();
1775 TypeHandle::CastResult r = fromHandle.CanCastToNoGC(toHandle);
1776 if (r == TypeHandle::MaybeCast)
1778 HELPER_METHOD_FRAME_BEGIN_RET_2(refType, refTarget);
1779 iRetVal = fromHandle.CanCastTo(toHandle);
1780 HELPER_METHOD_FRAME_END();
1784 iRetVal = (r == TypeHandle::CanCast);
1787 // We allow T to be cast to Nullable<T>
1788 if (!iRetVal && Nullable::IsNullableType(toHandle) && !fromHandle.IsTypeDesc())
1790 HELPER_METHOD_FRAME_BEGIN_RET_2(refType, refTarget);
1791 if (Nullable::IsNullableForType(toHandle, fromHandle.AsMethodTable()))
1795 HELPER_METHOD_FRAME_END();
1798 FC_RETURN_BOOL(iRetVal);
1802 void QCALLTYPE RuntimeTypeHandle::GetTypeByNameUsingCARules(LPCWSTR pwzClassName, QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retType)
1806 TypeHandle typeHandle;
1811 COMPlusThrowArgumentNull(W("className"),W("ArgumentNull_String"));
1813 typeHandle = TypeName::GetTypeUsingCASearchRules(pwzClassName, pModule->GetAssembly());
1816 retType.Set(typeHandle.GetManagedClassObject());
1823 void QCALLTYPE RuntimeTypeHandle::GetTypeByName(LPCWSTR pwzClassName, BOOL bThrowOnError, BOOL bIgnoreCase, BOOL bReflectionOnly,
1824 QCall::StackCrawlMarkHandle pStackMark,
1825 ICLRPrivBinder * pPrivHostBinder,
1826 BOOL bLoadTypeFromPartialNameHack, QCall::ObjectHandleOnStack retType,
1827 QCall::ObjectHandleOnStack keepAlive)
1831 TypeHandle typeHandle;
1836 COMPlusThrowArgumentNull(W("className"),W("ArgumentNull_String"));
1839 typeHandle = TypeName::GetTypeManaged(pwzClassName, NULL, bThrowOnError, bIgnoreCase, bReflectionOnly, /*bProhibitAsmQualifiedName =*/ FALSE, pStackMark,
1840 bLoadTypeFromPartialNameHack, (OBJECTREF*)keepAlive.m_ppObject,
1844 if (!typeHandle.IsNull())
1847 retType.Set(typeHandle.GetManagedClassObject());
1855 FCIMPL6(FC_BOOL_RET, RuntimeTypeHandle::SatisfiesConstraints, PTR_ReflectClassBaseObject pParamTypeUNSAFE, TypeHandle *typeContextArgs, INT32 typeContextCount, TypeHandle *methodContextArgs, INT32 methodContextCount, PTR_ReflectClassBaseObject pArgumentTypeUNSAFE);
1859 PRECONDITION(CheckPointer(typeContextArgs, NULL_OK));
1860 PRECONDITION(CheckPointer(methodContextArgs, NULL_OK));
1864 REFLECTCLASSBASEREF refParamType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pParamTypeUNSAFE);
1865 REFLECTCLASSBASEREF refArgumentType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pArgumentTypeUNSAFE);
1867 TypeHandle thGenericParameter = refParamType->GetType();
1868 TypeHandle thGenericArgument = refArgumentType->GetType();
1869 BOOL bResult = FALSE;
1870 SigTypeContext typeContext;
1872 Instantiation classInst;
1873 Instantiation methodInst;
1875 if (typeContextArgs != NULL)
1877 classInst = Instantiation(typeContextArgs, typeContextCount);
1880 if (methodContextArgs != NULL)
1882 methodInst = Instantiation(methodContextArgs, methodContextCount);
1885 SigTypeContext::InitTypeContext(classInst, methodInst, &typeContext);
1887 HELPER_METHOD_FRAME_BEGIN_RET_2(refParamType, refArgumentType);
1889 bResult = thGenericParameter.AsGenericVariable()->SatisfiesConstraints(&typeContext, thGenericArgument);
1891 HELPER_METHOD_FRAME_END();
1893 FC_RETURN_BOOL(bResult);
1897 void QCALLTYPE RuntimeTypeHandle::GetInstantiation(EnregisteredTypeHandle pType, QCall::ObjectHandleOnStack retTypes, BOOL fAsRuntimeTypeArray)
1903 TypeHandle typeHandle = TypeHandle::FromPtr(pType);
1904 Instantiation inst = typeHandle.GetInstantiation();
1906 retTypes.Set(CopyRuntimeTypeHandles(NULL, inst.GetRawArgs(), inst.GetNumArgs(), fAsRuntimeTypeArray ? CLASS__CLASS : CLASS__TYPE));
1912 void QCALLTYPE RuntimeTypeHandle::MakeArray(EnregisteredTypeHandle pTypeHandle, INT32 rank, QCall::ObjectHandleOnStack retType)
1916 TypeHandle arrayHandle;
1919 arrayHandle = TypeHandle::FromPtr(pTypeHandle).MakeArray(rank);
1921 retType.Set(arrayHandle.GetManagedClassObject());
1927 void QCALLTYPE RuntimeTypeHandle::MakeSZArray(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType)
1931 TypeHandle arrayHandle;
1934 arrayHandle = TypeHandle::FromPtr(pTypeHandle).MakeSZArray();
1936 retType.Set(arrayHandle.GetManagedClassObject());
1942 void QCALLTYPE RuntimeTypeHandle::MakePointer(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType)
1946 TypeHandle pointerHandle;
1949 pointerHandle = TypeHandle::FromPtr(pTypeHandle).MakePointer();
1951 retType.Set(pointerHandle.GetManagedClassObject());
1957 void QCALLTYPE RuntimeTypeHandle::MakeByRef(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType)
1961 TypeHandle byRefHandle;
1964 byRefHandle = TypeHandle::FromPtr(pTypeHandle).MakeByRef();
1966 retType.Set(byRefHandle.GetManagedClassObject());
1972 BOOL QCALLTYPE RuntimeTypeHandle::IsCollectible(EnregisteredTypeHandle pTypeHandle)
1976 BOOL retVal = FALSE;
1979 retVal = TypeHandle::FromPtr(pTypeHandle).GetLoaderAllocator()->IsCollectible();
1985 void QCALLTYPE RuntimeTypeHandle::Instantiate(EnregisteredTypeHandle pTypeHandle, TypeHandle * pInstArray, INT32 cInstArray, QCall::ObjectHandleOnStack retType)
1992 type = TypeHandle::FromPtr(pTypeHandle).Instantiate(Instantiation(pInstArray, cInstArray));
1994 retType.Set(type.GetManagedClassObject());
2000 void QCALLTYPE RuntimeTypeHandle::GetGenericTypeDefinition(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType)
2008 TypeHandle genericType = TypeHandle::FromPtr(pTypeHandle);
2010 typeDef = ClassLoader::LoadTypeDefThrowing(genericType.GetModule(),
2011 genericType.GetMethodTable()->GetCl(),
2012 ClassLoader::ThrowIfNotFound,
2013 ClassLoader::PermitUninstDefOrRef);
2016 retType.Set(typeDef.GetManagedClassObject());
2023 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::CompareCanonicalHandles, ReflectClassBaseObject *pLeftUNSAFE, ReflectClassBaseObject *pRightUNSAFE)
2027 REFLECTCLASSBASEREF refLeft = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pLeftUNSAFE);
2028 REFLECTCLASSBASEREF refRight = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pRightUNSAFE);
2030 if ((refLeft == NULL) || (refRight == NULL))
2031 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2033 FC_RETURN_BOOL(refLeft->GetType().GetCanonicalMethodTable() == refRight->GetType().GetCanonicalMethodTable());
2037 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::HasInstantiation, PTR_ReflectClassBaseObject pTypeUNSAFE)
2041 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
2043 if (refType == NULL)
2044 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2046 FC_RETURN_BOOL(refType->GetType().HasInstantiation());
2050 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsGenericTypeDefinition, PTR_ReflectClassBaseObject pTypeUNSAFE)
2054 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
2056 if (refType == NULL)
2057 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2059 FC_RETURN_BOOL(refType->GetType().IsGenericTypeDefinition());
2063 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsGenericVariable, PTR_ReflectClassBaseObject pTypeUNSAFE)
2067 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
2069 if (refType == NULL)
2070 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2072 FC_RETURN_BOOL(refType->GetType().IsGenericVariable());
2076 FCIMPL1(INT32, RuntimeTypeHandle::GetGenericVariableIndex, PTR_ReflectClassBaseObject pTypeUNSAFE)
2080 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
2082 if (refType == NULL)
2083 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2085 return (INT32)refType->GetType().AsGenericVariable()->GetIndex();
2089 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::ContainsGenericVariables, PTR_ReflectClassBaseObject pTypeUNSAFE)
2093 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
2095 if (refType == NULL)
2096 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2098 FC_RETURN_BOOL(refType->GetType().ContainsGenericVariables());
2102 FCIMPL1(IMDInternalImport*, RuntimeTypeHandle::GetMetadataImport, ReflectClassBaseObject * pTypeUNSAFE)
2106 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
2108 if (refType == NULL)
2109 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2111 Module *pModule = refType->GetType().GetModule();
2113 return pModule->GetMDImport();
2118 //***********************************************************************************
2119 //***********************************************************************************
2120 //***********************************************************************************
2122 void * QCALLTYPE RuntimeMethodHandle::GetFunctionPointer(MethodDesc * pMethod)
2130 funcPtr = (void*)pMethod->GetMultiCallableAddrOfCode();
2137 FCIMPL1(LPCUTF8, RuntimeMethodHandle::GetUtf8Name, MethodDesc *pMethod) {
2143 LPCUTF8 szName = NULL;
2146 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2148 szName = pMethod->GetName();
2150 _ASSERTE(CheckPointer(szName, NULL_OK));
2156 FCIMPL2(FC_BOOL_RET, RuntimeMethodHandle::MatchesNameHash, MethodDesc * pMethod, ULONG hash)
2160 FC_RETURN_BOOL(pMethod->MightHaveName(hash));
2164 FCIMPL1(StringObject*, RuntimeMethodHandle::GetName, MethodDesc *pMethod) {
2171 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2173 STRINGREF refName = NULL;
2175 HELPER_METHOD_FRAME_BEGIN_RET_0();
2176 refName = StringObject::NewString(pMethod->GetName());
2177 HELPER_METHOD_FRAME_END();
2179 return (StringObject*)OBJECTREFToObject(refName);
2183 FCIMPL1(INT32, RuntimeMethodHandle::GetAttributes, MethodDesc *pMethod) {
2190 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2193 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
2194 retVal = (INT32)pMethod->GetAttrs();
2195 END_SO_INTOLERANT_CODE;
2200 FCIMPL1(INT32, RuntimeMethodHandle::GetImplAttributes, ReflectMethodObject *pMethodUNSAFE) {
2207 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2209 MethodDesc* pMethod = pMethodUNSAFE->GetMethod();
2210 INT32 attributes = 0;
2212 if (IsNilToken(pMethod->GetMemberDef()))
2215 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
2217 attributes = (INT32)pMethod->GetImplAttrs();
2219 END_SO_INTOLERANT_CODE;
2226 FCIMPL1(ReflectClassBaseObject*, RuntimeMethodHandle::GetDeclaringType, MethodDesc *pMethod) {
2229 PRECONDITION(CheckPointer(pMethod));
2234 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2236 MethodTable *pMT = pMethod->GetMethodTable();
2237 TypeHandle declType(pMT);
2240 HELPER_METHOD_FRAME_BEGIN_RET_0();
2242 // Load the TypeDesc for the array type. Note the returned type is approximate, i.e.
2243 // if shared between reference array types then we will get object[] back.
2244 DWORD rank = pMT->GetRank();
2245 TypeHandle elemType = pMT->GetApproxArrayElementTypeHandle();
2246 declType = ClassLoader::LoadArrayTypeThrowing(elemType, pMT->GetInternalCorElementType(), rank);
2247 HELPER_METHOD_FRAME_END();
2249 RETURN_CLASS_OBJECT(declType, NULL);
2253 FCIMPL1(INT32, RuntimeMethodHandle::GetSlot, MethodDesc *pMethod) {
2260 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2262 return (INT32)pMethod->GetSlot();
2266 FCIMPL3(Object *, SignatureNative::GetCustomModifiers, SignatureNative* pSignatureUNSAFE,
2267 INT32 parameter, CLR_BOOL fRequired)
2276 SIGNATURENATIVEREF pSig;
2280 gc.pSig = (SIGNATURENATIVEREF)pSignatureUNSAFE;
2283 HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
2286 BYTE callConv = *(BYTE*)gc.pSig->GetCorSig();
2287 SigTypeContext typeContext;
2288 gc.pSig->GetTypeContext(&typeContext);
2289 MetaSig sig(gc.pSig->GetCorSig(),
2290 gc.pSig->GetCorSigSize(),
2291 gc.pSig->GetModule(),
2293 (callConv & IMAGE_CEE_CS_CALLCONV_MASK) == IMAGE_CEE_CS_CALLCONV_FIELD ? MetaSig::sigField : MetaSig::sigMember);
2294 _ASSERTE(callConv == sig.GetCallingConventionInfo());
2296 SigPointer argument(NULL, 0);
2298 PRECONDITION(sig.GetCallingConvention() != IMAGE_CEE_CS_CALLCONV_FIELD || parameter == 1);
2302 argument = sig.GetReturnProps();
2306 for(INT32 i = 0; i < parameter; i++)
2309 argument = sig.GetArgProps();
2312 //if (parameter < 0 || parameter > (INT32)sig.NumFixedArgs())
2313 // FCThrowResVoid(kArgumentNullException, W("Arg_ArgumentOutOfRangeException"));
2315 SigPointer sp = argument;
2316 Module* pModule = sig.GetModule();
2318 CorElementType cmodType;
2320 CorElementType cmodTypeExpected = fRequired ? ELEMENT_TYPE_CMOD_REQD : ELEMENT_TYPE_CMOD_OPT;
2322 // Discover the number of required and optional custom modifiers.
2326 IfFailThrow(sp.GetByte(&data));
2327 cmodType = (CorElementType)data;
2329 if (cmodType == ELEMENT_TYPE_CMOD_REQD || cmodType == ELEMENT_TYPE_CMOD_OPT)
2331 if (cmodType == cmodTypeExpected)
2336 else if (cmodType != ELEMENT_TYPE_SENTINEL)
2341 IfFailThrow(sp.GetToken(NULL));
2344 // Reset sp and populate the arrays for the required and optional custom
2345 // modifiers now that we know how long they should be.
2348 MethodTable *pMT = MscorlibBinder::GetClass(CLASS__TYPE);
2349 TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pMT), ELEMENT_TYPE_SZARRAY);
2351 gc.retVal = (PTRARRAYREF) AllocateArrayEx(arrayHandle, &cMods, 1);
2356 IfFailThrow(sp.GetByte(&data));
2357 cmodType = (CorElementType)data;
2360 IfFailThrow(sp.GetToken(&token));
2362 if (cmodType == cmodTypeExpected)
2364 TypeHandle th = ClassLoader::LoadTypeDefOrRefOrSpecThrowing(pModule, token,
2366 ClassLoader::ThrowIfNotFound,
2367 ClassLoader::FailIfUninstDefOrRef);
2369 OBJECTREF refType = th.GetManagedClassObject();
2370 gc.retVal->SetAt(--cMods, refType);
2374 HELPER_METHOD_FRAME_END();
2376 return OBJECTREFToObject(gc.retVal);
2380 FCIMPL1(INT32, RuntimeMethodHandle::GetMethodDef, ReflectMethodObject *pMethodUNSAFE) {
2387 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2389 MethodDesc* pMethod = pMethodUNSAFE->GetMethod();
2391 if (pMethod->HasMethodInstantiation())
2393 HELPER_METHOD_FRAME_BEGIN_RET_1(pMethodUNSAFE);
2395 pMethod = pMethod->StripMethodInstantiation();
2397 HELPER_METHOD_FRAME_END();
2400 INT32 tkMethodDef = (INT32)pMethod->GetMemberDef();
2401 _ASSERTE(TypeFromToken(tkMethodDef) == mdtMethodDef);
2403 if (IsNilToken(tkMethodDef) || TypeFromToken(tkMethodDef) != mdtMethodDef)
2404 return mdMethodDefNil;
2410 FCIMPL6(void, SignatureNative::GetSignature,
2411 SignatureNative* pSignatureNativeUNSAFE,
2412 PCCOR_SIGNATURE pCorSig, DWORD cCorSig,
2413 FieldDesc *pFieldDesc, ReflectMethodObject *pMethodUNSAFE, ReflectClassBaseObject *pDeclaringTypeUNSAFE) {
2416 PRECONDITION(pDeclaringTypeUNSAFE || pMethodUNSAFE->GetMethod()->IsDynamicMethod());
2417 PRECONDITION(CheckPointer(pCorSig, NULL_OK));
2418 PRECONDITION(CheckPointer(pMethodUNSAFE, NULL_OK));
2419 PRECONDITION(CheckPointer(pFieldDesc, NULL_OK));
2425 REFLECTCLASSBASEREF refDeclaringType;
2426 REFLECTMETHODREF refMethod;
2427 SIGNATURENATIVEREF pSig;
2430 gc.refDeclaringType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pDeclaringTypeUNSAFE);
2431 gc.refMethod = (REFLECTMETHODREF)ObjectToOBJECTREF(pMethodUNSAFE);
2432 gc.pSig = (SIGNATURENATIVEREF)pSignatureNativeUNSAFE;
2434 MethodDesc *pMethod;
2435 TypeHandle declType;
2437 if (gc.refDeclaringType == NULL)
2439 // for dynamic method, see precondition
2440 pMethod = gc.refMethod->GetMethod();
2441 declType = pMethod->GetMethodTable();
2445 pMethod = gc.refMethod != NULL ? gc.refMethod->GetMethod() : NULL;
2446 declType = gc.refDeclaringType->GetType();
2449 HELPER_METHOD_FRAME_BEGIN_PROTECT(gc);
2451 Module* pModule = declType.GetModule();
2455 pMethod->GetSig(&pCorSig, &cCorSig);
2456 if (pMethod->GetClassification() == mcInstantiated)
2458 LoaderAllocator *pLoaderAllocator = pMethod->GetLoaderAllocator();
2459 if (pLoaderAllocator->IsCollectible())
2460 gc.pSig->SetKeepAlive(pLoaderAllocator->GetExposedObject());
2463 else if (pFieldDesc)
2464 pFieldDesc->GetSig(&pCorSig, &cCorSig);
2466 gc.pSig->m_sig = pCorSig;
2467 gc.pSig->m_cSig = cCorSig;
2468 gc.pSig->m_pMethod = pMethod;
2470 REFLECTCLASSBASEREF refDeclType = (REFLECTCLASSBASEREF)declType.GetManagedClassObject();
2471 gc.pSig->SetDeclaringType(refDeclType);
2473 PREFIX_ASSUME(pCorSig!= NULL);
2474 BYTE callConv = *(BYTE*)pCorSig;
2475 SigTypeContext typeContext;
2477 SigTypeContext::InitTypeContext(
2478 pMethod, declType.GetClassOrArrayInstantiation(), pMethod->LoadMethodInstantiation(), &typeContext);
2480 SigTypeContext::InitTypeContext(declType, &typeContext);
2481 MetaSig msig(pCorSig, cCorSig, pModule, &typeContext,
2482 (callConv & IMAGE_CEE_CS_CALLCONV_MASK) == IMAGE_CEE_CS_CALLCONV_FIELD ? MetaSig::sigField : MetaSig::sigMember);
2484 if (callConv == IMAGE_CEE_CS_CALLCONV_FIELD)
2486 msig.NextArgNormalized();
2488 OBJECTREF refRetType = msig.GetLastTypeHandleThrowing().GetManagedClassObject();
2489 gc.pSig->SetReturnType(refRetType);
2493 gc.pSig->SetCallingConvention(msig.GetCallingConventionInfo());
2495 OBJECTREF refRetType = msig.GetRetTypeHandleThrowing().GetManagedClassObject();
2496 gc.pSig->SetReturnType(refRetType);
2498 INT32 nArgs = msig.NumFixedArgs();
2499 TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(g_pRuntimeTypeClass), ELEMENT_TYPE_SZARRAY);
2501 PTRARRAYREF ptrArrayarguments = (PTRARRAYREF) AllocateArrayEx(arrayHandle, &nArgs, 1);
2502 gc.pSig->SetArgumentArray(ptrArrayarguments);
2504 for (INT32 i = 0; i < nArgs; i++)
2508 OBJECTREF refArgType = msig.GetLastTypeHandleThrowing().GetManagedClassObject();
2509 gc.pSig->SetArgument(i, refArgType);
2512 _ASSERTE(gc.pSig->m_returnType != NULL);
2515 HELPER_METHOD_FRAME_END();
2519 FCIMPL2(FC_BOOL_RET, SignatureNative::CompareSig, SignatureNative* pLhsUNSAFE, SignatureNative* pRhsUNSAFE)
2527 SIGNATURENATIVEREF pLhs;
2528 SIGNATURENATIVEREF pRhs;
2531 gc.pLhs = (SIGNATURENATIVEREF)pLhsUNSAFE;
2532 gc.pRhs = (SIGNATURENATIVEREF)pRhsUNSAFE;
2534 HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
2536 ret = MetaSig::CompareMethodSigs(
2537 gc.pLhs->GetCorSig(), gc.pLhs->GetCorSigSize(), gc.pLhs->GetModule(), NULL,
2538 gc.pRhs->GetCorSig(), gc.pRhs->GetCorSigSize(), gc.pRhs->GetModule(), NULL);
2540 HELPER_METHOD_FRAME_END();
2541 FC_RETURN_BOOL(ret);
2545 void QCALLTYPE RuntimeMethodHandle::GetMethodInstantiation(MethodDesc * pMethod, QCall::ObjectHandleOnStack retTypes, BOOL fAsRuntimeTypeArray)
2550 Instantiation inst = pMethod->LoadMethodInstantiation();
2553 retTypes.Set(CopyRuntimeTypeHandles(NULL, inst.GetRawArgs(), inst.GetNumArgs(), fAsRuntimeTypeArray ? CLASS__CLASS : CLASS__TYPE));
2559 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::HasMethodInstantiation, MethodDesc * pMethod)
2563 FC_RETURN_BOOL(pMethod->HasMethodInstantiation());
2567 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsGenericMethodDefinition, MethodDesc * pMethod)
2571 FC_RETURN_BOOL(pMethod->IsGenericMethodDefinition());
2575 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsDynamicMethod, MethodDesc * pMethod)
2579 FC_RETURN_BOOL(pMethod->IsNoMetadata());
2583 FCIMPL1(Object*, RuntimeMethodHandle::GetResolver, MethodDesc * pMethod)
2588 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2590 OBJECTREF resolver = NULL;
2591 if (pMethod->IsLCGMethod())
2593 resolver = pMethod->AsDynamicMethodDesc()->GetLCGMethodResolver()->GetManagedResolver();
2595 return OBJECTREFToObject(resolver);
2599 void QCALLTYPE RuntimeMethodHandle::Destroy(MethodDesc * pMethod)
2605 if (pMethod == NULL)
2606 COMPlusThrowArgumentNull(NULL, W("Arg_InvalidHandle"));
2608 DynamicMethodDesc* pDynamicMethodDesc = pMethod->AsDynamicMethodDesc();
2612 // Destroy should be called only if the managed part is gone.
2613 _ASSERTE(OBJECTREFToObject(pDynamicMethodDesc->GetLCGMethodResolver()->GetManagedResolver()) == NULL);
2615 // Fire Unload Dynamic Method Event here
2616 ETW::MethodLog::DynamicMethodDestroyed(pMethod);
2618 pDynamicMethodDesc->Destroy();
2623 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsTypicalMethodDefinition, ReflectMethodObject *pMethodUNSAFE)
2628 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2630 MethodDesc* pMethod = pMethodUNSAFE->GetMethod();
2632 FC_RETURN_BOOL(pMethod->IsTypicalMethodDefinition());
2636 void QCALLTYPE RuntimeMethodHandle::GetTypicalMethodDefinition(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod)
2644 _ASSERTE(((ReflectMethodObject *)(*refMethod.m_ppObject))->GetMethod() == pMethod);
2647 MethodDesc *pMethodTypical = pMethod->LoadTypicalMethodDefinition();
2648 if (pMethodTypical != pMethod)
2651 refMethod.Set(pMethodTypical->GetStubMethodInfo());
2658 void QCALLTYPE RuntimeMethodHandle::StripMethodInstantiation(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod)
2665 COMPlusThrowArgumentNull(NULL, W("Arg_InvalidHandle"));
2670 _ASSERTE(((ReflectMethodObject *)(*refMethod.m_ppObject))->GetMethod() == pMethod);
2673 MethodDesc *pMethodStripped = pMethod->StripMethodInstantiation();
2674 if (pMethodStripped != pMethod)
2677 refMethod.Set(pMethodStripped->GetStubMethodInfo());
2684 // In the VM there might be more than one MethodDescs for a "method"
2685 // examples are methods on generic types which may have additional instantiating stubs
2686 // and methods on value types which may have additional unboxing stubs.
2688 // For generic methods we always hand out an instantiating stub except for a generic method definition
2689 // For non-generic methods on generic types we need an instantiating stub if it's one of the following
2690 // - static method on a generic class
2691 // - static or instance method on a generic interface
2692 // - static or instance method on a generic value type
2693 // The Reflection policy is to always hand out instantiating stubs in these cases
2695 // For methods on non-generic value types we can use either the cannonical method or the unboxing stub
2696 // The Reflection policy is to always hand out unboxing stubs if the methods are virtual methods
2697 // The reason for this is that in the current implementation of the class loader, the v-table slots for
2698 // those methods point to unboxing stubs already. Note that this is just a implementation choice
2699 // that might change in the future. But we should always keep this Reflection policy an invariant.
2701 // For virtual methods on generic value types (intersection of the two cases), reflection will hand
2702 // out an unboxing instantiating stub
2704 // GetInstantiatingStub is called to:
2705 // 1. create an InstantiatedMethodDesc for a generic method when calling BindGenericArguments() on a generic
2706 // method. In this case instArray will not be null.
2707 // 2. create an InstantiatedMethodDesc for a method in a generic class. In this case instArray will be null.
2708 // 3. create an UnboxingStub for a method in a value type. In this case instArray will be null.
2709 // For case 2 and 3, an instantiating stub or unboxing stub might not be needed in which case the original
2710 // MethodDesc is returned.
2711 FCIMPL3(MethodDesc*, RuntimeMethodHandle::GetStubIfNeeded,
2712 MethodDesc *pMethod,
2713 ReflectClassBaseObject *pTypeUNSAFE,
2714 PtrArray* instArrayUNSAFE)
2721 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
2722 PTRARRAYREF instArray = (PTRARRAYREF)ObjectToOBJECTREF(instArrayUNSAFE);
2724 if (refType == NULL)
2725 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2727 TypeHandle instType = refType->GetType();
2728 MethodDesc *pNewMethod = pMethod;
2732 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
2734 if (instType.IsNull())
2735 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2737 // Perf optimization: this logic is actually duplicated in FindOrCreateAssociatedMethodDescForReflection, but since it
2738 // is the more common case it's worth the duplicate check here to avoid the helper method frame
2739 if ( instArray == NULL &&
2740 ( pMethod->HasMethodInstantiation() ||
2741 ( !instType.IsValueType() &&
2742 ( !instType.HasInstantiation() || instType.IsGenericTypeDefinition() ) ) ) )
2747 HELPER_METHOD_FRAME_BEGIN_RET_2(refType, instArray);
2749 TypeHandle *inst = NULL;
2752 if (instArray != NULL)
2754 ntypars = instArray->GetNumComponents();
2756 size_t size = ntypars * sizeof(TypeHandle);
2757 if ((size / sizeof(TypeHandle)) != ntypars) // uint over/underflow
2758 COMPlusThrow(kArgumentException);
2759 inst = (TypeHandle*) _alloca(size);
2761 for (DWORD i = 0; i < ntypars; i++)
2763 REFLECTCLASSBASEREF instRef = (REFLECTCLASSBASEREF)instArray->GetAt(i);
2765 if (instRef == NULL)
2766 COMPlusThrowArgumentNull(W("inst"), W("ArgumentNull_ArrayElement"));
2768 inst[i] = instRef->GetType();
2772 pNewMethod = MethodDesc::FindOrCreateAssociatedMethodDescForReflection(pMethod, instType, Instantiation(inst, ntypars));
2774 HELPER_METHOD_FRAME_END();
2781 FCIMPL2(MethodDesc*, RuntimeMethodHandle::GetMethodFromCanonical, MethodDesc *pMethod, ReflectClassBaseObject *pTypeUNSAFE)
2785 PRECONDITION(CheckPointer(pMethod));
2789 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
2791 TypeHandle instType = refType->GetType();
2792 MethodDesc* pMDescInCanonMT = instType.GetMethodTable()->GetParallelMethodDesc(pMethod);
2794 return pMDescInCanonMT;
2799 FCIMPL2(MethodBody *, RuntimeMethodHandle::GetMethodBody, ReflectMethodObject *pMethodUNSAFE, ReflectClassBaseObject *pDeclaringTypeUNSAFE)
2809 METHODBODYREF MethodBodyObj;
2810 EXCEPTIONHANDLINGCLAUSEREF EHClauseObj;
2811 LOCALVARIABLEINFOREF LocalVariableInfoObj;
2813 BASEARRAYREF TempArray;
2814 REFLECTCLASSBASEREF declaringType;
2815 REFLECTMETHODREF refMethod;
2818 gc.MethodBodyObj = NULL;
2819 gc.EHClauseObj = NULL;
2820 gc.LocalVariableInfoObj = NULL;
2822 gc.TempArray = NULL;
2823 gc.declaringType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pDeclaringTypeUNSAFE);
2824 gc.refMethod = (REFLECTMETHODREF)ObjectToOBJECTREF(pMethodUNSAFE);
2828 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2830 MethodDesc* pMethod = gc.refMethod->GetMethod();
2832 TypeHandle declaringType = gc.declaringType == NULL ? TypeHandle() : gc.declaringType->GetType();
2834 if (!pMethod->IsIL())
2837 HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
2839 MethodDesc *pMethodIL = pMethod;
2840 if (pMethod->IsWrapperStub())
2841 pMethodIL = pMethod->GetWrappedMethodDesc();
2843 COR_ILMETHOD* pILHeader = pMethodIL->GetILHeader();
2847 MethodTable * pExceptionHandlingClauseMT = MscorlibBinder::GetClass(CLASS__EH_CLAUSE);
2848 TypeHandle thEHClauseArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pExceptionHandlingClauseMT), ELEMENT_TYPE_SZARRAY);
2850 MethodTable * pLocalVariableMT = MscorlibBinder::GetClass(CLASS__LOCAL_VARIABLE_INFO);
2851 TypeHandle thLocalVariableArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pLocalVariableMT), ELEMENT_TYPE_SZARRAY);
2853 Module* pModule = pMethod->GetModule();
2854 COR_ILMETHOD_DECODER::DecoderStatus status;
2855 COR_ILMETHOD_DECODER header(pILHeader, pModule->GetMDImport(), &status);
2857 if (status != COR_ILMETHOD_DECODER::SUCCESS)
2859 if (status == COR_ILMETHOD_DECODER::VERIFICATION_ERROR)
2861 // Throw a verification HR
2862 COMPlusThrowHR(COR_E_VERIFICATION);
2866 COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
2870 gc.MethodBodyObj = (METHODBODYREF)AllocateObject(MscorlibBinder::GetClass(CLASS__METHOD_BODY));
2872 gc.MethodBodyObj->m_maxStackSize = header.GetMaxStack();
2873 gc.MethodBodyObj->m_initLocals = !!(header.GetFlags() & CorILMethod_InitLocals);
2876 gc.MethodBodyObj->m_localVarSigToken = header.GetLocalVarSigTok();
2878 gc.MethodBodyObj->m_localVarSigToken = 0;
2880 // Allocate the array of IL and fill it in from the method header.
2881 BYTE* pIL = const_cast<BYTE*>(header.Code);
2882 COUNT_T cIL = header.GetCodeSize();
2883 gc.U1Array = (U1ARRAYREF) AllocatePrimitiveArray(ELEMENT_TYPE_U1, cIL);
2885 SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->m_IL, gc.U1Array, GetAppDomain());
2886 memcpyNoGCRefs(gc.MethodBodyObj->m_IL->GetDataPtr(), pIL, cIL);
2888 // Allocate the array of exception clauses.
2889 INT32 cEh = (INT32)header.EHCount();
2890 const COR_ILMETHOD_SECT_EH* ehInfo = header.EH;
2891 gc.TempArray = (BASEARRAYREF) AllocateArrayEx(thEHClauseArray, &cEh, 1);
2893 SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->m_exceptionClauses, gc.TempArray, GetAppDomain());
2895 for (INT32 i = 0; i < cEh; i++)
2897 COR_ILMETHOD_SECT_EH_CLAUSE_FAT ehBuff;
2898 const COR_ILMETHOD_SECT_EH_CLAUSE_FAT* ehClause =
2899 (const COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)ehInfo->EHClause(i, &ehBuff);
2901 gc.EHClauseObj = (EXCEPTIONHANDLINGCLAUSEREF) AllocateObject(pExceptionHandlingClauseMT);
2903 gc.EHClauseObj->m_flags = ehClause->GetFlags();
2904 gc.EHClauseObj->m_tryOffset = ehClause->GetTryOffset();
2905 gc.EHClauseObj->m_tryLength = ehClause->GetTryLength();
2906 gc.EHClauseObj->m_handlerOffset = ehClause->GetHandlerOffset();
2907 gc.EHClauseObj->m_handlerLength = ehClause->GetHandlerLength();
2909 if ((ehClause->GetFlags() & COR_ILEXCEPTION_CLAUSE_FILTER) == 0)
2910 gc.EHClauseObj->m_catchToken = ehClause->GetClassToken();
2912 gc.EHClauseObj->m_filterOffset = ehClause->GetFilterOffset();
2914 gc.MethodBodyObj->m_exceptionClauses->SetAt(i, (OBJECTREF) gc.EHClauseObj);
2915 SetObjectReference((OBJECTREF*)&(gc.EHClauseObj->m_methodBody), (OBJECTREF)gc.MethodBodyObj, GetAppDomain());
2918 if (header.LocalVarSig != NULL)
2920 SigTypeContext sigTypeContext(pMethod, declaringType, pMethod->LoadMethodInstantiation());
2921 MetaSig metaSig(header.LocalVarSig,
2922 header.cbLocalVarSig,
2925 MetaSig::sigLocalVars);
2926 INT32 cLocals = metaSig.NumFixedArgs();
2927 gc.TempArray = (BASEARRAYREF) AllocateArrayEx(thLocalVariableArray, &cLocals, 1);
2928 SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->m_localVariables, gc.TempArray, GetAppDomain());
2930 for (INT32 i = 0; i < cLocals; i ++)
2932 gc.LocalVariableInfoObj = (LOCALVARIABLEINFOREF)AllocateObject(pLocalVariableMT);
2934 gc.LocalVariableInfoObj->m_localIndex = i;
2938 CorElementType eType;
2939 IfFailThrow(metaSig.GetArgProps().PeekElemType(&eType));
2940 if (ELEMENT_TYPE_PINNED == eType)
2941 gc.LocalVariableInfoObj->m_bIsPinned = TRUE;
2943 TypeHandle tempType= metaSig.GetArgProps().GetTypeHandleThrowing(pModule, &sigTypeContext);
2944 OBJECTREF refLocalType = tempType.GetManagedClassObject();
2945 gc.LocalVariableInfoObj->SetType(refLocalType);
2946 gc.MethodBodyObj->m_localVariables->SetAt(i, (OBJECTREF) gc.LocalVariableInfoObj);
2952 gc.TempArray = (BASEARRAYREF) AllocateArrayEx(thLocalVariableArray, &cLocals, 1);
2953 SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->m_localVariables, gc.TempArray, GetAppDomain());
2957 HELPER_METHOD_FRAME_END();
2959 return (MethodBody*)OBJECTREFToObject(gc.MethodBodyObj);
2963 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsConstructor, MethodDesc *pMethod)
2967 PRECONDITION(CheckPointer(pMethod));
2972 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
2973 ret = (BOOL)pMethod->IsClassConstructorOrCtor();
2974 END_SO_INTOLERANT_CODE;
2975 FC_RETURN_BOOL(ret);
2979 FCIMPL1(Object*, RuntimeMethodHandle::GetLoaderAllocator, MethodDesc *pMethod)
2986 OBJECTREF loaderAllocator = NULL;
2989 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2991 HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(loaderAllocator);
2993 LoaderAllocator *pLoaderAllocator = pMethod->GetLoaderAllocator();
2994 loaderAllocator = pLoaderAllocator->GetExposedObject();
2996 HELPER_METHOD_FRAME_END();
2998 return OBJECTREFToObject(loaderAllocator);
3002 //*********************************************************************************************
3003 //*********************************************************************************************
3004 //*********************************************************************************************
3006 FCIMPL1(StringObject*, RuntimeFieldHandle::GetName, ReflectFieldObject *pFieldUNSAFE) {
3012 REFLECTFIELDREF refField = (REFLECTFIELDREF)ObjectToOBJECTREF(pFieldUNSAFE);
3014 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
3016 FieldDesc *pField = refField->GetField();
3018 STRINGREF refString = NULL;
3019 HELPER_METHOD_FRAME_BEGIN_RET_1(refField);
3021 refString = StringObject::NewString(pField->GetName());
3023 HELPER_METHOD_FRAME_END();
3024 return (StringObject*)OBJECTREFToObject(refString);
3028 FCIMPL1(LPCUTF8, RuntimeFieldHandle::GetUtf8Name, FieldDesc *pField) {
3031 PRECONDITION(CheckPointer(pField));
3035 LPCUTF8 szFieldName;
3037 if (FAILED(pField->GetName_NoThrow(&szFieldName)))
3039 FCThrow(kBadImageFormatException);
3045 FCIMPL2(FC_BOOL_RET, RuntimeFieldHandle::MatchesNameHash, FieldDesc * pField, ULONG hash)
3049 FC_RETURN_BOOL(pField->MightHaveName(hash));
3053 FCIMPL1(INT32, RuntimeFieldHandle::GetAttributes, FieldDesc *pField) {
3060 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
3063 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
3064 ret = (INT32)pField->GetAttributes();
3065 END_SO_INTOLERANT_CODE;
3070 FCIMPL1(ReflectClassBaseObject*, RuntimeFieldHandle::GetApproxDeclaringType, FieldDesc *pField) {
3077 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
3079 TypeHandle th = TypeHandle(pField->GetApproxEnclosingMethodTable()); // <REVISIT_TODO> this needs to be checked - see bug 184355 </REVISIT_TODO>
3080 RETURN_CLASS_OBJECT(th, NULL);
3084 FCIMPL1(INT32, RuntimeFieldHandle::GetToken, ReflectFieldObject *pFieldUNSAFE) {
3090 REFLECTFIELDREF refField = (REFLECTFIELDREF)ObjectToOBJECTREF(pFieldUNSAFE);
3092 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
3094 FieldDesc *pField = refField->GetField();
3096 INT32 tkFieldDef = (INT32)pField->GetMemberDef();
3097 _ASSERTE(!IsNilToken(tkFieldDef) || tkFieldDef == mdFieldDefNil);
3102 FCIMPL2(FieldDesc*, RuntimeFieldHandle::GetStaticFieldForGenericType, FieldDesc *pField, ReflectClassBaseObject *pDeclaringTypeUNSAFE)
3109 REFLECTCLASSBASEREF refDeclaringType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pDeclaringTypeUNSAFE);
3111 if ((refDeclaringType == NULL) || (pField == NULL))
3112 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
3114 TypeHandle declaringType = refDeclaringType->GetType();
3117 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
3118 if (declaringType.IsTypeDesc())
3119 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
3120 MethodTable *pMT = declaringType.AsMethodTable();
3122 _ASSERTE(pField->IsStatic());
3123 if (pMT->HasGenericsStaticsInfo())
3124 pField = pMT->GetFieldDescByIndex(pField->GetApproxEnclosingMethodTable()->GetIndexForFieldDesc(pField));
3125 _ASSERTE(!pField->IsSharedByGenericInstantiations());
3126 _ASSERTE(pField->GetEnclosingMethodTable() == pMT);
3132 FCIMPL1(ReflectModuleBaseObject*, AssemblyHandle::GetManifestModule, AssemblyBaseObject* pAssemblyUNSAFE) {
3135 ASSEMBLYREF refAssembly = (ASSEMBLYREF)ObjectToOBJECTREF(pAssemblyUNSAFE);
3137 if (refAssembly == NULL)
3138 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
3140 DomainAssembly *pAssembly = refAssembly->GetDomainAssembly();
3141 Assembly* currentAssembly = pAssembly->GetCurrentAssembly();
3143 if (currentAssembly == NULL)
3146 Module *pModule = currentAssembly->GetManifestModule();
3147 DomainFile * pDomainFile = pModule->FindDomainFile(GetAppDomain());
3152 HELPER_METHOD_FRAME_BEGIN_RET_1(refAssembly);
3153 orModule = (pDomainFile != NULL) ? pDomainFile->GetExposedModuleObjectIfExists() : NULL;
3154 if (orModule == NULL)
3155 orModule = pModule->GetExposedObject();
3157 OBJECTREF orModule = (pDomainFile != NULL) ? pDomainFile->GetExposedModuleObjectIfExists() : NULL;
3158 if (orModule != NULL)
3159 return (ReflectModuleBaseObject*)OBJECTREFToObject(orModule);
3161 HELPER_METHOD_FRAME_BEGIN_RET_1(refAssembly);
3162 orModule = pModule->GetExposedObject();
3165 HELPER_METHOD_FRAME_END();
3166 return (ReflectModuleBaseObject*)OBJECTREFToObject(orModule);
3171 FCIMPL1(INT32, AssemblyHandle::GetToken, AssemblyBaseObject* pAssemblyUNSAFE) {
3174 ASSEMBLYREF refAssembly = (ASSEMBLYREF)ObjectToOBJECTREF(pAssemblyUNSAFE);
3176 if (refAssembly == NULL)
3177 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
3179 DomainAssembly *pAssembly = refAssembly->GetDomainAssembly();
3180 mdAssembly token = mdAssemblyNil;
3182 IMDInternalImport *mdImport = pAssembly->GetCurrentAssembly()->GetManifestImport();
3186 if (FAILED(mdImport->GetAssemblyFromScope(&token)))
3188 FCThrow(kBadImageFormatException);
3197 void QCALLTYPE ModuleHandle::GetPEKind(QCall::ModuleHandle pModule, DWORD* pdwPEKind, DWORD* pdwMachine)
3202 pModule->GetFile()->GetPEKindAndMachine(pdwPEKind, pdwMachine);
3206 FCIMPL1(INT32, ModuleHandle::GetMDStreamVersion, ReflectModuleBaseObject * pModuleUNSAFE)
3210 REFLECTMODULEBASEREF refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
3212 if (refModule == NULL)
3213 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
3215 Module *pModule = refModule->GetModule();
3217 if (pModule->IsResource())
3220 return pModule->GetMDImport()->GetMetadataStreamVersion();
3224 void QCALLTYPE ModuleHandle::GetModuleType(QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retType)
3228 TypeHandle globalTypeHandle = TypeHandle();
3234 globalTypeHandle = TypeHandle(pModule->GetGlobalMethodTable());
3236 EX_SWALLOW_NONTRANSIENT;
3238 if (!globalTypeHandle.IsNull())
3241 retType.Set(globalTypeHandle.GetManagedClassObject());
3249 FCIMPL1(INT32, ModuleHandle::GetToken, ReflectModuleBaseObject * pModuleUNSAFE) {
3255 REFLECTMODULEBASEREF refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
3257 if (refModule == NULL)
3258 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
3260 Module *pModule = refModule->GetModule();
3262 if (pModule->IsResource())
3265 return pModule->GetMDImport()->GetModuleFromScope();
3269 FCIMPL1(IMDInternalImport*, ModuleHandle::GetMetadataImport, ReflectModuleBaseObject * pModuleUNSAFE)
3273 REFLECTMODULEBASEREF refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
3275 if (refModule == NULL)
3276 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
3278 Module *pModule = refModule->GetModule();
3280 if (pModule->IsResource())
3283 return pModule->GetMDImport();
3287 BOOL QCALLTYPE ModuleHandle::ContainsPropertyMatchingHash(QCall::ModuleHandle pModule, INT32 tkProperty, ULONG hash)
3291 BOOL fContains = TRUE;
3295 fContains = pModule->MightContainMatchingProperty(tkProperty, hash);
3302 void QCALLTYPE ModuleHandle::ResolveType(QCall::ModuleHandle pModule, INT32 tkType, TypeHandle *typeArgs, INT32 typeArgsCount, TypeHandle *methodArgs, INT32 methodArgsCount, QCall::ObjectHandleOnStack retType)
3306 TypeHandle typeHandle;
3310 _ASSERTE(!IsNilToken(tkType));
3312 SigTypeContext typeContext(Instantiation(typeArgs, typeArgsCount), Instantiation(methodArgs, methodArgsCount));
3313 typeHandle = ClassLoader::LoadTypeDefOrRefOrSpecThrowing(pModule, tkType, &typeContext,
3314 ClassLoader::ThrowIfNotFound,
3315 ClassLoader::PermitUninstDefOrRef);
3318 retType.Set(typeHandle.GetManagedClassObject());
3325 MethodDesc *QCALLTYPE ModuleHandle::ResolveMethod(QCall::ModuleHandle pModule, INT32 tkMemberRef, TypeHandle *typeArgs, INT32 typeArgsCount, TypeHandle *methodArgs, INT32 methodArgsCount)
3329 MethodDesc* pMD = NULL;
3333 _ASSERTE(!IsNilToken(tkMemberRef));
3335 BOOL strictMetadataChecks = (TypeFromToken(tkMemberRef) == mdtMethodSpec);
3337 SigTypeContext typeContext(Instantiation(typeArgs, typeArgsCount), Instantiation(methodArgs, methodArgsCount));
3338 pMD = MemberLoader::GetMethodDescFromMemberDefOrRefOrSpec(pModule, tkMemberRef, &typeContext, strictMetadataChecks, FALSE);
3340 // This will get us the instantiating or unboxing stub if needed
3341 pMD = MethodDesc::FindOrCreateAssociatedMethodDescForReflection(pMD, pMD->GetMethodTable(), pMD->GetMethodInstantiation());
3348 void QCALLTYPE ModuleHandle::ResolveField(QCall::ModuleHandle pModule, INT32 tkMemberRef, TypeHandle *typeArgs, INT32 typeArgsCount, TypeHandle *methodArgs, INT32 methodArgsCount, QCall::ObjectHandleOnStack retField)
3352 FieldDesc* pField = NULL;
3356 _ASSERTE(!IsNilToken(tkMemberRef));
3358 SigTypeContext typeContext(Instantiation(typeArgs, typeArgsCount), Instantiation(methodArgs, methodArgsCount));
3359 pField = MemberLoader::GetFieldDescFromMemberDefOrRef(pModule, tkMemberRef, &typeContext, FALSE);
3361 retField.Set(pField->GetStubFieldInfo());
3368 void QCALLTYPE ModuleHandle::GetAssembly(QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retAssembly)
3372 DomainAssembly *pAssembly = NULL;
3375 pAssembly = pModule->GetDomainAssembly();
3378 retAssembly.Set(pAssembly->GetExposedAssemblyObject());
3384 FCIMPL5(ReflectMethodObject*, ModuleHandle::GetDynamicMethod, ReflectMethodObject *pMethodUNSAFE, ReflectModuleBaseObject *pModuleUNSAFE, StringObject *name, U1Array *sig, Object *resolver) {
3387 PRECONDITION(CheckPointer(name));
3388 PRECONDITION(CheckPointer(sig));
3392 DynamicMethodDesc *pNewMD = NULL;
3397 OBJECTREF resolverRef;
3398 OBJECTREF methodRef;
3399 REFLECTMETHODREF retMethod;
3400 REFLECTMODULEBASEREF refModule;
3402 gc.nameRef = (STRINGREF)name;
3403 gc.resolverRef = (OBJECTREF)resolver;
3404 gc.methodRef = ObjectToOBJECTREF(pMethodUNSAFE);
3405 gc.retMethod = NULL;
3406 gc.refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
3408 if (gc.refModule == NULL)
3409 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
3411 Module *pModule = gc.refModule->GetModule();
3413 HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
3415 DomainFile *pDomainModule = pModule->GetDomainFile();
3417 U1ARRAYREF dataArray = (U1ARRAYREF)sig;
3418 DWORD sigSize = dataArray->GetNumComponents();
3419 NewHolder<BYTE> pSig(new BYTE[sigSize]);
3420 memcpy(pSig, dataArray->GetDataPtr(), sigSize);
3422 DWORD length = gc.nameRef->GetStringLength();
3423 NewArrayHolder<char> pName(new char[(length + 1) * 2]);
3425 length = WszWideCharToMultiByte(CP_UTF8, 0, gc.nameRef->GetBuffer(), length, pName, (length + 1) * 2 - sizeof(char), NULL, NULL);
3427 pName[length / sizeof(char)] = '\0';
3429 DynamicMethodTable *pMTForDynamicMethods = pDomainModule->GetDynamicMethodTable();
3430 pNewMD = pMTForDynamicMethods->GetDynamicMethod(pSig, sigSize, pName);
3431 _ASSERTE(pNewMD != NULL);
3432 // pNewMD now owns pSig and pName.
3433 pSig.SuppressRelease();
3434 pName.SuppressRelease();
3436 // create a handle to hold the resolver objectref
3437 OBJECTHANDLE resolverHandle = pDomainModule->GetAppDomain()->CreateLongWeakHandle(gc.resolverRef);
3438 pNewMD->GetLCGMethodResolver()->SetManagedResolver(resolverHandle);
3439 gc.retMethod = pNewMD->GetStubMethodInfo();
3440 gc.retMethod->SetKeepAlive(gc.resolverRef);
3442 LoaderAllocator *pLoaderAllocator = pModule->GetLoaderAllocator();
3444 if (pLoaderAllocator->IsCollectible())
3445 pLoaderAllocator->AddReference();
3447 HELPER_METHOD_FRAME_END();
3449 return (ReflectMethodObject*)OBJECTREFToObject(gc.retMethod);
3453 void QCALLTYPE RuntimeMethodHandle::GetCallerType(QCall::StackCrawlMarkHandle pStackMark, QCall::ObjectHandleOnStack retType)
3459 MethodTable *pMT = NULL;
3461 pMT = SystemDomain::GetCallersType(pStackMark);
3464 retType.Set(pMT->GetManagedClassObject());