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"
31 #include "eventtrace.h"
32 #include "invokeutil.h"
35 FCIMPL3(FC_BOOL_RET, Utf8String::EqualsCaseSensitive, LPCUTF8 szLhs, LPCUTF8 szRhs, INT32 stringNumBytes)
39 PRECONDITION(CheckPointer(szLhs));
40 PRECONDITION(CheckPointer(szRhs));
44 // Important: the string in pSsz isn't null terminated so the length must be used
45 // when performing operations on the string.
47 // At this point, both the left and right strings are guaranteed to have the
49 FC_RETURN_BOOL(strncmp(szLhs, szRhs, stringNumBytes) == 0);
53 BOOL QCALLTYPE Utf8String::EqualsCaseInsensitive(LPCUTF8 szLhs, LPCUTF8 szRhs, INT32 stringNumBytes)
57 // Important: the string in pSsz isn't null terminated so the length must be used
58 // when performing operations on the string.
60 BOOL fStringsEqual = FALSE;
64 _ASSERTE(CheckPointer(szLhs));
65 _ASSERTE(CheckPointer(szRhs));
67 // At this point, both the left and right strings are guaranteed to have the
69 StackSString lhs(SString::Utf8, szLhs, stringNumBytes);
70 StackSString rhs(SString::Utf8, szRhs, stringNumBytes);
72 // We can use SString for simple case insensitive compares
73 fStringsEqual = lhs.EqualsCaseInsensitive(rhs);
80 ULONG QCALLTYPE Utf8String::HashCaseInsensitive(LPCUTF8 sz, INT32 stringNumBytes)
84 // Important: the string in pSsz isn't null terminated so the length must be used
85 // when performing operations on the string.
91 StackSString str(SString::Utf8, sz, stringNumBytes);
92 hashValue = str.HashCaseInsensitive();
99 static BOOL CheckCAVisibilityFromDecoratedType(MethodTable* pCAMT, MethodDesc* pCACtor, MethodTable* pDecoratedMT, Module* pDecoratedModule)
106 PRECONDITION(CheckPointer(pCAMT));
107 PRECONDITION(CheckPointer(pCACtor, NULL_OK));
108 PRECONDITION(CheckPointer(pDecoratedMT, NULL_OK));
109 PRECONDITION(CheckPointer(pDecoratedModule));
113 DWORD dwAttr = mdPublic;
117 // Allowing a dangerous method to be called in custom attribute instantiation is, well, dangerous.
118 // E.g. a malicious user can craft a custom attribute record that fools us into creating a DynamicMethod
119 // object attached to typeof(System.Reflection.CustomAttribute) and thus gain access to mscorlib internals.
120 if (InvokeUtil::IsDangerousMethod(pCACtor))
123 _ASSERTE(pCACtor->IsCtor());
125 dwAttr = pCACtor->GetAttrs();
128 StaticAccessCheckContext accessContext(NULL, pDecoratedMT, pDecoratedModule->GetAssembly());
130 return ClassLoader::CanAccess(
133 pCAMT->GetAssembly(),
137 *AccessCheckOptions::s_pNormalAccessChecks);
140 BOOL QCALLTYPE RuntimeMethodHandle::IsCAVisibleFromDecoratedType(
141 EnregisteredTypeHandle targetTypeHandle,
142 MethodDesc * pTargetCtor,
143 EnregisteredTypeHandle sourceTypeHandle,
144 QCall::ModuleHandle sourceModuleHandle)
151 TypeHandle sourceHandle = TypeHandle::FromPtr(sourceTypeHandle);
152 TypeHandle targetHandle = TypeHandle::FromPtr(targetTypeHandle);
154 _ASSERTE((sourceHandle.IsNull() || !sourceHandle.IsTypeDesc()) &&
155 !targetHandle.IsNull() &&
156 !targetHandle.IsTypeDesc());
158 if (sourceHandle.IsTypeDesc() ||
159 targetHandle.IsNull() ||
160 targetHandle.IsTypeDesc())
161 COMPlusThrowArgumentNull(NULL, W("Arg_InvalidHandle"));
163 bResult = CheckCAVisibilityFromDecoratedType(targetHandle.AsMethodTable(), pTargetCtor, sourceHandle.AsMethodTable(), sourceModuleHandle);
170 NOINLINE static ReflectClassBaseObject* GetRuntimeTypeHelper(LPVOID __me, TypeHandle typeHandle, OBJECTREF keepAlive)
172 FC_INNER_PROLOG_NO_ME_SETUP();
173 if (typeHandle.AsPtr() == NULL)
176 // RuntimeTypeHandle::GetRuntimeType has picked off the most common case, but does not cover array types.
177 // Before we do the really heavy weight option of setting up a helper method frame, check if we have to.
178 OBJECTREF refType = typeHandle.GetManagedClassObjectFast();
180 return (ReflectClassBaseObject*)OBJECTREFToObject(refType);
182 HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_1(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, keepAlive);
183 refType = typeHandle.GetManagedClassObject();
184 HELPER_METHOD_FRAME_END();
187 return (ReflectClassBaseObject*)OBJECTREFToObject(refType);
190 #define RETURN_CLASS_OBJECT(typeHandle, keepAlive) FC_INNER_RETURN(ReflectClassBaseObject*, GetRuntimeTypeHelper(__me, typeHandle, keepAlive))
192 NOINLINE ReflectModuleBaseObject* GetRuntimeModuleHelper(LPVOID __me, Module *pModule, OBJECTREF keepAlive)
194 FC_INNER_PROLOG_NO_ME_SETUP();
198 DomainFile * pDomainFile = pModule->FindDomainFile(GetAppDomain());
200 OBJECTREF refModule = (pDomainFile != NULL) ? pDomainFile->GetExposedModuleObjectIfExists() : NULL;
202 if(refModule != NULL)
203 return (ReflectModuleBaseObject*)OBJECTREFToObject(refModule);
205 HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_1(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, keepAlive);
206 refModule = pModule->GetExposedObject();
207 HELPER_METHOD_FRAME_END();
210 return (ReflectModuleBaseObject*)OBJECTREFToObject(refModule);
213 NOINLINE AssemblyBaseObject* GetRuntimeAssemblyHelper(LPVOID __me, DomainAssembly *pAssembly, OBJECTREF keepAlive)
215 FC_INNER_PROLOG_NO_ME_SETUP();
216 if (pAssembly == NULL)
219 OBJECTREF refAssembly = (pAssembly != NULL) ? pAssembly->GetExposedAssemblyObjectIfExists() : NULL;
221 if(refAssembly != NULL)
222 return (AssemblyBaseObject*)OBJECTREFToObject(refAssembly);
224 HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_1(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, keepAlive);
225 refAssembly = pAssembly->GetExposedAssemblyObject();
226 HELPER_METHOD_FRAME_END();
229 return (AssemblyBaseObject*)OBJECTREFToObject(refAssembly);
233 // This is the routine that is called by the 'typeof()' operator in C#. It is one of the most commonly used
234 // reflection operations. This call should be optimized away in nearly all situations
235 FCIMPL1_V(ReflectClassBaseObject*, RuntimeTypeHandle::GetTypeFromHandle, FCALLRuntimeTypeHandle th)
240 return FCALL_RTH_TO_REFLECTCLASS(th);
244 FCIMPL1(ReflectClassBaseObject*, RuntimeTypeHandle::GetRuntimeType, EnregisteredTypeHandle th)
248 TypeHandle typeHandle = TypeHandle::FromPtr(th);
249 _ASSERTE(CheckPointer(typeHandle.AsPtr(), NULL_OK));
250 if (typeHandle.AsPtr()!= NULL)
252 if (!typeHandle.IsTypeDesc())
254 OBJECTREF typePtr = typeHandle.AsMethodTable()->GetManagedClassObjectIfExists();
257 return (ReflectClassBaseObject*)OBJECTREFToObject(typePtr);
264 RETURN_CLASS_OBJECT(typeHandle, NULL);
268 FCIMPL1_V(EnregisteredTypeHandle, RuntimeTypeHandle::GetValueInternal, FCALLRuntimeTypeHandle RTH)
272 if (FCALL_RTH_TO_REFLECTCLASS(RTH) == NULL)
275 return FCALL_RTH_TO_REFLECTCLASS(RTH) ->GetType().AsPtr();
279 // TypeEqualsHelper and TypeNotEqualsHelper are almost identical.
280 // Unfortunately we cannot combime them because they need to hardcode the caller's name
281 NOINLINE static BOOL TypeEqualSlow(OBJECTREF refL, OBJECTREF refR, LPVOID __me)
285 FC_INNER_PROLOG_NO_ME_SETUP();
287 _ASSERTE(refL != NULL && refR != NULL);
289 HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_2(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, refL, refR);
291 MethodDescCallSite TypeEqualsMethod(METHOD__OBJECT__EQUALS, &refL);
299 ret = TypeEqualsMethod.Call_RetBool(args);
301 HELPER_METHOD_FRAME_END();
310 #include <optsmallperfcritical.h>
312 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::TypeEQ, Object* left, Object* right)
316 OBJECTREF refL = (OBJECTREF)left;
317 OBJECTREF refR = (OBJECTREF)right;
321 FC_RETURN_BOOL(TRUE);
326 FC_RETURN_BOOL(FALSE);
329 if ((refL->GetMethodTable() == g_pRuntimeTypeClass || refR->GetMethodTable() == g_pRuntimeTypeClass))
331 // Quick path for negative common case
332 FC_RETURN_BOOL(FALSE);
335 // The fast path didn't get us the result
336 // Let's try the slow path: refL.Equals(refR);
337 FC_INNER_RETURN(FC_BOOL_RET, (FC_BOOL_RET)(!!TypeEqualSlow(refL, refR, __me)));
341 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::TypeNEQ, Object* left, Object* right)
345 OBJECTREF refL = (OBJECTREF)left;
346 OBJECTREF refR = (OBJECTREF)right;
350 FC_RETURN_BOOL(FALSE);
355 FC_RETURN_BOOL(TRUE);
358 if ((refL->GetMethodTable() == g_pRuntimeTypeClass || refR->GetMethodTable() == g_pRuntimeTypeClass))
360 // Quick path for negative common case
361 FC_RETURN_BOOL(TRUE);
364 // The fast path didn't get us the result
365 // Let's try the slow path: refL.Equals(refR);
366 FC_INNER_RETURN(FC_BOOL_RET, (FC_BOOL_RET)(!TypeEqualSlow(refL, refR, __me)));
370 #include <optdefault.h>
375 #ifdef FEATURE_COMINTEROP
376 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsWindowsRuntimeObjectType, ReflectClassBaseObject *rtTypeUNSAFE)
380 BOOL isWindowsRuntimeType = FALSE;
382 TypeHandle typeHandle = rtTypeUNSAFE->GetType();
383 MethodTable *pMT = typeHandle.GetMethodTable();
387 isWindowsRuntimeType = pMT->IsWinRTObjectType();
390 FC_RETURN_BOOL(isWindowsRuntimeType);
394 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsTypeExportedToWindowsRuntime, ReflectClassBaseObject *rtTypeUNSAFE)
398 BOOL isExportedToWinRT = FALSE;
400 TypeHandle typeHandle = rtTypeUNSAFE->GetType();
401 MethodTable *pMT = typeHandle.GetMethodTable();
405 isExportedToWinRT = pMT->IsExportedToWinRT();
408 FC_RETURN_BOOL(isExportedToWinRT);
411 #endif // FEATURE_COMINTEROP
413 NOINLINE static MethodDesc * RestoreMethodHelper(MethodDesc * pMethod, LPVOID __me)
415 FC_INNER_PROLOG_NO_ME_SETUP();
417 HELPER_METHOD_FRAME_BEGIN_RET_0();
418 pMethod->CheckRestore();
419 HELPER_METHOD_FRAME_END();
426 FCIMPL1(MethodDesc *, RuntimeTypeHandle::GetFirstIntroducedMethod, ReflectClassBaseObject *pTypeUNSAFE) {
429 PRECONDITION(CheckPointer(pTypeUNSAFE));
433 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
434 TypeHandle typeHandle = refType->GetType();
436 if (typeHandle.IsGenericVariable())
437 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
439 if (typeHandle.IsTypeDesc()) {
440 if (!typeHandle.IsArray())
444 MethodTable* pMT = typeHandle.GetMethodTable();
448 MethodDesc* pMethod = MethodTable::IntroducedMethodIterator::GetFirst(pMT);
450 // The only method that can show up here unrestored is instantiated methods. Check for it before performing the expensive IsRestored() check.
451 if (pMethod != NULL && pMethod->GetClassification() == mcInstantiated && !pMethod->IsRestored()) {
452 FC_INNER_RETURN(MethodDesc *, RestoreMethodHelper(pMethod, __me));
455 _ASSERTE(pMethod == NULL || pMethod->IsRestored());
460 #include <optsmallperfcritical.h>
461 FCIMPL1(void, RuntimeTypeHandle::GetNextIntroducedMethod, MethodDesc ** ppMethod) {
464 PRECONDITION(CheckPointer(ppMethod));
465 PRECONDITION(CheckPointer(*ppMethod));
469 MethodDesc *pMethod = MethodTable::IntroducedMethodIterator::GetNext(*ppMethod);
473 if (pMethod != NULL && pMethod->GetClassification() == mcInstantiated && !pMethod->IsRestored()) {
474 FC_INNER_RETURN_VOID(RestoreMethodHelper(pMethod, __me));
477 _ASSERTE(pMethod == NULL || pMethod->IsRestored());
480 #include <optdefault.h>
482 FCIMPL1(INT32, RuntimeTypeHandle::GetCorElementType, ReflectClassBaseObject *pTypeUNSAFE) {
488 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
491 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
493 return refType->GetType().GetSignatureCorElementType();
497 FCIMPL1(AssemblyBaseObject*, RuntimeTypeHandle::GetAssembly, ReflectClassBaseObject *pTypeUNSAFE) {
503 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
506 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
508 DomainFile *pDomainFile = NULL;
510 Module *pModule = refType->GetType().GetAssembly()->GetManifestModule();
512 pDomainFile = pModule->FindDomainFile(GetAppDomain());
513 #ifdef FEATURE_LOADER_OPTIMIZATION
514 if (pDomainFile == NULL)
516 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
518 pDomainFile = GetAppDomain()->LoadDomainNeutralModuleDependency(pModule, FILE_LOADED);
520 HELPER_METHOD_FRAME_END();
522 #endif // FEATURE_LOADER_OPTIMIZATION
525 FC_RETURN_ASSEMBLY_OBJECT((DomainAssembly *)pDomainFile, refType);
530 FCIMPL1(FC_BOOL_RET, RuntimeFieldHandle::AcquiresContextFromThis, FieldDesc *pField)
534 PRECONDITION(CheckPointer(pField));
538 FC_RETURN_BOOL(pField->IsSharedByGenericInstantiations());
543 FCIMPL1(ReflectModuleBaseObject*, RuntimeTypeHandle::GetModule, ReflectClassBaseObject *pTypeUNSAFE) {
551 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
554 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
556 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
558 result = refType->GetType().GetModule();
560 END_SO_INTOLERANT_CODE;
562 FC_RETURN_MODULE_OBJECT(result, refType);
566 FCIMPL1(ReflectClassBaseObject *, RuntimeTypeHandle::GetBaseType, ReflectClassBaseObject *pTypeUNSAFE) {
572 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
575 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
577 TypeHandle typeHandle = refType->GetType();
579 if (typeHandle.IsGenericVariable())
580 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
582 if (typeHandle.IsTypeDesc()) {
583 if (!typeHandle.IsArray())
587 RETURN_CLASS_OBJECT(typeHandle.GetParent(), refType);
591 FCIMPL1(ReflectClassBaseObject *, RuntimeTypeHandle::GetElementType, ReflectClassBaseObject *pTypeUNSAFE) {
597 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
600 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
602 TypeHandle typeHandle = refType->GetType();
604 if (!typeHandle.IsTypeDesc())
607 if (typeHandle.IsGenericVariable())
610 TypeHandle typeReturn;
612 if (typeHandle.IsArray())
613 typeReturn = typeHandle.AsArray()->GetArrayElementTypeHandle();
615 typeReturn = typeHandle.AsTypeDesc()->GetTypeParam();
617 RETURN_CLASS_OBJECT(typeReturn, refType);
621 FCIMPL1(INT32, RuntimeTypeHandle::GetArrayRank, ReflectClassBaseObject *pTypeUNSAFE) {
624 PRECONDITION(CheckPointer(pTypeUNSAFE));
625 PRECONDITION(pTypeUNSAFE->GetType().IsArray());
629 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
631 return (INT32)refType->GetType().AsArray()->GetRank();
635 FCIMPL1(INT32, RuntimeTypeHandle::GetNumVirtuals, ReflectClassBaseObject *pTypeUNSAFE) {
641 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
644 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
646 TypeHandle typeHandle = refType->GetType();
648 if (typeHandle.IsGenericVariable())
649 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
651 MethodTable *pMT = typeHandle.GetMethodTable();
654 return (INT32)pMT->GetNumVirtuals();
656 return 0; //REVIEW: should this return the number of methods in Object?
660 FCIMPL2(MethodDesc *, RuntimeTypeHandle::GetMethodAt, ReflectClassBaseObject *pTypeUNSAFE, INT32 slot) {
666 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
669 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
671 TypeHandle typeHandle = refType->GetType();
673 MethodDesc* pRetMethod = NULL;
675 if (typeHandle.IsGenericVariable())
676 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
678 if (slot < 0 || slot >= (INT32)typeHandle.GetMethodTable()->GetNumVirtuals())
679 FCThrowRes(kArgumentException, W("Arg_ArgumentOutOfRangeException"));
681 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
682 pRetMethod = typeHandle.GetMethodTable()->GetMethodDescForSlot((DWORD)slot);
683 HELPER_METHOD_FRAME_END();
690 FCIMPL3(FC_BOOL_RET, RuntimeTypeHandle::GetFields, ReflectClassBaseObject *pTypeUNSAFE, INT32 **result, INT32 *pCount) {
696 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
698 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
700 TypeHandle typeHandle = refType->GetType();
702 if (!pCount || !result)
703 FCThrow(kArgumentNullException);
705 if (typeHandle.IsGenericVariable())
706 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
708 if (typeHandle.IsTypeDesc()) {
710 FC_RETURN_BOOL(TRUE);
713 MethodTable *pMT= typeHandle.GetMethodTable();
715 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
718 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
719 // <TODO>Check this approximation - we may be losing exact type information </TODO>
720 ApproxFieldDescIterator fdIterator(pMT, ApproxFieldDescIterator::ALL_FIELDS);
721 INT32 count = (INT32)fdIterator.Count();
729 for(INT32 i = 0; i < count; i ++)
730 result[i] = (INT32*)fdIterator.Next();
735 HELPER_METHOD_FRAME_END();
736 FC_RETURN_BOOL(retVal);
740 void QCALLTYPE RuntimeMethodHandle::ConstructInstantiation(MethodDesc * pMethod, DWORD format, QCall::StringHandleOnStack retString)
747 TypeString::AppendInst(ss, pMethod->LoadMethodInstantiation(), format);
753 void QCALLTYPE RuntimeTypeHandle::ConstructName(EnregisteredTypeHandle pTypeHandle, DWORD format, QCall::StringHandleOnStack retString)
760 TypeString::AppendType(ss, TypeHandle::FromPtr(pTypeHandle), format);
766 PTRARRAYREF CopyRuntimeTypeHandles(TypeHandle * prgTH, FixupPointer<TypeHandle> * prgTH2, INT32 numTypeHandles, BinderClassID arrayElemType)
775 PTRARRAYREF refReturn = NULL;
776 PTRARRAYREF refArray = NULL;
778 if (numTypeHandles == 0)
781 _ASSERTE((prgTH != NULL) || (prgTH2 != NULL));
784 _ASSERTE(prgTH2 == NULL);
787 GCPROTECT_BEGIN(refArray);
788 TypeHandle thRuntimeType = TypeHandle(MscorlibBinder::GetClass(arrayElemType));
789 TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(thRuntimeType, ELEMENT_TYPE_SZARRAY);
790 refArray = (PTRARRAYREF)AllocateArrayEx(arrayHandle, &numTypeHandles, 1);
792 for (INT32 i = 0; i < numTypeHandles; i++)
799 th = prgTH2[i].GetValue();
801 OBJECTREF refType = th.GetManagedClassObject();
802 refArray->SetAt(i, refType);
805 refReturn = refArray;
811 void QCALLTYPE RuntimeTypeHandle::GetConstraints(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retTypeArray)
815 TypeHandle* constraints = NULL;
819 TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
821 if (!typeHandle.IsGenericVariable())
822 COMPlusThrow(kArgumentException, W("Arg_InvalidHandle"));
824 TypeVarTypeDesc* pGenericVariable = typeHandle.AsGenericVariable();
827 constraints = pGenericVariable->GetConstraints(&dwCount);
830 retTypeArray.Set(CopyRuntimeTypeHandles(constraints, NULL, dwCount, CLASS__TYPE));
837 FCIMPL1(PtrArray*, RuntimeTypeHandle::GetInterfaces, ReflectClassBaseObject *pTypeUNSAFE) {
843 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
846 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
848 TypeHandle typeHandle = refType->GetType();
850 if (typeHandle.IsGenericVariable())
851 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
853 INT32 ifaceCount = 0;
855 PTRARRAYREF refRetVal = NULL;
856 HELPER_METHOD_FRAME_BEGIN_RET_2(refRetVal, refType);
858 if (typeHandle.IsTypeDesc())
860 if (typeHandle.IsArray())
862 ifaceCount = typeHandle.GetMethodTable()->GetNumInterfaces();
871 ifaceCount = typeHandle.GetMethodTable()->GetNumInterfaces();
874 // Allocate the array
877 TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(g_pRuntimeTypeClass), ELEMENT_TYPE_SZARRAY);
878 refRetVal = (PTRARRAYREF)AllocateArrayEx(arrayHandle, &ifaceCount, 1);
880 // populate type array
883 MethodTable::InterfaceMapIterator it = typeHandle.GetMethodTable()->IterateInterfaceMap();
886 OBJECTREF refInterface = it.GetInterface()->GetManagedClassObject();
887 refRetVal->SetAt(i, refInterface);
888 _ASSERTE(refRetVal->GetAt(i) != NULL);
893 HELPER_METHOD_FRAME_END();
895 return (PtrArray*)OBJECTREFToObject(refRetVal);
899 FCIMPL1(INT32, RuntimeTypeHandle::GetAttributes, ReflectClassBaseObject *pTypeUNSAFE) {
905 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
908 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
910 TypeHandle typeHandle = refType->GetType();
912 if (typeHandle.IsTypeDesc()) {
914 if (typeHandle.IsGenericVariable()) {
918 if (!typeHandle.IsArray())
922 #ifdef FEATURE_COMINTEROP
923 // __ComObject types are always public.
924 if (IsComObjectClass(typeHandle))
925 return (typeHandle.GetMethodTable()->GetAttrClass() & tdVisibilityMask) | tdPublic;
926 #endif // FEATURE_COMINTEROP
930 ret = (INT32)typeHandle.GetMethodTable()->GetAttrClass();
936 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsValueType, ReflectClassBaseObject *pTypeUNSAFE)
943 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
945 _ASSERTE(refType != NULL);
947 TypeHandle typeHandle = refType->GetType();
949 FC_RETURN_BOOL(typeHandle.IsValueType());
953 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsInterface, ReflectClassBaseObject *pTypeUNSAFE)
960 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
962 _ASSERTE(refType != NULL);
964 TypeHandle typeHandle = refType->GetType();
966 FC_RETURN_BOOL(typeHandle.IsInterface());
971 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsByRefLike, ReflectClassBaseObject *pTypeUNSAFE)
978 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
980 _ASSERTE(refType != NULL);
982 TypeHandle typeHandle = refType->GetType();
984 FC_RETURN_BOOL(typeHandle.IsByRefLike());
990 RuntimeTypeHandle::IsVisible(
991 EnregisteredTypeHandle pTypeHandle)
999 BOOL fIsExternallyVisible = FALSE;
1003 TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
1005 _ASSERTE(!typeHandle.IsNull());
1007 fIsExternallyVisible = typeHandle.IsExternallyVisible();
1011 return fIsExternallyVisible;
1012 } // RuntimeTypeHandle::IsVisible
1014 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::IsComObject, ReflectClassBaseObject *pTypeUNSAFE, CLR_BOOL isGenericCOM) {
1015 #ifdef FEATURE_COMINTEROP
1023 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1025 if (refType == NULL)
1026 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1028 TypeHandle typeHandle = refType->GetType();
1030 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
1033 ret = IsComObjectClass(typeHandle);
1035 ret = IsComWrapperClass(typeHandle);
1037 HELPER_METHOD_FRAME_END();
1039 FC_RETURN_BOOL(ret);
1045 PRECONDITION(CheckPointer(pTypeUNSAFE));
1049 FC_RETURN_BOOL(FALSE);
1054 FCIMPL1(LPCUTF8, RuntimeTypeHandle::GetUtf8Name, ReflectClassBaseObject* pTypeUNSAFE) {
1060 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1062 if (refType == NULL)
1063 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1065 TypeHandle typeHandle = refType->GetType();
1066 INT32 tkTypeDef = mdTypeDefNil;
1067 LPCUTF8 szName = NULL;
1069 if (typeHandle.IsGenericVariable())
1070 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1072 if (typeHandle.IsTypeDesc())
1073 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1075 MethodTable* pMT= typeHandle.GetMethodTable();
1078 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1080 tkTypeDef = (INT32)pMT->GetCl();
1082 if (IsNilToken(tkTypeDef))
1083 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1085 if (FAILED(pMT->GetMDImport()->GetNameOfTypeDef(tkTypeDef, &szName, NULL)))
1087 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1090 _ASSERTE(CheckPointer(szName, NULL_OK));
1096 FCIMPL1(INT32, RuntimeTypeHandle::GetToken, ReflectClassBaseObject *pTypeUNSAFE) {
1102 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1104 if (refType == NULL)
1105 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1107 TypeHandle typeHandle = refType->GetType();
1109 if (typeHandle.IsTypeDesc())
1111 if (typeHandle.IsGenericVariable())
1113 INT32 tkTypeDef = typeHandle.AsGenericVariable()->GetToken();
1115 _ASSERTE(!IsNilToken(tkTypeDef) && TypeFromToken(tkTypeDef) == mdtGenericParam);
1120 return mdTypeDefNil;
1123 return (INT32)typeHandle.AsMethodTable()->GetCl();
1127 PVOID QCALLTYPE RuntimeTypeHandle::GetGCHandle(EnregisteredTypeHandle pTypeHandle, INT32 handleType)
1131 OBJECTHANDLE objHandle = NULL;
1137 TypeHandle th = TypeHandle::FromPtr(pTypeHandle);
1138 assert(handleType >= HNDTYPE_WEAK_SHORT && handleType <= HNDTYPE_WEAK_WINRT);
1139 objHandle = th.GetDomain()->CreateTypedHandle(NULL, static_cast<HandleType>(handleType));
1140 th.GetLoaderAllocator()->RegisterHandleForCleanup(objHandle);
1147 void QCALLTYPE RuntimeTypeHandle::VerifyInterfaceIsImplemented(EnregisteredTypeHandle pTypeHandle, EnregisteredTypeHandle pIFaceHandle)
1153 TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
1154 TypeHandle ifaceHandle = TypeHandle::FromPtr(pIFaceHandle);
1156 if (typeHandle.IsGenericVariable())
1157 COMPlusThrow(kArgumentException, W("Arg_InvalidHandle"));
1159 if (typeHandle.IsTypeDesc()) {
1160 if (!typeHandle.IsArray())
1161 COMPlusThrow(kArgumentException, W("Arg_NotFoundIFace"));
1164 if (typeHandle.IsInterface())
1165 COMPlusThrow(kArgumentException, W("Argument_InterfaceMap"));
1167 if (!ifaceHandle.IsInterface())
1168 COMPlusThrow(kArgumentException, W("Arg_MustBeInterface"));
1170 // First try the cheap check, which amounts to iterating the interface map looking for
1171 // the ifaceHandle MethodTable.
1172 if (!typeHandle.GetMethodTable()->ImplementsInterface(ifaceHandle.AsMethodTable()))
1173 { // If the cheap check fails, try the more expensive but complete check.
1174 if (!typeHandle.CanCastTo(ifaceHandle))
1175 { // If the complete check fails, we're certain that this type
1176 // does not implement the interface specified.
1177 COMPlusThrow(kArgumentException, W("Arg_NotFoundIFace"));
1184 INT32 QCALLTYPE RuntimeTypeHandle::GetInterfaceMethodImplementationSlot(EnregisteredTypeHandle pTypeHandle, EnregisteredTypeHandle pOwner, MethodDesc * pMD)
1188 INT32 slotNumber = -1;
1192 TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
1193 TypeHandle thOwnerOfMD = TypeHandle::FromPtr(pOwner);
1195 // Ok to have INVALID_SLOT in the case where abstract class does not implement an interface method.
1196 // This case can not be reproed using C# "implements" all interface methods
1197 // with at least an abstract method. b19897_GetInterfaceMap_Abstract.exe tests this case.
1198 //@TODO:STUBDISPATCH: Don't need to track down the implementation, just the declaration, and this can
1199 //@TODO: be done faster - just need to make a function FindDispatchDecl.
1200 DispatchSlot slot(typeHandle.GetMethodTable()->FindDispatchSlotForInterfaceMD(thOwnerOfMD, pMD));
1202 slotNumber = slot.GetMethodDesc()->GetSlot();
1209 void QCALLTYPE RuntimeTypeHandle::GetDefaultConstructor(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retMethod)
1215 MethodDesc* pCtor = NULL;
1217 TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
1219 if (!typeHandle.IsTypeDesc())
1221 MethodTable* pMethodTable = typeHandle.AsMethodTable();
1222 if (pMethodTable->HasDefaultConstructor())
1223 pCtor = pMethodTable->GetDefaultConstructor();
1229 retMethod.Set(pCtor->GetStubMethodInfo());
1236 FCIMPL1(ReflectMethodObject*, RuntimeTypeHandle::GetDeclaringMethod, ReflectClassBaseObject *pTypeUNSAFE) {
1242 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1244 if (refType == NULL)
1245 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1247 TypeHandle typeHandle = refType->GetType();;
1249 if (!typeHandle.IsTypeDesc())
1252 TypeVarTypeDesc* pGenericVariable = typeHandle.AsGenericVariable();
1253 mdToken defToken = pGenericVariable->GetTypeOrMethodDef();
1254 if (TypeFromToken(defToken) != mdtMethodDef)
1257 REFLECTMETHODREF pRet = NULL;
1258 HELPER_METHOD_FRAME_BEGIN_RET_0();
1259 MethodDesc * pMD = pGenericVariable->LoadOwnerMethod();
1260 pMD->CheckRestore();
1261 pRet = pMD->GetStubMethodInfo();
1262 HELPER_METHOD_FRAME_END();
1264 return (ReflectMethodObject*)OBJECTREFToObject(pRet);
1268 FCIMPL1(ReflectClassBaseObject*, RuntimeTypeHandle::GetDeclaringType, ReflectClassBaseObject *pTypeUNSAFE) {
1274 TypeHandle retTypeHandle;
1276 BOOL fThrowException = FALSE;
1277 LPCWSTR argName = W("Arg_InvalidHandle");
1278 RuntimeExceptionKind reKind = kArgumentNullException;
1280 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1282 if (refType == NULL)
1283 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1285 TypeHandle typeHandle = refType->GetType();
1287 MethodTable* pMT = NULL;
1288 mdTypeDef tkTypeDef = mdTokenNil;
1290 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
1291 if (typeHandle.IsTypeDesc()) {
1293 if (typeHandle.IsGenericVariable()) {
1294 TypeVarTypeDesc* pGenericVariable = typeHandle.AsGenericVariable();
1295 mdToken defToken = pGenericVariable->GetTypeOrMethodDef();
1297 // Try the fast way first (if the declaring type has been loaded already).
1298 if (TypeFromToken(defToken) == mdtMethodDef)
1300 MethodDesc * retMethod = pGenericVariable->GetModule()->LookupMethodDef(defToken);
1301 if (retMethod != NULL)
1302 retTypeHandle = retMethod->GetMethodTable();
1306 retTypeHandle = pGenericVariable->GetModule()->LookupTypeDef(defToken);
1309 if (!retTypeHandle.IsNull() && retTypeHandle.IsFullyLoaded())
1312 // OK, need to go the slow way and load the type first.
1313 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
1315 if (TypeFromToken(defToken) == mdtMethodDef)
1317 retTypeHandle = pGenericVariable->LoadOwnerMethod()->GetMethodTable();
1321 retTypeHandle = pGenericVariable->LoadOwnerType();
1323 retTypeHandle.CheckRestore();
1325 HELPER_METHOD_FRAME_END();
1328 if (!typeHandle.IsArray())
1330 retTypeHandle = TypeHandle();
1335 pMT = typeHandle.GetMethodTable();
1339 fThrowException = TRUE;
1343 if(!pMT->GetClass()->IsNested())
1345 retTypeHandle = TypeHandle();
1349 tkTypeDef = pMT->GetCl();
1351 if (FAILED(typeHandle.GetModule()->GetMDImport()->GetNestedClassProps(tkTypeDef, &tkTypeDef)))
1353 fThrowException = TRUE;
1354 reKind = kBadImageFormatException;
1359 // Try the fast way first (if the declaring type has been loaded already).
1360 retTypeHandle = typeHandle.GetModule()->LookupTypeDef(tkTypeDef);
1361 if (retTypeHandle.IsNull())
1363 // OK, need to go the slow way and load the type first.
1364 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
1366 retTypeHandle = ClassLoader::LoadTypeDefThrowing(typeHandle.GetModule(), tkTypeDef,
1367 ClassLoader::ThrowIfNotFound,
1368 ClassLoader::PermitUninstDefOrRef);
1370 HELPER_METHOD_FRAME_END();
1374 END_SO_INTOLERANT_CODE;
1376 if (fThrowException)
1378 FCThrowRes(reKind, argName);
1381 RETURN_CLASS_OBJECT(retTypeHandle, refType);
1385 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::CanCastTo, ReflectClassBaseObject *pTypeUNSAFE, ReflectClassBaseObject *pTargetUNSAFE) {
1392 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1393 REFLECTCLASSBASEREF refTarget = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTargetUNSAFE);
1395 if ((refType == NULL) || (refTarget == NULL))
1396 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1398 TypeHandle fromHandle = refType->GetType();
1399 TypeHandle toHandle = refTarget->GetType();
1403 TypeHandle::CastResult r = fromHandle.CanCastToNoGC(toHandle);
1404 if (r == TypeHandle::MaybeCast)
1406 HELPER_METHOD_FRAME_BEGIN_RET_2(refType, refTarget);
1407 iRetVal = fromHandle.CanCastTo(toHandle);
1408 HELPER_METHOD_FRAME_END();
1412 iRetVal = (r == TypeHandle::CanCast);
1415 // We allow T to be cast to Nullable<T>
1416 if (!iRetVal && Nullable::IsNullableType(toHandle) && !fromHandle.IsTypeDesc())
1418 HELPER_METHOD_FRAME_BEGIN_RET_2(refType, refTarget);
1419 if (Nullable::IsNullableForType(toHandle, fromHandle.AsMethodTable()))
1423 HELPER_METHOD_FRAME_END();
1426 FC_RETURN_BOOL(iRetVal);
1430 void QCALLTYPE RuntimeTypeHandle::GetTypeByNameUsingCARules(LPCWSTR pwzClassName, QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retType)
1434 TypeHandle typeHandle;
1439 COMPlusThrowArgumentNull(W("className"),W("ArgumentNull_String"));
1441 typeHandle = TypeName::GetTypeUsingCASearchRules(pwzClassName, pModule->GetAssembly());
1444 retType.Set(typeHandle.GetManagedClassObject());
1451 void QCALLTYPE RuntimeTypeHandle::GetTypeByName(LPCWSTR pwzClassName, BOOL bThrowOnError, BOOL bIgnoreCase, BOOL bReflectionOnly,
1452 QCall::StackCrawlMarkHandle pStackMark,
1453 ICLRPrivBinder * pPrivHostBinder,
1454 BOOL bLoadTypeFromPartialNameHack, QCall::ObjectHandleOnStack retType,
1455 QCall::ObjectHandleOnStack keepAlive)
1459 TypeHandle typeHandle;
1464 COMPlusThrowArgumentNull(W("className"),W("ArgumentNull_String"));
1467 typeHandle = TypeName::GetTypeManaged(pwzClassName, NULL, bThrowOnError, bIgnoreCase, bReflectionOnly, /*bProhibitAsmQualifiedName =*/ FALSE, pStackMark,
1468 bLoadTypeFromPartialNameHack, (OBJECTREF*)keepAlive.m_ppObject,
1472 if (!typeHandle.IsNull())
1475 retType.Set(typeHandle.GetManagedClassObject());
1483 FCIMPL6(FC_BOOL_RET, RuntimeTypeHandle::SatisfiesConstraints, PTR_ReflectClassBaseObject pParamTypeUNSAFE, TypeHandle *typeContextArgs, INT32 typeContextCount, TypeHandle *methodContextArgs, INT32 methodContextCount, PTR_ReflectClassBaseObject pArgumentTypeUNSAFE);
1487 PRECONDITION(CheckPointer(typeContextArgs, NULL_OK));
1488 PRECONDITION(CheckPointer(methodContextArgs, NULL_OK));
1492 REFLECTCLASSBASEREF refParamType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pParamTypeUNSAFE);
1493 REFLECTCLASSBASEREF refArgumentType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pArgumentTypeUNSAFE);
1495 TypeHandle thGenericParameter = refParamType->GetType();
1496 TypeHandle thGenericArgument = refArgumentType->GetType();
1497 BOOL bResult = FALSE;
1498 SigTypeContext typeContext;
1500 Instantiation classInst;
1501 Instantiation methodInst;
1503 if (typeContextArgs != NULL)
1505 classInst = Instantiation(typeContextArgs, typeContextCount);
1508 if (methodContextArgs != NULL)
1510 methodInst = Instantiation(methodContextArgs, methodContextCount);
1513 SigTypeContext::InitTypeContext(classInst, methodInst, &typeContext);
1515 HELPER_METHOD_FRAME_BEGIN_RET_2(refParamType, refArgumentType);
1517 bResult = thGenericParameter.AsGenericVariable()->SatisfiesConstraints(&typeContext, thGenericArgument);
1519 HELPER_METHOD_FRAME_END();
1521 FC_RETURN_BOOL(bResult);
1525 void QCALLTYPE RuntimeTypeHandle::GetInstantiation(EnregisteredTypeHandle pType, QCall::ObjectHandleOnStack retTypes, BOOL fAsRuntimeTypeArray)
1531 TypeHandle typeHandle = TypeHandle::FromPtr(pType);
1532 Instantiation inst = typeHandle.GetInstantiation();
1534 retTypes.Set(CopyRuntimeTypeHandles(NULL, inst.GetRawArgs(), inst.GetNumArgs(), fAsRuntimeTypeArray ? CLASS__CLASS : CLASS__TYPE));
1540 void QCALLTYPE RuntimeTypeHandle::MakeArray(EnregisteredTypeHandle pTypeHandle, INT32 rank, QCall::ObjectHandleOnStack retType)
1544 TypeHandle arrayHandle;
1547 arrayHandle = TypeHandle::FromPtr(pTypeHandle).MakeArray(rank);
1549 retType.Set(arrayHandle.GetManagedClassObject());
1555 void QCALLTYPE RuntimeTypeHandle::MakeSZArray(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType)
1559 TypeHandle arrayHandle;
1562 arrayHandle = TypeHandle::FromPtr(pTypeHandle).MakeSZArray();
1564 retType.Set(arrayHandle.GetManagedClassObject());
1570 void QCALLTYPE RuntimeTypeHandle::MakePointer(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType)
1574 TypeHandle pointerHandle;
1577 pointerHandle = TypeHandle::FromPtr(pTypeHandle).MakePointer();
1579 retType.Set(pointerHandle.GetManagedClassObject());
1585 void QCALLTYPE RuntimeTypeHandle::MakeByRef(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType)
1589 TypeHandle byRefHandle;
1592 byRefHandle = TypeHandle::FromPtr(pTypeHandle).MakeByRef();
1594 retType.Set(byRefHandle.GetManagedClassObject());
1600 BOOL QCALLTYPE RuntimeTypeHandle::IsCollectible(EnregisteredTypeHandle pTypeHandle)
1604 BOOL retVal = FALSE;
1607 retVal = TypeHandle::FromPtr(pTypeHandle).GetLoaderAllocator()->IsCollectible();
1613 void QCALLTYPE RuntimeTypeHandle::Instantiate(EnregisteredTypeHandle pTypeHandle, TypeHandle * pInstArray, INT32 cInstArray, QCall::ObjectHandleOnStack retType)
1620 type = TypeHandle::FromPtr(pTypeHandle).Instantiate(Instantiation(pInstArray, cInstArray));
1622 retType.Set(type.GetManagedClassObject());
1628 void QCALLTYPE RuntimeTypeHandle::GetGenericTypeDefinition(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType)
1636 TypeHandle genericType = TypeHandle::FromPtr(pTypeHandle);
1638 typeDef = ClassLoader::LoadTypeDefThrowing(genericType.GetModule(),
1639 genericType.GetMethodTable()->GetCl(),
1640 ClassLoader::ThrowIfNotFound,
1641 ClassLoader::PermitUninstDefOrRef);
1644 retType.Set(typeDef.GetManagedClassObject());
1651 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::CompareCanonicalHandles, ReflectClassBaseObject *pLeftUNSAFE, ReflectClassBaseObject *pRightUNSAFE)
1655 REFLECTCLASSBASEREF refLeft = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pLeftUNSAFE);
1656 REFLECTCLASSBASEREF refRight = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pRightUNSAFE);
1658 if ((refLeft == NULL) || (refRight == NULL))
1659 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1661 FC_RETURN_BOOL(refLeft->GetType().GetCanonicalMethodTable() == refRight->GetType().GetCanonicalMethodTable());
1665 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::HasInstantiation, PTR_ReflectClassBaseObject pTypeUNSAFE)
1669 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1671 if (refType == NULL)
1672 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1674 FC_RETURN_BOOL(refType->GetType().HasInstantiation());
1678 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsGenericTypeDefinition, PTR_ReflectClassBaseObject pTypeUNSAFE)
1682 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1684 if (refType == NULL)
1685 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1687 FC_RETURN_BOOL(refType->GetType().IsGenericTypeDefinition());
1691 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsGenericVariable, PTR_ReflectClassBaseObject pTypeUNSAFE)
1695 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1697 if (refType == NULL)
1698 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1700 FC_RETURN_BOOL(refType->GetType().IsGenericVariable());
1704 FCIMPL1(INT32, RuntimeTypeHandle::GetGenericVariableIndex, PTR_ReflectClassBaseObject pTypeUNSAFE)
1708 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1710 if (refType == NULL)
1711 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1713 return (INT32)refType->GetType().AsGenericVariable()->GetIndex();
1717 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::ContainsGenericVariables, PTR_ReflectClassBaseObject pTypeUNSAFE)
1721 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1723 if (refType == NULL)
1724 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1726 FC_RETURN_BOOL(refType->GetType().ContainsGenericVariables());
1730 FCIMPL1(IMDInternalImport*, RuntimeTypeHandle::GetMetadataImport, ReflectClassBaseObject * pTypeUNSAFE)
1734 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1736 if (refType == NULL)
1737 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1739 Module *pModule = refType->GetType().GetModule();
1741 return pModule->GetMDImport();
1746 //***********************************************************************************
1747 //***********************************************************************************
1748 //***********************************************************************************
1750 void * QCALLTYPE RuntimeMethodHandle::GetFunctionPointer(MethodDesc * pMethod)
1758 funcPtr = (void*)pMethod->GetMultiCallableAddrOfCode();
1765 FCIMPL1(LPCUTF8, RuntimeMethodHandle::GetUtf8Name, MethodDesc *pMethod) {
1771 LPCUTF8 szName = NULL;
1774 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1776 szName = pMethod->GetName();
1778 _ASSERTE(CheckPointer(szName, NULL_OK));
1784 FCIMPL2(FC_BOOL_RET, RuntimeMethodHandle::MatchesNameHash, MethodDesc * pMethod, ULONG hash)
1788 FC_RETURN_BOOL(pMethod->MightHaveName(hash));
1792 FCIMPL1(StringObject*, RuntimeMethodHandle::GetName, MethodDesc *pMethod) {
1799 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1801 STRINGREF refName = NULL;
1803 HELPER_METHOD_FRAME_BEGIN_RET_0();
1804 refName = StringObject::NewString(pMethod->GetName());
1805 HELPER_METHOD_FRAME_END();
1807 return (StringObject*)OBJECTREFToObject(refName);
1811 FCIMPL1(INT32, RuntimeMethodHandle::GetAttributes, MethodDesc *pMethod) {
1818 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1821 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
1822 retVal = (INT32)pMethod->GetAttrs();
1823 END_SO_INTOLERANT_CODE;
1828 FCIMPL1(INT32, RuntimeMethodHandle::GetImplAttributes, ReflectMethodObject *pMethodUNSAFE) {
1835 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1837 MethodDesc* pMethod = pMethodUNSAFE->GetMethod();
1838 INT32 attributes = 0;
1840 if (IsNilToken(pMethod->GetMemberDef()))
1843 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
1845 attributes = (INT32)pMethod->GetImplAttrs();
1847 END_SO_INTOLERANT_CODE;
1854 FCIMPL1(ReflectClassBaseObject*, RuntimeMethodHandle::GetDeclaringType, MethodDesc *pMethod) {
1857 PRECONDITION(CheckPointer(pMethod));
1862 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1864 MethodTable *pMT = pMethod->GetMethodTable();
1865 TypeHandle declType(pMT);
1868 HELPER_METHOD_FRAME_BEGIN_RET_0();
1870 // Load the TypeDesc for the array type. Note the returned type is approximate, i.e.
1871 // if shared between reference array types then we will get object[] back.
1872 DWORD rank = pMT->GetRank();
1873 TypeHandle elemType = pMT->GetApproxArrayElementTypeHandle();
1874 declType = ClassLoader::LoadArrayTypeThrowing(elemType, pMT->GetInternalCorElementType(), rank);
1875 HELPER_METHOD_FRAME_END();
1877 RETURN_CLASS_OBJECT(declType, NULL);
1881 FCIMPL1(INT32, RuntimeMethodHandle::GetSlot, MethodDesc *pMethod) {
1888 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1890 return (INT32)pMethod->GetSlot();
1894 FCIMPL3(Object *, SignatureNative::GetCustomModifiers, SignatureNative* pSignatureUNSAFE,
1895 INT32 parameter, CLR_BOOL fRequired)
1904 SIGNATURENATIVEREF pSig;
1908 gc.pSig = (SIGNATURENATIVEREF)pSignatureUNSAFE;
1911 HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
1914 BYTE callConv = *(BYTE*)gc.pSig->GetCorSig();
1915 SigTypeContext typeContext;
1916 gc.pSig->GetTypeContext(&typeContext);
1917 MetaSig sig(gc.pSig->GetCorSig(),
1918 gc.pSig->GetCorSigSize(),
1919 gc.pSig->GetModule(),
1921 (callConv & IMAGE_CEE_CS_CALLCONV_MASK) == IMAGE_CEE_CS_CALLCONV_FIELD ? MetaSig::sigField : MetaSig::sigMember);
1922 _ASSERTE(callConv == sig.GetCallingConventionInfo());
1924 SigPointer argument(NULL, 0);
1926 PRECONDITION(sig.GetCallingConvention() != IMAGE_CEE_CS_CALLCONV_FIELD || parameter == 1);
1930 argument = sig.GetReturnProps();
1934 for(INT32 i = 0; i < parameter; i++)
1937 argument = sig.GetArgProps();
1940 //if (parameter < 0 || parameter > (INT32)sig.NumFixedArgs())
1941 // FCThrowResVoid(kArgumentNullException, W("Arg_ArgumentOutOfRangeException"));
1943 SigPointer sp = argument;
1944 Module* pModule = sig.GetModule();
1946 CorElementType cmodType;
1948 CorElementType cmodTypeExpected = fRequired ? ELEMENT_TYPE_CMOD_REQD : ELEMENT_TYPE_CMOD_OPT;
1950 // Discover the number of required and optional custom modifiers.
1954 IfFailThrow(sp.GetByte(&data));
1955 cmodType = (CorElementType)data;
1957 if (cmodType == ELEMENT_TYPE_CMOD_REQD || cmodType == ELEMENT_TYPE_CMOD_OPT)
1959 if (cmodType == cmodTypeExpected)
1964 else if (cmodType != ELEMENT_TYPE_SENTINEL)
1969 IfFailThrow(sp.GetToken(NULL));
1972 // Reset sp and populate the arrays for the required and optional custom
1973 // modifiers now that we know how long they should be.
1976 MethodTable *pMT = MscorlibBinder::GetClass(CLASS__TYPE);
1977 TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pMT), ELEMENT_TYPE_SZARRAY);
1979 gc.retVal = (PTRARRAYREF) AllocateArrayEx(arrayHandle, &cMods, 1);
1984 IfFailThrow(sp.GetByte(&data));
1985 cmodType = (CorElementType)data;
1988 IfFailThrow(sp.GetToken(&token));
1990 if (cmodType == cmodTypeExpected)
1992 TypeHandle th = ClassLoader::LoadTypeDefOrRefOrSpecThrowing(pModule, token,
1994 ClassLoader::ThrowIfNotFound,
1995 ClassLoader::FailIfUninstDefOrRef);
1997 OBJECTREF refType = th.GetManagedClassObject();
1998 gc.retVal->SetAt(--cMods, refType);
2002 HELPER_METHOD_FRAME_END();
2004 return OBJECTREFToObject(gc.retVal);
2008 FCIMPL1(INT32, RuntimeMethodHandle::GetMethodDef, ReflectMethodObject *pMethodUNSAFE) {
2015 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2017 MethodDesc* pMethod = pMethodUNSAFE->GetMethod();
2019 if (pMethod->HasMethodInstantiation())
2021 HELPER_METHOD_FRAME_BEGIN_RET_1(pMethodUNSAFE);
2023 pMethod = pMethod->StripMethodInstantiation();
2025 HELPER_METHOD_FRAME_END();
2028 INT32 tkMethodDef = (INT32)pMethod->GetMemberDef();
2029 _ASSERTE(TypeFromToken(tkMethodDef) == mdtMethodDef);
2031 if (IsNilToken(tkMethodDef) || TypeFromToken(tkMethodDef) != mdtMethodDef)
2032 return mdMethodDefNil;
2038 FCIMPL6(void, SignatureNative::GetSignature,
2039 SignatureNative* pSignatureNativeUNSAFE,
2040 PCCOR_SIGNATURE pCorSig, DWORD cCorSig,
2041 FieldDesc *pFieldDesc, ReflectMethodObject *pMethodUNSAFE, ReflectClassBaseObject *pDeclaringTypeUNSAFE) {
2044 PRECONDITION(pDeclaringTypeUNSAFE || pMethodUNSAFE->GetMethod()->IsDynamicMethod());
2045 PRECONDITION(CheckPointer(pCorSig, NULL_OK));
2046 PRECONDITION(CheckPointer(pMethodUNSAFE, NULL_OK));
2047 PRECONDITION(CheckPointer(pFieldDesc, NULL_OK));
2053 REFLECTCLASSBASEREF refDeclaringType;
2054 REFLECTMETHODREF refMethod;
2055 SIGNATURENATIVEREF pSig;
2058 gc.refDeclaringType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pDeclaringTypeUNSAFE);
2059 gc.refMethod = (REFLECTMETHODREF)ObjectToOBJECTREF(pMethodUNSAFE);
2060 gc.pSig = (SIGNATURENATIVEREF)pSignatureNativeUNSAFE;
2062 MethodDesc *pMethod;
2063 TypeHandle declType;
2065 if (gc.refDeclaringType == NULL)
2067 // for dynamic method, see precondition
2068 pMethod = gc.refMethod->GetMethod();
2069 declType = pMethod->GetMethodTable();
2073 pMethod = gc.refMethod != NULL ? gc.refMethod->GetMethod() : NULL;
2074 declType = gc.refDeclaringType->GetType();
2077 HELPER_METHOD_FRAME_BEGIN_PROTECT(gc);
2079 Module* pModule = declType.GetModule();
2083 pMethod->GetSig(&pCorSig, &cCorSig);
2084 if (pMethod->GetClassification() == mcInstantiated)
2086 LoaderAllocator *pLoaderAllocator = pMethod->GetLoaderAllocator();
2087 if (pLoaderAllocator->IsCollectible())
2088 gc.pSig->SetKeepAlive(pLoaderAllocator->GetExposedObject());
2091 else if (pFieldDesc)
2092 pFieldDesc->GetSig(&pCorSig, &cCorSig);
2094 gc.pSig->m_sig = pCorSig;
2095 gc.pSig->m_cSig = cCorSig;
2096 gc.pSig->m_pMethod = pMethod;
2098 REFLECTCLASSBASEREF refDeclType = (REFLECTCLASSBASEREF)declType.GetManagedClassObject();
2099 gc.pSig->SetDeclaringType(refDeclType);
2101 PREFIX_ASSUME(pCorSig!= NULL);
2102 BYTE callConv = *(BYTE*)pCorSig;
2103 SigTypeContext typeContext;
2105 SigTypeContext::InitTypeContext(
2106 pMethod, declType.GetClassOrArrayInstantiation(), pMethod->LoadMethodInstantiation(), &typeContext);
2108 SigTypeContext::InitTypeContext(declType, &typeContext);
2109 MetaSig msig(pCorSig, cCorSig, pModule, &typeContext,
2110 (callConv & IMAGE_CEE_CS_CALLCONV_MASK) == IMAGE_CEE_CS_CALLCONV_FIELD ? MetaSig::sigField : MetaSig::sigMember);
2112 if (callConv == IMAGE_CEE_CS_CALLCONV_FIELD)
2114 msig.NextArgNormalized();
2116 OBJECTREF refRetType = msig.GetLastTypeHandleThrowing().GetManagedClassObject();
2117 gc.pSig->SetReturnType(refRetType);
2121 gc.pSig->SetCallingConvention(msig.GetCallingConventionInfo());
2123 OBJECTREF refRetType = msig.GetRetTypeHandleThrowing().GetManagedClassObject();
2124 gc.pSig->SetReturnType(refRetType);
2126 INT32 nArgs = msig.NumFixedArgs();
2127 TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(g_pRuntimeTypeClass), ELEMENT_TYPE_SZARRAY);
2129 PTRARRAYREF ptrArrayarguments = (PTRARRAYREF) AllocateArrayEx(arrayHandle, &nArgs, 1);
2130 gc.pSig->SetArgumentArray(ptrArrayarguments);
2132 for (INT32 i = 0; i < nArgs; i++)
2136 OBJECTREF refArgType = msig.GetLastTypeHandleThrowing().GetManagedClassObject();
2137 gc.pSig->SetArgument(i, refArgType);
2140 _ASSERTE(gc.pSig->m_returnType != NULL);
2143 HELPER_METHOD_FRAME_END();
2147 FCIMPL2(FC_BOOL_RET, SignatureNative::CompareSig, SignatureNative* pLhsUNSAFE, SignatureNative* pRhsUNSAFE)
2155 SIGNATURENATIVEREF pLhs;
2156 SIGNATURENATIVEREF pRhs;
2159 gc.pLhs = (SIGNATURENATIVEREF)pLhsUNSAFE;
2160 gc.pRhs = (SIGNATURENATIVEREF)pRhsUNSAFE;
2162 HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
2164 ret = MetaSig::CompareMethodSigs(
2165 gc.pLhs->GetCorSig(), gc.pLhs->GetCorSigSize(), gc.pLhs->GetModule(), NULL,
2166 gc.pRhs->GetCorSig(), gc.pRhs->GetCorSigSize(), gc.pRhs->GetModule(), NULL);
2168 HELPER_METHOD_FRAME_END();
2169 FC_RETURN_BOOL(ret);
2173 void QCALLTYPE RuntimeMethodHandle::GetMethodInstantiation(MethodDesc * pMethod, QCall::ObjectHandleOnStack retTypes, BOOL fAsRuntimeTypeArray)
2178 Instantiation inst = pMethod->LoadMethodInstantiation();
2181 retTypes.Set(CopyRuntimeTypeHandles(NULL, inst.GetRawArgs(), inst.GetNumArgs(), fAsRuntimeTypeArray ? CLASS__CLASS : CLASS__TYPE));
2187 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::HasMethodInstantiation, MethodDesc * pMethod)
2191 FC_RETURN_BOOL(pMethod->HasMethodInstantiation());
2195 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsGenericMethodDefinition, MethodDesc * pMethod)
2199 FC_RETURN_BOOL(pMethod->IsGenericMethodDefinition());
2203 FCIMPL1(INT32, RuntimeMethodHandle::GetGenericParameterCount, MethodDesc * pMethod)
2207 return pMethod->GetNumGenericMethodArgs();
2211 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsDynamicMethod, MethodDesc * pMethod)
2215 FC_RETURN_BOOL(pMethod->IsNoMetadata());
2219 FCIMPL1(Object*, RuntimeMethodHandle::GetResolver, MethodDesc * pMethod)
2224 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2226 OBJECTREF resolver = NULL;
2227 if (pMethod->IsLCGMethod())
2229 resolver = pMethod->AsDynamicMethodDesc()->GetLCGMethodResolver()->GetManagedResolver();
2231 return OBJECTREFToObject(resolver);
2235 void QCALLTYPE RuntimeMethodHandle::Destroy(MethodDesc * pMethod)
2241 if (pMethod == NULL)
2242 COMPlusThrowArgumentNull(NULL, W("Arg_InvalidHandle"));
2244 DynamicMethodDesc* pDynamicMethodDesc = pMethod->AsDynamicMethodDesc();
2248 // Destroy should be called only if the managed part is gone.
2249 _ASSERTE(OBJECTREFToObject(pDynamicMethodDesc->GetLCGMethodResolver()->GetManagedResolver()) == NULL);
2251 // Fire Unload Dynamic Method Event here
2252 ETW::MethodLog::DynamicMethodDestroyed(pMethod);
2254 BEGIN_PIN_PROFILER(CORProfilerIsMonitoringDynamicFunctionUnloads());
2255 g_profControlBlock.pProfInterface->DynamicMethodUnloaded((FunctionID)pMethod);
2258 pDynamicMethodDesc->Destroy();
2263 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsTypicalMethodDefinition, ReflectMethodObject *pMethodUNSAFE)
2268 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2270 MethodDesc* pMethod = pMethodUNSAFE->GetMethod();
2272 FC_RETURN_BOOL(pMethod->IsTypicalMethodDefinition());
2276 void QCALLTYPE RuntimeMethodHandle::GetTypicalMethodDefinition(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod)
2284 _ASSERTE(((ReflectMethodObject *)(*refMethod.m_ppObject))->GetMethod() == pMethod);
2287 MethodDesc *pMethodTypical = pMethod->LoadTypicalMethodDefinition();
2288 if (pMethodTypical != pMethod)
2291 refMethod.Set(pMethodTypical->GetStubMethodInfo());
2298 void QCALLTYPE RuntimeMethodHandle::StripMethodInstantiation(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod)
2305 COMPlusThrowArgumentNull(NULL, W("Arg_InvalidHandle"));
2310 _ASSERTE(((ReflectMethodObject *)(*refMethod.m_ppObject))->GetMethod() == pMethod);
2313 MethodDesc *pMethodStripped = pMethod->StripMethodInstantiation();
2314 if (pMethodStripped != pMethod)
2317 refMethod.Set(pMethodStripped->GetStubMethodInfo());
2324 // In the VM there might be more than one MethodDescs for a "method"
2325 // examples are methods on generic types which may have additional instantiating stubs
2326 // and methods on value types which may have additional unboxing stubs.
2328 // For generic methods we always hand out an instantiating stub except for a generic method definition
2329 // For non-generic methods on generic types we need an instantiating stub if it's one of the following
2330 // - static method on a generic class
2331 // - static or instance method on a generic interface
2332 // - static or instance method on a generic value type
2333 // The Reflection policy is to always hand out instantiating stubs in these cases
2335 // For methods on non-generic value types we can use either the cannonical method or the unboxing stub
2336 // The Reflection policy is to always hand out unboxing stubs if the methods are virtual methods
2337 // The reason for this is that in the current implementation of the class loader, the v-table slots for
2338 // those methods point to unboxing stubs already. Note that this is just a implementation choice
2339 // that might change in the future. But we should always keep this Reflection policy an invariant.
2341 // For virtual methods on generic value types (intersection of the two cases), reflection will hand
2342 // out an unboxing instantiating stub
2344 // GetInstantiatingStub is called to:
2345 // 1. create an InstantiatedMethodDesc for a generic method when calling BindGenericArguments() on a generic
2346 // method. In this case instArray will not be null.
2347 // 2. create an InstantiatedMethodDesc for a method in a generic class. In this case instArray will be null.
2348 // 3. create an UnboxingStub for a method in a value type. In this case instArray will be null.
2349 // For case 2 and 3, an instantiating stub or unboxing stub might not be needed in which case the original
2350 // MethodDesc is returned.
2351 FCIMPL3(MethodDesc*, RuntimeMethodHandle::GetStubIfNeeded,
2352 MethodDesc *pMethod,
2353 ReflectClassBaseObject *pTypeUNSAFE,
2354 PtrArray* instArrayUNSAFE)
2361 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
2362 PTRARRAYREF instArray = (PTRARRAYREF)ObjectToOBJECTREF(instArrayUNSAFE);
2364 if (refType == NULL)
2365 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2367 TypeHandle instType = refType->GetType();
2368 MethodDesc *pNewMethod = pMethod;
2372 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
2374 if (instType.IsNull())
2375 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2377 // Perf optimization: this logic is actually duplicated in FindOrCreateAssociatedMethodDescForReflection, but since it
2378 // is the more common case it's worth the duplicate check here to avoid the helper method frame
2379 if ( instArray == NULL &&
2380 ( pMethod->HasMethodInstantiation() ||
2381 ( !instType.IsValueType() &&
2382 ( !instType.HasInstantiation() || instType.IsGenericTypeDefinition() ) ) ) )
2387 HELPER_METHOD_FRAME_BEGIN_RET_2(refType, instArray);
2389 TypeHandle *inst = NULL;
2392 if (instArray != NULL)
2394 ntypars = instArray->GetNumComponents();
2396 size_t size = ntypars * sizeof(TypeHandle);
2397 if ((size / sizeof(TypeHandle)) != ntypars) // uint over/underflow
2398 COMPlusThrow(kArgumentException);
2399 inst = (TypeHandle*) _alloca(size);
2401 for (DWORD i = 0; i < ntypars; i++)
2403 REFLECTCLASSBASEREF instRef = (REFLECTCLASSBASEREF)instArray->GetAt(i);
2405 if (instRef == NULL)
2406 COMPlusThrowArgumentNull(W("inst"), W("ArgumentNull_ArrayElement"));
2408 inst[i] = instRef->GetType();
2412 pNewMethod = MethodDesc::FindOrCreateAssociatedMethodDescForReflection(pMethod, instType, Instantiation(inst, ntypars));
2414 HELPER_METHOD_FRAME_END();
2421 FCIMPL2(MethodDesc*, RuntimeMethodHandle::GetMethodFromCanonical, MethodDesc *pMethod, ReflectClassBaseObject *pTypeUNSAFE)
2425 PRECONDITION(CheckPointer(pMethod));
2429 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
2431 TypeHandle instType = refType->GetType();
2432 MethodDesc* pMDescInCanonMT = instType.GetMethodTable()->GetParallelMethodDesc(pMethod);
2434 return pMDescInCanonMT;
2439 FCIMPL2(MethodBody *, RuntimeMethodHandle::GetMethodBody, ReflectMethodObject *pMethodUNSAFE, ReflectClassBaseObject *pDeclaringTypeUNSAFE)
2449 METHODBODYREF MethodBodyObj;
2450 EXCEPTIONHANDLINGCLAUSEREF EHClauseObj;
2451 LOCALVARIABLEINFOREF LocalVariableInfoObj;
2453 BASEARRAYREF TempArray;
2454 REFLECTCLASSBASEREF declaringType;
2455 REFLECTMETHODREF refMethod;
2458 gc.MethodBodyObj = NULL;
2459 gc.EHClauseObj = NULL;
2460 gc.LocalVariableInfoObj = NULL;
2462 gc.TempArray = NULL;
2463 gc.declaringType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pDeclaringTypeUNSAFE);
2464 gc.refMethod = (REFLECTMETHODREF)ObjectToOBJECTREF(pMethodUNSAFE);
2468 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2470 MethodDesc* pMethod = gc.refMethod->GetMethod();
2472 TypeHandle declaringType = gc.declaringType == NULL ? TypeHandle() : gc.declaringType->GetType();
2474 if (!pMethod->IsIL())
2477 HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
2479 MethodDesc *pMethodIL = pMethod;
2480 if (pMethod->IsWrapperStub())
2481 pMethodIL = pMethod->GetWrappedMethodDesc();
2483 COR_ILMETHOD* pILHeader = pMethodIL->GetILHeader();
2487 MethodTable * pExceptionHandlingClauseMT = MscorlibBinder::GetClass(CLASS__EH_CLAUSE);
2488 TypeHandle thEHClauseArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pExceptionHandlingClauseMT), ELEMENT_TYPE_SZARRAY);
2490 MethodTable * pLocalVariableMT = MscorlibBinder::GetClass(CLASS__LOCAL_VARIABLE_INFO);
2491 TypeHandle thLocalVariableArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pLocalVariableMT), ELEMENT_TYPE_SZARRAY);
2493 Module* pModule = pMethod->GetModule();
2494 COR_ILMETHOD_DECODER::DecoderStatus status;
2495 COR_ILMETHOD_DECODER header(pILHeader, pModule->GetMDImport(), &status);
2497 if (status != COR_ILMETHOD_DECODER::SUCCESS)
2499 if (status == COR_ILMETHOD_DECODER::VERIFICATION_ERROR)
2501 // Throw a verification HR
2502 COMPlusThrowHR(COR_E_VERIFICATION);
2506 COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
2510 gc.MethodBodyObj = (METHODBODYREF)AllocateObject(MscorlibBinder::GetClass(CLASS__METHOD_BODY));
2512 gc.MethodBodyObj->m_maxStackSize = header.GetMaxStack();
2513 gc.MethodBodyObj->m_initLocals = !!(header.GetFlags() & CorILMethod_InitLocals);
2516 gc.MethodBodyObj->m_localVarSigToken = header.GetLocalVarSigTok();
2518 gc.MethodBodyObj->m_localVarSigToken = 0;
2520 // Allocate the array of IL and fill it in from the method header.
2521 BYTE* pIL = const_cast<BYTE*>(header.Code);
2522 COUNT_T cIL = header.GetCodeSize();
2523 gc.U1Array = (U1ARRAYREF) AllocatePrimitiveArray(ELEMENT_TYPE_U1, cIL);
2525 SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->m_IL, gc.U1Array, GetAppDomain());
2526 memcpyNoGCRefs(gc.MethodBodyObj->m_IL->GetDataPtr(), pIL, cIL);
2528 // Allocate the array of exception clauses.
2529 INT32 cEh = (INT32)header.EHCount();
2530 const COR_ILMETHOD_SECT_EH* ehInfo = header.EH;
2531 gc.TempArray = (BASEARRAYREF) AllocateArrayEx(thEHClauseArray, &cEh, 1);
2533 SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->m_exceptionClauses, gc.TempArray, GetAppDomain());
2535 for (INT32 i = 0; i < cEh; i++)
2537 COR_ILMETHOD_SECT_EH_CLAUSE_FAT ehBuff;
2538 const COR_ILMETHOD_SECT_EH_CLAUSE_FAT* ehClause =
2539 (const COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)ehInfo->EHClause(i, &ehBuff);
2541 gc.EHClauseObj = (EXCEPTIONHANDLINGCLAUSEREF) AllocateObject(pExceptionHandlingClauseMT);
2543 gc.EHClauseObj->m_flags = ehClause->GetFlags();
2544 gc.EHClauseObj->m_tryOffset = ehClause->GetTryOffset();
2545 gc.EHClauseObj->m_tryLength = ehClause->GetTryLength();
2546 gc.EHClauseObj->m_handlerOffset = ehClause->GetHandlerOffset();
2547 gc.EHClauseObj->m_handlerLength = ehClause->GetHandlerLength();
2549 if ((ehClause->GetFlags() & COR_ILEXCEPTION_CLAUSE_FILTER) == 0)
2550 gc.EHClauseObj->m_catchToken = ehClause->GetClassToken();
2552 gc.EHClauseObj->m_filterOffset = ehClause->GetFilterOffset();
2554 gc.MethodBodyObj->m_exceptionClauses->SetAt(i, (OBJECTREF) gc.EHClauseObj);
2555 SetObjectReference((OBJECTREF*)&(gc.EHClauseObj->m_methodBody), (OBJECTREF)gc.MethodBodyObj, GetAppDomain());
2558 if (header.LocalVarSig != NULL)
2560 SigTypeContext sigTypeContext(pMethod, declaringType, pMethod->LoadMethodInstantiation());
2561 MetaSig metaSig(header.LocalVarSig,
2562 header.cbLocalVarSig,
2565 MetaSig::sigLocalVars);
2566 INT32 cLocals = metaSig.NumFixedArgs();
2567 gc.TempArray = (BASEARRAYREF) AllocateArrayEx(thLocalVariableArray, &cLocals, 1);
2568 SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->m_localVariables, gc.TempArray, GetAppDomain());
2570 for (INT32 i = 0; i < cLocals; i ++)
2572 gc.LocalVariableInfoObj = (LOCALVARIABLEINFOREF)AllocateObject(pLocalVariableMT);
2574 gc.LocalVariableInfoObj->m_localIndex = i;
2578 CorElementType eType;
2579 IfFailThrow(metaSig.GetArgProps().PeekElemType(&eType));
2580 if (ELEMENT_TYPE_PINNED == eType)
2581 gc.LocalVariableInfoObj->m_bIsPinned = TRUE;
2583 TypeHandle tempType= metaSig.GetArgProps().GetTypeHandleThrowing(pModule, &sigTypeContext);
2584 OBJECTREF refLocalType = tempType.GetManagedClassObject();
2585 gc.LocalVariableInfoObj->SetType(refLocalType);
2586 gc.MethodBodyObj->m_localVariables->SetAt(i, (OBJECTREF) gc.LocalVariableInfoObj);
2592 gc.TempArray = (BASEARRAYREF) AllocateArrayEx(thLocalVariableArray, &cLocals, 1);
2593 SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->m_localVariables, gc.TempArray, GetAppDomain());
2597 HELPER_METHOD_FRAME_END();
2599 return (MethodBody*)OBJECTREFToObject(gc.MethodBodyObj);
2603 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsConstructor, MethodDesc *pMethod)
2607 PRECONDITION(CheckPointer(pMethod));
2612 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
2613 ret = (BOOL)pMethod->IsClassConstructorOrCtor();
2614 END_SO_INTOLERANT_CODE;
2615 FC_RETURN_BOOL(ret);
2619 FCIMPL1(Object*, RuntimeMethodHandle::GetLoaderAllocator, MethodDesc *pMethod)
2626 OBJECTREF loaderAllocator = NULL;
2629 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2631 HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(loaderAllocator);
2633 LoaderAllocator *pLoaderAllocator = pMethod->GetLoaderAllocator();
2634 loaderAllocator = pLoaderAllocator->GetExposedObject();
2636 HELPER_METHOD_FRAME_END();
2638 return OBJECTREFToObject(loaderAllocator);
2642 //*********************************************************************************************
2643 //*********************************************************************************************
2644 //*********************************************************************************************
2646 FCIMPL1(StringObject*, RuntimeFieldHandle::GetName, ReflectFieldObject *pFieldUNSAFE) {
2652 REFLECTFIELDREF refField = (REFLECTFIELDREF)ObjectToOBJECTREF(pFieldUNSAFE);
2654 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2656 FieldDesc *pField = refField->GetField();
2658 STRINGREF refString = NULL;
2659 HELPER_METHOD_FRAME_BEGIN_RET_1(refField);
2661 refString = StringObject::NewString(pField->GetName());
2663 HELPER_METHOD_FRAME_END();
2664 return (StringObject*)OBJECTREFToObject(refString);
2668 FCIMPL1(LPCUTF8, RuntimeFieldHandle::GetUtf8Name, FieldDesc *pField) {
2671 PRECONDITION(CheckPointer(pField));
2675 LPCUTF8 szFieldName;
2677 if (FAILED(pField->GetName_NoThrow(&szFieldName)))
2679 FCThrow(kBadImageFormatException);
2685 FCIMPL2(FC_BOOL_RET, RuntimeFieldHandle::MatchesNameHash, FieldDesc * pField, ULONG hash)
2689 FC_RETURN_BOOL(pField->MightHaveName(hash));
2693 FCIMPL1(INT32, RuntimeFieldHandle::GetAttributes, FieldDesc *pField) {
2700 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2703 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
2704 ret = (INT32)pField->GetAttributes();
2705 END_SO_INTOLERANT_CODE;
2710 FCIMPL1(ReflectClassBaseObject*, RuntimeFieldHandle::GetApproxDeclaringType, FieldDesc *pField) {
2717 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2719 TypeHandle th = TypeHandle(pField->GetApproxEnclosingMethodTable()); // <REVISIT_TODO> this needs to be checked - see bug 184355 </REVISIT_TODO>
2720 RETURN_CLASS_OBJECT(th, NULL);
2724 FCIMPL1(INT32, RuntimeFieldHandle::GetToken, ReflectFieldObject *pFieldUNSAFE) {
2730 REFLECTFIELDREF refField = (REFLECTFIELDREF)ObjectToOBJECTREF(pFieldUNSAFE);
2732 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2734 FieldDesc *pField = refField->GetField();
2736 INT32 tkFieldDef = (INT32)pField->GetMemberDef();
2737 _ASSERTE(!IsNilToken(tkFieldDef) || tkFieldDef == mdFieldDefNil);
2742 FCIMPL2(FieldDesc*, RuntimeFieldHandle::GetStaticFieldForGenericType, FieldDesc *pField, ReflectClassBaseObject *pDeclaringTypeUNSAFE)
2749 REFLECTCLASSBASEREF refDeclaringType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pDeclaringTypeUNSAFE);
2751 if ((refDeclaringType == NULL) || (pField == NULL))
2752 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2754 TypeHandle declaringType = refDeclaringType->GetType();
2757 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2758 if (declaringType.IsTypeDesc())
2759 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2760 MethodTable *pMT = declaringType.AsMethodTable();
2762 _ASSERTE(pField->IsStatic());
2763 if (pMT->HasGenericsStaticsInfo())
2764 pField = pMT->GetFieldDescByIndex(pField->GetApproxEnclosingMethodTable()->GetIndexForFieldDesc(pField));
2765 _ASSERTE(!pField->IsSharedByGenericInstantiations());
2766 _ASSERTE(pField->GetEnclosingMethodTable() == pMT);
2772 FCIMPL1(ReflectModuleBaseObject*, AssemblyHandle::GetManifestModule, AssemblyBaseObject* pAssemblyUNSAFE) {
2775 ASSEMBLYREF refAssembly = (ASSEMBLYREF)ObjectToOBJECTREF(pAssemblyUNSAFE);
2777 if (refAssembly == NULL)
2778 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2780 DomainAssembly *pAssembly = refAssembly->GetDomainAssembly();
2781 Assembly* currentAssembly = pAssembly->GetCurrentAssembly();
2783 if (currentAssembly == NULL)
2786 Module *pModule = currentAssembly->GetManifestModule();
2787 DomainFile * pDomainFile = pModule->FindDomainFile(GetAppDomain());
2792 HELPER_METHOD_FRAME_BEGIN_RET_1(refAssembly);
2793 orModule = (pDomainFile != NULL) ? pDomainFile->GetExposedModuleObjectIfExists() : NULL;
2794 if (orModule == NULL)
2795 orModule = pModule->GetExposedObject();
2797 OBJECTREF orModule = (pDomainFile != NULL) ? pDomainFile->GetExposedModuleObjectIfExists() : NULL;
2798 if (orModule != NULL)
2799 return (ReflectModuleBaseObject*)OBJECTREFToObject(orModule);
2801 HELPER_METHOD_FRAME_BEGIN_RET_1(refAssembly);
2802 orModule = pModule->GetExposedObject();
2805 HELPER_METHOD_FRAME_END();
2806 return (ReflectModuleBaseObject*)OBJECTREFToObject(orModule);
2811 FCIMPL1(INT32, AssemblyHandle::GetToken, AssemblyBaseObject* pAssemblyUNSAFE) {
2814 ASSEMBLYREF refAssembly = (ASSEMBLYREF)ObjectToOBJECTREF(pAssemblyUNSAFE);
2816 if (refAssembly == NULL)
2817 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2819 DomainAssembly *pAssembly = refAssembly->GetDomainAssembly();
2820 mdAssembly token = mdAssemblyNil;
2822 IMDInternalImport *mdImport = pAssembly->GetCurrentAssembly()->GetManifestImport();
2826 if (FAILED(mdImport->GetAssemblyFromScope(&token)))
2828 FCThrow(kBadImageFormatException);
2837 void QCALLTYPE ModuleHandle::GetPEKind(QCall::ModuleHandle pModule, DWORD* pdwPEKind, DWORD* pdwMachine)
2842 pModule->GetFile()->GetPEKindAndMachine(pdwPEKind, pdwMachine);
2846 FCIMPL1(INT32, ModuleHandle::GetMDStreamVersion, ReflectModuleBaseObject * pModuleUNSAFE)
2850 REFLECTMODULEBASEREF refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
2852 if (refModule == NULL)
2853 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2855 Module *pModule = refModule->GetModule();
2857 if (pModule->IsResource())
2860 return pModule->GetMDImport()->GetMetadataStreamVersion();
2864 void QCALLTYPE ModuleHandle::GetModuleType(QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retType)
2868 TypeHandle globalTypeHandle = TypeHandle();
2874 globalTypeHandle = TypeHandle(pModule->GetGlobalMethodTable());
2876 EX_SWALLOW_NONTRANSIENT;
2878 if (!globalTypeHandle.IsNull())
2881 retType.Set(globalTypeHandle.GetManagedClassObject());
2889 FCIMPL1(INT32, ModuleHandle::GetToken, ReflectModuleBaseObject * pModuleUNSAFE) {
2895 REFLECTMODULEBASEREF refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
2897 if (refModule == NULL)
2898 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2900 Module *pModule = refModule->GetModule();
2902 if (pModule->IsResource())
2905 return pModule->GetMDImport()->GetModuleFromScope();
2909 FCIMPL1(IMDInternalImport*, ModuleHandle::GetMetadataImport, ReflectModuleBaseObject * pModuleUNSAFE)
2913 REFLECTMODULEBASEREF refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
2915 if (refModule == NULL)
2916 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2918 Module *pModule = refModule->GetModule();
2920 if (pModule->IsResource())
2923 return pModule->GetMDImport();
2927 BOOL QCALLTYPE ModuleHandle::ContainsPropertyMatchingHash(QCall::ModuleHandle pModule, INT32 tkProperty, ULONG hash)
2931 BOOL fContains = TRUE;
2935 fContains = pModule->MightContainMatchingProperty(tkProperty, hash);
2942 void QCALLTYPE ModuleHandle::ResolveType(QCall::ModuleHandle pModule, INT32 tkType, TypeHandle *typeArgs, INT32 typeArgsCount, TypeHandle *methodArgs, INT32 methodArgsCount, QCall::ObjectHandleOnStack retType)
2946 TypeHandle typeHandle;
2950 _ASSERTE(!IsNilToken(tkType));
2952 SigTypeContext typeContext(Instantiation(typeArgs, typeArgsCount), Instantiation(methodArgs, methodArgsCount));
2953 typeHandle = ClassLoader::LoadTypeDefOrRefOrSpecThrowing(pModule, tkType, &typeContext,
2954 ClassLoader::ThrowIfNotFound,
2955 ClassLoader::PermitUninstDefOrRef);
2958 retType.Set(typeHandle.GetManagedClassObject());
2965 MethodDesc *QCALLTYPE ModuleHandle::ResolveMethod(QCall::ModuleHandle pModule, INT32 tkMemberRef, TypeHandle *typeArgs, INT32 typeArgsCount, TypeHandle *methodArgs, INT32 methodArgsCount)
2969 MethodDesc* pMD = NULL;
2973 _ASSERTE(!IsNilToken(tkMemberRef));
2975 BOOL strictMetadataChecks = (TypeFromToken(tkMemberRef) == mdtMethodSpec);
2977 SigTypeContext typeContext(Instantiation(typeArgs, typeArgsCount), Instantiation(methodArgs, methodArgsCount));
2978 pMD = MemberLoader::GetMethodDescFromMemberDefOrRefOrSpec(pModule, tkMemberRef, &typeContext, strictMetadataChecks, FALSE);
2980 // This will get us the instantiating or unboxing stub if needed
2981 pMD = MethodDesc::FindOrCreateAssociatedMethodDescForReflection(pMD, pMD->GetMethodTable(), pMD->GetMethodInstantiation());
2988 void QCALLTYPE ModuleHandle::ResolveField(QCall::ModuleHandle pModule, INT32 tkMemberRef, TypeHandle *typeArgs, INT32 typeArgsCount, TypeHandle *methodArgs, INT32 methodArgsCount, QCall::ObjectHandleOnStack retField)
2992 FieldDesc* pField = NULL;
2996 _ASSERTE(!IsNilToken(tkMemberRef));
2998 SigTypeContext typeContext(Instantiation(typeArgs, typeArgsCount), Instantiation(methodArgs, methodArgsCount));
2999 pField = MemberLoader::GetFieldDescFromMemberDefOrRef(pModule, tkMemberRef, &typeContext, FALSE);
3001 retField.Set(pField->GetStubFieldInfo());
3008 void QCALLTYPE ModuleHandle::GetAssembly(QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retAssembly)
3012 DomainAssembly *pAssembly = NULL;
3015 pAssembly = pModule->GetDomainAssembly();
3018 retAssembly.Set(pAssembly->GetExposedAssemblyObject());
3024 FCIMPL5(ReflectMethodObject*, ModuleHandle::GetDynamicMethod, ReflectMethodObject *pMethodUNSAFE, ReflectModuleBaseObject *pModuleUNSAFE, StringObject *name, U1Array *sig, Object *resolver) {
3027 PRECONDITION(CheckPointer(name));
3028 PRECONDITION(CheckPointer(sig));
3032 DynamicMethodDesc *pNewMD = NULL;
3037 OBJECTREF resolverRef;
3038 OBJECTREF methodRef;
3039 REFLECTMETHODREF retMethod;
3040 REFLECTMODULEBASEREF refModule;
3042 gc.nameRef = (STRINGREF)name;
3043 gc.resolverRef = (OBJECTREF)resolver;
3044 gc.methodRef = ObjectToOBJECTREF(pMethodUNSAFE);
3045 gc.retMethod = NULL;
3046 gc.refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
3048 if (gc.refModule == NULL)
3049 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
3051 Module *pModule = gc.refModule->GetModule();
3053 HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
3055 DomainFile *pDomainModule = pModule->GetDomainFile();
3057 U1ARRAYREF dataArray = (U1ARRAYREF)sig;
3058 DWORD sigSize = dataArray->GetNumComponents();
3059 NewHolder<BYTE> pSig(new BYTE[sigSize]);
3060 memcpy(pSig, dataArray->GetDataPtr(), sigSize);
3062 DWORD length = gc.nameRef->GetStringLength();
3063 NewArrayHolder<char> pName(new char[(length + 1) * 2]);
3065 length = WszWideCharToMultiByte(CP_UTF8, 0, gc.nameRef->GetBuffer(), length, pName, (length + 1) * 2 - sizeof(char), NULL, NULL);
3067 pName[length / sizeof(char)] = '\0';
3069 DynamicMethodTable *pMTForDynamicMethods = pDomainModule->GetDynamicMethodTable();
3070 pNewMD = pMTForDynamicMethods->GetDynamicMethod(pSig, sigSize, pName);
3071 _ASSERTE(pNewMD != NULL);
3072 // pNewMD now owns pSig and pName.
3073 pSig.SuppressRelease();
3074 pName.SuppressRelease();
3076 // create a handle to hold the resolver objectref
3077 OBJECTHANDLE resolverHandle = pDomainModule->GetAppDomain()->CreateLongWeakHandle(gc.resolverRef);
3078 pNewMD->GetLCGMethodResolver()->SetManagedResolver(resolverHandle);
3079 gc.retMethod = pNewMD->GetStubMethodInfo();
3080 gc.retMethod->SetKeepAlive(gc.resolverRef);
3082 LoaderAllocator *pLoaderAllocator = pModule->GetLoaderAllocator();
3084 if (pLoaderAllocator->IsCollectible())
3085 pLoaderAllocator->AddReference();
3087 HELPER_METHOD_FRAME_END();
3089 return (ReflectMethodObject*)OBJECTREFToObject(gc.retMethod);
3093 void QCALLTYPE RuntimeMethodHandle::GetCallerType(QCall::StackCrawlMarkHandle pStackMark, QCall::ObjectHandleOnStack retType)
3099 MethodTable *pMT = NULL;
3101 pMT = SystemDomain::GetCallersType(pStackMark);
3104 retType.Set(pMT->GetManagedClassObject());