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 "interoputil.h"
27 #include "virtualcallstub.h"
28 #include "contractimpl.h"
29 #include "dynamicmethod.h"
30 #include "peimagelayout.inl"
32 #include "eventtrace.h"
33 #include "invokeutil.h"
36 FCIMPL3(FC_BOOL_RET, Utf8String::EqualsCaseSensitive, LPCUTF8 szLhs, LPCUTF8 szRhs, INT32 stringNumBytes)
40 PRECONDITION(CheckPointer(szLhs));
41 PRECONDITION(CheckPointer(szRhs));
45 // Important: the string in pSsz isn't null terminated so the length must be used
46 // when performing operations on the string.
48 // At this point, both the left and right strings are guaranteed to have the
50 FC_RETURN_BOOL(strncmp(szLhs, szRhs, stringNumBytes) == 0);
54 BOOL QCALLTYPE Utf8String::EqualsCaseInsensitive(LPCUTF8 szLhs, LPCUTF8 szRhs, INT32 stringNumBytes)
58 // Important: the string in pSsz isn't null terminated so the length must be used
59 // when performing operations on the string.
61 BOOL fStringsEqual = FALSE;
65 _ASSERTE(CheckPointer(szLhs));
66 _ASSERTE(CheckPointer(szRhs));
68 // At this point, both the left and right strings are guaranteed to have the
70 StackSString lhs(SString::Utf8, szLhs, stringNumBytes);
71 StackSString rhs(SString::Utf8, szRhs, stringNumBytes);
73 // We can use SString for simple case insensitive compares
74 fStringsEqual = lhs.EqualsCaseInsensitive(rhs);
81 ULONG QCALLTYPE Utf8String::HashCaseInsensitive(LPCUTF8 sz, INT32 stringNumBytes)
85 // Important: the string in pSsz isn't null terminated so the length must be used
86 // when performing operations on the string.
92 StackSString str(SString::Utf8, sz, stringNumBytes);
93 hashValue = str.HashCaseInsensitive();
100 static BOOL CheckCAVisibilityFromDecoratedType(MethodTable* pCAMT, MethodDesc* pCACtor, MethodTable* pDecoratedMT, Module* pDecoratedModule)
107 PRECONDITION(CheckPointer(pCAMT));
108 PRECONDITION(CheckPointer(pCACtor, NULL_OK));
109 PRECONDITION(CheckPointer(pDecoratedMT, NULL_OK));
110 PRECONDITION(CheckPointer(pDecoratedModule));
114 DWORD dwAttr = mdPublic;
118 // Allowing a dangerous method to be called in custom attribute instantiation is, well, dangerous.
119 // E.g. a malicious user can craft a custom attribute record that fools us into creating a DynamicMethod
120 // object attached to typeof(System.Reflection.CustomAttribute) and thus gain access to mscorlib internals.
121 if (InvokeUtil::IsDangerousMethod(pCACtor))
124 _ASSERTE(pCACtor->IsCtor());
126 dwAttr = pCACtor->GetAttrs();
129 StaticAccessCheckContext accessContext(NULL, pDecoratedMT, pDecoratedModule->GetAssembly());
131 return ClassLoader::CanAccess(
134 pCAMT->GetAssembly(),
138 *AccessCheckOptions::s_pNormalAccessChecks,
143 BOOL QCALLTYPE RuntimeMethodHandle::IsCAVisibleFromDecoratedType(
144 EnregisteredTypeHandle targetTypeHandle,
145 MethodDesc * pTargetCtor,
146 EnregisteredTypeHandle sourceTypeHandle,
147 QCall::ModuleHandle sourceModuleHandle)
154 TypeHandle sourceHandle = TypeHandle::FromPtr(sourceTypeHandle);
155 TypeHandle targetHandle = TypeHandle::FromPtr(targetTypeHandle);
157 _ASSERTE((sourceHandle.IsNull() || !sourceHandle.IsTypeDesc()) &&
158 !targetHandle.IsNull() &&
159 !targetHandle.IsTypeDesc());
161 if (sourceHandle.IsTypeDesc() ||
162 targetHandle.IsNull() ||
163 targetHandle.IsTypeDesc())
164 COMPlusThrowArgumentNull(NULL, W("Arg_InvalidHandle"));
166 bResult = CheckCAVisibilityFromDecoratedType(targetHandle.AsMethodTable(), pTargetCtor, sourceHandle.AsMethodTable(), sourceModuleHandle);
173 NOINLINE static ReflectClassBaseObject* GetRuntimeTypeHelper(LPVOID __me, TypeHandle typeHandle, OBJECTREF keepAlive)
175 FC_INNER_PROLOG_NO_ME_SETUP();
176 if (typeHandle.AsPtr() == NULL)
179 // RuntimeTypeHandle::GetRuntimeType has picked off the most common case, but does not cover array types.
180 // Before we do the really heavy weight option of setting up a helper method frame, check if we have to.
181 OBJECTREF refType = typeHandle.GetManagedClassObjectFast();
183 return (ReflectClassBaseObject*)OBJECTREFToObject(refType);
185 HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_1(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, keepAlive);
186 refType = typeHandle.GetManagedClassObject();
187 HELPER_METHOD_FRAME_END();
190 return (ReflectClassBaseObject*)OBJECTREFToObject(refType);
193 #define RETURN_CLASS_OBJECT(typeHandle, keepAlive) FC_INNER_RETURN(ReflectClassBaseObject*, GetRuntimeTypeHelper(__me, typeHandle, keepAlive))
195 NOINLINE ReflectModuleBaseObject* GetRuntimeModuleHelper(LPVOID __me, Module *pModule, OBJECTREF keepAlive)
197 FC_INNER_PROLOG_NO_ME_SETUP();
201 DomainFile * pDomainFile = pModule->FindDomainFile(GetAppDomain());
203 OBJECTREF refModule = (pDomainFile != NULL) ? pDomainFile->GetExposedModuleObjectIfExists() : NULL;
205 if(refModule != NULL)
206 return (ReflectModuleBaseObject*)OBJECTREFToObject(refModule);
208 HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_1(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, keepAlive);
209 refModule = pModule->GetExposedObject();
210 HELPER_METHOD_FRAME_END();
213 return (ReflectModuleBaseObject*)OBJECTREFToObject(refModule);
216 NOINLINE AssemblyBaseObject* GetRuntimeAssemblyHelper(LPVOID __me, DomainAssembly *pAssembly, OBJECTREF keepAlive)
218 FC_INNER_PROLOG_NO_ME_SETUP();
219 if (pAssembly == NULL)
222 OBJECTREF refAssembly = (pAssembly != NULL) ? pAssembly->GetExposedAssemblyObjectIfExists() : NULL;
224 if(refAssembly != NULL)
225 return (AssemblyBaseObject*)OBJECTREFToObject(refAssembly);
227 HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_1(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, keepAlive);
228 refAssembly = pAssembly->GetExposedAssemblyObject();
229 HELPER_METHOD_FRAME_END();
232 return (AssemblyBaseObject*)OBJECTREFToObject(refAssembly);
236 // This is the routine that is called by the 'typeof()' operator in C#. It is one of the most commonly used
237 // reflection operations. This call should be optimized away in nearly all situations
238 FCIMPL1_V(ReflectClassBaseObject*, RuntimeTypeHandle::GetTypeFromHandle, FCALLRuntimeTypeHandle th)
243 return FCALL_RTH_TO_REFLECTCLASS(th);
247 FCIMPL1(ReflectClassBaseObject*, RuntimeTypeHandle::GetRuntimeType, EnregisteredTypeHandle th)
251 TypeHandle typeHandle = TypeHandle::FromPtr(th);
252 _ASSERTE(CheckPointer(typeHandle.AsPtr(), NULL_OK));
253 if (typeHandle.AsPtr()!= NULL)
255 if (!typeHandle.IsTypeDesc())
257 OBJECTREF typePtr = typeHandle.AsMethodTable()->GetManagedClassObjectIfExists();
260 return (ReflectClassBaseObject*)OBJECTREFToObject(typePtr);
267 RETURN_CLASS_OBJECT(typeHandle, NULL);
271 FCIMPL1_V(EnregisteredTypeHandle, RuntimeTypeHandle::GetValueInternal, FCALLRuntimeTypeHandle RTH)
275 if (FCALL_RTH_TO_REFLECTCLASS(RTH) == NULL)
278 return FCALL_RTH_TO_REFLECTCLASS(RTH) ->GetType().AsPtr();
282 // TypeEqualsHelper and TypeNotEqualsHelper are almost identical.
283 // Unfortunately we cannot combime them because they need to hardcode the caller's name
284 NOINLINE static BOOL TypeEqualSlow(OBJECTREF refL, OBJECTREF refR, LPVOID __me)
288 FC_INNER_PROLOG_NO_ME_SETUP();
290 _ASSERTE(refL != NULL && refR != NULL);
292 HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_2(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, refL, refR);
294 MethodDescCallSite TypeEqualsMethod(METHOD__OBJECT__EQUALS, &refL);
302 ret = TypeEqualsMethod.Call_RetBool(args);
304 HELPER_METHOD_FRAME_END();
313 #include <optsmallperfcritical.h>
315 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::TypeEQ, Object* left, Object* right)
319 OBJECTREF refL = (OBJECTREF)left;
320 OBJECTREF refR = (OBJECTREF)right;
324 FC_RETURN_BOOL(TRUE);
329 FC_RETURN_BOOL(FALSE);
332 if ((refL->GetMethodTable() == g_pRuntimeTypeClass || refR->GetMethodTable() == g_pRuntimeTypeClass))
334 // Quick path for negative common case
335 FC_RETURN_BOOL(FALSE);
338 // The fast path didn't get us the result
339 // Let's try the slow path: refL.Equals(refR);
340 FC_INNER_RETURN(FC_BOOL_RET, (FC_BOOL_RET)(!!TypeEqualSlow(refL, refR, __me)));
344 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::TypeNEQ, Object* left, Object* right)
348 OBJECTREF refL = (OBJECTREF)left;
349 OBJECTREF refR = (OBJECTREF)right;
353 FC_RETURN_BOOL(FALSE);
358 FC_RETURN_BOOL(TRUE);
361 if ((refL->GetMethodTable() == g_pRuntimeTypeClass || refR->GetMethodTable() == g_pRuntimeTypeClass))
363 // Quick path for negative common case
364 FC_RETURN_BOOL(TRUE);
367 // The fast path didn't get us the result
368 // Let's try the slow path: refL.Equals(refR);
369 FC_INNER_RETURN(FC_BOOL_RET, (FC_BOOL_RET)(!TypeEqualSlow(refL, refR, __me)));
373 #include <optdefault.h>
378 #ifdef FEATURE_COMINTEROP
379 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsWindowsRuntimeObjectType, ReflectClassBaseObject *rtTypeUNSAFE)
383 BOOL isWindowsRuntimeType = FALSE;
385 TypeHandle typeHandle = rtTypeUNSAFE->GetType();
386 MethodTable *pMT = typeHandle.GetMethodTable();
390 isWindowsRuntimeType = pMT->IsWinRTObjectType();
393 FC_RETURN_BOOL(isWindowsRuntimeType);
397 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsTypeExportedToWindowsRuntime, ReflectClassBaseObject *rtTypeUNSAFE)
401 BOOL isExportedToWinRT = FALSE;
403 TypeHandle typeHandle = rtTypeUNSAFE->GetType();
404 MethodTable *pMT = typeHandle.GetMethodTable();
408 isExportedToWinRT = pMT->IsExportedToWinRT();
411 FC_RETURN_BOOL(isExportedToWinRT);
414 #endif // FEATURE_COMINTEROP
416 NOINLINE static MethodDesc * RestoreMethodHelper(MethodDesc * pMethod, LPVOID __me)
418 FC_INNER_PROLOG_NO_ME_SETUP();
420 HELPER_METHOD_FRAME_BEGIN_RET_0();
421 pMethod->CheckRestore();
422 HELPER_METHOD_FRAME_END();
429 FCIMPL1(MethodDesc *, RuntimeTypeHandle::GetFirstIntroducedMethod, ReflectClassBaseObject *pTypeUNSAFE) {
432 PRECONDITION(CheckPointer(pTypeUNSAFE));
436 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
437 TypeHandle typeHandle = refType->GetType();
439 if (typeHandle.IsGenericVariable())
440 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
442 if (typeHandle.IsTypeDesc()) {
443 if (!typeHandle.IsArray())
447 MethodTable* pMT = typeHandle.GetMethodTable();
451 MethodDesc* pMethod = MethodTable::IntroducedMethodIterator::GetFirst(pMT);
453 // The only method that can show up here unrestored is instantiated methods. Check for it before performing the expensive IsRestored() check.
454 if (pMethod != NULL && pMethod->GetClassification() == mcInstantiated && !pMethod->IsRestored()) {
455 FC_INNER_RETURN(MethodDesc *, RestoreMethodHelper(pMethod, __me));
458 _ASSERTE(pMethod == NULL || pMethod->IsRestored());
463 #include <optsmallperfcritical.h>
464 FCIMPL1(void, RuntimeTypeHandle::GetNextIntroducedMethod, MethodDesc ** ppMethod) {
467 PRECONDITION(CheckPointer(ppMethod));
468 PRECONDITION(CheckPointer(*ppMethod));
472 MethodDesc *pMethod = MethodTable::IntroducedMethodIterator::GetNext(*ppMethod);
476 if (pMethod != NULL && pMethod->GetClassification() == mcInstantiated && !pMethod->IsRestored()) {
477 FC_INNER_RETURN_VOID(RestoreMethodHelper(pMethod, __me));
480 _ASSERTE(pMethod == NULL || pMethod->IsRestored());
483 #include <optdefault.h>
485 FCIMPL1(INT32, RuntimeTypeHandle::GetCorElementType, ReflectClassBaseObject *pTypeUNSAFE) {
491 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
494 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
496 return refType->GetType().GetSignatureCorElementType();
500 FCIMPL1(AssemblyBaseObject*, RuntimeTypeHandle::GetAssembly, ReflectClassBaseObject *pTypeUNSAFE) {
506 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
509 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
511 DomainFile *pDomainFile = NULL;
513 Module *pModule = refType->GetType().GetAssembly()->GetManifestModule();
515 pDomainFile = pModule->FindDomainFile(GetAppDomain());
516 #ifdef FEATURE_LOADER_OPTIMIZATION
517 if (pDomainFile == NULL)
519 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
521 pDomainFile = GetAppDomain()->LoadDomainNeutralModuleDependency(pModule, FILE_LOADED);
523 HELPER_METHOD_FRAME_END();
525 #endif // FEATURE_LOADER_OPTIMIZATION
528 FC_RETURN_ASSEMBLY_OBJECT((DomainAssembly *)pDomainFile, refType);
533 FCIMPL1(FC_BOOL_RET, RuntimeFieldHandle::AcquiresContextFromThis, FieldDesc *pField)
537 PRECONDITION(CheckPointer(pField));
541 FC_RETURN_BOOL(pField->IsSharedByGenericInstantiations());
546 FCIMPL1(ReflectModuleBaseObject*, RuntimeTypeHandle::GetModule, ReflectClassBaseObject *pTypeUNSAFE) {
554 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
557 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
559 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
561 result = refType->GetType().GetModule();
563 END_SO_INTOLERANT_CODE;
565 FC_RETURN_MODULE_OBJECT(result, refType);
569 FCIMPL1(ReflectClassBaseObject *, RuntimeTypeHandle::GetBaseType, ReflectClassBaseObject *pTypeUNSAFE) {
575 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
578 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
580 TypeHandle typeHandle = refType->GetType();
582 if (typeHandle.IsGenericVariable())
583 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
585 if (typeHandle.IsTypeDesc()) {
586 if (!typeHandle.IsArray())
590 RETURN_CLASS_OBJECT(typeHandle.GetParent(), refType);
594 FCIMPL1(ReflectClassBaseObject *, RuntimeTypeHandle::GetElementType, ReflectClassBaseObject *pTypeUNSAFE) {
600 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
603 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
605 TypeHandle typeHandle = refType->GetType();
607 if (!typeHandle.IsTypeDesc())
610 if (typeHandle.IsGenericVariable())
613 TypeHandle typeReturn;
615 if (typeHandle.IsArray())
616 typeReturn = typeHandle.AsArray()->GetArrayElementTypeHandle();
618 typeReturn = typeHandle.AsTypeDesc()->GetTypeParam();
620 RETURN_CLASS_OBJECT(typeReturn, refType);
624 FCIMPL1(INT32, RuntimeTypeHandle::GetArrayRank, ReflectClassBaseObject *pTypeUNSAFE) {
627 PRECONDITION(CheckPointer(pTypeUNSAFE));
628 PRECONDITION(pTypeUNSAFE->GetType().IsArray());
632 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
634 return (INT32)refType->GetType().AsArray()->GetRank();
638 FCIMPL1(INT32, RuntimeTypeHandle::GetNumVirtuals, ReflectClassBaseObject *pTypeUNSAFE) {
644 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
647 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
649 TypeHandle typeHandle = refType->GetType();
651 if (typeHandle.IsGenericVariable())
652 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
654 MethodTable *pMT = typeHandle.GetMethodTable();
657 return (INT32)pMT->GetNumVirtuals();
659 return 0; //REVIEW: should this return the number of methods in Object?
663 FCIMPL2(MethodDesc *, RuntimeTypeHandle::GetMethodAt, ReflectClassBaseObject *pTypeUNSAFE, INT32 slot) {
669 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
672 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
674 TypeHandle typeHandle = refType->GetType();
676 MethodDesc* pRetMethod = NULL;
678 if (typeHandle.IsGenericVariable())
679 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
681 if (slot < 0 || slot >= (INT32)typeHandle.GetMethodTable()->GetNumVirtuals())
682 FCThrowRes(kArgumentException, W("Arg_ArgumentOutOfRangeException"));
684 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
685 pRetMethod = typeHandle.GetMethodTable()->GetMethodDescForSlot((DWORD)slot);
686 HELPER_METHOD_FRAME_END();
693 FCIMPL3(FC_BOOL_RET, RuntimeTypeHandle::GetFields, ReflectClassBaseObject *pTypeUNSAFE, INT32 **result, INT32 *pCount) {
699 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
701 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
703 TypeHandle typeHandle = refType->GetType();
705 if (!pCount || !result)
706 FCThrow(kArgumentNullException);
708 if (typeHandle.IsGenericVariable())
709 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
711 if (typeHandle.IsTypeDesc()) {
713 FC_RETURN_BOOL(TRUE);
716 MethodTable *pMT= typeHandle.GetMethodTable();
718 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
721 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
722 // <TODO>Check this approximation - we may be losing exact type information </TODO>
723 ApproxFieldDescIterator fdIterator(pMT, ApproxFieldDescIterator::ALL_FIELDS);
724 INT32 count = (INT32)fdIterator.Count();
732 for(INT32 i = 0; i < count; i ++)
733 result[i] = (INT32*)fdIterator.Next();
738 HELPER_METHOD_FRAME_END();
739 FC_RETURN_BOOL(retVal);
743 void QCALLTYPE RuntimeMethodHandle::ConstructInstantiation(MethodDesc * pMethod, DWORD format, QCall::StringHandleOnStack retString)
750 TypeString::AppendInst(ss, pMethod->LoadMethodInstantiation(), format);
756 void QCALLTYPE RuntimeTypeHandle::ConstructName(EnregisteredTypeHandle pTypeHandle, DWORD format, QCall::StringHandleOnStack retString)
763 TypeString::AppendType(ss, TypeHandle::FromPtr(pTypeHandle), format);
769 PTRARRAYREF CopyRuntimeTypeHandles(TypeHandle * prgTH, FixupPointer<TypeHandle> * prgTH2, INT32 numTypeHandles, BinderClassID arrayElemType)
778 PTRARRAYREF refReturn = NULL;
779 PTRARRAYREF refArray = NULL;
781 if (numTypeHandles == 0)
784 _ASSERTE((prgTH != NULL) || (prgTH2 != NULL));
787 _ASSERTE(prgTH2 == NULL);
790 GCPROTECT_BEGIN(refArray);
791 TypeHandle thRuntimeType = TypeHandle(MscorlibBinder::GetClass(arrayElemType));
792 TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(thRuntimeType, ELEMENT_TYPE_SZARRAY);
793 refArray = (PTRARRAYREF)AllocateArrayEx(arrayHandle, &numTypeHandles, 1);
795 for (INT32 i = 0; i < numTypeHandles; i++)
802 th = prgTH2[i].GetValue();
804 OBJECTREF refType = th.GetManagedClassObject();
805 refArray->SetAt(i, refType);
808 refReturn = refArray;
814 void QCALLTYPE RuntimeTypeHandle::GetConstraints(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retTypeArray)
818 TypeHandle* constraints = NULL;
822 TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
824 if (!typeHandle.IsGenericVariable())
825 COMPlusThrow(kArgumentException, W("Arg_InvalidHandle"));
827 TypeVarTypeDesc* pGenericVariable = typeHandle.AsGenericVariable();
830 constraints = pGenericVariable->GetConstraints(&dwCount);
833 retTypeArray.Set(CopyRuntimeTypeHandles(constraints, NULL, dwCount, CLASS__TYPE));
840 FCIMPL1(PtrArray*, RuntimeTypeHandle::GetInterfaces, ReflectClassBaseObject *pTypeUNSAFE) {
846 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
849 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
851 TypeHandle typeHandle = refType->GetType();
853 if (typeHandle.IsGenericVariable())
854 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
856 INT32 ifaceCount = 0;
858 PTRARRAYREF refRetVal = NULL;
859 HELPER_METHOD_FRAME_BEGIN_RET_2(refRetVal, refType);
861 if (typeHandle.IsTypeDesc())
863 if (typeHandle.IsArray())
865 ifaceCount = typeHandle.GetMethodTable()->GetNumInterfaces();
874 ifaceCount = typeHandle.GetMethodTable()->GetNumInterfaces();
877 // Allocate the array
880 TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(g_pRuntimeTypeClass), ELEMENT_TYPE_SZARRAY);
881 refRetVal = (PTRARRAYREF)AllocateArrayEx(arrayHandle, &ifaceCount, 1);
883 // populate type array
886 MethodTable::InterfaceMapIterator it = typeHandle.GetMethodTable()->IterateInterfaceMap();
889 OBJECTREF refInterface = it.GetInterface()->GetManagedClassObject();
890 refRetVal->SetAt(i, refInterface);
891 _ASSERTE(refRetVal->GetAt(i) != NULL);
896 HELPER_METHOD_FRAME_END();
898 return (PtrArray*)OBJECTREFToObject(refRetVal);
902 FCIMPL1(INT32, RuntimeTypeHandle::GetAttributes, ReflectClassBaseObject *pTypeUNSAFE) {
908 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
911 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
913 TypeHandle typeHandle = refType->GetType();
915 if (typeHandle.IsTypeDesc()) {
917 if (typeHandle.IsGenericVariable()) {
921 if (!typeHandle.IsArray())
925 #ifdef FEATURE_COMINTEROP
926 // __ComObject types are always public.
927 if (IsComObjectClass(typeHandle))
928 return (typeHandle.GetMethodTable()->GetAttrClass() & tdVisibilityMask) | tdPublic;
929 #endif // FEATURE_COMINTEROP
933 ret = (INT32)typeHandle.GetMethodTable()->GetAttrClass();
939 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsValueType, ReflectClassBaseObject *pTypeUNSAFE)
946 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
948 _ASSERTE(refType != NULL);
950 TypeHandle typeHandle = refType->GetType();
952 FC_RETURN_BOOL(typeHandle.IsValueType());
956 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsInterface, ReflectClassBaseObject *pTypeUNSAFE)
963 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
965 _ASSERTE(refType != NULL);
967 TypeHandle typeHandle = refType->GetType();
969 FC_RETURN_BOOL(typeHandle.IsInterface());
974 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsByRefLike, ReflectClassBaseObject *pTypeUNSAFE)
981 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
983 _ASSERTE(refType != NULL);
985 TypeHandle typeHandle = refType->GetType();
987 FC_RETURN_BOOL(typeHandle.IsByRefLike());
993 RuntimeTypeHandle::IsVisible(
994 EnregisteredTypeHandle pTypeHandle)
1002 BOOL fIsExternallyVisible = FALSE;
1006 TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
1008 _ASSERTE(!typeHandle.IsNull());
1010 fIsExternallyVisible = typeHandle.IsExternallyVisible();
1014 return fIsExternallyVisible;
1015 } // RuntimeTypeHandle::IsVisible
1017 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::HasProxyAttribute, ReflectClassBaseObject *pTypeUNSAFE) {
1023 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1025 if (refType == NULL)
1026 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1028 TypeHandle typeHandle = refType->GetType();
1030 // TODO: Justify this
1031 if (typeHandle.IsGenericVariable())
1032 FC_RETURN_BOOL(FALSE);
1034 if (typeHandle.IsTypeDesc()) {
1035 if (!typeHandle.IsArray())
1036 FC_RETURN_BOOL(FALSE);
1039 MethodTable* pMT= typeHandle.GetMethodTable();
1042 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1044 FC_RETURN_BOOL(pMT->GetClass()->HasRemotingProxyAttribute());
1048 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::IsComObject, ReflectClassBaseObject *pTypeUNSAFE, CLR_BOOL isGenericCOM) {
1049 #ifdef FEATURE_COMINTEROP
1057 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1059 if (refType == NULL)
1060 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1062 TypeHandle typeHandle = refType->GetType();
1064 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
1067 ret = IsComObjectClass(typeHandle);
1069 ret = IsComWrapperClass(typeHandle);
1071 HELPER_METHOD_FRAME_END();
1073 FC_RETURN_BOOL(ret);
1079 PRECONDITION(CheckPointer(pTypeUNSAFE));
1083 FC_RETURN_BOOL(FALSE);
1088 FCIMPL1(LPCUTF8, RuntimeTypeHandle::GetUtf8Name, ReflectClassBaseObject* pTypeUNSAFE) {
1094 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1096 if (refType == NULL)
1097 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1099 TypeHandle typeHandle = refType->GetType();
1100 INT32 tkTypeDef = mdTypeDefNil;
1101 LPCUTF8 szName = NULL;
1103 if (typeHandle.IsGenericVariable())
1104 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1106 if (typeHandle.IsTypeDesc())
1107 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1109 MethodTable* pMT= typeHandle.GetMethodTable();
1112 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1114 tkTypeDef = (INT32)pMT->GetCl();
1116 if (IsNilToken(tkTypeDef))
1117 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1119 if (FAILED(pMT->GetMDImport()->GetNameOfTypeDef(tkTypeDef, &szName, NULL)))
1121 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1124 _ASSERTE(CheckPointer(szName, NULL_OK));
1130 FCIMPL1(INT32, RuntimeTypeHandle::GetToken, ReflectClassBaseObject *pTypeUNSAFE) {
1136 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1138 if (refType == NULL)
1139 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1141 TypeHandle typeHandle = refType->GetType();
1143 if (typeHandle.IsTypeDesc())
1145 if (typeHandle.IsGenericVariable())
1147 INT32 tkTypeDef = typeHandle.AsGenericVariable()->GetToken();
1149 _ASSERTE(!IsNilToken(tkTypeDef) && TypeFromToken(tkTypeDef) == mdtGenericParam);
1154 return mdTypeDefNil;
1157 return (INT32)typeHandle.AsMethodTable()->GetCl();
1161 PVOID QCALLTYPE RuntimeTypeHandle::GetGCHandle(EnregisteredTypeHandle pTypeHandle, INT32 handleType)
1165 OBJECTHANDLE objHandle = NULL;
1171 TypeHandle th = TypeHandle::FromPtr(pTypeHandle);
1172 assert(handleType >= HNDTYPE_WEAK_SHORT && handleType <= HNDTYPE_WEAK_WINRT);
1173 objHandle = th.GetDomain()->CreateTypedHandle(NULL, static_cast<HandleType>(handleType));
1174 th.GetLoaderAllocator()->RegisterHandleForCleanup(objHandle);
1181 void QCALLTYPE RuntimeTypeHandle::VerifyInterfaceIsImplemented(EnregisteredTypeHandle pTypeHandle, EnregisteredTypeHandle pIFaceHandle)
1187 TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
1188 TypeHandle ifaceHandle = TypeHandle::FromPtr(pIFaceHandle);
1190 if (typeHandle.IsGenericVariable())
1191 COMPlusThrow(kArgumentException, W("Arg_InvalidHandle"));
1193 if (typeHandle.IsTypeDesc()) {
1194 if (!typeHandle.IsArray())
1195 COMPlusThrow(kArgumentException, W("Arg_NotFoundIFace"));
1198 if (typeHandle.IsInterface())
1199 COMPlusThrow(kArgumentException, W("Argument_InterfaceMap"));
1201 if (!ifaceHandle.IsInterface())
1202 COMPlusThrow(kArgumentException, W("Arg_MustBeInterface"));
1204 // First try the cheap check, which amounts to iterating the interface map looking for
1205 // the ifaceHandle MethodTable.
1206 if (!typeHandle.GetMethodTable()->ImplementsInterface(ifaceHandle.AsMethodTable()))
1207 { // If the cheap check fails, try the more expensive but complete check.
1208 if (!typeHandle.CanCastTo(ifaceHandle))
1209 { // If the complete check fails, we're certain that this type
1210 // does not implement the interface specified.
1211 COMPlusThrow(kArgumentException, W("Arg_NotFoundIFace"));
1218 INT32 QCALLTYPE RuntimeTypeHandle::GetInterfaceMethodImplementationSlot(EnregisteredTypeHandle pTypeHandle, EnregisteredTypeHandle pOwner, MethodDesc * pMD)
1222 INT32 slotNumber = -1;
1226 TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
1227 TypeHandle thOwnerOfMD = TypeHandle::FromPtr(pOwner);
1229 // Ok to have INVALID_SLOT in the case where abstract class does not implement an interface method.
1230 // This case can not be reproed using C# "implements" all interface methods
1231 // with at least an abstract method. b19897_GetInterfaceMap_Abstract.exe tests this case.
1232 //@TODO:STUBDISPATCH: Don't need to track down the implementation, just the declaration, and this can
1233 //@TODO: be done faster - just need to make a function FindDispatchDecl.
1234 DispatchSlot slot(typeHandle.GetMethodTable()->FindDispatchSlotForInterfaceMD(thOwnerOfMD, pMD));
1236 slotNumber = slot.GetMethodDesc()->GetSlot();
1243 void QCALLTYPE RuntimeTypeHandle::GetDefaultConstructor(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retMethod)
1249 MethodDesc* pCtor = NULL;
1251 TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
1253 if (!typeHandle.IsTypeDesc())
1255 MethodTable* pMethodTable = typeHandle.AsMethodTable();
1256 if (pMethodTable->HasDefaultConstructor())
1257 pCtor = pMethodTable->GetDefaultConstructor();
1263 retMethod.Set(pCtor->GetStubMethodInfo());
1270 FCIMPL1(ReflectMethodObject*, RuntimeTypeHandle::GetDeclaringMethod, ReflectClassBaseObject *pTypeUNSAFE) {
1276 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1278 if (refType == NULL)
1279 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1281 TypeHandle typeHandle = refType->GetType();;
1283 if (!typeHandle.IsTypeDesc())
1286 TypeVarTypeDesc* pGenericVariable = typeHandle.AsGenericVariable();
1287 mdToken defToken = pGenericVariable->GetTypeOrMethodDef();
1288 if (TypeFromToken(defToken) != mdtMethodDef)
1291 REFLECTMETHODREF pRet = NULL;
1292 HELPER_METHOD_FRAME_BEGIN_RET_0();
1293 MethodDesc * pMD = pGenericVariable->LoadOwnerMethod();
1294 pMD->CheckRestore();
1295 pRet = pMD->GetStubMethodInfo();
1296 HELPER_METHOD_FRAME_END();
1298 return (ReflectMethodObject*)OBJECTREFToObject(pRet);
1302 FCIMPL1(ReflectClassBaseObject*, RuntimeTypeHandle::GetDeclaringType, ReflectClassBaseObject *pTypeUNSAFE) {
1308 TypeHandle retTypeHandle;
1310 BOOL fThrowException = FALSE;
1311 LPCWSTR argName = W("Arg_InvalidHandle");
1312 RuntimeExceptionKind reKind = kArgumentNullException;
1314 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1316 if (refType == NULL)
1317 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1319 TypeHandle typeHandle = refType->GetType();
1321 MethodTable* pMT = NULL;
1322 mdTypeDef tkTypeDef = mdTokenNil;
1324 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
1325 if (typeHandle.IsTypeDesc()) {
1327 if (typeHandle.IsGenericVariable()) {
1328 TypeVarTypeDesc* pGenericVariable = typeHandle.AsGenericVariable();
1329 mdToken defToken = pGenericVariable->GetTypeOrMethodDef();
1331 // Try the fast way first (if the declaring type has been loaded already).
1332 if (TypeFromToken(defToken) == mdtMethodDef)
1334 MethodDesc * retMethod = pGenericVariable->GetModule()->LookupMethodDef(defToken);
1335 if (retMethod != NULL)
1336 retTypeHandle = retMethod->GetMethodTable();
1340 retTypeHandle = pGenericVariable->GetModule()->LookupTypeDef(defToken);
1343 if (!retTypeHandle.IsNull() && retTypeHandle.IsFullyLoaded())
1346 // OK, need to go the slow way and load the type first.
1347 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
1349 if (TypeFromToken(defToken) == mdtMethodDef)
1351 retTypeHandle = pGenericVariable->LoadOwnerMethod()->GetMethodTable();
1355 retTypeHandle = pGenericVariable->LoadOwnerType();
1357 retTypeHandle.CheckRestore();
1359 HELPER_METHOD_FRAME_END();
1362 if (!typeHandle.IsArray())
1364 retTypeHandle = TypeHandle();
1369 pMT = typeHandle.GetMethodTable();
1373 fThrowException = TRUE;
1377 if(!pMT->GetClass()->IsNested())
1379 retTypeHandle = TypeHandle();
1383 tkTypeDef = pMT->GetCl();
1385 if (FAILED(typeHandle.GetModule()->GetMDImport()->GetNestedClassProps(tkTypeDef, &tkTypeDef)))
1387 fThrowException = TRUE;
1388 reKind = kBadImageFormatException;
1393 // Try the fast way first (if the declaring type has been loaded already).
1394 retTypeHandle = typeHandle.GetModule()->LookupTypeDef(tkTypeDef);
1395 if (retTypeHandle.IsNull())
1397 // OK, need to go the slow way and load the type first.
1398 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
1400 retTypeHandle = ClassLoader::LoadTypeDefThrowing(typeHandle.GetModule(), tkTypeDef,
1401 ClassLoader::ThrowIfNotFound,
1402 ClassLoader::PermitUninstDefOrRef);
1404 HELPER_METHOD_FRAME_END();
1408 END_SO_INTOLERANT_CODE;
1410 if (fThrowException)
1412 FCThrowRes(reKind, argName);
1415 RETURN_CLASS_OBJECT(retTypeHandle, refType);
1419 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::CanCastTo, ReflectClassBaseObject *pTypeUNSAFE, ReflectClassBaseObject *pTargetUNSAFE) {
1426 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1427 REFLECTCLASSBASEREF refTarget = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTargetUNSAFE);
1429 if ((refType == NULL) || (refTarget == NULL))
1430 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1432 TypeHandle fromHandle = refType->GetType();
1433 TypeHandle toHandle = refTarget->GetType();
1437 TypeHandle::CastResult r = fromHandle.CanCastToNoGC(toHandle);
1438 if (r == TypeHandle::MaybeCast)
1440 HELPER_METHOD_FRAME_BEGIN_RET_2(refType, refTarget);
1441 iRetVal = fromHandle.CanCastTo(toHandle);
1442 HELPER_METHOD_FRAME_END();
1446 iRetVal = (r == TypeHandle::CanCast);
1449 // We allow T to be cast to Nullable<T>
1450 if (!iRetVal && Nullable::IsNullableType(toHandle) && !fromHandle.IsTypeDesc())
1452 HELPER_METHOD_FRAME_BEGIN_RET_2(refType, refTarget);
1453 if (Nullable::IsNullableForType(toHandle, fromHandle.AsMethodTable()))
1457 HELPER_METHOD_FRAME_END();
1460 FC_RETURN_BOOL(iRetVal);
1464 void QCALLTYPE RuntimeTypeHandle::GetTypeByNameUsingCARules(LPCWSTR pwzClassName, QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retType)
1468 TypeHandle typeHandle;
1473 COMPlusThrowArgumentNull(W("className"),W("ArgumentNull_String"));
1475 typeHandle = TypeName::GetTypeUsingCASearchRules(pwzClassName, pModule->GetAssembly());
1478 retType.Set(typeHandle.GetManagedClassObject());
1485 void QCALLTYPE RuntimeTypeHandle::GetTypeByName(LPCWSTR pwzClassName, BOOL bThrowOnError, BOOL bIgnoreCase, BOOL bReflectionOnly,
1486 QCall::StackCrawlMarkHandle pStackMark,
1487 ICLRPrivBinder * pPrivHostBinder,
1488 BOOL bLoadTypeFromPartialNameHack, QCall::ObjectHandleOnStack retType,
1489 QCall::ObjectHandleOnStack keepAlive)
1493 TypeHandle typeHandle;
1498 COMPlusThrowArgumentNull(W("className"),W("ArgumentNull_String"));
1501 typeHandle = TypeName::GetTypeManaged(pwzClassName, NULL, bThrowOnError, bIgnoreCase, bReflectionOnly, /*bProhibitAsmQualifiedName =*/ FALSE, pStackMark,
1502 bLoadTypeFromPartialNameHack, (OBJECTREF*)keepAlive.m_ppObject,
1506 if (!typeHandle.IsNull())
1509 retType.Set(typeHandle.GetManagedClassObject());
1517 FCIMPL6(FC_BOOL_RET, RuntimeTypeHandle::SatisfiesConstraints, PTR_ReflectClassBaseObject pParamTypeUNSAFE, TypeHandle *typeContextArgs, INT32 typeContextCount, TypeHandle *methodContextArgs, INT32 methodContextCount, PTR_ReflectClassBaseObject pArgumentTypeUNSAFE);
1521 PRECONDITION(CheckPointer(typeContextArgs, NULL_OK));
1522 PRECONDITION(CheckPointer(methodContextArgs, NULL_OK));
1526 REFLECTCLASSBASEREF refParamType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pParamTypeUNSAFE);
1527 REFLECTCLASSBASEREF refArgumentType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pArgumentTypeUNSAFE);
1529 TypeHandle thGenericParameter = refParamType->GetType();
1530 TypeHandle thGenericArgument = refArgumentType->GetType();
1531 BOOL bResult = FALSE;
1532 SigTypeContext typeContext;
1534 Instantiation classInst;
1535 Instantiation methodInst;
1537 if (typeContextArgs != NULL)
1539 classInst = Instantiation(typeContextArgs, typeContextCount);
1542 if (methodContextArgs != NULL)
1544 methodInst = Instantiation(methodContextArgs, methodContextCount);
1547 SigTypeContext::InitTypeContext(classInst, methodInst, &typeContext);
1549 HELPER_METHOD_FRAME_BEGIN_RET_2(refParamType, refArgumentType);
1551 bResult = thGenericParameter.AsGenericVariable()->SatisfiesConstraints(&typeContext, thGenericArgument);
1553 HELPER_METHOD_FRAME_END();
1555 FC_RETURN_BOOL(bResult);
1559 void QCALLTYPE RuntimeTypeHandle::GetInstantiation(EnregisteredTypeHandle pType, QCall::ObjectHandleOnStack retTypes, BOOL fAsRuntimeTypeArray)
1565 TypeHandle typeHandle = TypeHandle::FromPtr(pType);
1566 Instantiation inst = typeHandle.GetInstantiation();
1568 retTypes.Set(CopyRuntimeTypeHandles(NULL, inst.GetRawArgs(), inst.GetNumArgs(), fAsRuntimeTypeArray ? CLASS__CLASS : CLASS__TYPE));
1574 void QCALLTYPE RuntimeTypeHandle::MakeArray(EnregisteredTypeHandle pTypeHandle, INT32 rank, QCall::ObjectHandleOnStack retType)
1578 TypeHandle arrayHandle;
1581 arrayHandle = TypeHandle::FromPtr(pTypeHandle).MakeArray(rank);
1583 retType.Set(arrayHandle.GetManagedClassObject());
1589 void QCALLTYPE RuntimeTypeHandle::MakeSZArray(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType)
1593 TypeHandle arrayHandle;
1596 arrayHandle = TypeHandle::FromPtr(pTypeHandle).MakeSZArray();
1598 retType.Set(arrayHandle.GetManagedClassObject());
1604 void QCALLTYPE RuntimeTypeHandle::MakePointer(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType)
1608 TypeHandle pointerHandle;
1611 pointerHandle = TypeHandle::FromPtr(pTypeHandle).MakePointer();
1613 retType.Set(pointerHandle.GetManagedClassObject());
1619 void QCALLTYPE RuntimeTypeHandle::MakeByRef(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType)
1623 TypeHandle byRefHandle;
1626 byRefHandle = TypeHandle::FromPtr(pTypeHandle).MakeByRef();
1628 retType.Set(byRefHandle.GetManagedClassObject());
1634 BOOL QCALLTYPE RuntimeTypeHandle::IsCollectible(EnregisteredTypeHandle pTypeHandle)
1638 BOOL retVal = FALSE;
1641 retVal = TypeHandle::FromPtr(pTypeHandle).GetLoaderAllocator()->IsCollectible();
1647 void QCALLTYPE RuntimeTypeHandle::Instantiate(EnregisteredTypeHandle pTypeHandle, TypeHandle * pInstArray, INT32 cInstArray, QCall::ObjectHandleOnStack retType)
1654 type = TypeHandle::FromPtr(pTypeHandle).Instantiate(Instantiation(pInstArray, cInstArray));
1656 retType.Set(type.GetManagedClassObject());
1662 void QCALLTYPE RuntimeTypeHandle::GetGenericTypeDefinition(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType)
1670 TypeHandle genericType = TypeHandle::FromPtr(pTypeHandle);
1672 typeDef = ClassLoader::LoadTypeDefThrowing(genericType.GetModule(),
1673 genericType.GetMethodTable()->GetCl(),
1674 ClassLoader::ThrowIfNotFound,
1675 ClassLoader::PermitUninstDefOrRef);
1678 retType.Set(typeDef.GetManagedClassObject());
1685 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::CompareCanonicalHandles, ReflectClassBaseObject *pLeftUNSAFE, ReflectClassBaseObject *pRightUNSAFE)
1689 REFLECTCLASSBASEREF refLeft = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pLeftUNSAFE);
1690 REFLECTCLASSBASEREF refRight = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pRightUNSAFE);
1692 if ((refLeft == NULL) || (refRight == NULL))
1693 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1695 FC_RETURN_BOOL(refLeft->GetType().GetCanonicalMethodTable() == refRight->GetType().GetCanonicalMethodTable());
1699 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::HasInstantiation, PTR_ReflectClassBaseObject pTypeUNSAFE)
1703 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1705 if (refType == NULL)
1706 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1708 FC_RETURN_BOOL(refType->GetType().HasInstantiation());
1712 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsGenericTypeDefinition, PTR_ReflectClassBaseObject pTypeUNSAFE)
1716 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1718 if (refType == NULL)
1719 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1721 FC_RETURN_BOOL(refType->GetType().IsGenericTypeDefinition());
1725 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsGenericVariable, PTR_ReflectClassBaseObject pTypeUNSAFE)
1729 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1731 if (refType == NULL)
1732 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1734 FC_RETURN_BOOL(refType->GetType().IsGenericVariable());
1738 FCIMPL1(INT32, RuntimeTypeHandle::GetGenericVariableIndex, PTR_ReflectClassBaseObject pTypeUNSAFE)
1742 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1744 if (refType == NULL)
1745 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1747 return (INT32)refType->GetType().AsGenericVariable()->GetIndex();
1751 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::ContainsGenericVariables, PTR_ReflectClassBaseObject pTypeUNSAFE)
1755 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1757 if (refType == NULL)
1758 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1760 FC_RETURN_BOOL(refType->GetType().ContainsGenericVariables());
1764 FCIMPL1(IMDInternalImport*, RuntimeTypeHandle::GetMetadataImport, ReflectClassBaseObject * pTypeUNSAFE)
1768 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1770 if (refType == NULL)
1771 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1773 Module *pModule = refType->GetType().GetModule();
1775 return pModule->GetMDImport();
1780 //***********************************************************************************
1781 //***********************************************************************************
1782 //***********************************************************************************
1784 void * QCALLTYPE RuntimeMethodHandle::GetFunctionPointer(MethodDesc * pMethod)
1792 funcPtr = (void*)pMethod->GetMultiCallableAddrOfCode();
1799 FCIMPL1(LPCUTF8, RuntimeMethodHandle::GetUtf8Name, MethodDesc *pMethod) {
1805 LPCUTF8 szName = NULL;
1808 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1810 szName = pMethod->GetName();
1812 _ASSERTE(CheckPointer(szName, NULL_OK));
1818 FCIMPL2(FC_BOOL_RET, RuntimeMethodHandle::MatchesNameHash, MethodDesc * pMethod, ULONG hash)
1822 FC_RETURN_BOOL(pMethod->MightHaveName(hash));
1826 FCIMPL1(StringObject*, RuntimeMethodHandle::GetName, MethodDesc *pMethod) {
1833 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1835 STRINGREF refName = NULL;
1837 HELPER_METHOD_FRAME_BEGIN_RET_0();
1838 refName = StringObject::NewString(pMethod->GetName());
1839 HELPER_METHOD_FRAME_END();
1841 return (StringObject*)OBJECTREFToObject(refName);
1845 FCIMPL1(INT32, RuntimeMethodHandle::GetAttributes, MethodDesc *pMethod) {
1852 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1855 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
1856 retVal = (INT32)pMethod->GetAttrs();
1857 END_SO_INTOLERANT_CODE;
1862 FCIMPL1(INT32, RuntimeMethodHandle::GetImplAttributes, ReflectMethodObject *pMethodUNSAFE) {
1869 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1871 MethodDesc* pMethod = pMethodUNSAFE->GetMethod();
1872 INT32 attributes = 0;
1874 if (IsNilToken(pMethod->GetMemberDef()))
1877 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
1879 attributes = (INT32)pMethod->GetImplAttrs();
1881 END_SO_INTOLERANT_CODE;
1888 FCIMPL1(ReflectClassBaseObject*, RuntimeMethodHandle::GetDeclaringType, MethodDesc *pMethod) {
1891 PRECONDITION(CheckPointer(pMethod));
1896 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1898 MethodTable *pMT = pMethod->GetMethodTable();
1899 TypeHandle declType(pMT);
1902 HELPER_METHOD_FRAME_BEGIN_RET_0();
1904 // Load the TypeDesc for the array type. Note the returned type is approximate, i.e.
1905 // if shared between reference array types then we will get object[] back.
1906 DWORD rank = pMT->GetRank();
1907 TypeHandle elemType = pMT->GetApproxArrayElementTypeHandle();
1908 declType = ClassLoader::LoadArrayTypeThrowing(elemType, pMT->GetInternalCorElementType(), rank);
1909 HELPER_METHOD_FRAME_END();
1911 RETURN_CLASS_OBJECT(declType, NULL);
1915 FCIMPL1(INT32, RuntimeMethodHandle::GetSlot, MethodDesc *pMethod) {
1922 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1924 return (INT32)pMethod->GetSlot();
1928 FCIMPL3(Object *, SignatureNative::GetCustomModifiers, SignatureNative* pSignatureUNSAFE,
1929 INT32 parameter, CLR_BOOL fRequired)
1938 SIGNATURENATIVEREF pSig;
1942 gc.pSig = (SIGNATURENATIVEREF)pSignatureUNSAFE;
1945 HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
1948 BYTE callConv = *(BYTE*)gc.pSig->GetCorSig();
1949 SigTypeContext typeContext;
1950 gc.pSig->GetTypeContext(&typeContext);
1951 MetaSig sig(gc.pSig->GetCorSig(),
1952 gc.pSig->GetCorSigSize(),
1953 gc.pSig->GetModule(),
1955 (callConv & IMAGE_CEE_CS_CALLCONV_MASK) == IMAGE_CEE_CS_CALLCONV_FIELD ? MetaSig::sigField : MetaSig::sigMember);
1956 _ASSERTE(callConv == sig.GetCallingConventionInfo());
1958 SigPointer argument(NULL, 0);
1960 PRECONDITION(sig.GetCallingConvention() != IMAGE_CEE_CS_CALLCONV_FIELD || parameter == 1);
1964 argument = sig.GetReturnProps();
1968 for(INT32 i = 0; i < parameter; i++)
1971 argument = sig.GetArgProps();
1974 //if (parameter < 0 || parameter > (INT32)sig.NumFixedArgs())
1975 // FCThrowResVoid(kArgumentNullException, W("Arg_ArgumentOutOfRangeException"));
1977 SigPointer sp = argument;
1978 Module* pModule = sig.GetModule();
1980 CorElementType cmodType;
1982 CorElementType cmodTypeExpected = fRequired ? ELEMENT_TYPE_CMOD_REQD : ELEMENT_TYPE_CMOD_OPT;
1984 // Discover the number of required and optional custom modifiers.
1988 IfFailThrow(sp.GetByte(&data));
1989 cmodType = (CorElementType)data;
1991 if (cmodType == ELEMENT_TYPE_CMOD_REQD || cmodType == ELEMENT_TYPE_CMOD_OPT)
1993 if (cmodType == cmodTypeExpected)
1998 else if (cmodType != ELEMENT_TYPE_SENTINEL)
2003 IfFailThrow(sp.GetToken(NULL));
2006 // Reset sp and populate the arrays for the required and optional custom
2007 // modifiers now that we know how long they should be.
2010 MethodTable *pMT = MscorlibBinder::GetClass(CLASS__TYPE);
2011 TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pMT), ELEMENT_TYPE_SZARRAY);
2013 gc.retVal = (PTRARRAYREF) AllocateArrayEx(arrayHandle, &cMods, 1);
2018 IfFailThrow(sp.GetByte(&data));
2019 cmodType = (CorElementType)data;
2022 IfFailThrow(sp.GetToken(&token));
2024 if (cmodType == cmodTypeExpected)
2026 TypeHandle th = ClassLoader::LoadTypeDefOrRefOrSpecThrowing(pModule, token,
2028 ClassLoader::ThrowIfNotFound,
2029 ClassLoader::FailIfUninstDefOrRef);
2031 OBJECTREF refType = th.GetManagedClassObject();
2032 gc.retVal->SetAt(--cMods, refType);
2036 HELPER_METHOD_FRAME_END();
2038 return OBJECTREFToObject(gc.retVal);
2042 FCIMPL1(INT32, RuntimeMethodHandle::GetMethodDef, ReflectMethodObject *pMethodUNSAFE) {
2049 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2051 MethodDesc* pMethod = pMethodUNSAFE->GetMethod();
2053 if (pMethod->HasMethodInstantiation())
2055 HELPER_METHOD_FRAME_BEGIN_RET_1(pMethodUNSAFE);
2057 pMethod = pMethod->StripMethodInstantiation();
2059 HELPER_METHOD_FRAME_END();
2062 INT32 tkMethodDef = (INT32)pMethod->GetMemberDef();
2063 _ASSERTE(TypeFromToken(tkMethodDef) == mdtMethodDef);
2065 if (IsNilToken(tkMethodDef) || TypeFromToken(tkMethodDef) != mdtMethodDef)
2066 return mdMethodDefNil;
2072 FCIMPL6(void, SignatureNative::GetSignature,
2073 SignatureNative* pSignatureNativeUNSAFE,
2074 PCCOR_SIGNATURE pCorSig, DWORD cCorSig,
2075 FieldDesc *pFieldDesc, ReflectMethodObject *pMethodUNSAFE, ReflectClassBaseObject *pDeclaringTypeUNSAFE) {
2078 PRECONDITION(pDeclaringTypeUNSAFE || pMethodUNSAFE->GetMethod()->IsDynamicMethod());
2079 PRECONDITION(CheckPointer(pCorSig, NULL_OK));
2080 PRECONDITION(CheckPointer(pMethodUNSAFE, NULL_OK));
2081 PRECONDITION(CheckPointer(pFieldDesc, NULL_OK));
2087 REFLECTCLASSBASEREF refDeclaringType;
2088 REFLECTMETHODREF refMethod;
2089 SIGNATURENATIVEREF pSig;
2092 gc.refDeclaringType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pDeclaringTypeUNSAFE);
2093 gc.refMethod = (REFLECTMETHODREF)ObjectToOBJECTREF(pMethodUNSAFE);
2094 gc.pSig = (SIGNATURENATIVEREF)pSignatureNativeUNSAFE;
2096 MethodDesc *pMethod;
2097 TypeHandle declType;
2099 if (gc.refDeclaringType == NULL)
2101 // for dynamic method, see precondition
2102 pMethod = gc.refMethod->GetMethod();
2103 declType = pMethod->GetMethodTable();
2107 pMethod = gc.refMethod != NULL ? gc.refMethod->GetMethod() : NULL;
2108 declType = gc.refDeclaringType->GetType();
2111 HELPER_METHOD_FRAME_BEGIN_PROTECT(gc);
2113 Module* pModule = declType.GetModule();
2117 pMethod->GetSig(&pCorSig, &cCorSig);
2118 if (pMethod->GetClassification() == mcInstantiated)
2120 LoaderAllocator *pLoaderAllocator = pMethod->GetLoaderAllocator();
2121 if (pLoaderAllocator->IsCollectible())
2122 gc.pSig->SetKeepAlive(pLoaderAllocator->GetExposedObject());
2125 else if (pFieldDesc)
2126 pFieldDesc->GetSig(&pCorSig, &cCorSig);
2128 gc.pSig->m_sig = pCorSig;
2129 gc.pSig->m_cSig = cCorSig;
2130 gc.pSig->m_pMethod = pMethod;
2132 REFLECTCLASSBASEREF refDeclType = (REFLECTCLASSBASEREF)declType.GetManagedClassObject();
2133 gc.pSig->SetDeclaringType(refDeclType);
2135 PREFIX_ASSUME(pCorSig!= NULL);
2136 BYTE callConv = *(BYTE*)pCorSig;
2137 SigTypeContext typeContext;
2139 SigTypeContext::InitTypeContext(
2140 pMethod, declType.GetClassOrArrayInstantiation(), pMethod->LoadMethodInstantiation(), &typeContext);
2142 SigTypeContext::InitTypeContext(declType, &typeContext);
2143 MetaSig msig(pCorSig, cCorSig, pModule, &typeContext,
2144 (callConv & IMAGE_CEE_CS_CALLCONV_MASK) == IMAGE_CEE_CS_CALLCONV_FIELD ? MetaSig::sigField : MetaSig::sigMember);
2146 if (callConv == IMAGE_CEE_CS_CALLCONV_FIELD)
2148 msig.NextArgNormalized();
2150 OBJECTREF refRetType = msig.GetLastTypeHandleThrowing().GetManagedClassObject();
2151 gc.pSig->SetReturnType(refRetType);
2155 gc.pSig->SetCallingConvention(msig.GetCallingConventionInfo());
2157 OBJECTREF refRetType = msig.GetRetTypeHandleThrowing().GetManagedClassObject();
2158 gc.pSig->SetReturnType(refRetType);
2160 INT32 nArgs = msig.NumFixedArgs();
2161 TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(g_pRuntimeTypeClass), ELEMENT_TYPE_SZARRAY);
2163 PTRARRAYREF ptrArrayarguments = (PTRARRAYREF) AllocateArrayEx(arrayHandle, &nArgs, 1);
2164 gc.pSig->SetArgumentArray(ptrArrayarguments);
2166 for (INT32 i = 0; i < nArgs; i++)
2170 OBJECTREF refArgType = msig.GetLastTypeHandleThrowing().GetManagedClassObject();
2171 gc.pSig->SetArgument(i, refArgType);
2174 _ASSERTE(gc.pSig->m_returnType != NULL);
2177 HELPER_METHOD_FRAME_END();
2181 FCIMPL2(FC_BOOL_RET, SignatureNative::CompareSig, SignatureNative* pLhsUNSAFE, SignatureNative* pRhsUNSAFE)
2189 SIGNATURENATIVEREF pLhs;
2190 SIGNATURENATIVEREF pRhs;
2193 gc.pLhs = (SIGNATURENATIVEREF)pLhsUNSAFE;
2194 gc.pRhs = (SIGNATURENATIVEREF)pRhsUNSAFE;
2196 HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
2198 ret = MetaSig::CompareMethodSigs(
2199 gc.pLhs->GetCorSig(), gc.pLhs->GetCorSigSize(), gc.pLhs->GetModule(), NULL,
2200 gc.pRhs->GetCorSig(), gc.pRhs->GetCorSigSize(), gc.pRhs->GetModule(), NULL);
2202 HELPER_METHOD_FRAME_END();
2203 FC_RETURN_BOOL(ret);
2207 void QCALLTYPE RuntimeMethodHandle::GetMethodInstantiation(MethodDesc * pMethod, QCall::ObjectHandleOnStack retTypes, BOOL fAsRuntimeTypeArray)
2212 Instantiation inst = pMethod->LoadMethodInstantiation();
2215 retTypes.Set(CopyRuntimeTypeHandles(NULL, inst.GetRawArgs(), inst.GetNumArgs(), fAsRuntimeTypeArray ? CLASS__CLASS : CLASS__TYPE));
2221 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::HasMethodInstantiation, MethodDesc * pMethod)
2225 FC_RETURN_BOOL(pMethod->HasMethodInstantiation());
2229 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsGenericMethodDefinition, MethodDesc * pMethod)
2233 FC_RETURN_BOOL(pMethod->IsGenericMethodDefinition());
2237 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsDynamicMethod, MethodDesc * pMethod)
2241 FC_RETURN_BOOL(pMethod->IsNoMetadata());
2245 FCIMPL1(Object*, RuntimeMethodHandle::GetResolver, MethodDesc * pMethod)
2250 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2252 OBJECTREF resolver = NULL;
2253 if (pMethod->IsLCGMethod())
2255 resolver = pMethod->AsDynamicMethodDesc()->GetLCGMethodResolver()->GetManagedResolver();
2257 return OBJECTREFToObject(resolver);
2261 void QCALLTYPE RuntimeMethodHandle::Destroy(MethodDesc * pMethod)
2267 if (pMethod == NULL)
2268 COMPlusThrowArgumentNull(NULL, W("Arg_InvalidHandle"));
2270 DynamicMethodDesc* pDynamicMethodDesc = pMethod->AsDynamicMethodDesc();
2274 // Destroy should be called only if the managed part is gone.
2275 _ASSERTE(OBJECTREFToObject(pDynamicMethodDesc->GetLCGMethodResolver()->GetManagedResolver()) == NULL);
2277 // Fire Unload Dynamic Method Event here
2278 ETW::MethodLog::DynamicMethodDestroyed(pMethod);
2280 BEGIN_PIN_PROFILER(CORProfilerIsMonitoringDynamicFunctionUnloads());
2281 g_profControlBlock.pProfInterface->DynamicMethodUnloaded((FunctionID)pMethod);
2284 pDynamicMethodDesc->Destroy();
2289 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsTypicalMethodDefinition, ReflectMethodObject *pMethodUNSAFE)
2294 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2296 MethodDesc* pMethod = pMethodUNSAFE->GetMethod();
2298 FC_RETURN_BOOL(pMethod->IsTypicalMethodDefinition());
2302 void QCALLTYPE RuntimeMethodHandle::GetTypicalMethodDefinition(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod)
2310 _ASSERTE(((ReflectMethodObject *)(*refMethod.m_ppObject))->GetMethod() == pMethod);
2313 MethodDesc *pMethodTypical = pMethod->LoadTypicalMethodDefinition();
2314 if (pMethodTypical != pMethod)
2317 refMethod.Set(pMethodTypical->GetStubMethodInfo());
2324 void QCALLTYPE RuntimeMethodHandle::StripMethodInstantiation(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod)
2331 COMPlusThrowArgumentNull(NULL, W("Arg_InvalidHandle"));
2336 _ASSERTE(((ReflectMethodObject *)(*refMethod.m_ppObject))->GetMethod() == pMethod);
2339 MethodDesc *pMethodStripped = pMethod->StripMethodInstantiation();
2340 if (pMethodStripped != pMethod)
2343 refMethod.Set(pMethodStripped->GetStubMethodInfo());
2350 // In the VM there might be more than one MethodDescs for a "method"
2351 // examples are methods on generic types which may have additional instantiating stubs
2352 // and methods on value types which may have additional unboxing stubs.
2354 // For generic methods we always hand out an instantiating stub except for a generic method definition
2355 // For non-generic methods on generic types we need an instantiating stub if it's one of the following
2356 // - static method on a generic class
2357 // - static or instance method on a generic interface
2358 // - static or instance method on a generic value type
2359 // The Reflection policy is to always hand out instantiating stubs in these cases
2361 // For methods on non-generic value types we can use either the cannonical method or the unboxing stub
2362 // The Reflection policy is to always hand out unboxing stubs if the methods are virtual methods
2363 // The reason for this is that in the current implementation of the class loader, the v-table slots for
2364 // those methods point to unboxing stubs already. Note that this is just a implementation choice
2365 // that might change in the future. But we should always keep this Reflection policy an invariant.
2367 // For virtual methods on generic value types (intersection of the two cases), reflection will hand
2368 // out an unboxing instantiating stub
2370 // GetInstantiatingStub is called to:
2371 // 1. create an InstantiatedMethodDesc for a generic method when calling BindGenericArguments() on a generic
2372 // method. In this case instArray will not be null.
2373 // 2. create an InstantiatedMethodDesc for a method in a generic class. In this case instArray will be null.
2374 // 3. create an UnboxingStub for a method in a value type. In this case instArray will be null.
2375 // For case 2 and 3, an instantiating stub or unboxing stub might not be needed in which case the original
2376 // MethodDesc is returned.
2377 FCIMPL3(MethodDesc*, RuntimeMethodHandle::GetStubIfNeeded,
2378 MethodDesc *pMethod,
2379 ReflectClassBaseObject *pTypeUNSAFE,
2380 PtrArray* instArrayUNSAFE)
2387 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
2388 PTRARRAYREF instArray = (PTRARRAYREF)ObjectToOBJECTREF(instArrayUNSAFE);
2390 if (refType == NULL)
2391 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2393 TypeHandle instType = refType->GetType();
2394 MethodDesc *pNewMethod = pMethod;
2398 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
2400 if (instType.IsNull())
2401 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2403 // Perf optimization: this logic is actually duplicated in FindOrCreateAssociatedMethodDescForReflection, but since it
2404 // is the more common case it's worth the duplicate check here to avoid the helper method frame
2405 if ( instArray == NULL &&
2406 ( pMethod->HasMethodInstantiation() ||
2407 ( !instType.IsValueType() &&
2408 ( !instType.HasInstantiation() || instType.IsGenericTypeDefinition() ) ) ) )
2413 HELPER_METHOD_FRAME_BEGIN_RET_2(refType, instArray);
2415 TypeHandle *inst = NULL;
2418 if (instArray != NULL)
2420 ntypars = instArray->GetNumComponents();
2422 size_t size = ntypars * sizeof(TypeHandle);
2423 if ((size / sizeof(TypeHandle)) != ntypars) // uint over/underflow
2424 COMPlusThrow(kArgumentException);
2425 inst = (TypeHandle*) _alloca(size);
2427 for (DWORD i = 0; i < ntypars; i++)
2429 REFLECTCLASSBASEREF instRef = (REFLECTCLASSBASEREF)instArray->GetAt(i);
2431 if (instRef == NULL)
2432 COMPlusThrowArgumentNull(W("inst"), W("ArgumentNull_ArrayElement"));
2434 inst[i] = instRef->GetType();
2438 pNewMethod = MethodDesc::FindOrCreateAssociatedMethodDescForReflection(pMethod, instType, Instantiation(inst, ntypars));
2440 HELPER_METHOD_FRAME_END();
2447 FCIMPL2(MethodDesc*, RuntimeMethodHandle::GetMethodFromCanonical, MethodDesc *pMethod, ReflectClassBaseObject *pTypeUNSAFE)
2451 PRECONDITION(CheckPointer(pMethod));
2455 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
2457 TypeHandle instType = refType->GetType();
2458 MethodDesc* pMDescInCanonMT = instType.GetMethodTable()->GetParallelMethodDesc(pMethod);
2460 return pMDescInCanonMT;
2465 FCIMPL2(MethodBody *, RuntimeMethodHandle::GetMethodBody, ReflectMethodObject *pMethodUNSAFE, ReflectClassBaseObject *pDeclaringTypeUNSAFE)
2475 METHODBODYREF MethodBodyObj;
2476 EXCEPTIONHANDLINGCLAUSEREF EHClauseObj;
2477 LOCALVARIABLEINFOREF LocalVariableInfoObj;
2479 BASEARRAYREF TempArray;
2480 REFLECTCLASSBASEREF declaringType;
2481 REFLECTMETHODREF refMethod;
2484 gc.MethodBodyObj = NULL;
2485 gc.EHClauseObj = NULL;
2486 gc.LocalVariableInfoObj = NULL;
2488 gc.TempArray = NULL;
2489 gc.declaringType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pDeclaringTypeUNSAFE);
2490 gc.refMethod = (REFLECTMETHODREF)ObjectToOBJECTREF(pMethodUNSAFE);
2494 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2496 MethodDesc* pMethod = gc.refMethod->GetMethod();
2498 TypeHandle declaringType = gc.declaringType == NULL ? TypeHandle() : gc.declaringType->GetType();
2500 if (!pMethod->IsIL())
2503 HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
2505 MethodDesc *pMethodIL = pMethod;
2506 if (pMethod->IsWrapperStub())
2507 pMethodIL = pMethod->GetWrappedMethodDesc();
2509 COR_ILMETHOD* pILHeader = pMethodIL->GetILHeader();
2513 MethodTable * pExceptionHandlingClauseMT = MscorlibBinder::GetClass(CLASS__EH_CLAUSE);
2514 TypeHandle thEHClauseArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pExceptionHandlingClauseMT), ELEMENT_TYPE_SZARRAY);
2516 MethodTable * pLocalVariableMT = MscorlibBinder::GetClass(CLASS__LOCAL_VARIABLE_INFO);
2517 TypeHandle thLocalVariableArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pLocalVariableMT), ELEMENT_TYPE_SZARRAY);
2519 Module* pModule = pMethod->GetModule();
2520 COR_ILMETHOD_DECODER::DecoderStatus status;
2521 COR_ILMETHOD_DECODER header(pILHeader, pModule->GetMDImport(), &status);
2523 if (status != COR_ILMETHOD_DECODER::SUCCESS)
2525 if (status == COR_ILMETHOD_DECODER::VERIFICATION_ERROR)
2527 // Throw a verification HR
2528 COMPlusThrowHR(COR_E_VERIFICATION);
2532 COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
2536 gc.MethodBodyObj = (METHODBODYREF)AllocateObject(MscorlibBinder::GetClass(CLASS__METHOD_BODY));
2538 gc.MethodBodyObj->m_maxStackSize = header.GetMaxStack();
2539 gc.MethodBodyObj->m_initLocals = !!(header.GetFlags() & CorILMethod_InitLocals);
2542 gc.MethodBodyObj->m_localVarSigToken = header.GetLocalVarSigTok();
2544 gc.MethodBodyObj->m_localVarSigToken = 0;
2546 // Allocate the array of IL and fill it in from the method header.
2547 BYTE* pIL = const_cast<BYTE*>(header.Code);
2548 COUNT_T cIL = header.GetCodeSize();
2549 gc.U1Array = (U1ARRAYREF) AllocatePrimitiveArray(ELEMENT_TYPE_U1, cIL);
2551 SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->m_IL, gc.U1Array, GetAppDomain());
2552 memcpyNoGCRefs(gc.MethodBodyObj->m_IL->GetDataPtr(), pIL, cIL);
2554 // Allocate the array of exception clauses.
2555 INT32 cEh = (INT32)header.EHCount();
2556 const COR_ILMETHOD_SECT_EH* ehInfo = header.EH;
2557 gc.TempArray = (BASEARRAYREF) AllocateArrayEx(thEHClauseArray, &cEh, 1);
2559 SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->m_exceptionClauses, gc.TempArray, GetAppDomain());
2561 for (INT32 i = 0; i < cEh; i++)
2563 COR_ILMETHOD_SECT_EH_CLAUSE_FAT ehBuff;
2564 const COR_ILMETHOD_SECT_EH_CLAUSE_FAT* ehClause =
2565 (const COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)ehInfo->EHClause(i, &ehBuff);
2567 gc.EHClauseObj = (EXCEPTIONHANDLINGCLAUSEREF) AllocateObject(pExceptionHandlingClauseMT);
2569 gc.EHClauseObj->m_flags = ehClause->GetFlags();
2570 gc.EHClauseObj->m_tryOffset = ehClause->GetTryOffset();
2571 gc.EHClauseObj->m_tryLength = ehClause->GetTryLength();
2572 gc.EHClauseObj->m_handlerOffset = ehClause->GetHandlerOffset();
2573 gc.EHClauseObj->m_handlerLength = ehClause->GetHandlerLength();
2575 if ((ehClause->GetFlags() & COR_ILEXCEPTION_CLAUSE_FILTER) == 0)
2576 gc.EHClauseObj->m_catchToken = ehClause->GetClassToken();
2578 gc.EHClauseObj->m_filterOffset = ehClause->GetFilterOffset();
2580 gc.MethodBodyObj->m_exceptionClauses->SetAt(i, (OBJECTREF) gc.EHClauseObj);
2581 SetObjectReference((OBJECTREF*)&(gc.EHClauseObj->m_methodBody), (OBJECTREF)gc.MethodBodyObj, GetAppDomain());
2584 if (header.LocalVarSig != NULL)
2586 SigTypeContext sigTypeContext(pMethod, declaringType, pMethod->LoadMethodInstantiation());
2587 MetaSig metaSig(header.LocalVarSig,
2588 header.cbLocalVarSig,
2591 MetaSig::sigLocalVars);
2592 INT32 cLocals = metaSig.NumFixedArgs();
2593 gc.TempArray = (BASEARRAYREF) AllocateArrayEx(thLocalVariableArray, &cLocals, 1);
2594 SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->m_localVariables, gc.TempArray, GetAppDomain());
2596 for (INT32 i = 0; i < cLocals; i ++)
2598 gc.LocalVariableInfoObj = (LOCALVARIABLEINFOREF)AllocateObject(pLocalVariableMT);
2600 gc.LocalVariableInfoObj->m_localIndex = i;
2604 CorElementType eType;
2605 IfFailThrow(metaSig.GetArgProps().PeekElemType(&eType));
2606 if (ELEMENT_TYPE_PINNED == eType)
2607 gc.LocalVariableInfoObj->m_bIsPinned = TRUE;
2609 TypeHandle tempType= metaSig.GetArgProps().GetTypeHandleThrowing(pModule, &sigTypeContext);
2610 OBJECTREF refLocalType = tempType.GetManagedClassObject();
2611 gc.LocalVariableInfoObj->SetType(refLocalType);
2612 gc.MethodBodyObj->m_localVariables->SetAt(i, (OBJECTREF) gc.LocalVariableInfoObj);
2618 gc.TempArray = (BASEARRAYREF) AllocateArrayEx(thLocalVariableArray, &cLocals, 1);
2619 SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->m_localVariables, gc.TempArray, GetAppDomain());
2623 HELPER_METHOD_FRAME_END();
2625 return (MethodBody*)OBJECTREFToObject(gc.MethodBodyObj);
2629 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsConstructor, MethodDesc *pMethod)
2633 PRECONDITION(CheckPointer(pMethod));
2638 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
2639 ret = (BOOL)pMethod->IsClassConstructorOrCtor();
2640 END_SO_INTOLERANT_CODE;
2641 FC_RETURN_BOOL(ret);
2645 FCIMPL1(Object*, RuntimeMethodHandle::GetLoaderAllocator, MethodDesc *pMethod)
2652 OBJECTREF loaderAllocator = NULL;
2655 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2657 HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(loaderAllocator);
2659 LoaderAllocator *pLoaderAllocator = pMethod->GetLoaderAllocator();
2660 loaderAllocator = pLoaderAllocator->GetExposedObject();
2662 HELPER_METHOD_FRAME_END();
2664 return OBJECTREFToObject(loaderAllocator);
2668 //*********************************************************************************************
2669 //*********************************************************************************************
2670 //*********************************************************************************************
2672 FCIMPL1(StringObject*, RuntimeFieldHandle::GetName, ReflectFieldObject *pFieldUNSAFE) {
2678 REFLECTFIELDREF refField = (REFLECTFIELDREF)ObjectToOBJECTREF(pFieldUNSAFE);
2680 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2682 FieldDesc *pField = refField->GetField();
2684 STRINGREF refString = NULL;
2685 HELPER_METHOD_FRAME_BEGIN_RET_1(refField);
2687 refString = StringObject::NewString(pField->GetName());
2689 HELPER_METHOD_FRAME_END();
2690 return (StringObject*)OBJECTREFToObject(refString);
2694 FCIMPL1(LPCUTF8, RuntimeFieldHandle::GetUtf8Name, FieldDesc *pField) {
2697 PRECONDITION(CheckPointer(pField));
2701 LPCUTF8 szFieldName;
2703 if (FAILED(pField->GetName_NoThrow(&szFieldName)))
2705 FCThrow(kBadImageFormatException);
2711 FCIMPL2(FC_BOOL_RET, RuntimeFieldHandle::MatchesNameHash, FieldDesc * pField, ULONG hash)
2715 FC_RETURN_BOOL(pField->MightHaveName(hash));
2719 FCIMPL1(INT32, RuntimeFieldHandle::GetAttributes, FieldDesc *pField) {
2726 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2729 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
2730 ret = (INT32)pField->GetAttributes();
2731 END_SO_INTOLERANT_CODE;
2736 FCIMPL1(ReflectClassBaseObject*, RuntimeFieldHandle::GetApproxDeclaringType, FieldDesc *pField) {
2743 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2745 TypeHandle th = TypeHandle(pField->GetApproxEnclosingMethodTable()); // <REVISIT_TODO> this needs to be checked - see bug 184355 </REVISIT_TODO>
2746 RETURN_CLASS_OBJECT(th, NULL);
2750 FCIMPL1(INT32, RuntimeFieldHandle::GetToken, ReflectFieldObject *pFieldUNSAFE) {
2756 REFLECTFIELDREF refField = (REFLECTFIELDREF)ObjectToOBJECTREF(pFieldUNSAFE);
2758 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2760 FieldDesc *pField = refField->GetField();
2762 INT32 tkFieldDef = (INT32)pField->GetMemberDef();
2763 _ASSERTE(!IsNilToken(tkFieldDef) || tkFieldDef == mdFieldDefNil);
2768 FCIMPL2(FieldDesc*, RuntimeFieldHandle::GetStaticFieldForGenericType, FieldDesc *pField, ReflectClassBaseObject *pDeclaringTypeUNSAFE)
2775 REFLECTCLASSBASEREF refDeclaringType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pDeclaringTypeUNSAFE);
2777 if ((refDeclaringType == NULL) || (pField == NULL))
2778 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2780 TypeHandle declaringType = refDeclaringType->GetType();
2783 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2784 if (declaringType.IsTypeDesc())
2785 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2786 MethodTable *pMT = declaringType.AsMethodTable();
2788 _ASSERTE(pField->IsStatic());
2789 if (pMT->HasGenericsStaticsInfo())
2790 pField = pMT->GetFieldDescByIndex(pField->GetApproxEnclosingMethodTable()->GetIndexForFieldDesc(pField));
2791 _ASSERTE(!pField->IsSharedByGenericInstantiations());
2792 _ASSERTE(pField->GetEnclosingMethodTable() == pMT);
2798 FCIMPL1(ReflectModuleBaseObject*, AssemblyHandle::GetManifestModule, AssemblyBaseObject* pAssemblyUNSAFE) {
2801 ASSEMBLYREF refAssembly = (ASSEMBLYREF)ObjectToOBJECTREF(pAssemblyUNSAFE);
2803 if (refAssembly == NULL)
2804 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2806 DomainAssembly *pAssembly = refAssembly->GetDomainAssembly();
2807 Assembly* currentAssembly = pAssembly->GetCurrentAssembly();
2809 if (currentAssembly == NULL)
2812 Module *pModule = currentAssembly->GetManifestModule();
2813 DomainFile * pDomainFile = pModule->FindDomainFile(GetAppDomain());
2818 HELPER_METHOD_FRAME_BEGIN_RET_1(refAssembly);
2819 orModule = (pDomainFile != NULL) ? pDomainFile->GetExposedModuleObjectIfExists() : NULL;
2820 if (orModule == NULL)
2821 orModule = pModule->GetExposedObject();
2823 OBJECTREF orModule = (pDomainFile != NULL) ? pDomainFile->GetExposedModuleObjectIfExists() : NULL;
2824 if (orModule != NULL)
2825 return (ReflectModuleBaseObject*)OBJECTREFToObject(orModule);
2827 HELPER_METHOD_FRAME_BEGIN_RET_1(refAssembly);
2828 orModule = pModule->GetExposedObject();
2831 HELPER_METHOD_FRAME_END();
2832 return (ReflectModuleBaseObject*)OBJECTREFToObject(orModule);
2837 FCIMPL1(INT32, AssemblyHandle::GetToken, AssemblyBaseObject* pAssemblyUNSAFE) {
2840 ASSEMBLYREF refAssembly = (ASSEMBLYREF)ObjectToOBJECTREF(pAssemblyUNSAFE);
2842 if (refAssembly == NULL)
2843 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2845 DomainAssembly *pAssembly = refAssembly->GetDomainAssembly();
2846 mdAssembly token = mdAssemblyNil;
2848 IMDInternalImport *mdImport = pAssembly->GetCurrentAssembly()->GetManifestImport();
2852 if (FAILED(mdImport->GetAssemblyFromScope(&token)))
2854 FCThrow(kBadImageFormatException);
2863 void QCALLTYPE ModuleHandle::GetPEKind(QCall::ModuleHandle pModule, DWORD* pdwPEKind, DWORD* pdwMachine)
2868 pModule->GetFile()->GetPEKindAndMachine(pdwPEKind, pdwMachine);
2872 FCIMPL1(INT32, ModuleHandle::GetMDStreamVersion, ReflectModuleBaseObject * pModuleUNSAFE)
2876 REFLECTMODULEBASEREF refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
2878 if (refModule == NULL)
2879 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2881 Module *pModule = refModule->GetModule();
2883 if (pModule->IsResource())
2886 return pModule->GetMDImport()->GetMetadataStreamVersion();
2890 void QCALLTYPE ModuleHandle::GetModuleType(QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retType)
2894 TypeHandle globalTypeHandle = TypeHandle();
2900 globalTypeHandle = TypeHandle(pModule->GetGlobalMethodTable());
2902 EX_SWALLOW_NONTRANSIENT;
2904 if (!globalTypeHandle.IsNull())
2907 retType.Set(globalTypeHandle.GetManagedClassObject());
2915 FCIMPL1(INT32, ModuleHandle::GetToken, ReflectModuleBaseObject * pModuleUNSAFE) {
2921 REFLECTMODULEBASEREF refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
2923 if (refModule == NULL)
2924 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2926 Module *pModule = refModule->GetModule();
2928 if (pModule->IsResource())
2931 return pModule->GetMDImport()->GetModuleFromScope();
2935 FCIMPL1(IMDInternalImport*, ModuleHandle::GetMetadataImport, ReflectModuleBaseObject * pModuleUNSAFE)
2939 REFLECTMODULEBASEREF refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
2941 if (refModule == NULL)
2942 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2944 Module *pModule = refModule->GetModule();
2946 if (pModule->IsResource())
2949 return pModule->GetMDImport();
2953 BOOL QCALLTYPE ModuleHandle::ContainsPropertyMatchingHash(QCall::ModuleHandle pModule, INT32 tkProperty, ULONG hash)
2957 BOOL fContains = TRUE;
2961 fContains = pModule->MightContainMatchingProperty(tkProperty, hash);
2968 void QCALLTYPE ModuleHandle::ResolveType(QCall::ModuleHandle pModule, INT32 tkType, TypeHandle *typeArgs, INT32 typeArgsCount, TypeHandle *methodArgs, INT32 methodArgsCount, QCall::ObjectHandleOnStack retType)
2972 TypeHandle typeHandle;
2976 _ASSERTE(!IsNilToken(tkType));
2978 SigTypeContext typeContext(Instantiation(typeArgs, typeArgsCount), Instantiation(methodArgs, methodArgsCount));
2979 typeHandle = ClassLoader::LoadTypeDefOrRefOrSpecThrowing(pModule, tkType, &typeContext,
2980 ClassLoader::ThrowIfNotFound,
2981 ClassLoader::PermitUninstDefOrRef);
2984 retType.Set(typeHandle.GetManagedClassObject());
2991 MethodDesc *QCALLTYPE ModuleHandle::ResolveMethod(QCall::ModuleHandle pModule, INT32 tkMemberRef, TypeHandle *typeArgs, INT32 typeArgsCount, TypeHandle *methodArgs, INT32 methodArgsCount)
2995 MethodDesc* pMD = NULL;
2999 _ASSERTE(!IsNilToken(tkMemberRef));
3001 BOOL strictMetadataChecks = (TypeFromToken(tkMemberRef) == mdtMethodSpec);
3003 SigTypeContext typeContext(Instantiation(typeArgs, typeArgsCount), Instantiation(methodArgs, methodArgsCount));
3004 pMD = MemberLoader::GetMethodDescFromMemberDefOrRefOrSpec(pModule, tkMemberRef, &typeContext, strictMetadataChecks, FALSE);
3006 // This will get us the instantiating or unboxing stub if needed
3007 pMD = MethodDesc::FindOrCreateAssociatedMethodDescForReflection(pMD, pMD->GetMethodTable(), pMD->GetMethodInstantiation());
3014 void QCALLTYPE ModuleHandle::ResolveField(QCall::ModuleHandle pModule, INT32 tkMemberRef, TypeHandle *typeArgs, INT32 typeArgsCount, TypeHandle *methodArgs, INT32 methodArgsCount, QCall::ObjectHandleOnStack retField)
3018 FieldDesc* pField = NULL;
3022 _ASSERTE(!IsNilToken(tkMemberRef));
3024 SigTypeContext typeContext(Instantiation(typeArgs, typeArgsCount), Instantiation(methodArgs, methodArgsCount));
3025 pField = MemberLoader::GetFieldDescFromMemberDefOrRef(pModule, tkMemberRef, &typeContext, FALSE);
3027 retField.Set(pField->GetStubFieldInfo());
3034 void QCALLTYPE ModuleHandle::GetAssembly(QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retAssembly)
3038 DomainAssembly *pAssembly = NULL;
3041 pAssembly = pModule->GetDomainAssembly();
3044 retAssembly.Set(pAssembly->GetExposedAssemblyObject());
3050 FCIMPL5(ReflectMethodObject*, ModuleHandle::GetDynamicMethod, ReflectMethodObject *pMethodUNSAFE, ReflectModuleBaseObject *pModuleUNSAFE, StringObject *name, U1Array *sig, Object *resolver) {
3053 PRECONDITION(CheckPointer(name));
3054 PRECONDITION(CheckPointer(sig));
3058 DynamicMethodDesc *pNewMD = NULL;
3063 OBJECTREF resolverRef;
3064 OBJECTREF methodRef;
3065 REFLECTMETHODREF retMethod;
3066 REFLECTMODULEBASEREF refModule;
3068 gc.nameRef = (STRINGREF)name;
3069 gc.resolverRef = (OBJECTREF)resolver;
3070 gc.methodRef = ObjectToOBJECTREF(pMethodUNSAFE);
3071 gc.retMethod = NULL;
3072 gc.refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
3074 if (gc.refModule == NULL)
3075 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
3077 Module *pModule = gc.refModule->GetModule();
3079 HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
3081 DomainFile *pDomainModule = pModule->GetDomainFile();
3083 U1ARRAYREF dataArray = (U1ARRAYREF)sig;
3084 DWORD sigSize = dataArray->GetNumComponents();
3085 NewHolder<BYTE> pSig(new BYTE[sigSize]);
3086 memcpy(pSig, dataArray->GetDataPtr(), sigSize);
3088 DWORD length = gc.nameRef->GetStringLength();
3089 NewArrayHolder<char> pName(new char[(length + 1) * 2]);
3091 length = WszWideCharToMultiByte(CP_UTF8, 0, gc.nameRef->GetBuffer(), length, pName, (length + 1) * 2 - sizeof(char), NULL, NULL);
3093 pName[length / sizeof(char)] = '\0';
3095 DynamicMethodTable *pMTForDynamicMethods = pDomainModule->GetDynamicMethodTable();
3096 pNewMD = pMTForDynamicMethods->GetDynamicMethod(pSig, sigSize, pName);
3097 _ASSERTE(pNewMD != NULL);
3098 // pNewMD now owns pSig and pName.
3099 pSig.SuppressRelease();
3100 pName.SuppressRelease();
3102 // create a handle to hold the resolver objectref
3103 OBJECTHANDLE resolverHandle = pDomainModule->GetAppDomain()->CreateLongWeakHandle(gc.resolverRef);
3104 pNewMD->GetLCGMethodResolver()->SetManagedResolver(resolverHandle);
3105 gc.retMethod = pNewMD->GetStubMethodInfo();
3106 gc.retMethod->SetKeepAlive(gc.resolverRef);
3108 LoaderAllocator *pLoaderAllocator = pModule->GetLoaderAllocator();
3110 if (pLoaderAllocator->IsCollectible())
3111 pLoaderAllocator->AddReference();
3113 HELPER_METHOD_FRAME_END();
3115 return (ReflectMethodObject*)OBJECTREFToObject(gc.retMethod);
3119 void QCALLTYPE RuntimeMethodHandle::GetCallerType(QCall::StackCrawlMarkHandle pStackMark, QCall::ObjectHandleOnStack retType)
3125 MethodTable *pMT = NULL;
3127 pMT = SystemDomain::GetCallersType(pStackMark);
3130 retType.Set(pMT->GetManagedClassObject());