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 return ClassLoader::CanAccess(
135 pCAMT->GetAssembly(),
139 *AccessCheckOptions::s_pNormalAccessChecks,
144 BOOL QCALLTYPE RuntimeMethodHandle::IsCAVisibleFromDecoratedType(
145 EnregisteredTypeHandle targetTypeHandle,
146 MethodDesc * pTargetCtor,
147 EnregisteredTypeHandle sourceTypeHandle,
148 QCall::ModuleHandle sourceModuleHandle)
155 TypeHandle sourceHandle = TypeHandle::FromPtr(sourceTypeHandle);
156 TypeHandle targetHandle = TypeHandle::FromPtr(targetTypeHandle);
158 _ASSERTE((sourceHandle.IsNull() || !sourceHandle.IsTypeDesc()) &&
159 !targetHandle.IsNull() &&
160 !targetHandle.IsTypeDesc());
162 if (sourceHandle.IsTypeDesc() ||
163 targetHandle.IsNull() ||
164 targetHandle.IsTypeDesc())
165 COMPlusThrowArgumentNull(NULL, W("Arg_InvalidHandle"));
167 bResult = CheckCAVisibilityFromDecoratedType(targetHandle.AsMethodTable(), pTargetCtor, sourceHandle.AsMethodTable(), sourceModuleHandle);
174 NOINLINE static ReflectClassBaseObject* GetRuntimeTypeHelper(LPVOID __me, TypeHandle typeHandle, OBJECTREF keepAlive)
176 FC_INNER_PROLOG_NO_ME_SETUP();
177 if (typeHandle.AsPtr() == NULL)
180 // RuntimeTypeHandle::GetRuntimeType has picked off the most common case, but does not cover array types.
181 // Before we do the really heavy weight option of setting up a helper method frame, check if we have to.
182 OBJECTREF refType = typeHandle.GetManagedClassObjectFast();
184 return (ReflectClassBaseObject*)OBJECTREFToObject(refType);
186 HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_1(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, keepAlive);
187 refType = typeHandle.GetManagedClassObject();
188 HELPER_METHOD_FRAME_END();
191 return (ReflectClassBaseObject*)OBJECTREFToObject(refType);
194 #define RETURN_CLASS_OBJECT(typeHandle, keepAlive) FC_INNER_RETURN(ReflectClassBaseObject*, GetRuntimeTypeHelper(__me, typeHandle, keepAlive))
196 NOINLINE ReflectModuleBaseObject* GetRuntimeModuleHelper(LPVOID __me, Module *pModule, OBJECTREF keepAlive)
198 FC_INNER_PROLOG_NO_ME_SETUP();
202 DomainFile * pDomainFile = pModule->FindDomainFile(GetAppDomain());
204 OBJECTREF refModule = (pDomainFile != NULL) ? pDomainFile->GetExposedModuleObjectIfExists() : NULL;
206 if(refModule != NULL)
207 return (ReflectModuleBaseObject*)OBJECTREFToObject(refModule);
209 HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_1(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, keepAlive);
210 refModule = pModule->GetExposedObject();
211 HELPER_METHOD_FRAME_END();
214 return (ReflectModuleBaseObject*)OBJECTREFToObject(refModule);
217 NOINLINE AssemblyBaseObject* GetRuntimeAssemblyHelper(LPVOID __me, DomainAssembly *pAssembly, OBJECTREF keepAlive)
219 FC_INNER_PROLOG_NO_ME_SETUP();
220 if (pAssembly == NULL)
223 OBJECTREF refAssembly = (pAssembly != NULL) ? pAssembly->GetExposedAssemblyObjectIfExists() : NULL;
225 if(refAssembly != NULL)
226 return (AssemblyBaseObject*)OBJECTREFToObject(refAssembly);
228 HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_1(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, keepAlive);
229 refAssembly = pAssembly->GetExposedAssemblyObject();
230 HELPER_METHOD_FRAME_END();
233 return (AssemblyBaseObject*)OBJECTREFToObject(refAssembly);
237 // This is the routine that is called by the 'typeof()' operator in C#. It is one of the most commonly used
238 // reflection operations. This call should be optimized away in nearly all situations
239 FCIMPL1_V(ReflectClassBaseObject*, RuntimeTypeHandle::GetTypeFromHandle, FCALLRuntimeTypeHandle th)
244 return FCALL_RTH_TO_REFLECTCLASS(th);
248 FCIMPL1(ReflectClassBaseObject*, RuntimeTypeHandle::GetRuntimeType, EnregisteredTypeHandle th)
252 TypeHandle typeHandle = TypeHandle::FromPtr(th);
253 _ASSERTE(CheckPointer(typeHandle.AsPtr(), NULL_OK));
254 if (typeHandle.AsPtr()!= NULL)
256 if (!typeHandle.IsTypeDesc())
258 OBJECTREF typePtr = typeHandle.AsMethodTable()->GetManagedClassObjectIfExists();
261 return (ReflectClassBaseObject*)OBJECTREFToObject(typePtr);
268 RETURN_CLASS_OBJECT(typeHandle, NULL);
272 FCIMPL1_V(EnregisteredTypeHandle, RuntimeTypeHandle::GetValueInternal, FCALLRuntimeTypeHandle RTH)
276 if (FCALL_RTH_TO_REFLECTCLASS(RTH) == NULL)
279 return FCALL_RTH_TO_REFLECTCLASS(RTH) ->GetType().AsPtr();
283 // TypeEqualsHelper and TypeNotEqualsHelper are almost identical.
284 // Unfortunately we cannot combime them because they need to hardcode the caller's name
285 NOINLINE static BOOL TypeEqualSlow(OBJECTREF refL, OBJECTREF refR, LPVOID __me)
289 FC_INNER_PROLOG_NO_ME_SETUP();
291 _ASSERTE(refL != NULL && refR != NULL);
293 HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_2(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, refL, refR);
295 MethodDescCallSite TypeEqualsMethod(METHOD__OBJECT__EQUALS, &refL);
303 ret = TypeEqualsMethod.Call_RetBool(args);
305 HELPER_METHOD_FRAME_END();
314 #include <optsmallperfcritical.h>
316 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::TypeEQ, Object* left, Object* right)
320 OBJECTREF refL = (OBJECTREF)left;
321 OBJECTREF refR = (OBJECTREF)right;
325 FC_RETURN_BOOL(TRUE);
330 FC_RETURN_BOOL(FALSE);
333 if ((refL->GetMethodTable() == g_pRuntimeTypeClass || refR->GetMethodTable() == g_pRuntimeTypeClass))
335 // Quick path for negative common case
336 FC_RETURN_BOOL(FALSE);
339 // The fast path didn't get us the result
340 // Let's try the slow path: refL.Equals(refR);
341 FC_INNER_RETURN(FC_BOOL_RET, (FC_BOOL_RET)(!!TypeEqualSlow(refL, refR, __me)));
345 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::TypeNEQ, Object* left, Object* right)
349 OBJECTREF refL = (OBJECTREF)left;
350 OBJECTREF refR = (OBJECTREF)right;
354 FC_RETURN_BOOL(FALSE);
359 FC_RETURN_BOOL(TRUE);
362 if ((refL->GetMethodTable() == g_pRuntimeTypeClass || refR->GetMethodTable() == g_pRuntimeTypeClass))
364 // Quick path for negative common case
365 FC_RETURN_BOOL(TRUE);
368 // The fast path didn't get us the result
369 // Let's try the slow path: refL.Equals(refR);
370 FC_INNER_RETURN(FC_BOOL_RET, (FC_BOOL_RET)(!TypeEqualSlow(refL, refR, __me)));
374 #include <optdefault.h>
379 #ifdef FEATURE_COMINTEROP
380 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsWindowsRuntimeObjectType, ReflectClassBaseObject *rtTypeUNSAFE)
384 BOOL isWindowsRuntimeType = FALSE;
386 TypeHandle typeHandle = rtTypeUNSAFE->GetType();
387 MethodTable *pMT = typeHandle.GetMethodTable();
391 isWindowsRuntimeType = pMT->IsWinRTObjectType();
394 FC_RETURN_BOOL(isWindowsRuntimeType);
398 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsTypeExportedToWindowsRuntime, ReflectClassBaseObject *rtTypeUNSAFE)
402 BOOL isExportedToWinRT = FALSE;
404 TypeHandle typeHandle = rtTypeUNSAFE->GetType();
405 MethodTable *pMT = typeHandle.GetMethodTable();
409 isExportedToWinRT = pMT->IsExportedToWinRT();
412 FC_RETURN_BOOL(isExportedToWinRT);
415 #endif // FEATURE_COMINTEROP
417 NOINLINE static MethodDesc * RestoreMethodHelper(MethodDesc * pMethod, LPVOID __me)
419 FC_INNER_PROLOG_NO_ME_SETUP();
421 HELPER_METHOD_FRAME_BEGIN_RET_0();
422 pMethod->CheckRestore();
423 HELPER_METHOD_FRAME_END();
430 FCIMPL1(MethodDesc *, RuntimeTypeHandle::GetFirstIntroducedMethod, ReflectClassBaseObject *pTypeUNSAFE) {
433 PRECONDITION(CheckPointer(pTypeUNSAFE));
437 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
438 TypeHandle typeHandle = refType->GetType();
440 if (typeHandle.IsGenericVariable())
441 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
443 if (typeHandle.IsTypeDesc()) {
444 if (!typeHandle.IsArray())
448 MethodTable* pMT = typeHandle.GetMethodTable();
452 MethodDesc* pMethod = MethodTable::IntroducedMethodIterator::GetFirst(pMT);
454 // The only method that can show up here unrestored is instantiated methods. Check for it before performing the expensive IsRestored() check.
455 if (pMethod != NULL && pMethod->GetClassification() == mcInstantiated && !pMethod->IsRestored()) {
456 FC_INNER_RETURN(MethodDesc *, RestoreMethodHelper(pMethod, __me));
459 _ASSERTE(pMethod == NULL || pMethod->IsRestored());
464 #include <optsmallperfcritical.h>
465 FCIMPL1(void, RuntimeTypeHandle::GetNextIntroducedMethod, MethodDesc ** ppMethod) {
468 PRECONDITION(CheckPointer(ppMethod));
469 PRECONDITION(CheckPointer(*ppMethod));
473 MethodDesc *pMethod = MethodTable::IntroducedMethodIterator::GetNext(*ppMethod);
477 if (pMethod != NULL && pMethod->GetClassification() == mcInstantiated && !pMethod->IsRestored()) {
478 FC_INNER_RETURN_VOID(RestoreMethodHelper(pMethod, __me));
481 _ASSERTE(pMethod == NULL || pMethod->IsRestored());
484 #include <optdefault.h>
486 FCIMPL1(INT32, RuntimeTypeHandle::GetCorElementType, ReflectClassBaseObject *pTypeUNSAFE) {
492 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
495 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
497 return refType->GetType().GetSignatureCorElementType();
501 FCIMPL1(AssemblyBaseObject*, RuntimeTypeHandle::GetAssembly, ReflectClassBaseObject *pTypeUNSAFE) {
507 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
510 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
512 DomainFile *pDomainFile = NULL;
514 Module *pModule = refType->GetType().GetAssembly()->GetManifestModule();
516 pDomainFile = pModule->FindDomainFile(GetAppDomain());
517 #ifdef FEATURE_LOADER_OPTIMIZATION
518 if (pDomainFile == NULL)
520 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
522 pDomainFile = GetAppDomain()->LoadDomainNeutralModuleDependency(pModule, FILE_LOADED);
524 HELPER_METHOD_FRAME_END();
526 #endif // FEATURE_LOADER_OPTIMIZATION
529 FC_RETURN_ASSEMBLY_OBJECT((DomainAssembly *)pDomainFile, refType);
534 FCIMPL1(FC_BOOL_RET, RuntimeFieldHandle::AcquiresContextFromThis, FieldDesc *pField)
538 PRECONDITION(CheckPointer(pField));
542 FC_RETURN_BOOL(pField->IsSharedByGenericInstantiations());
547 FCIMPL1(ReflectModuleBaseObject*, RuntimeTypeHandle::GetModule, ReflectClassBaseObject *pTypeUNSAFE) {
555 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
558 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
560 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
562 result = refType->GetType().GetModule();
564 END_SO_INTOLERANT_CODE;
566 FC_RETURN_MODULE_OBJECT(result, refType);
570 FCIMPL1(ReflectClassBaseObject *, RuntimeTypeHandle::GetBaseType, ReflectClassBaseObject *pTypeUNSAFE) {
576 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
579 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
581 TypeHandle typeHandle = refType->GetType();
583 if (typeHandle.IsGenericVariable())
584 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
586 if (typeHandle.IsTypeDesc()) {
587 if (!typeHandle.IsArray())
591 RETURN_CLASS_OBJECT(typeHandle.GetParent(), refType);
595 FCIMPL1(ReflectClassBaseObject *, RuntimeTypeHandle::GetElementType, ReflectClassBaseObject *pTypeUNSAFE) {
601 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
604 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
606 TypeHandle typeHandle = refType->GetType();
608 if (!typeHandle.IsTypeDesc())
611 if (typeHandle.IsGenericVariable())
614 TypeHandle typeReturn;
616 if (typeHandle.IsArray())
617 typeReturn = typeHandle.AsArray()->GetArrayElementTypeHandle();
619 typeReturn = typeHandle.AsTypeDesc()->GetTypeParam();
621 RETURN_CLASS_OBJECT(typeReturn, refType);
625 FCIMPL1(INT32, RuntimeTypeHandle::GetArrayRank, ReflectClassBaseObject *pTypeUNSAFE) {
628 PRECONDITION(CheckPointer(pTypeUNSAFE));
629 PRECONDITION(pTypeUNSAFE->GetType().IsArray());
633 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
635 return (INT32)refType->GetType().AsArray()->GetRank();
639 FCIMPL1(INT32, RuntimeTypeHandle::GetNumVirtuals, ReflectClassBaseObject *pTypeUNSAFE) {
645 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
648 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
650 TypeHandle typeHandle = refType->GetType();
652 if (typeHandle.IsGenericVariable())
653 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
655 MethodTable *pMT = typeHandle.GetMethodTable();
658 return (INT32)pMT->GetNumVirtuals();
660 return 0; //REVIEW: should this return the number of methods in Object?
664 FCIMPL2(MethodDesc *, RuntimeTypeHandle::GetMethodAt, ReflectClassBaseObject *pTypeUNSAFE, INT32 slot) {
670 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
673 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
675 TypeHandle typeHandle = refType->GetType();
677 MethodDesc* pRetMethod = NULL;
679 if (typeHandle.IsGenericVariable())
680 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
682 if (slot < 0 || slot >= (INT32)typeHandle.GetMethodTable()->GetNumVirtuals())
683 FCThrowRes(kArgumentException, W("Arg_ArgumentOutOfRangeException"));
685 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
686 pRetMethod = typeHandle.GetMethodTable()->GetMethodDescForSlot((DWORD)slot);
687 HELPER_METHOD_FRAME_END();
694 FCIMPL3(FC_BOOL_RET, RuntimeTypeHandle::GetFields, ReflectClassBaseObject *pTypeUNSAFE, INT32 **result, INT32 *pCount) {
700 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
702 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
704 TypeHandle typeHandle = refType->GetType();
706 if (!pCount || !result)
707 FCThrow(kArgumentNullException);
709 if (typeHandle.IsGenericVariable())
710 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
712 if (typeHandle.IsTypeDesc()) {
714 FC_RETURN_BOOL(TRUE);
717 MethodTable *pMT= typeHandle.GetMethodTable();
719 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
722 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
723 // <TODO>Check this approximation - we may be losing exact type information </TODO>
724 ApproxFieldDescIterator fdIterator(pMT, ApproxFieldDescIterator::ALL_FIELDS);
725 INT32 count = (INT32)fdIterator.Count();
733 for(INT32 i = 0; i < count; i ++)
734 result[i] = (INT32*)fdIterator.Next();
739 HELPER_METHOD_FRAME_END();
740 FC_RETURN_BOOL(retVal);
744 void QCALLTYPE RuntimeMethodHandle::ConstructInstantiation(MethodDesc * pMethod, DWORD format, QCall::StringHandleOnStack retString)
751 TypeString::AppendInst(ss, pMethod->LoadMethodInstantiation(), format);
757 void QCALLTYPE RuntimeTypeHandle::ConstructName(EnregisteredTypeHandle pTypeHandle, DWORD format, QCall::StringHandleOnStack retString)
764 TypeString::AppendType(ss, TypeHandle::FromPtr(pTypeHandle), format);
770 PTRARRAYREF CopyRuntimeTypeHandles(TypeHandle * prgTH, FixupPointer<TypeHandle> * prgTH2, INT32 numTypeHandles, BinderClassID arrayElemType)
779 PTRARRAYREF refReturn = NULL;
780 PTRARRAYREF refArray = NULL;
782 if (numTypeHandles == 0)
785 _ASSERTE((prgTH != NULL) || (prgTH2 != NULL));
788 _ASSERTE(prgTH2 == NULL);
791 GCPROTECT_BEGIN(refArray);
792 TypeHandle thRuntimeType = TypeHandle(MscorlibBinder::GetClass(arrayElemType));
793 TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(thRuntimeType, ELEMENT_TYPE_SZARRAY);
794 refArray = (PTRARRAYREF)AllocateArrayEx(arrayHandle, &numTypeHandles, 1);
796 for (INT32 i = 0; i < numTypeHandles; i++)
803 th = prgTH2[i].GetValue();
805 OBJECTREF refType = th.GetManagedClassObject();
806 refArray->SetAt(i, refType);
809 refReturn = refArray;
815 void QCALLTYPE RuntimeTypeHandle::GetConstraints(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retTypeArray)
819 TypeHandle* constraints = NULL;
823 TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
825 if (!typeHandle.IsGenericVariable())
826 COMPlusThrow(kArgumentException, W("Arg_InvalidHandle"));
828 TypeVarTypeDesc* pGenericVariable = typeHandle.AsGenericVariable();
831 constraints = pGenericVariable->GetConstraints(&dwCount);
834 retTypeArray.Set(CopyRuntimeTypeHandles(constraints, NULL, dwCount, CLASS__TYPE));
841 FCIMPL1(PtrArray*, RuntimeTypeHandle::GetInterfaces, ReflectClassBaseObject *pTypeUNSAFE) {
847 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
850 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
852 TypeHandle typeHandle = refType->GetType();
854 if (typeHandle.IsGenericVariable())
855 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
857 INT32 ifaceCount = 0;
859 PTRARRAYREF refRetVal = NULL;
860 HELPER_METHOD_FRAME_BEGIN_RET_2(refRetVal, refType);
862 if (typeHandle.IsTypeDesc())
864 if (typeHandle.IsArray())
866 ifaceCount = typeHandle.GetMethodTable()->GetNumInterfaces();
875 ifaceCount = typeHandle.GetMethodTable()->GetNumInterfaces();
878 // Allocate the array
881 TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(g_pRuntimeTypeClass), ELEMENT_TYPE_SZARRAY);
882 refRetVal = (PTRARRAYREF)AllocateArrayEx(arrayHandle, &ifaceCount, 1);
884 // populate type array
887 MethodTable::InterfaceMapIterator it = typeHandle.GetMethodTable()->IterateInterfaceMap();
890 OBJECTREF refInterface = it.GetInterface()->GetManagedClassObject();
891 refRetVal->SetAt(i, refInterface);
892 _ASSERTE(refRetVal->GetAt(i) != NULL);
897 HELPER_METHOD_FRAME_END();
899 return (PtrArray*)OBJECTREFToObject(refRetVal);
903 FCIMPL1(INT32, RuntimeTypeHandle::GetAttributes, ReflectClassBaseObject *pTypeUNSAFE) {
909 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
912 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
914 TypeHandle typeHandle = refType->GetType();
916 if (typeHandle.IsTypeDesc()) {
918 if (typeHandle.IsGenericVariable()) {
922 if (!typeHandle.IsArray())
926 #ifdef FEATURE_COMINTEROP
927 // __ComObject types are always public.
928 if (IsComObjectClass(typeHandle))
929 return (typeHandle.GetMethodTable()->GetAttrClass() & tdVisibilityMask) | tdPublic;
930 #endif // FEATURE_COMINTEROP
934 ret = (INT32)typeHandle.GetMethodTable()->GetAttrClass();
940 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsValueType, ReflectClassBaseObject *pTypeUNSAFE)
947 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
949 _ASSERTE(refType != NULL);
951 TypeHandle typeHandle = refType->GetType();
953 FC_RETURN_BOOL(typeHandle.IsValueType());
957 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsInterface, ReflectClassBaseObject *pTypeUNSAFE)
964 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
966 _ASSERTE(refType != NULL);
968 TypeHandle typeHandle = refType->GetType();
970 FC_RETURN_BOOL(typeHandle.IsInterface());
976 RuntimeTypeHandle::IsVisible(
977 EnregisteredTypeHandle pTypeHandle)
985 BOOL fIsExternallyVisible = FALSE;
989 TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
991 _ASSERTE(!typeHandle.IsNull());
993 fIsExternallyVisible = typeHandle.IsExternallyVisible();
997 return fIsExternallyVisible;
998 } // RuntimeTypeHandle::IsVisible
1000 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::HasProxyAttribute, ReflectClassBaseObject *pTypeUNSAFE) {
1006 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1008 if (refType == NULL)
1009 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1011 TypeHandle typeHandle = refType->GetType();
1013 // TODO: Justify this
1014 if (typeHandle.IsGenericVariable())
1015 FC_RETURN_BOOL(FALSE);
1017 if (typeHandle.IsTypeDesc()) {
1018 if (!typeHandle.IsArray())
1019 FC_RETURN_BOOL(FALSE);
1022 MethodTable* pMT= typeHandle.GetMethodTable();
1025 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1027 FC_RETURN_BOOL(pMT->GetClass()->HasRemotingProxyAttribute());
1031 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::IsComObject, ReflectClassBaseObject *pTypeUNSAFE, CLR_BOOL isGenericCOM) {
1032 #ifdef FEATURE_COMINTEROP
1040 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1042 if (refType == NULL)
1043 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1045 TypeHandle typeHandle = refType->GetType();
1047 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
1050 ret = IsComObjectClass(typeHandle);
1052 ret = IsComWrapperClass(typeHandle);
1054 HELPER_METHOD_FRAME_END();
1056 FC_RETURN_BOOL(ret);
1062 PRECONDITION(CheckPointer(pTypeUNSAFE));
1066 FC_RETURN_BOOL(FALSE);
1071 FCIMPL1(LPCUTF8, RuntimeTypeHandle::GetUtf8Name, ReflectClassBaseObject* pTypeUNSAFE) {
1077 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1079 if (refType == NULL)
1080 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1082 TypeHandle typeHandle = refType->GetType();
1083 INT32 tkTypeDef = mdTypeDefNil;
1084 LPCUTF8 szName = NULL;
1086 if (typeHandle.IsGenericVariable())
1087 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1089 if (typeHandle.IsTypeDesc())
1090 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1092 MethodTable* pMT= typeHandle.GetMethodTable();
1095 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1097 tkTypeDef = (INT32)pMT->GetCl();
1099 if (IsNilToken(tkTypeDef))
1100 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1102 if (FAILED(pMT->GetMDImport()->GetNameOfTypeDef(tkTypeDef, &szName, NULL)))
1104 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1107 _ASSERTE(CheckPointer(szName, NULL_OK));
1113 FCIMPL1(INT32, RuntimeTypeHandle::GetToken, ReflectClassBaseObject *pTypeUNSAFE) {
1119 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1121 if (refType == NULL)
1122 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1124 TypeHandle typeHandle = refType->GetType();
1126 if (typeHandle.IsTypeDesc())
1128 if (typeHandle.IsGenericVariable())
1130 INT32 tkTypeDef = typeHandle.AsGenericVariable()->GetToken();
1132 _ASSERTE(!IsNilToken(tkTypeDef) && TypeFromToken(tkTypeDef) == mdtGenericParam);
1137 return mdTypeDefNil;
1140 return (INT32)typeHandle.AsMethodTable()->GetCl();
1144 PVOID QCALLTYPE RuntimeTypeHandle::GetGCHandle(EnregisteredTypeHandle pTypeHandle, INT32 handleType)
1148 OBJECTHANDLE objHandle = NULL;
1154 TypeHandle th = TypeHandle::FromPtr(pTypeHandle);
1155 assert(handleType >= HNDTYPE_WEAK_SHORT && handleType <= HNDTYPE_WEAK_WINRT);
1156 objHandle = th.GetDomain()->CreateTypedHandle(NULL, static_cast<HandleType>(handleType));
1157 th.GetLoaderAllocator()->RegisterHandleForCleanup(objHandle);
1164 void QCALLTYPE RuntimeTypeHandle::VerifyInterfaceIsImplemented(EnregisteredTypeHandle pTypeHandle, EnregisteredTypeHandle pIFaceHandle)
1170 TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
1171 TypeHandle ifaceHandle = TypeHandle::FromPtr(pIFaceHandle);
1173 if (typeHandle.IsGenericVariable())
1174 COMPlusThrow(kArgumentException, W("Arg_InvalidHandle"));
1176 if (typeHandle.IsTypeDesc()) {
1177 if (!typeHandle.IsArray())
1178 COMPlusThrow(kArgumentException, W("Arg_NotFoundIFace"));
1181 if (typeHandle.IsInterface())
1182 COMPlusThrow(kArgumentException, W("Argument_InterfaceMap"));
1184 if (!ifaceHandle.IsInterface())
1185 COMPlusThrow(kArgumentException, W("Arg_MustBeInterface"));
1187 // First try the cheap check, which amounts to iterating the interface map looking for
1188 // the ifaceHandle MethodTable.
1189 if (!typeHandle.GetMethodTable()->ImplementsInterface(ifaceHandle.AsMethodTable()))
1190 { // If the cheap check fails, try the more expensive but complete check.
1191 if (!typeHandle.CanCastTo(ifaceHandle))
1192 { // If the complete check fails, we're certain that this type
1193 // does not implement the interface specified.
1194 COMPlusThrow(kArgumentException, W("Arg_NotFoundIFace"));
1201 INT32 QCALLTYPE RuntimeTypeHandle::GetInterfaceMethodImplementationSlot(EnregisteredTypeHandle pTypeHandle, EnregisteredTypeHandle pOwner, MethodDesc * pMD)
1205 INT32 slotNumber = -1;
1209 TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
1210 TypeHandle thOwnerOfMD = TypeHandle::FromPtr(pOwner);
1212 // Ok to have INVALID_SLOT in the case where abstract class does not implement an interface method.
1213 // This case can not be reproed using C# "implements" all interface methods
1214 // with at least an abstract method. b19897_GetInterfaceMap_Abstract.exe tests this case.
1215 //@TODO:STUBDISPATCH: Don't need to track down the implementation, just the declaration, and this can
1216 //@TODO: be done faster - just need to make a function FindDispatchDecl.
1217 DispatchSlot slot(typeHandle.GetMethodTable()->FindDispatchSlotForInterfaceMD(thOwnerOfMD, pMD));
1219 slotNumber = slot.GetMethodDesc()->GetSlot();
1226 void QCALLTYPE RuntimeTypeHandle::GetDefaultConstructor(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retMethod)
1232 MethodDesc* pCtor = NULL;
1234 TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
1236 if (!typeHandle.IsTypeDesc())
1238 MethodTable* pMethodTable = typeHandle.AsMethodTable();
1239 if (pMethodTable->HasDefaultConstructor())
1240 pCtor = pMethodTable->GetDefaultConstructor();
1246 retMethod.Set(pCtor->GetStubMethodInfo());
1253 FCIMPL1(ReflectMethodObject*, RuntimeTypeHandle::GetDeclaringMethod, ReflectClassBaseObject *pTypeUNSAFE) {
1259 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1261 if (refType == NULL)
1262 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1264 TypeHandle typeHandle = refType->GetType();;
1266 if (!typeHandle.IsTypeDesc())
1269 TypeVarTypeDesc* pGenericVariable = typeHandle.AsGenericVariable();
1270 mdToken defToken = pGenericVariable->GetTypeOrMethodDef();
1271 if (TypeFromToken(defToken) != mdtMethodDef)
1274 REFLECTMETHODREF pRet = NULL;
1275 HELPER_METHOD_FRAME_BEGIN_RET_0();
1276 MethodDesc * pMD = pGenericVariable->LoadOwnerMethod();
1277 pMD->CheckRestore();
1278 pRet = pMD->GetStubMethodInfo();
1279 HELPER_METHOD_FRAME_END();
1281 return (ReflectMethodObject*)OBJECTREFToObject(pRet);
1285 FCIMPL1(ReflectClassBaseObject*, RuntimeTypeHandle::GetDeclaringType, ReflectClassBaseObject *pTypeUNSAFE) {
1291 TypeHandle retTypeHandle;
1293 BOOL fThrowException = FALSE;
1294 LPCWSTR argName = W("Arg_InvalidHandle");
1295 RuntimeExceptionKind reKind = kArgumentNullException;
1297 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1299 if (refType == NULL)
1300 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1302 TypeHandle typeHandle = refType->GetType();
1304 MethodTable* pMT = NULL;
1305 mdTypeDef tkTypeDef = mdTokenNil;
1307 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
1308 if (typeHandle.IsTypeDesc()) {
1310 if (typeHandle.IsGenericVariable()) {
1311 TypeVarTypeDesc* pGenericVariable = typeHandle.AsGenericVariable();
1312 mdToken defToken = pGenericVariable->GetTypeOrMethodDef();
1314 // Try the fast way first (if the declaring type has been loaded already).
1315 if (TypeFromToken(defToken) == mdtMethodDef)
1317 MethodDesc * retMethod = pGenericVariable->GetModule()->LookupMethodDef(defToken);
1318 if (retMethod != NULL)
1319 retTypeHandle = retMethod->GetMethodTable();
1323 retTypeHandle = pGenericVariable->GetModule()->LookupTypeDef(defToken);
1326 if (!retTypeHandle.IsNull() && retTypeHandle.IsFullyLoaded())
1329 // OK, need to go the slow way and load the type first.
1330 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
1332 if (TypeFromToken(defToken) == mdtMethodDef)
1334 retTypeHandle = pGenericVariable->LoadOwnerMethod()->GetMethodTable();
1338 retTypeHandle = pGenericVariable->LoadOwnerType();
1340 retTypeHandle.CheckRestore();
1342 HELPER_METHOD_FRAME_END();
1345 if (!typeHandle.IsArray())
1347 retTypeHandle = TypeHandle();
1352 pMT = typeHandle.GetMethodTable();
1356 fThrowException = TRUE;
1360 if(!pMT->GetClass()->IsNested())
1362 retTypeHandle = TypeHandle();
1366 tkTypeDef = pMT->GetCl();
1368 if (FAILED(typeHandle.GetModule()->GetMDImport()->GetNestedClassProps(tkTypeDef, &tkTypeDef)))
1370 fThrowException = TRUE;
1371 reKind = kBadImageFormatException;
1376 // Try the fast way first (if the declaring type has been loaded already).
1377 retTypeHandle = typeHandle.GetModule()->LookupTypeDef(tkTypeDef);
1378 if (retTypeHandle.IsNull())
1380 // OK, need to go the slow way and load the type first.
1381 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
1383 retTypeHandle = ClassLoader::LoadTypeDefThrowing(typeHandle.GetModule(), tkTypeDef,
1384 ClassLoader::ThrowIfNotFound,
1385 ClassLoader::PermitUninstDefOrRef);
1387 HELPER_METHOD_FRAME_END();
1391 END_SO_INTOLERANT_CODE;
1393 if (fThrowException)
1395 FCThrowRes(reKind, argName);
1398 RETURN_CLASS_OBJECT(retTypeHandle, refType);
1402 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::CanCastTo, ReflectClassBaseObject *pTypeUNSAFE, ReflectClassBaseObject *pTargetUNSAFE) {
1409 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1410 REFLECTCLASSBASEREF refTarget = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTargetUNSAFE);
1412 if ((refType == NULL) || (refTarget == NULL))
1413 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1415 TypeHandle fromHandle = refType->GetType();
1416 TypeHandle toHandle = refTarget->GetType();
1420 TypeHandle::CastResult r = fromHandle.CanCastToNoGC(toHandle);
1421 if (r == TypeHandle::MaybeCast)
1423 HELPER_METHOD_FRAME_BEGIN_RET_2(refType, refTarget);
1424 iRetVal = fromHandle.CanCastTo(toHandle);
1425 HELPER_METHOD_FRAME_END();
1429 iRetVal = (r == TypeHandle::CanCast);
1432 // We allow T to be cast to Nullable<T>
1433 if (!iRetVal && Nullable::IsNullableType(toHandle) && !fromHandle.IsTypeDesc())
1435 HELPER_METHOD_FRAME_BEGIN_RET_2(refType, refTarget);
1436 if (Nullable::IsNullableForType(toHandle, fromHandle.AsMethodTable()))
1440 HELPER_METHOD_FRAME_END();
1443 FC_RETURN_BOOL(iRetVal);
1447 void QCALLTYPE RuntimeTypeHandle::GetTypeByNameUsingCARules(LPCWSTR pwzClassName, QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retType)
1451 TypeHandle typeHandle;
1456 COMPlusThrowArgumentNull(W("className"),W("ArgumentNull_String"));
1458 typeHandle = TypeName::GetTypeUsingCASearchRules(pwzClassName, pModule->GetAssembly());
1461 retType.Set(typeHandle.GetManagedClassObject());
1468 void QCALLTYPE RuntimeTypeHandle::GetTypeByName(LPCWSTR pwzClassName, BOOL bThrowOnError, BOOL bIgnoreCase, BOOL bReflectionOnly,
1469 QCall::StackCrawlMarkHandle pStackMark,
1470 ICLRPrivBinder * pPrivHostBinder,
1471 BOOL bLoadTypeFromPartialNameHack, QCall::ObjectHandleOnStack retType,
1472 QCall::ObjectHandleOnStack keepAlive)
1476 TypeHandle typeHandle;
1481 COMPlusThrowArgumentNull(W("className"),W("ArgumentNull_String"));
1484 typeHandle = TypeName::GetTypeManaged(pwzClassName, NULL, bThrowOnError, bIgnoreCase, bReflectionOnly, /*bProhibitAsmQualifiedName =*/ FALSE, pStackMark,
1485 bLoadTypeFromPartialNameHack, (OBJECTREF*)keepAlive.m_ppObject,
1489 if (!typeHandle.IsNull())
1492 retType.Set(typeHandle.GetManagedClassObject());
1500 FCIMPL6(FC_BOOL_RET, RuntimeTypeHandle::SatisfiesConstraints, PTR_ReflectClassBaseObject pParamTypeUNSAFE, TypeHandle *typeContextArgs, INT32 typeContextCount, TypeHandle *methodContextArgs, INT32 methodContextCount, PTR_ReflectClassBaseObject pArgumentTypeUNSAFE);
1504 PRECONDITION(CheckPointer(typeContextArgs, NULL_OK));
1505 PRECONDITION(CheckPointer(methodContextArgs, NULL_OK));
1509 REFLECTCLASSBASEREF refParamType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pParamTypeUNSAFE);
1510 REFLECTCLASSBASEREF refArgumentType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pArgumentTypeUNSAFE);
1512 TypeHandle thGenericParameter = refParamType->GetType();
1513 TypeHandle thGenericArgument = refArgumentType->GetType();
1514 BOOL bResult = FALSE;
1515 SigTypeContext typeContext;
1517 Instantiation classInst;
1518 Instantiation methodInst;
1520 if (typeContextArgs != NULL)
1522 classInst = Instantiation(typeContextArgs, typeContextCount);
1525 if (methodContextArgs != NULL)
1527 methodInst = Instantiation(methodContextArgs, methodContextCount);
1530 SigTypeContext::InitTypeContext(classInst, methodInst, &typeContext);
1532 HELPER_METHOD_FRAME_BEGIN_RET_2(refParamType, refArgumentType);
1534 bResult = thGenericParameter.AsGenericVariable()->SatisfiesConstraints(&typeContext, thGenericArgument);
1536 HELPER_METHOD_FRAME_END();
1538 FC_RETURN_BOOL(bResult);
1542 void QCALLTYPE RuntimeTypeHandle::GetInstantiation(EnregisteredTypeHandle pType, QCall::ObjectHandleOnStack retTypes, BOOL fAsRuntimeTypeArray)
1548 TypeHandle typeHandle = TypeHandle::FromPtr(pType);
1549 Instantiation inst = typeHandle.GetInstantiation();
1551 retTypes.Set(CopyRuntimeTypeHandles(NULL, inst.GetRawArgs(), inst.GetNumArgs(), fAsRuntimeTypeArray ? CLASS__CLASS : CLASS__TYPE));
1557 void QCALLTYPE RuntimeTypeHandle::MakeArray(EnregisteredTypeHandle pTypeHandle, INT32 rank, QCall::ObjectHandleOnStack retType)
1561 TypeHandle arrayHandle;
1564 arrayHandle = TypeHandle::FromPtr(pTypeHandle).MakeArray(rank);
1566 retType.Set(arrayHandle.GetManagedClassObject());
1572 void QCALLTYPE RuntimeTypeHandle::MakeSZArray(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType)
1576 TypeHandle arrayHandle;
1579 arrayHandle = TypeHandle::FromPtr(pTypeHandle).MakeSZArray();
1581 retType.Set(arrayHandle.GetManagedClassObject());
1587 void QCALLTYPE RuntimeTypeHandle::MakePointer(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType)
1591 TypeHandle pointerHandle;
1594 pointerHandle = TypeHandle::FromPtr(pTypeHandle).MakePointer();
1596 retType.Set(pointerHandle.GetManagedClassObject());
1602 void QCALLTYPE RuntimeTypeHandle::MakeByRef(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType)
1606 TypeHandle byRefHandle;
1609 byRefHandle = TypeHandle::FromPtr(pTypeHandle).MakeByRef();
1611 retType.Set(byRefHandle.GetManagedClassObject());
1617 BOOL QCALLTYPE RuntimeTypeHandle::IsCollectible(EnregisteredTypeHandle pTypeHandle)
1621 BOOL retVal = FALSE;
1624 retVal = TypeHandle::FromPtr(pTypeHandle).GetLoaderAllocator()->IsCollectible();
1630 void QCALLTYPE RuntimeTypeHandle::Instantiate(EnregisteredTypeHandle pTypeHandle, TypeHandle * pInstArray, INT32 cInstArray, QCall::ObjectHandleOnStack retType)
1637 type = TypeHandle::FromPtr(pTypeHandle).Instantiate(Instantiation(pInstArray, cInstArray));
1639 retType.Set(type.GetManagedClassObject());
1645 void QCALLTYPE RuntimeTypeHandle::GetGenericTypeDefinition(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType)
1653 TypeHandle genericType = TypeHandle::FromPtr(pTypeHandle);
1655 typeDef = ClassLoader::LoadTypeDefThrowing(genericType.GetModule(),
1656 genericType.GetMethodTable()->GetCl(),
1657 ClassLoader::ThrowIfNotFound,
1658 ClassLoader::PermitUninstDefOrRef);
1661 retType.Set(typeDef.GetManagedClassObject());
1668 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::CompareCanonicalHandles, ReflectClassBaseObject *pLeftUNSAFE, ReflectClassBaseObject *pRightUNSAFE)
1672 REFLECTCLASSBASEREF refLeft = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pLeftUNSAFE);
1673 REFLECTCLASSBASEREF refRight = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pRightUNSAFE);
1675 if ((refLeft == NULL) || (refRight == NULL))
1676 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1678 FC_RETURN_BOOL(refLeft->GetType().GetCanonicalMethodTable() == refRight->GetType().GetCanonicalMethodTable());
1682 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::HasInstantiation, PTR_ReflectClassBaseObject pTypeUNSAFE)
1686 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1688 if (refType == NULL)
1689 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1691 FC_RETURN_BOOL(refType->GetType().HasInstantiation());
1695 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsGenericTypeDefinition, PTR_ReflectClassBaseObject pTypeUNSAFE)
1699 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1701 if (refType == NULL)
1702 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1704 FC_RETURN_BOOL(refType->GetType().IsGenericTypeDefinition());
1708 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsGenericVariable, PTR_ReflectClassBaseObject pTypeUNSAFE)
1712 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1714 if (refType == NULL)
1715 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1717 FC_RETURN_BOOL(refType->GetType().IsGenericVariable());
1721 FCIMPL1(INT32, RuntimeTypeHandle::GetGenericVariableIndex, PTR_ReflectClassBaseObject pTypeUNSAFE)
1725 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1727 if (refType == NULL)
1728 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1730 return (INT32)refType->GetType().AsGenericVariable()->GetIndex();
1734 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::ContainsGenericVariables, PTR_ReflectClassBaseObject pTypeUNSAFE)
1738 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1740 if (refType == NULL)
1741 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1743 FC_RETURN_BOOL(refType->GetType().ContainsGenericVariables());
1747 FCIMPL1(IMDInternalImport*, RuntimeTypeHandle::GetMetadataImport, ReflectClassBaseObject * pTypeUNSAFE)
1751 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1753 if (refType == NULL)
1754 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1756 Module *pModule = refType->GetType().GetModule();
1758 return pModule->GetMDImport();
1763 //***********************************************************************************
1764 //***********************************************************************************
1765 //***********************************************************************************
1767 void * QCALLTYPE RuntimeMethodHandle::GetFunctionPointer(MethodDesc * pMethod)
1775 funcPtr = (void*)pMethod->GetMultiCallableAddrOfCode();
1782 FCIMPL1(LPCUTF8, RuntimeMethodHandle::GetUtf8Name, MethodDesc *pMethod) {
1788 LPCUTF8 szName = NULL;
1791 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1793 szName = pMethod->GetName();
1795 _ASSERTE(CheckPointer(szName, NULL_OK));
1801 FCIMPL2(FC_BOOL_RET, RuntimeMethodHandle::MatchesNameHash, MethodDesc * pMethod, ULONG hash)
1805 FC_RETURN_BOOL(pMethod->MightHaveName(hash));
1809 FCIMPL1(StringObject*, RuntimeMethodHandle::GetName, MethodDesc *pMethod) {
1816 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1818 STRINGREF refName = NULL;
1820 HELPER_METHOD_FRAME_BEGIN_RET_0();
1821 refName = StringObject::NewString(pMethod->GetName());
1822 HELPER_METHOD_FRAME_END();
1824 return (StringObject*)OBJECTREFToObject(refName);
1828 FCIMPL1(INT32, RuntimeMethodHandle::GetAttributes, MethodDesc *pMethod) {
1835 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1838 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
1839 retVal = (INT32)pMethod->GetAttrs();
1840 END_SO_INTOLERANT_CODE;
1845 FCIMPL1(INT32, RuntimeMethodHandle::GetImplAttributes, ReflectMethodObject *pMethodUNSAFE) {
1852 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1854 MethodDesc* pMethod = pMethodUNSAFE->GetMethod();
1855 INT32 attributes = 0;
1857 if (IsNilToken(pMethod->GetMemberDef()))
1860 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
1862 attributes = (INT32)pMethod->GetImplAttrs();
1864 END_SO_INTOLERANT_CODE;
1871 FCIMPL1(ReflectClassBaseObject*, RuntimeMethodHandle::GetDeclaringType, MethodDesc *pMethod) {
1874 PRECONDITION(CheckPointer(pMethod));
1879 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1881 MethodTable *pMT = pMethod->GetMethodTable();
1882 TypeHandle declType(pMT);
1885 HELPER_METHOD_FRAME_BEGIN_RET_0();
1887 // Load the TypeDesc for the array type. Note the returned type is approximate, i.e.
1888 // if shared between reference array types then we will get object[] back.
1889 DWORD rank = pMT->GetRank();
1890 TypeHandle elemType = pMT->GetApproxArrayElementTypeHandle();
1891 declType = ClassLoader::LoadArrayTypeThrowing(elemType, pMT->GetInternalCorElementType(), rank);
1892 HELPER_METHOD_FRAME_END();
1894 RETURN_CLASS_OBJECT(declType, NULL);
1898 FCIMPL1(INT32, RuntimeMethodHandle::GetSlot, MethodDesc *pMethod) {
1905 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1907 return (INT32)pMethod->GetSlot();
1911 FCIMPL3(Object *, SignatureNative::GetCustomModifiers, SignatureNative* pSignatureUNSAFE,
1912 INT32 parameter, CLR_BOOL fRequired)
1921 SIGNATURENATIVEREF pSig;
1925 gc.pSig = (SIGNATURENATIVEREF)pSignatureUNSAFE;
1928 HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
1931 BYTE callConv = *(BYTE*)gc.pSig->GetCorSig();
1932 SigTypeContext typeContext;
1933 gc.pSig->GetTypeContext(&typeContext);
1934 MetaSig sig(gc.pSig->GetCorSig(),
1935 gc.pSig->GetCorSigSize(),
1936 gc.pSig->GetModule(),
1938 (callConv & IMAGE_CEE_CS_CALLCONV_MASK) == IMAGE_CEE_CS_CALLCONV_FIELD ? MetaSig::sigField : MetaSig::sigMember);
1939 _ASSERTE(callConv == sig.GetCallingConventionInfo());
1941 SigPointer argument(NULL, 0);
1943 PRECONDITION(sig.GetCallingConvention() != IMAGE_CEE_CS_CALLCONV_FIELD || parameter == 1);
1947 argument = sig.GetReturnProps();
1951 for(INT32 i = 0; i < parameter; i++)
1954 argument = sig.GetArgProps();
1957 //if (parameter < 0 || parameter > (INT32)sig.NumFixedArgs())
1958 // FCThrowResVoid(kArgumentNullException, W("Arg_ArgumentOutOfRangeException"));
1960 SigPointer sp = argument;
1961 Module* pModule = sig.GetModule();
1963 CorElementType cmodType;
1965 CorElementType cmodTypeExpected = fRequired ? ELEMENT_TYPE_CMOD_REQD : ELEMENT_TYPE_CMOD_OPT;
1967 // Discover the number of required and optional custom modifiers.
1971 IfFailThrow(sp.GetByte(&data));
1972 cmodType = (CorElementType)data;
1974 if (cmodType == ELEMENT_TYPE_CMOD_REQD || cmodType == ELEMENT_TYPE_CMOD_OPT)
1976 if (cmodType == cmodTypeExpected)
1981 else if (cmodType != ELEMENT_TYPE_SENTINEL)
1986 IfFailThrow(sp.GetToken(NULL));
1989 // Reset sp and populate the arrays for the required and optional custom
1990 // modifiers now that we know how long they should be.
1993 MethodTable *pMT = MscorlibBinder::GetClass(CLASS__TYPE);
1994 TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pMT), ELEMENT_TYPE_SZARRAY);
1996 gc.retVal = (PTRARRAYREF) AllocateArrayEx(arrayHandle, &cMods, 1);
2001 IfFailThrow(sp.GetByte(&data));
2002 cmodType = (CorElementType)data;
2005 IfFailThrow(sp.GetToken(&token));
2007 if (cmodType == cmodTypeExpected)
2009 TypeHandle th = ClassLoader::LoadTypeDefOrRefOrSpecThrowing(pModule, token,
2011 ClassLoader::ThrowIfNotFound,
2012 ClassLoader::FailIfUninstDefOrRef);
2014 OBJECTREF refType = th.GetManagedClassObject();
2015 gc.retVal->SetAt(--cMods, refType);
2019 HELPER_METHOD_FRAME_END();
2021 return OBJECTREFToObject(gc.retVal);
2025 FCIMPL1(INT32, RuntimeMethodHandle::GetMethodDef, ReflectMethodObject *pMethodUNSAFE) {
2032 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2034 MethodDesc* pMethod = pMethodUNSAFE->GetMethod();
2036 if (pMethod->HasMethodInstantiation())
2038 HELPER_METHOD_FRAME_BEGIN_RET_1(pMethodUNSAFE);
2040 pMethod = pMethod->StripMethodInstantiation();
2042 HELPER_METHOD_FRAME_END();
2045 INT32 tkMethodDef = (INT32)pMethod->GetMemberDef();
2046 _ASSERTE(TypeFromToken(tkMethodDef) == mdtMethodDef);
2048 if (IsNilToken(tkMethodDef) || TypeFromToken(tkMethodDef) != mdtMethodDef)
2049 return mdMethodDefNil;
2055 FCIMPL6(void, SignatureNative::GetSignature,
2056 SignatureNative* pSignatureNativeUNSAFE,
2057 PCCOR_SIGNATURE pCorSig, DWORD cCorSig,
2058 FieldDesc *pFieldDesc, ReflectMethodObject *pMethodUNSAFE, ReflectClassBaseObject *pDeclaringTypeUNSAFE) {
2061 PRECONDITION(pDeclaringTypeUNSAFE || pMethodUNSAFE->GetMethod()->IsDynamicMethod());
2062 PRECONDITION(CheckPointer(pCorSig, NULL_OK));
2063 PRECONDITION(CheckPointer(pMethodUNSAFE, NULL_OK));
2064 PRECONDITION(CheckPointer(pFieldDesc, NULL_OK));
2070 REFLECTCLASSBASEREF refDeclaringType;
2071 REFLECTMETHODREF refMethod;
2072 SIGNATURENATIVEREF pSig;
2075 gc.refDeclaringType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pDeclaringTypeUNSAFE);
2076 gc.refMethod = (REFLECTMETHODREF)ObjectToOBJECTREF(pMethodUNSAFE);
2077 gc.pSig = (SIGNATURENATIVEREF)pSignatureNativeUNSAFE;
2079 MethodDesc *pMethod;
2080 TypeHandle declType;
2082 if (gc.refDeclaringType == NULL)
2084 // for dynamic method, see precondition
2085 pMethod = gc.refMethod->GetMethod();
2086 declType = pMethod->GetMethodTable();
2090 pMethod = gc.refMethod != NULL ? gc.refMethod->GetMethod() : NULL;
2091 declType = gc.refDeclaringType->GetType();
2094 HELPER_METHOD_FRAME_BEGIN_PROTECT(gc);
2096 Module* pModule = declType.GetModule();
2100 pMethod->GetSig(&pCorSig, &cCorSig);
2101 if (pMethod->GetClassification() == mcInstantiated)
2103 LoaderAllocator *pLoaderAllocator = pMethod->GetLoaderAllocator();
2104 if (pLoaderAllocator->IsCollectible())
2105 gc.pSig->SetKeepAlive(pLoaderAllocator->GetExposedObject());
2108 else if (pFieldDesc)
2109 pFieldDesc->GetSig(&pCorSig, &cCorSig);
2111 gc.pSig->m_sig = pCorSig;
2112 gc.pSig->m_cSig = cCorSig;
2113 gc.pSig->m_pMethod = pMethod;
2115 REFLECTCLASSBASEREF refDeclType = (REFLECTCLASSBASEREF)declType.GetManagedClassObject();
2116 gc.pSig->SetDeclaringType(refDeclType);
2118 PREFIX_ASSUME(pCorSig!= NULL);
2119 BYTE callConv = *(BYTE*)pCorSig;
2120 SigTypeContext typeContext;
2122 SigTypeContext::InitTypeContext(
2123 pMethod, declType.GetClassOrArrayInstantiation(), pMethod->LoadMethodInstantiation(), &typeContext);
2125 SigTypeContext::InitTypeContext(declType, &typeContext);
2126 MetaSig msig(pCorSig, cCorSig, pModule, &typeContext,
2127 (callConv & IMAGE_CEE_CS_CALLCONV_MASK) == IMAGE_CEE_CS_CALLCONV_FIELD ? MetaSig::sigField : MetaSig::sigMember);
2129 if (callConv == IMAGE_CEE_CS_CALLCONV_FIELD)
2131 msig.NextArgNormalized();
2133 OBJECTREF refRetType = msig.GetLastTypeHandleThrowing().GetManagedClassObject();
2134 gc.pSig->SetReturnType(refRetType);
2138 gc.pSig->SetCallingConvention(msig.GetCallingConventionInfo());
2140 OBJECTREF refRetType = msig.GetRetTypeHandleThrowing().GetManagedClassObject();
2141 gc.pSig->SetReturnType(refRetType);
2143 INT32 nArgs = msig.NumFixedArgs();
2144 TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(g_pRuntimeTypeClass), ELEMENT_TYPE_SZARRAY);
2146 PTRARRAYREF ptrArrayarguments = (PTRARRAYREF) AllocateArrayEx(arrayHandle, &nArgs, 1);
2147 gc.pSig->SetArgumentArray(ptrArrayarguments);
2149 for (INT32 i = 0; i < nArgs; i++)
2153 OBJECTREF refArgType = msig.GetLastTypeHandleThrowing().GetManagedClassObject();
2154 gc.pSig->SetArgument(i, refArgType);
2157 _ASSERTE(gc.pSig->m_returnType != NULL);
2160 HELPER_METHOD_FRAME_END();
2164 FCIMPL2(FC_BOOL_RET, SignatureNative::CompareSig, SignatureNative* pLhsUNSAFE, SignatureNative* pRhsUNSAFE)
2172 SIGNATURENATIVEREF pLhs;
2173 SIGNATURENATIVEREF pRhs;
2176 gc.pLhs = (SIGNATURENATIVEREF)pLhsUNSAFE;
2177 gc.pRhs = (SIGNATURENATIVEREF)pRhsUNSAFE;
2179 HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
2181 ret = MetaSig::CompareMethodSigs(
2182 gc.pLhs->GetCorSig(), gc.pLhs->GetCorSigSize(), gc.pLhs->GetModule(), NULL,
2183 gc.pRhs->GetCorSig(), gc.pRhs->GetCorSigSize(), gc.pRhs->GetModule(), NULL);
2185 HELPER_METHOD_FRAME_END();
2186 FC_RETURN_BOOL(ret);
2190 void QCALLTYPE RuntimeMethodHandle::GetMethodInstantiation(MethodDesc * pMethod, QCall::ObjectHandleOnStack retTypes, BOOL fAsRuntimeTypeArray)
2195 Instantiation inst = pMethod->LoadMethodInstantiation();
2198 retTypes.Set(CopyRuntimeTypeHandles(NULL, inst.GetRawArgs(), inst.GetNumArgs(), fAsRuntimeTypeArray ? CLASS__CLASS : CLASS__TYPE));
2204 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::HasMethodInstantiation, MethodDesc * pMethod)
2208 FC_RETURN_BOOL(pMethod->HasMethodInstantiation());
2212 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsGenericMethodDefinition, MethodDesc * pMethod)
2216 FC_RETURN_BOOL(pMethod->IsGenericMethodDefinition());
2220 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsDynamicMethod, MethodDesc * pMethod)
2224 FC_RETURN_BOOL(pMethod->IsNoMetadata());
2228 FCIMPL1(Object*, RuntimeMethodHandle::GetResolver, MethodDesc * pMethod)
2233 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2235 OBJECTREF resolver = NULL;
2236 if (pMethod->IsLCGMethod())
2238 resolver = pMethod->AsDynamicMethodDesc()->GetLCGMethodResolver()->GetManagedResolver();
2240 return OBJECTREFToObject(resolver);
2244 void QCALLTYPE RuntimeMethodHandle::Destroy(MethodDesc * pMethod)
2250 if (pMethod == NULL)
2251 COMPlusThrowArgumentNull(NULL, W("Arg_InvalidHandle"));
2253 DynamicMethodDesc* pDynamicMethodDesc = pMethod->AsDynamicMethodDesc();
2257 // Destroy should be called only if the managed part is gone.
2258 _ASSERTE(OBJECTREFToObject(pDynamicMethodDesc->GetLCGMethodResolver()->GetManagedResolver()) == NULL);
2260 // Fire Unload Dynamic Method Event here
2261 ETW::MethodLog::DynamicMethodDestroyed(pMethod);
2263 BEGIN_PIN_PROFILER(CORProfilerIsMonitoringDynamicFunctionUnloads());
2264 g_profControlBlock.pProfInterface->DynamicMethodUnloaded((FunctionID)pMethod);
2267 pDynamicMethodDesc->Destroy();
2272 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsTypicalMethodDefinition, ReflectMethodObject *pMethodUNSAFE)
2277 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2279 MethodDesc* pMethod = pMethodUNSAFE->GetMethod();
2281 FC_RETURN_BOOL(pMethod->IsTypicalMethodDefinition());
2285 void QCALLTYPE RuntimeMethodHandle::GetTypicalMethodDefinition(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod)
2293 _ASSERTE(((ReflectMethodObject *)(*refMethod.m_ppObject))->GetMethod() == pMethod);
2296 MethodDesc *pMethodTypical = pMethod->LoadTypicalMethodDefinition();
2297 if (pMethodTypical != pMethod)
2300 refMethod.Set(pMethodTypical->GetStubMethodInfo());
2307 void QCALLTYPE RuntimeMethodHandle::StripMethodInstantiation(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod)
2314 COMPlusThrowArgumentNull(NULL, W("Arg_InvalidHandle"));
2319 _ASSERTE(((ReflectMethodObject *)(*refMethod.m_ppObject))->GetMethod() == pMethod);
2322 MethodDesc *pMethodStripped = pMethod->StripMethodInstantiation();
2323 if (pMethodStripped != pMethod)
2326 refMethod.Set(pMethodStripped->GetStubMethodInfo());
2333 // In the VM there might be more than one MethodDescs for a "method"
2334 // examples are methods on generic types which may have additional instantiating stubs
2335 // and methods on value types which may have additional unboxing stubs.
2337 // For generic methods we always hand out an instantiating stub except for a generic method definition
2338 // For non-generic methods on generic types we need an instantiating stub if it's one of the following
2339 // - static method on a generic class
2340 // - static or instance method on a generic interface
2341 // - static or instance method on a generic value type
2342 // The Reflection policy is to always hand out instantiating stubs in these cases
2344 // For methods on non-generic value types we can use either the cannonical method or the unboxing stub
2345 // The Reflection policy is to always hand out unboxing stubs if the methods are virtual methods
2346 // The reason for this is that in the current implementation of the class loader, the v-table slots for
2347 // those methods point to unboxing stubs already. Note that this is just a implementation choice
2348 // that might change in the future. But we should always keep this Reflection policy an invariant.
2350 // For virtual methods on generic value types (intersection of the two cases), reflection will hand
2351 // out an unboxing instantiating stub
2353 // GetInstantiatingStub is called to:
2354 // 1. create an InstantiatedMethodDesc for a generic method when calling BindGenericArguments() on a generic
2355 // method. In this case instArray will not be null.
2356 // 2. create an InstantiatedMethodDesc for a method in a generic class. In this case instArray will be null.
2357 // 3. create an UnboxingStub for a method in a value type. In this case instArray will be null.
2358 // For case 2 and 3, an instantiating stub or unboxing stub might not be needed in which case the original
2359 // MethodDesc is returned.
2360 FCIMPL3(MethodDesc*, RuntimeMethodHandle::GetStubIfNeeded,
2361 MethodDesc *pMethod,
2362 ReflectClassBaseObject *pTypeUNSAFE,
2363 PtrArray* instArrayUNSAFE)
2370 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
2371 PTRARRAYREF instArray = (PTRARRAYREF)ObjectToOBJECTREF(instArrayUNSAFE);
2373 if (refType == NULL)
2374 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2376 TypeHandle instType = refType->GetType();
2377 MethodDesc *pNewMethod = pMethod;
2381 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
2383 if (instType.IsNull())
2384 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2386 // Perf optimization: this logic is actually duplicated in FindOrCreateAssociatedMethodDescForReflection, but since it
2387 // is the more common case it's worth the duplicate check here to avoid the helper method frame
2388 if ( instArray == NULL &&
2389 ( pMethod->HasMethodInstantiation() ||
2390 ( !instType.IsValueType() &&
2391 ( !instType.HasInstantiation() || instType.IsGenericTypeDefinition() ) ) ) )
2396 HELPER_METHOD_FRAME_BEGIN_RET_2(refType, instArray);
2398 TypeHandle *inst = NULL;
2401 if (instArray != NULL)
2403 ntypars = instArray->GetNumComponents();
2405 size_t size = ntypars * sizeof(TypeHandle);
2406 if ((size / sizeof(TypeHandle)) != ntypars) // uint over/underflow
2407 COMPlusThrow(kArgumentException);
2408 inst = (TypeHandle*) _alloca(size);
2410 for (DWORD i = 0; i < ntypars; i++)
2412 REFLECTCLASSBASEREF instRef = (REFLECTCLASSBASEREF)instArray->GetAt(i);
2414 if (instRef == NULL)
2415 COMPlusThrowArgumentNull(W("inst"), W("ArgumentNull_ArrayElement"));
2417 inst[i] = instRef->GetType();
2421 pNewMethod = MethodDesc::FindOrCreateAssociatedMethodDescForReflection(pMethod, instType, Instantiation(inst, ntypars));
2423 HELPER_METHOD_FRAME_END();
2430 FCIMPL2(MethodDesc*, RuntimeMethodHandle::GetMethodFromCanonical, MethodDesc *pMethod, ReflectClassBaseObject *pTypeUNSAFE)
2434 PRECONDITION(CheckPointer(pMethod));
2438 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
2440 TypeHandle instType = refType->GetType();
2441 MethodDesc* pMDescInCanonMT = instType.GetMethodTable()->GetParallelMethodDesc(pMethod);
2443 return pMDescInCanonMT;
2448 FCIMPL2(MethodBody *, RuntimeMethodHandle::GetMethodBody, ReflectMethodObject *pMethodUNSAFE, ReflectClassBaseObject *pDeclaringTypeUNSAFE)
2458 METHODBODYREF MethodBodyObj;
2459 EXCEPTIONHANDLINGCLAUSEREF EHClauseObj;
2460 LOCALVARIABLEINFOREF LocalVariableInfoObj;
2462 BASEARRAYREF TempArray;
2463 REFLECTCLASSBASEREF declaringType;
2464 REFLECTMETHODREF refMethod;
2467 gc.MethodBodyObj = NULL;
2468 gc.EHClauseObj = NULL;
2469 gc.LocalVariableInfoObj = NULL;
2471 gc.TempArray = NULL;
2472 gc.declaringType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pDeclaringTypeUNSAFE);
2473 gc.refMethod = (REFLECTMETHODREF)ObjectToOBJECTREF(pMethodUNSAFE);
2477 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2479 MethodDesc* pMethod = gc.refMethod->GetMethod();
2481 TypeHandle declaringType = gc.declaringType == NULL ? TypeHandle() : gc.declaringType->GetType();
2483 if (!pMethod->IsIL())
2486 HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
2488 MethodDesc *pMethodIL = pMethod;
2489 if (pMethod->IsWrapperStub())
2490 pMethodIL = pMethod->GetWrappedMethodDesc();
2492 COR_ILMETHOD* pILHeader = pMethodIL->GetILHeader();
2496 MethodTable * pExceptionHandlingClauseMT = MscorlibBinder::GetClass(CLASS__EH_CLAUSE);
2497 TypeHandle thEHClauseArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pExceptionHandlingClauseMT), ELEMENT_TYPE_SZARRAY);
2499 MethodTable * pLocalVariableMT = MscorlibBinder::GetClass(CLASS__LOCAL_VARIABLE_INFO);
2500 TypeHandle thLocalVariableArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pLocalVariableMT), ELEMENT_TYPE_SZARRAY);
2502 Module* pModule = pMethod->GetModule();
2503 COR_ILMETHOD_DECODER::DecoderStatus status;
2504 COR_ILMETHOD_DECODER header(pILHeader, pModule->GetMDImport(), &status);
2506 if (status != COR_ILMETHOD_DECODER::SUCCESS)
2508 if (status == COR_ILMETHOD_DECODER::VERIFICATION_ERROR)
2510 // Throw a verification HR
2511 COMPlusThrowHR(COR_E_VERIFICATION);
2515 COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
2519 gc.MethodBodyObj = (METHODBODYREF)AllocateObject(MscorlibBinder::GetClass(CLASS__METHOD_BODY));
2521 gc.MethodBodyObj->m_maxStackSize = header.GetMaxStack();
2522 gc.MethodBodyObj->m_initLocals = !!(header.GetFlags() & CorILMethod_InitLocals);
2525 gc.MethodBodyObj->m_localVarSigToken = header.GetLocalVarSigTok();
2527 gc.MethodBodyObj->m_localVarSigToken = 0;
2529 // Allocate the array of IL and fill it in from the method header.
2530 BYTE* pIL = const_cast<BYTE*>(header.Code);
2531 COUNT_T cIL = header.GetCodeSize();
2532 gc.U1Array = (U1ARRAYREF) AllocatePrimitiveArray(ELEMENT_TYPE_U1, cIL);
2534 SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->m_IL, gc.U1Array, GetAppDomain());
2535 memcpyNoGCRefs(gc.MethodBodyObj->m_IL->GetDataPtr(), pIL, cIL);
2537 // Allocate the array of exception clauses.
2538 INT32 cEh = (INT32)header.EHCount();
2539 const COR_ILMETHOD_SECT_EH* ehInfo = header.EH;
2540 gc.TempArray = (BASEARRAYREF) AllocateArrayEx(thEHClauseArray, &cEh, 1);
2542 SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->m_exceptionClauses, gc.TempArray, GetAppDomain());
2544 for (INT32 i = 0; i < cEh; i++)
2546 COR_ILMETHOD_SECT_EH_CLAUSE_FAT ehBuff;
2547 const COR_ILMETHOD_SECT_EH_CLAUSE_FAT* ehClause =
2548 (const COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)ehInfo->EHClause(i, &ehBuff);
2550 gc.EHClauseObj = (EXCEPTIONHANDLINGCLAUSEREF) AllocateObject(pExceptionHandlingClauseMT);
2552 gc.EHClauseObj->m_flags = ehClause->GetFlags();
2553 gc.EHClauseObj->m_tryOffset = ehClause->GetTryOffset();
2554 gc.EHClauseObj->m_tryLength = ehClause->GetTryLength();
2555 gc.EHClauseObj->m_handlerOffset = ehClause->GetHandlerOffset();
2556 gc.EHClauseObj->m_handlerLength = ehClause->GetHandlerLength();
2558 if ((ehClause->GetFlags() & COR_ILEXCEPTION_CLAUSE_FILTER) == 0)
2559 gc.EHClauseObj->m_catchToken = ehClause->GetClassToken();
2561 gc.EHClauseObj->m_filterOffset = ehClause->GetFilterOffset();
2563 gc.MethodBodyObj->m_exceptionClauses->SetAt(i, (OBJECTREF) gc.EHClauseObj);
2564 SetObjectReference((OBJECTREF*)&(gc.EHClauseObj->m_methodBody), (OBJECTREF)gc.MethodBodyObj, GetAppDomain());
2567 if (header.LocalVarSig != NULL)
2569 SigTypeContext sigTypeContext(pMethod, declaringType, pMethod->LoadMethodInstantiation());
2570 MetaSig metaSig(header.LocalVarSig,
2571 header.cbLocalVarSig,
2574 MetaSig::sigLocalVars);
2575 INT32 cLocals = metaSig.NumFixedArgs();
2576 gc.TempArray = (BASEARRAYREF) AllocateArrayEx(thLocalVariableArray, &cLocals, 1);
2577 SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->m_localVariables, gc.TempArray, GetAppDomain());
2579 for (INT32 i = 0; i < cLocals; i ++)
2581 gc.LocalVariableInfoObj = (LOCALVARIABLEINFOREF)AllocateObject(pLocalVariableMT);
2583 gc.LocalVariableInfoObj->m_localIndex = i;
2587 CorElementType eType;
2588 IfFailThrow(metaSig.GetArgProps().PeekElemType(&eType));
2589 if (ELEMENT_TYPE_PINNED == eType)
2590 gc.LocalVariableInfoObj->m_bIsPinned = TRUE;
2592 TypeHandle tempType= metaSig.GetArgProps().GetTypeHandleThrowing(pModule, &sigTypeContext);
2593 OBJECTREF refLocalType = tempType.GetManagedClassObject();
2594 gc.LocalVariableInfoObj->SetType(refLocalType);
2595 gc.MethodBodyObj->m_localVariables->SetAt(i, (OBJECTREF) gc.LocalVariableInfoObj);
2601 gc.TempArray = (BASEARRAYREF) AllocateArrayEx(thLocalVariableArray, &cLocals, 1);
2602 SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->m_localVariables, gc.TempArray, GetAppDomain());
2606 HELPER_METHOD_FRAME_END();
2608 return (MethodBody*)OBJECTREFToObject(gc.MethodBodyObj);
2612 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsConstructor, MethodDesc *pMethod)
2616 PRECONDITION(CheckPointer(pMethod));
2621 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
2622 ret = (BOOL)pMethod->IsClassConstructorOrCtor();
2623 END_SO_INTOLERANT_CODE;
2624 FC_RETURN_BOOL(ret);
2628 FCIMPL1(Object*, RuntimeMethodHandle::GetLoaderAllocator, MethodDesc *pMethod)
2635 OBJECTREF loaderAllocator = NULL;
2638 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2640 HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(loaderAllocator);
2642 LoaderAllocator *pLoaderAllocator = pMethod->GetLoaderAllocator();
2643 loaderAllocator = pLoaderAllocator->GetExposedObject();
2645 HELPER_METHOD_FRAME_END();
2647 return OBJECTREFToObject(loaderAllocator);
2651 //*********************************************************************************************
2652 //*********************************************************************************************
2653 //*********************************************************************************************
2655 FCIMPL1(StringObject*, RuntimeFieldHandle::GetName, ReflectFieldObject *pFieldUNSAFE) {
2661 REFLECTFIELDREF refField = (REFLECTFIELDREF)ObjectToOBJECTREF(pFieldUNSAFE);
2663 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2665 FieldDesc *pField = refField->GetField();
2667 STRINGREF refString = NULL;
2668 HELPER_METHOD_FRAME_BEGIN_RET_1(refField);
2670 refString = StringObject::NewString(pField->GetName());
2672 HELPER_METHOD_FRAME_END();
2673 return (StringObject*)OBJECTREFToObject(refString);
2677 FCIMPL1(LPCUTF8, RuntimeFieldHandle::GetUtf8Name, FieldDesc *pField) {
2680 PRECONDITION(CheckPointer(pField));
2684 LPCUTF8 szFieldName;
2686 if (FAILED(pField->GetName_NoThrow(&szFieldName)))
2688 FCThrow(kBadImageFormatException);
2694 FCIMPL2(FC_BOOL_RET, RuntimeFieldHandle::MatchesNameHash, FieldDesc * pField, ULONG hash)
2698 FC_RETURN_BOOL(pField->MightHaveName(hash));
2702 FCIMPL1(INT32, RuntimeFieldHandle::GetAttributes, FieldDesc *pField) {
2709 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2712 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
2713 ret = (INT32)pField->GetAttributes();
2714 END_SO_INTOLERANT_CODE;
2719 FCIMPL1(ReflectClassBaseObject*, RuntimeFieldHandle::GetApproxDeclaringType, FieldDesc *pField) {
2726 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2728 TypeHandle th = TypeHandle(pField->GetApproxEnclosingMethodTable()); // <REVISIT_TODO> this needs to be checked - see bug 184355 </REVISIT_TODO>
2729 RETURN_CLASS_OBJECT(th, NULL);
2733 FCIMPL1(INT32, RuntimeFieldHandle::GetToken, ReflectFieldObject *pFieldUNSAFE) {
2739 REFLECTFIELDREF refField = (REFLECTFIELDREF)ObjectToOBJECTREF(pFieldUNSAFE);
2741 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2743 FieldDesc *pField = refField->GetField();
2745 INT32 tkFieldDef = (INT32)pField->GetMemberDef();
2746 _ASSERTE(!IsNilToken(tkFieldDef) || tkFieldDef == mdFieldDefNil);
2751 FCIMPL2(FieldDesc*, RuntimeFieldHandle::GetStaticFieldForGenericType, FieldDesc *pField, ReflectClassBaseObject *pDeclaringTypeUNSAFE)
2758 REFLECTCLASSBASEREF refDeclaringType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pDeclaringTypeUNSAFE);
2760 if ((refDeclaringType == NULL) || (pField == NULL))
2761 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2763 TypeHandle declaringType = refDeclaringType->GetType();
2766 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2767 if (declaringType.IsTypeDesc())
2768 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2769 MethodTable *pMT = declaringType.AsMethodTable();
2771 _ASSERTE(pField->IsStatic());
2772 if (pMT->HasGenericsStaticsInfo())
2773 pField = pMT->GetFieldDescByIndex(pField->GetApproxEnclosingMethodTable()->GetIndexForFieldDesc(pField));
2774 _ASSERTE(!pField->IsSharedByGenericInstantiations());
2775 _ASSERTE(pField->GetEnclosingMethodTable() == pMT);
2781 FCIMPL1(ReflectModuleBaseObject*, AssemblyHandle::GetManifestModule, AssemblyBaseObject* pAssemblyUNSAFE) {
2784 ASSEMBLYREF refAssembly = (ASSEMBLYREF)ObjectToOBJECTREF(pAssemblyUNSAFE);
2786 if (refAssembly == NULL)
2787 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2789 DomainAssembly *pAssembly = refAssembly->GetDomainAssembly();
2790 Assembly* currentAssembly = pAssembly->GetCurrentAssembly();
2792 if (currentAssembly == NULL)
2795 Module *pModule = currentAssembly->GetManifestModule();
2796 DomainFile * pDomainFile = pModule->FindDomainFile(GetAppDomain());
2801 HELPER_METHOD_FRAME_BEGIN_RET_1(refAssembly);
2802 orModule = (pDomainFile != NULL) ? pDomainFile->GetExposedModuleObjectIfExists() : NULL;
2803 if (orModule == NULL)
2804 orModule = pModule->GetExposedObject();
2806 OBJECTREF orModule = (pDomainFile != NULL) ? pDomainFile->GetExposedModuleObjectIfExists() : NULL;
2807 if (orModule != NULL)
2808 return (ReflectModuleBaseObject*)OBJECTREFToObject(orModule);
2810 HELPER_METHOD_FRAME_BEGIN_RET_1(refAssembly);
2811 orModule = pModule->GetExposedObject();
2814 HELPER_METHOD_FRAME_END();
2815 return (ReflectModuleBaseObject*)OBJECTREFToObject(orModule);
2820 FCIMPL1(INT32, AssemblyHandle::GetToken, AssemblyBaseObject* pAssemblyUNSAFE) {
2823 ASSEMBLYREF refAssembly = (ASSEMBLYREF)ObjectToOBJECTREF(pAssemblyUNSAFE);
2825 if (refAssembly == NULL)
2826 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2828 DomainAssembly *pAssembly = refAssembly->GetDomainAssembly();
2829 mdAssembly token = mdAssemblyNil;
2831 IMDInternalImport *mdImport = pAssembly->GetCurrentAssembly()->GetManifestImport();
2835 if (FAILED(mdImport->GetAssemblyFromScope(&token)))
2837 FCThrow(kBadImageFormatException);
2846 void QCALLTYPE ModuleHandle::GetPEKind(QCall::ModuleHandle pModule, DWORD* pdwPEKind, DWORD* pdwMachine)
2851 pModule->GetFile()->GetPEKindAndMachine(pdwPEKind, pdwMachine);
2855 FCIMPL1(INT32, ModuleHandle::GetMDStreamVersion, ReflectModuleBaseObject * pModuleUNSAFE)
2859 REFLECTMODULEBASEREF refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
2861 if (refModule == NULL)
2862 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2864 Module *pModule = refModule->GetModule();
2866 if (pModule->IsResource())
2869 return pModule->GetMDImport()->GetMetadataStreamVersion();
2873 void QCALLTYPE ModuleHandle::GetModuleType(QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retType)
2877 TypeHandle globalTypeHandle = TypeHandle();
2883 globalTypeHandle = TypeHandle(pModule->GetGlobalMethodTable());
2885 EX_SWALLOW_NONTRANSIENT;
2887 if (!globalTypeHandle.IsNull())
2890 retType.Set(globalTypeHandle.GetManagedClassObject());
2898 FCIMPL1(INT32, ModuleHandle::GetToken, ReflectModuleBaseObject * pModuleUNSAFE) {
2904 REFLECTMODULEBASEREF refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
2906 if (refModule == NULL)
2907 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2909 Module *pModule = refModule->GetModule();
2911 if (pModule->IsResource())
2914 return pModule->GetMDImport()->GetModuleFromScope();
2918 FCIMPL1(IMDInternalImport*, ModuleHandle::GetMetadataImport, ReflectModuleBaseObject * pModuleUNSAFE)
2922 REFLECTMODULEBASEREF refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
2924 if (refModule == NULL)
2925 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2927 Module *pModule = refModule->GetModule();
2929 if (pModule->IsResource())
2932 return pModule->GetMDImport();
2936 BOOL QCALLTYPE ModuleHandle::ContainsPropertyMatchingHash(QCall::ModuleHandle pModule, INT32 tkProperty, ULONG hash)
2940 BOOL fContains = TRUE;
2944 fContains = pModule->MightContainMatchingProperty(tkProperty, hash);
2951 void QCALLTYPE ModuleHandle::ResolveType(QCall::ModuleHandle pModule, INT32 tkType, TypeHandle *typeArgs, INT32 typeArgsCount, TypeHandle *methodArgs, INT32 methodArgsCount, QCall::ObjectHandleOnStack retType)
2955 TypeHandle typeHandle;
2959 _ASSERTE(!IsNilToken(tkType));
2961 SigTypeContext typeContext(Instantiation(typeArgs, typeArgsCount), Instantiation(methodArgs, methodArgsCount));
2962 typeHandle = ClassLoader::LoadTypeDefOrRefOrSpecThrowing(pModule, tkType, &typeContext,
2963 ClassLoader::ThrowIfNotFound,
2964 ClassLoader::PermitUninstDefOrRef);
2967 retType.Set(typeHandle.GetManagedClassObject());
2974 MethodDesc *QCALLTYPE ModuleHandle::ResolveMethod(QCall::ModuleHandle pModule, INT32 tkMemberRef, TypeHandle *typeArgs, INT32 typeArgsCount, TypeHandle *methodArgs, INT32 methodArgsCount)
2978 MethodDesc* pMD = NULL;
2982 _ASSERTE(!IsNilToken(tkMemberRef));
2984 BOOL strictMetadataChecks = (TypeFromToken(tkMemberRef) == mdtMethodSpec);
2986 SigTypeContext typeContext(Instantiation(typeArgs, typeArgsCount), Instantiation(methodArgs, methodArgsCount));
2987 pMD = MemberLoader::GetMethodDescFromMemberDefOrRefOrSpec(pModule, tkMemberRef, &typeContext, strictMetadataChecks, FALSE);
2989 // This will get us the instantiating or unboxing stub if needed
2990 pMD = MethodDesc::FindOrCreateAssociatedMethodDescForReflection(pMD, pMD->GetMethodTable(), pMD->GetMethodInstantiation());
2997 void QCALLTYPE ModuleHandle::ResolveField(QCall::ModuleHandle pModule, INT32 tkMemberRef, TypeHandle *typeArgs, INT32 typeArgsCount, TypeHandle *methodArgs, INT32 methodArgsCount, QCall::ObjectHandleOnStack retField)
3001 FieldDesc* pField = NULL;
3005 _ASSERTE(!IsNilToken(tkMemberRef));
3007 SigTypeContext typeContext(Instantiation(typeArgs, typeArgsCount), Instantiation(methodArgs, methodArgsCount));
3008 pField = MemberLoader::GetFieldDescFromMemberDefOrRef(pModule, tkMemberRef, &typeContext, FALSE);
3010 retField.Set(pField->GetStubFieldInfo());
3017 void QCALLTYPE ModuleHandle::GetAssembly(QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retAssembly)
3021 DomainAssembly *pAssembly = NULL;
3024 pAssembly = pModule->GetDomainAssembly();
3027 retAssembly.Set(pAssembly->GetExposedAssemblyObject());
3033 FCIMPL5(ReflectMethodObject*, ModuleHandle::GetDynamicMethod, ReflectMethodObject *pMethodUNSAFE, ReflectModuleBaseObject *pModuleUNSAFE, StringObject *name, U1Array *sig, Object *resolver) {
3036 PRECONDITION(CheckPointer(name));
3037 PRECONDITION(CheckPointer(sig));
3041 DynamicMethodDesc *pNewMD = NULL;
3046 OBJECTREF resolverRef;
3047 OBJECTREF methodRef;
3048 REFLECTMETHODREF retMethod;
3049 REFLECTMODULEBASEREF refModule;
3051 gc.nameRef = (STRINGREF)name;
3052 gc.resolverRef = (OBJECTREF)resolver;
3053 gc.methodRef = ObjectToOBJECTREF(pMethodUNSAFE);
3054 gc.retMethod = NULL;
3055 gc.refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
3057 if (gc.refModule == NULL)
3058 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
3060 Module *pModule = gc.refModule->GetModule();
3062 HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
3064 DomainFile *pDomainModule = pModule->GetDomainFile();
3066 U1ARRAYREF dataArray = (U1ARRAYREF)sig;
3067 DWORD sigSize = dataArray->GetNumComponents();
3068 NewHolder<BYTE> pSig(new BYTE[sigSize]);
3069 memcpy(pSig, dataArray->GetDataPtr(), sigSize);
3071 DWORD length = gc.nameRef->GetStringLength();
3072 NewArrayHolder<char> pName(new char[(length + 1) * 2]);
3074 length = WszWideCharToMultiByte(CP_UTF8, 0, gc.nameRef->GetBuffer(), length, pName, (length + 1) * 2 - sizeof(char), NULL, NULL);
3076 pName[length / sizeof(char)] = '\0';
3078 DynamicMethodTable *pMTForDynamicMethods = pDomainModule->GetDynamicMethodTable();
3079 pNewMD = pMTForDynamicMethods->GetDynamicMethod(pSig, sigSize, pName);
3080 _ASSERTE(pNewMD != NULL);
3081 // pNewMD now owns pSig and pName.
3082 pSig.SuppressRelease();
3083 pName.SuppressRelease();
3085 // create a handle to hold the resolver objectref
3086 OBJECTHANDLE resolverHandle = pDomainModule->GetAppDomain()->CreateLongWeakHandle(gc.resolverRef);
3087 pNewMD->GetLCGMethodResolver()->SetManagedResolver(resolverHandle);
3088 gc.retMethod = pNewMD->GetStubMethodInfo();
3089 gc.retMethod->SetKeepAlive(gc.resolverRef);
3091 LoaderAllocator *pLoaderAllocator = pModule->GetLoaderAllocator();
3093 if (pLoaderAllocator->IsCollectible())
3094 pLoaderAllocator->AddReference();
3096 HELPER_METHOD_FRAME_END();
3098 return (ReflectMethodObject*)OBJECTREFToObject(gc.retMethod);
3102 void QCALLTYPE RuntimeMethodHandle::GetCallerType(QCall::StackCrawlMarkHandle pStackMark, QCall::ObjectHandleOnStack retType)
3108 MethodTable *pMT = NULL;
3110 pMT = SystemDomain::GetCallersType(pStackMark);
3113 retType.Set(pMT->GetManagedClassObject());