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, MdUtf8String::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 MdUtf8String::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 MdUtf8String::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 _ASSERTE(pCACtor->IsCtor());
119 dwAttr = pCACtor->GetAttrs();
122 StaticAccessCheckContext accessContext(NULL, pDecoratedMT, pDecoratedModule->GetAssembly());
124 return ClassLoader::CanAccess(
127 pCAMT->GetAssembly(),
131 *AccessCheckOptions::s_pNormalAccessChecks);
134 BOOL QCALLTYPE RuntimeMethodHandle::IsCAVisibleFromDecoratedType(
135 EnregisteredTypeHandle targetTypeHandle,
136 MethodDesc * pTargetCtor,
137 EnregisteredTypeHandle sourceTypeHandle,
138 QCall::ModuleHandle sourceModuleHandle)
145 TypeHandle sourceHandle = TypeHandle::FromPtr(sourceTypeHandle);
146 TypeHandle targetHandle = TypeHandle::FromPtr(targetTypeHandle);
148 _ASSERTE((sourceHandle.IsNull() || !sourceHandle.IsTypeDesc()) &&
149 !targetHandle.IsNull() &&
150 !targetHandle.IsTypeDesc());
152 if (sourceHandle.IsTypeDesc() ||
153 targetHandle.IsNull() ||
154 targetHandle.IsTypeDesc())
155 COMPlusThrowArgumentNull(NULL, W("Arg_InvalidHandle"));
157 bResult = CheckCAVisibilityFromDecoratedType(targetHandle.AsMethodTable(), pTargetCtor, sourceHandle.AsMethodTable(), sourceModuleHandle);
164 NOINLINE static ReflectClassBaseObject* GetRuntimeTypeHelper(LPVOID __me, TypeHandle typeHandle, OBJECTREF keepAlive)
166 FC_INNER_PROLOG_NO_ME_SETUP();
167 if (typeHandle.AsPtr() == NULL)
170 // RuntimeTypeHandle::GetRuntimeType has picked off the most common case, but does not cover array types.
171 // Before we do the really heavy weight option of setting up a helper method frame, check if we have to.
172 OBJECTREF refType = typeHandle.GetManagedClassObjectFast();
174 return (ReflectClassBaseObject*)OBJECTREFToObject(refType);
176 HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_1(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, keepAlive);
177 refType = typeHandle.GetManagedClassObject();
178 HELPER_METHOD_FRAME_END();
181 return (ReflectClassBaseObject*)OBJECTREFToObject(refType);
184 #define RETURN_CLASS_OBJECT(typeHandle, keepAlive) FC_INNER_RETURN(ReflectClassBaseObject*, GetRuntimeTypeHelper(__me, typeHandle, keepAlive))
186 NOINLINE ReflectModuleBaseObject* GetRuntimeModuleHelper(LPVOID __me, Module *pModule, OBJECTREF keepAlive)
188 FC_INNER_PROLOG_NO_ME_SETUP();
192 DomainFile * pDomainFile = pModule->FindDomainFile(GetAppDomain());
194 OBJECTREF refModule = (pDomainFile != NULL) ? pDomainFile->GetExposedModuleObjectIfExists() : NULL;
196 if(refModule != NULL)
197 return (ReflectModuleBaseObject*)OBJECTREFToObject(refModule);
199 HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_1(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, keepAlive);
200 refModule = pModule->GetExposedObject();
201 HELPER_METHOD_FRAME_END();
204 return (ReflectModuleBaseObject*)OBJECTREFToObject(refModule);
207 NOINLINE AssemblyBaseObject* GetRuntimeAssemblyHelper(LPVOID __me, DomainAssembly *pAssembly, OBJECTREF keepAlive)
209 FC_INNER_PROLOG_NO_ME_SETUP();
210 if (pAssembly == NULL)
213 OBJECTREF refAssembly = (pAssembly != NULL) ? pAssembly->GetExposedAssemblyObjectIfExists() : NULL;
215 if(refAssembly != NULL)
216 return (AssemblyBaseObject*)OBJECTREFToObject(refAssembly);
218 HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_1(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, keepAlive);
219 refAssembly = pAssembly->GetExposedAssemblyObject();
220 HELPER_METHOD_FRAME_END();
223 return (AssemblyBaseObject*)OBJECTREFToObject(refAssembly);
227 // This is the routine that is called by the 'typeof()' operator in C#. It is one of the most commonly used
228 // reflection operations. This call should be optimized away in nearly all situations
229 FCIMPL1_V(ReflectClassBaseObject*, RuntimeTypeHandle::GetTypeFromHandle, FCALLRuntimeTypeHandle th)
234 return FCALL_RTH_TO_REFLECTCLASS(th);
238 FCIMPL1(ReflectClassBaseObject*, RuntimeTypeHandle::GetRuntimeType, EnregisteredTypeHandle th)
242 TypeHandle typeHandle = TypeHandle::FromPtr(th);
243 _ASSERTE(CheckPointer(typeHandle.AsPtr(), NULL_OK));
244 if (typeHandle.AsPtr()!= NULL)
246 if (!typeHandle.IsTypeDesc())
248 OBJECTREF typePtr = typeHandle.AsMethodTable()->GetManagedClassObjectIfExists();
251 return (ReflectClassBaseObject*)OBJECTREFToObject(typePtr);
258 RETURN_CLASS_OBJECT(typeHandle, NULL);
262 FCIMPL1_V(EnregisteredTypeHandle, RuntimeTypeHandle::GetValueInternal, FCALLRuntimeTypeHandle RTH)
266 if (FCALL_RTH_TO_REFLECTCLASS(RTH) == NULL)
269 return FCALL_RTH_TO_REFLECTCLASS(RTH) ->GetType().AsPtr();
273 // TypeEqualsHelper and TypeNotEqualsHelper are almost identical.
274 // Unfortunately we cannot combime them because they need to hardcode the caller's name
275 NOINLINE static BOOL TypeEqualSlow(OBJECTREF refL, OBJECTREF refR, LPVOID __me)
279 FC_INNER_PROLOG_NO_ME_SETUP();
281 _ASSERTE(refL != NULL && refR != NULL);
283 HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_2(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, refL, refR);
285 MethodDescCallSite TypeEqualsMethod(METHOD__OBJECT__EQUALS, &refL);
293 ret = TypeEqualsMethod.Call_RetBool(args);
295 HELPER_METHOD_FRAME_END();
304 #include <optsmallperfcritical.h>
306 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::TypeEQ, Object* left, Object* right)
310 OBJECTREF refL = (OBJECTREF)left;
311 OBJECTREF refR = (OBJECTREF)right;
315 FC_RETURN_BOOL(TRUE);
320 FC_RETURN_BOOL(FALSE);
323 if ((refL->GetMethodTable() == g_pRuntimeTypeClass || refR->GetMethodTable() == g_pRuntimeTypeClass))
325 // Quick path for negative common case
326 FC_RETURN_BOOL(FALSE);
329 // The fast path didn't get us the result
330 // Let's try the slow path: refL.Equals(refR);
331 FC_INNER_RETURN(FC_BOOL_RET, (FC_BOOL_RET)(!!TypeEqualSlow(refL, refR, __me)));
335 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::TypeNEQ, Object* left, Object* right)
339 OBJECTREF refL = (OBJECTREF)left;
340 OBJECTREF refR = (OBJECTREF)right;
344 FC_RETURN_BOOL(FALSE);
349 FC_RETURN_BOOL(TRUE);
352 if ((refL->GetMethodTable() == g_pRuntimeTypeClass || refR->GetMethodTable() == g_pRuntimeTypeClass))
354 // Quick path for negative common case
355 FC_RETURN_BOOL(TRUE);
358 // The fast path didn't get us the result
359 // Let's try the slow path: refL.Equals(refR);
360 FC_INNER_RETURN(FC_BOOL_RET, (FC_BOOL_RET)(!TypeEqualSlow(refL, refR, __me)));
364 #include <optdefault.h>
369 #ifdef FEATURE_COMINTEROP
370 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsWindowsRuntimeObjectType, ReflectClassBaseObject *rtTypeUNSAFE)
374 BOOL isWindowsRuntimeType = FALSE;
376 TypeHandle typeHandle = rtTypeUNSAFE->GetType();
377 MethodTable *pMT = typeHandle.GetMethodTable();
381 isWindowsRuntimeType = pMT->IsWinRTObjectType();
384 FC_RETURN_BOOL(isWindowsRuntimeType);
388 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsTypeExportedToWindowsRuntime, ReflectClassBaseObject *rtTypeUNSAFE)
392 BOOL isExportedToWinRT = FALSE;
394 TypeHandle typeHandle = rtTypeUNSAFE->GetType();
395 MethodTable *pMT = typeHandle.GetMethodTable();
399 isExportedToWinRT = pMT->IsExportedToWinRT();
402 FC_RETURN_BOOL(isExportedToWinRT);
405 #endif // FEATURE_COMINTEROP
407 NOINLINE static MethodDesc * RestoreMethodHelper(MethodDesc * pMethod, LPVOID __me)
409 FC_INNER_PROLOG_NO_ME_SETUP();
411 HELPER_METHOD_FRAME_BEGIN_RET_0();
412 pMethod->CheckRestore();
413 HELPER_METHOD_FRAME_END();
420 FCIMPL1(MethodDesc *, RuntimeTypeHandle::GetFirstIntroducedMethod, ReflectClassBaseObject *pTypeUNSAFE) {
423 PRECONDITION(CheckPointer(pTypeUNSAFE));
427 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
428 TypeHandle typeHandle = refType->GetType();
430 if (typeHandle.IsGenericVariable())
431 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
433 if (typeHandle.IsTypeDesc()) {
434 if (!typeHandle.IsArray())
438 MethodTable* pMT = typeHandle.GetMethodTable();
442 MethodDesc* pMethod = MethodTable::IntroducedMethodIterator::GetFirst(pMT);
444 // The only method that can show up here unrestored is instantiated methods. Check for it before performing the expensive IsRestored() check.
445 if (pMethod != NULL && pMethod->GetClassification() == mcInstantiated && !pMethod->IsRestored()) {
446 FC_INNER_RETURN(MethodDesc *, RestoreMethodHelper(pMethod, __me));
449 _ASSERTE(pMethod == NULL || pMethod->IsRestored());
454 #include <optsmallperfcritical.h>
455 FCIMPL1(void, RuntimeTypeHandle::GetNextIntroducedMethod, MethodDesc ** ppMethod) {
458 PRECONDITION(CheckPointer(ppMethod));
459 PRECONDITION(CheckPointer(*ppMethod));
463 MethodDesc *pMethod = MethodTable::IntroducedMethodIterator::GetNext(*ppMethod);
467 if (pMethod != NULL && pMethod->GetClassification() == mcInstantiated && !pMethod->IsRestored()) {
468 FC_INNER_RETURN_VOID(RestoreMethodHelper(pMethod, __me));
471 _ASSERTE(pMethod == NULL || pMethod->IsRestored());
474 #include <optdefault.h>
476 FCIMPL1(INT32, RuntimeTypeHandle::GetCorElementType, ReflectClassBaseObject *pTypeUNSAFE) {
482 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
485 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
487 return refType->GetType().GetSignatureCorElementType();
491 FCIMPL1(AssemblyBaseObject*, RuntimeTypeHandle::GetAssembly, ReflectClassBaseObject *pTypeUNSAFE) {
497 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
500 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
502 DomainFile *pDomainFile = NULL;
504 Module *pModule = refType->GetType().GetAssembly()->GetManifestModule();
506 pDomainFile = pModule->FindDomainFile(GetAppDomain());
507 #ifdef FEATURE_LOADER_OPTIMIZATION
508 if (pDomainFile == NULL)
510 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
512 pDomainFile = GetAppDomain()->LoadDomainNeutralModuleDependency(pModule, FILE_LOADED);
514 HELPER_METHOD_FRAME_END();
516 #endif // FEATURE_LOADER_OPTIMIZATION
519 FC_RETURN_ASSEMBLY_OBJECT((DomainAssembly *)pDomainFile, refType);
524 FCIMPL1(FC_BOOL_RET, RuntimeFieldHandle::AcquiresContextFromThis, FieldDesc *pField)
528 PRECONDITION(CheckPointer(pField));
532 FC_RETURN_BOOL(pField->IsSharedByGenericInstantiations());
537 FCIMPL1(ReflectModuleBaseObject*, RuntimeTypeHandle::GetModule, ReflectClassBaseObject *pTypeUNSAFE) {
545 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
548 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
550 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
552 result = refType->GetType().GetModule();
554 END_SO_INTOLERANT_CODE;
556 FC_RETURN_MODULE_OBJECT(result, refType);
560 FCIMPL1(ReflectClassBaseObject *, RuntimeTypeHandle::GetBaseType, ReflectClassBaseObject *pTypeUNSAFE) {
566 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
569 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
571 TypeHandle typeHandle = refType->GetType();
573 if (typeHandle.IsGenericVariable())
574 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
576 if (typeHandle.IsTypeDesc()) {
577 if (!typeHandle.IsArray())
581 RETURN_CLASS_OBJECT(typeHandle.GetParent(), refType);
585 FCIMPL1(ReflectClassBaseObject *, RuntimeTypeHandle::GetElementType, ReflectClassBaseObject *pTypeUNSAFE) {
591 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
594 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
596 TypeHandle typeHandle = refType->GetType();
598 if (!typeHandle.IsTypeDesc())
601 if (typeHandle.IsGenericVariable())
604 TypeHandle typeReturn;
606 if (typeHandle.IsArray())
607 typeReturn = typeHandle.AsArray()->GetArrayElementTypeHandle();
609 typeReturn = typeHandle.AsTypeDesc()->GetTypeParam();
611 RETURN_CLASS_OBJECT(typeReturn, refType);
615 FCIMPL1(INT32, RuntimeTypeHandle::GetArrayRank, ReflectClassBaseObject *pTypeUNSAFE) {
618 PRECONDITION(CheckPointer(pTypeUNSAFE));
619 PRECONDITION(pTypeUNSAFE->GetType().IsArray());
623 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
625 return (INT32)refType->GetType().AsArray()->GetRank();
629 FCIMPL1(INT32, RuntimeTypeHandle::GetNumVirtuals, ReflectClassBaseObject *pTypeUNSAFE) {
635 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
638 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
640 TypeHandle typeHandle = refType->GetType();
642 if (typeHandle.IsGenericVariable())
643 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
645 MethodTable *pMT = typeHandle.GetMethodTable();
648 return (INT32)pMT->GetNumVirtuals();
650 return 0; //REVIEW: should this return the number of methods in Object?
654 FCIMPL2(MethodDesc *, RuntimeTypeHandle::GetMethodAt, ReflectClassBaseObject *pTypeUNSAFE, INT32 slot) {
660 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
663 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
665 TypeHandle typeHandle = refType->GetType();
667 MethodDesc* pRetMethod = NULL;
669 if (typeHandle.IsGenericVariable())
670 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
672 if (slot < 0 || slot >= (INT32)typeHandle.GetMethodTable()->GetNumVirtuals())
673 FCThrowRes(kArgumentException, W("Arg_ArgumentOutOfRangeException"));
675 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
676 pRetMethod = typeHandle.GetMethodTable()->GetMethodDescForSlot((DWORD)slot);
677 HELPER_METHOD_FRAME_END();
684 FCIMPL3(FC_BOOL_RET, RuntimeTypeHandle::GetFields, ReflectClassBaseObject *pTypeUNSAFE, INT32 **result, INT32 *pCount) {
690 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
692 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
694 TypeHandle typeHandle = refType->GetType();
696 if (!pCount || !result)
697 FCThrow(kArgumentNullException);
699 if (typeHandle.IsGenericVariable())
700 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
702 if (typeHandle.IsTypeDesc()) {
704 FC_RETURN_BOOL(TRUE);
707 MethodTable *pMT= typeHandle.GetMethodTable();
709 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
712 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
713 // <TODO>Check this approximation - we may be losing exact type information </TODO>
714 ApproxFieldDescIterator fdIterator(pMT, ApproxFieldDescIterator::ALL_FIELDS);
715 INT32 count = (INT32)fdIterator.Count();
723 for(INT32 i = 0; i < count; i ++)
724 result[i] = (INT32*)fdIterator.Next();
729 HELPER_METHOD_FRAME_END();
730 FC_RETURN_BOOL(retVal);
734 void QCALLTYPE RuntimeMethodHandle::ConstructInstantiation(MethodDesc * pMethod, DWORD format, QCall::StringHandleOnStack retString)
741 TypeString::AppendInst(ss, pMethod->LoadMethodInstantiation(), format);
747 void QCALLTYPE RuntimeTypeHandle::ConstructName(EnregisteredTypeHandle pTypeHandle, DWORD format, QCall::StringHandleOnStack retString)
754 TypeString::AppendType(ss, TypeHandle::FromPtr(pTypeHandle), format);
760 PTRARRAYREF CopyRuntimeTypeHandles(TypeHandle * prgTH, FixupPointer<TypeHandle> * prgTH2, INT32 numTypeHandles, BinderClassID arrayElemType)
769 PTRARRAYREF refReturn = NULL;
770 PTRARRAYREF refArray = NULL;
772 if (numTypeHandles == 0)
775 _ASSERTE((prgTH != NULL) || (prgTH2 != NULL));
778 _ASSERTE(prgTH2 == NULL);
781 GCPROTECT_BEGIN(refArray);
782 TypeHandle thRuntimeType = TypeHandle(MscorlibBinder::GetClass(arrayElemType));
783 TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(thRuntimeType, ELEMENT_TYPE_SZARRAY);
784 refArray = (PTRARRAYREF)AllocateArrayEx(arrayHandle, &numTypeHandles, 1);
786 for (INT32 i = 0; i < numTypeHandles; i++)
793 th = prgTH2[i].GetValue();
795 OBJECTREF refType = th.GetManagedClassObject();
796 refArray->SetAt(i, refType);
799 refReturn = refArray;
805 void QCALLTYPE RuntimeTypeHandle::GetConstraints(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retTypeArray)
809 TypeHandle* constraints = NULL;
813 TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
815 if (!typeHandle.IsGenericVariable())
816 COMPlusThrow(kArgumentException, W("Arg_InvalidHandle"));
818 TypeVarTypeDesc* pGenericVariable = typeHandle.AsGenericVariable();
821 constraints = pGenericVariable->GetConstraints(&dwCount);
824 retTypeArray.Set(CopyRuntimeTypeHandles(constraints, NULL, dwCount, CLASS__TYPE));
831 FCIMPL1(PtrArray*, RuntimeTypeHandle::GetInterfaces, ReflectClassBaseObject *pTypeUNSAFE) {
837 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
840 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
842 TypeHandle typeHandle = refType->GetType();
844 if (typeHandle.IsGenericVariable())
845 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
847 INT32 ifaceCount = 0;
849 PTRARRAYREF refRetVal = NULL;
850 HELPER_METHOD_FRAME_BEGIN_RET_2(refRetVal, refType);
852 if (typeHandle.IsTypeDesc())
854 if (typeHandle.IsArray())
856 ifaceCount = typeHandle.GetMethodTable()->GetNumInterfaces();
865 ifaceCount = typeHandle.GetMethodTable()->GetNumInterfaces();
868 // Allocate the array
871 TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(g_pRuntimeTypeClass), ELEMENT_TYPE_SZARRAY);
872 refRetVal = (PTRARRAYREF)AllocateArrayEx(arrayHandle, &ifaceCount, 1);
874 // populate type array
877 MethodTable::InterfaceMapIterator it = typeHandle.GetMethodTable()->IterateInterfaceMap();
880 OBJECTREF refInterface = it.GetInterface()->GetManagedClassObject();
881 refRetVal->SetAt(i, refInterface);
882 _ASSERTE(refRetVal->GetAt(i) != NULL);
887 HELPER_METHOD_FRAME_END();
889 return (PtrArray*)OBJECTREFToObject(refRetVal);
893 FCIMPL1(INT32, RuntimeTypeHandle::GetAttributes, ReflectClassBaseObject *pTypeUNSAFE) {
899 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
902 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
904 TypeHandle typeHandle = refType->GetType();
906 if (typeHandle.IsTypeDesc()) {
908 if (typeHandle.IsGenericVariable()) {
912 if (!typeHandle.IsArray())
916 #ifdef FEATURE_COMINTEROP
917 // __ComObject types are always public.
918 if (IsComObjectClass(typeHandle))
919 return (typeHandle.GetMethodTable()->GetAttrClass() & tdVisibilityMask) | tdPublic;
920 #endif // FEATURE_COMINTEROP
924 ret = (INT32)typeHandle.GetMethodTable()->GetAttrClass();
930 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsValueType, ReflectClassBaseObject *pTypeUNSAFE)
937 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
939 _ASSERTE(refType != NULL);
941 TypeHandle typeHandle = refType->GetType();
943 FC_RETURN_BOOL(typeHandle.IsValueType());
947 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsInterface, ReflectClassBaseObject *pTypeUNSAFE)
954 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
956 _ASSERTE(refType != NULL);
958 TypeHandle typeHandle = refType->GetType();
960 FC_RETURN_BOOL(typeHandle.IsInterface());
965 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsByRefLike, ReflectClassBaseObject *pTypeUNSAFE)
972 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
974 _ASSERTE(refType != NULL);
976 TypeHandle typeHandle = refType->GetType();
978 FC_RETURN_BOOL(typeHandle.IsByRefLike());
984 RuntimeTypeHandle::IsVisible(
985 EnregisteredTypeHandle pTypeHandle)
993 BOOL fIsExternallyVisible = FALSE;
997 TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
999 _ASSERTE(!typeHandle.IsNull());
1001 fIsExternallyVisible = typeHandle.IsExternallyVisible();
1005 return fIsExternallyVisible;
1006 } // RuntimeTypeHandle::IsVisible
1008 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::IsComObject, ReflectClassBaseObject *pTypeUNSAFE, CLR_BOOL isGenericCOM) {
1016 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1018 if (refType == NULL)
1019 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1021 TypeHandle typeHandle = refType->GetType();
1023 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
1026 ret = IsComObjectClass(typeHandle);
1028 ret = IsComWrapperClass(typeHandle);
1030 HELPER_METHOD_FRAME_END();
1032 FC_RETURN_BOOL(ret);
1036 FCIMPL1(LPCUTF8, RuntimeTypeHandle::GetUtf8Name, ReflectClassBaseObject* pTypeUNSAFE) {
1042 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1044 if (refType == NULL)
1045 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1047 TypeHandle typeHandle = refType->GetType();
1048 INT32 tkTypeDef = mdTypeDefNil;
1049 LPCUTF8 szName = NULL;
1051 if (typeHandle.IsGenericVariable())
1052 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1054 if (typeHandle.IsTypeDesc())
1055 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1057 MethodTable* pMT= typeHandle.GetMethodTable();
1060 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1062 tkTypeDef = (INT32)pMT->GetCl();
1064 if (IsNilToken(tkTypeDef))
1065 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1067 if (FAILED(pMT->GetMDImport()->GetNameOfTypeDef(tkTypeDef, &szName, NULL)))
1069 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
1072 _ASSERTE(CheckPointer(szName, NULL_OK));
1078 FCIMPL1(INT32, RuntimeTypeHandle::GetToken, ReflectClassBaseObject *pTypeUNSAFE) {
1084 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1086 if (refType == NULL)
1087 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1089 TypeHandle typeHandle = refType->GetType();
1091 if (typeHandle.IsTypeDesc())
1093 if (typeHandle.IsGenericVariable())
1095 INT32 tkTypeDef = typeHandle.AsGenericVariable()->GetToken();
1097 _ASSERTE(!IsNilToken(tkTypeDef) && TypeFromToken(tkTypeDef) == mdtGenericParam);
1102 return mdTypeDefNil;
1105 return (INT32)typeHandle.AsMethodTable()->GetCl();
1109 PVOID QCALLTYPE RuntimeTypeHandle::GetGCHandle(EnregisteredTypeHandle pTypeHandle, INT32 handleType)
1113 OBJECTHANDLE objHandle = NULL;
1119 TypeHandle th = TypeHandle::FromPtr(pTypeHandle);
1120 assert(handleType >= HNDTYPE_WEAK_SHORT && handleType <= HNDTYPE_WEAK_WINRT);
1121 objHandle = th.GetDomain()->CreateTypedHandle(NULL, static_cast<HandleType>(handleType));
1122 th.GetLoaderAllocator()->RegisterHandleForCleanup(objHandle);
1129 void QCALLTYPE RuntimeTypeHandle::VerifyInterfaceIsImplemented(EnregisteredTypeHandle pTypeHandle, EnregisteredTypeHandle pIFaceHandle)
1135 TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
1136 TypeHandle ifaceHandle = TypeHandle::FromPtr(pIFaceHandle);
1138 if (typeHandle.IsGenericVariable())
1139 COMPlusThrow(kArgumentException, W("Arg_InvalidHandle"));
1141 if (typeHandle.IsTypeDesc()) {
1142 if (!typeHandle.IsArray())
1143 COMPlusThrow(kArgumentException, W("Arg_NotFoundIFace"));
1146 if (typeHandle.IsInterface())
1147 COMPlusThrow(kArgumentException, W("Argument_InterfaceMap"));
1149 if (!ifaceHandle.IsInterface())
1150 COMPlusThrow(kArgumentException, W("Arg_MustBeInterface"));
1152 // First try the cheap check, which amounts to iterating the interface map looking for
1153 // the ifaceHandle MethodTable.
1154 if (!typeHandle.GetMethodTable()->ImplementsInterface(ifaceHandle.AsMethodTable()))
1155 { // If the cheap check fails, try the more expensive but complete check.
1156 if (!typeHandle.CanCastTo(ifaceHandle))
1157 { // If the complete check fails, we're certain that this type
1158 // does not implement the interface specified.
1159 COMPlusThrow(kArgumentException, W("Arg_NotFoundIFace"));
1166 MethodDesc* QCALLTYPE RuntimeTypeHandle::GetInterfaceMethodImplementation(EnregisteredTypeHandle pTypeHandle, EnregisteredTypeHandle pOwner, MethodDesc * pMD)
1170 MethodDesc* pResult = nullptr;
1174 TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
1175 TypeHandle thOwnerOfMD = TypeHandle::FromPtr(pOwner);
1177 // Ok to have INVALID_SLOT in the case where abstract class does not implement an interface method.
1178 // This case can not be reproed using C# "implements" all interface methods
1179 // with at least an abstract method. b19897_GetInterfaceMap_Abstract.exe tests this case.
1180 //@TODO:STUBDISPATCH: Don't need to track down the implementation, just the declaration, and this can
1181 //@TODO: be done faster - just need to make a function FindDispatchDecl.
1182 DispatchSlot slot(typeHandle.GetMethodTable()->FindDispatchSlotForInterfaceMD(thOwnerOfMD, pMD));
1184 pResult = slot.GetMethodDesc();
1191 void QCALLTYPE RuntimeTypeHandle::GetDefaultConstructor(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retMethod)
1197 MethodDesc* pCtor = NULL;
1199 TypeHandle typeHandle = TypeHandle::FromPtr(pTypeHandle);
1201 if (!typeHandle.IsTypeDesc())
1203 MethodTable* pMethodTable = typeHandle.AsMethodTable();
1204 if (pMethodTable->HasDefaultConstructor())
1205 pCtor = pMethodTable->GetDefaultConstructor();
1211 retMethod.Set(pCtor->GetStubMethodInfo());
1218 FCIMPL1(ReflectMethodObject*, RuntimeTypeHandle::GetDeclaringMethod, ReflectClassBaseObject *pTypeUNSAFE) {
1224 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1226 if (refType == NULL)
1227 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1229 TypeHandle typeHandle = refType->GetType();;
1231 if (!typeHandle.IsTypeDesc())
1234 TypeVarTypeDesc* pGenericVariable = typeHandle.AsGenericVariable();
1235 mdToken defToken = pGenericVariable->GetTypeOrMethodDef();
1236 if (TypeFromToken(defToken) != mdtMethodDef)
1239 REFLECTMETHODREF pRet = NULL;
1240 HELPER_METHOD_FRAME_BEGIN_RET_0();
1241 MethodDesc * pMD = pGenericVariable->LoadOwnerMethod();
1242 pMD->CheckRestore();
1243 pRet = pMD->GetStubMethodInfo();
1244 HELPER_METHOD_FRAME_END();
1246 return (ReflectMethodObject*)OBJECTREFToObject(pRet);
1250 FCIMPL1(ReflectClassBaseObject*, RuntimeTypeHandle::GetDeclaringType, ReflectClassBaseObject *pTypeUNSAFE) {
1256 TypeHandle retTypeHandle;
1258 BOOL fThrowException = FALSE;
1259 LPCWSTR argName = W("Arg_InvalidHandle");
1260 RuntimeExceptionKind reKind = kArgumentNullException;
1262 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1264 if (refType == NULL)
1265 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1267 TypeHandle typeHandle = refType->GetType();
1269 MethodTable* pMT = NULL;
1270 mdTypeDef tkTypeDef = mdTokenNil;
1272 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
1273 if (typeHandle.IsTypeDesc()) {
1275 if (typeHandle.IsGenericVariable()) {
1276 TypeVarTypeDesc* pGenericVariable = typeHandle.AsGenericVariable();
1277 mdToken defToken = pGenericVariable->GetTypeOrMethodDef();
1279 // Try the fast way first (if the declaring type has been loaded already).
1280 if (TypeFromToken(defToken) == mdtMethodDef)
1282 MethodDesc * retMethod = pGenericVariable->GetModule()->LookupMethodDef(defToken);
1283 if (retMethod != NULL)
1284 retTypeHandle = retMethod->GetMethodTable();
1288 retTypeHandle = pGenericVariable->GetModule()->LookupTypeDef(defToken);
1291 if (!retTypeHandle.IsNull() && retTypeHandle.IsFullyLoaded())
1294 // OK, need to go the slow way and load the type first.
1295 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
1297 if (TypeFromToken(defToken) == mdtMethodDef)
1299 retTypeHandle = pGenericVariable->LoadOwnerMethod()->GetMethodTable();
1303 retTypeHandle = pGenericVariable->LoadOwnerType();
1305 retTypeHandle.CheckRestore();
1307 HELPER_METHOD_FRAME_END();
1310 if (!typeHandle.IsArray())
1312 retTypeHandle = TypeHandle();
1317 pMT = typeHandle.GetMethodTable();
1321 fThrowException = TRUE;
1325 if(!pMT->GetClass()->IsNested())
1327 retTypeHandle = TypeHandle();
1331 tkTypeDef = pMT->GetCl();
1333 if (FAILED(typeHandle.GetModule()->GetMDImport()->GetNestedClassProps(tkTypeDef, &tkTypeDef)))
1335 fThrowException = TRUE;
1336 reKind = kBadImageFormatException;
1341 // Try the fast way first (if the declaring type has been loaded already).
1342 retTypeHandle = typeHandle.GetModule()->LookupTypeDef(tkTypeDef);
1343 if (retTypeHandle.IsNull())
1345 // OK, need to go the slow way and load the type first.
1346 HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
1348 retTypeHandle = ClassLoader::LoadTypeDefThrowing(typeHandle.GetModule(), tkTypeDef,
1349 ClassLoader::ThrowIfNotFound,
1350 ClassLoader::PermitUninstDefOrRef);
1352 HELPER_METHOD_FRAME_END();
1356 END_SO_INTOLERANT_CODE;
1358 if (fThrowException)
1360 FCThrowRes(reKind, argName);
1363 RETURN_CLASS_OBJECT(retTypeHandle, refType);
1367 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::CanCastTo, ReflectClassBaseObject *pTypeUNSAFE, ReflectClassBaseObject *pTargetUNSAFE) {
1374 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1375 REFLECTCLASSBASEREF refTarget = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTargetUNSAFE);
1377 if ((refType == NULL) || (refTarget == NULL))
1378 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1380 TypeHandle fromHandle = refType->GetType();
1381 TypeHandle toHandle = refTarget->GetType();
1385 TypeHandle::CastResult r = fromHandle.CanCastToNoGC(toHandle);
1386 if (r == TypeHandle::MaybeCast)
1388 HELPER_METHOD_FRAME_BEGIN_RET_2(refType, refTarget);
1389 iRetVal = fromHandle.CanCastTo(toHandle);
1390 HELPER_METHOD_FRAME_END();
1394 iRetVal = (r == TypeHandle::CanCast);
1397 // We allow T to be cast to Nullable<T>
1398 if (!iRetVal && Nullable::IsNullableType(toHandle) && !fromHandle.IsTypeDesc())
1400 HELPER_METHOD_FRAME_BEGIN_RET_2(refType, refTarget);
1401 if (Nullable::IsNullableForType(toHandle, fromHandle.AsMethodTable()))
1405 HELPER_METHOD_FRAME_END();
1408 FC_RETURN_BOOL(iRetVal);
1412 void QCALLTYPE RuntimeTypeHandle::GetTypeByNameUsingCARules(LPCWSTR pwzClassName, QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retType)
1416 TypeHandle typeHandle;
1421 COMPlusThrowArgumentNull(W("className"),W("ArgumentNull_String"));
1423 typeHandle = TypeName::GetTypeUsingCASearchRules(pwzClassName, pModule->GetAssembly());
1426 retType.Set(typeHandle.GetManagedClassObject());
1433 void QCALLTYPE RuntimeTypeHandle::GetTypeByName(LPCWSTR pwzClassName, BOOL bThrowOnError, BOOL bIgnoreCase, BOOL bReflectionOnly,
1434 QCall::StackCrawlMarkHandle pStackMark,
1435 ICLRPrivBinder * pPrivHostBinder,
1436 BOOL bLoadTypeFromPartialNameHack, QCall::ObjectHandleOnStack retType,
1437 QCall::ObjectHandleOnStack keepAlive)
1441 TypeHandle typeHandle;
1446 COMPlusThrowArgumentNull(W("className"),W("ArgumentNull_String"));
1449 typeHandle = TypeName::GetTypeManaged(pwzClassName, NULL, bThrowOnError, bIgnoreCase, bReflectionOnly, /*bProhibitAsmQualifiedName =*/ FALSE, pStackMark,
1450 bLoadTypeFromPartialNameHack, (OBJECTREF*)keepAlive.m_ppObject,
1454 if (!typeHandle.IsNull())
1457 retType.Set(typeHandle.GetManagedClassObject());
1465 FCIMPL6(FC_BOOL_RET, RuntimeTypeHandle::SatisfiesConstraints, PTR_ReflectClassBaseObject pParamTypeUNSAFE, TypeHandle *typeContextArgs, INT32 typeContextCount, TypeHandle *methodContextArgs, INT32 methodContextCount, PTR_ReflectClassBaseObject pArgumentTypeUNSAFE);
1469 PRECONDITION(CheckPointer(typeContextArgs, NULL_OK));
1470 PRECONDITION(CheckPointer(methodContextArgs, NULL_OK));
1474 REFLECTCLASSBASEREF refParamType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pParamTypeUNSAFE);
1475 REFLECTCLASSBASEREF refArgumentType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pArgumentTypeUNSAFE);
1477 TypeHandle thGenericParameter = refParamType->GetType();
1478 TypeHandle thGenericArgument = refArgumentType->GetType();
1479 BOOL bResult = FALSE;
1480 SigTypeContext typeContext;
1482 Instantiation classInst;
1483 Instantiation methodInst;
1485 if (typeContextArgs != NULL)
1487 classInst = Instantiation(typeContextArgs, typeContextCount);
1490 if (methodContextArgs != NULL)
1492 methodInst = Instantiation(methodContextArgs, methodContextCount);
1495 SigTypeContext::InitTypeContext(classInst, methodInst, &typeContext);
1497 HELPER_METHOD_FRAME_BEGIN_RET_2(refParamType, refArgumentType);
1499 bResult = thGenericParameter.AsGenericVariable()->SatisfiesConstraints(&typeContext, thGenericArgument);
1501 HELPER_METHOD_FRAME_END();
1503 FC_RETURN_BOOL(bResult);
1507 void QCALLTYPE RuntimeTypeHandle::GetInstantiation(EnregisteredTypeHandle pType, QCall::ObjectHandleOnStack retTypes, BOOL fAsRuntimeTypeArray)
1513 TypeHandle typeHandle = TypeHandle::FromPtr(pType);
1514 Instantiation inst = typeHandle.GetInstantiation();
1516 retTypes.Set(CopyRuntimeTypeHandles(NULL, inst.GetRawArgs(), inst.GetNumArgs(), fAsRuntimeTypeArray ? CLASS__CLASS : CLASS__TYPE));
1522 void QCALLTYPE RuntimeTypeHandle::MakeArray(EnregisteredTypeHandle pTypeHandle, INT32 rank, QCall::ObjectHandleOnStack retType)
1526 TypeHandle arrayHandle;
1529 arrayHandle = TypeHandle::FromPtr(pTypeHandle).MakeArray(rank);
1531 retType.Set(arrayHandle.GetManagedClassObject());
1537 void QCALLTYPE RuntimeTypeHandle::MakeSZArray(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType)
1541 TypeHandle arrayHandle;
1544 arrayHandle = TypeHandle::FromPtr(pTypeHandle).MakeSZArray();
1546 retType.Set(arrayHandle.GetManagedClassObject());
1552 void QCALLTYPE RuntimeTypeHandle::MakePointer(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType)
1556 TypeHandle pointerHandle;
1559 pointerHandle = TypeHandle::FromPtr(pTypeHandle).MakePointer();
1561 retType.Set(pointerHandle.GetManagedClassObject());
1567 void QCALLTYPE RuntimeTypeHandle::MakeByRef(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType)
1571 TypeHandle byRefHandle;
1574 byRefHandle = TypeHandle::FromPtr(pTypeHandle).MakeByRef();
1576 retType.Set(byRefHandle.GetManagedClassObject());
1582 BOOL QCALLTYPE RuntimeTypeHandle::IsCollectible(EnregisteredTypeHandle pTypeHandle)
1586 BOOL retVal = FALSE;
1589 retVal = TypeHandle::FromPtr(pTypeHandle).GetLoaderAllocator()->IsCollectible();
1595 void QCALLTYPE RuntimeTypeHandle::Instantiate(EnregisteredTypeHandle pTypeHandle, TypeHandle * pInstArray, INT32 cInstArray, QCall::ObjectHandleOnStack retType)
1602 type = TypeHandle::FromPtr(pTypeHandle).Instantiate(Instantiation(pInstArray, cInstArray));
1604 retType.Set(type.GetManagedClassObject());
1610 void QCALLTYPE RuntimeTypeHandle::GetGenericTypeDefinition(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType)
1618 TypeHandle genericType = TypeHandle::FromPtr(pTypeHandle);
1620 typeDef = ClassLoader::LoadTypeDefThrowing(genericType.GetModule(),
1621 genericType.GetMethodTable()->GetCl(),
1622 ClassLoader::ThrowIfNotFound,
1623 ClassLoader::PermitUninstDefOrRef);
1626 retType.Set(typeDef.GetManagedClassObject());
1633 FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::CompareCanonicalHandles, ReflectClassBaseObject *pLeftUNSAFE, ReflectClassBaseObject *pRightUNSAFE)
1637 REFLECTCLASSBASEREF refLeft = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pLeftUNSAFE);
1638 REFLECTCLASSBASEREF refRight = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pRightUNSAFE);
1640 if ((refLeft == NULL) || (refRight == NULL))
1641 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1643 FC_RETURN_BOOL(refLeft->GetType().GetCanonicalMethodTable() == refRight->GetType().GetCanonicalMethodTable());
1647 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::HasInstantiation, PTR_ReflectClassBaseObject pTypeUNSAFE)
1651 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1653 if (refType == NULL)
1654 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1656 FC_RETURN_BOOL(refType->GetType().HasInstantiation());
1660 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsGenericTypeDefinition, PTR_ReflectClassBaseObject pTypeUNSAFE)
1664 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1666 if (refType == NULL)
1667 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1669 FC_RETURN_BOOL(refType->GetType().IsGenericTypeDefinition());
1673 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsGenericVariable, PTR_ReflectClassBaseObject pTypeUNSAFE)
1677 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1679 if (refType == NULL)
1680 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1682 FC_RETURN_BOOL(refType->GetType().IsGenericVariable());
1686 FCIMPL1(INT32, RuntimeTypeHandle::GetGenericVariableIndex, PTR_ReflectClassBaseObject pTypeUNSAFE)
1690 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1692 if (refType == NULL)
1693 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1695 return (INT32)refType->GetType().AsGenericVariable()->GetIndex();
1699 FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::ContainsGenericVariables, 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().ContainsGenericVariables());
1712 FCIMPL1(IMDInternalImport*, RuntimeTypeHandle::GetMetadataImport, ReflectClassBaseObject * pTypeUNSAFE)
1716 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
1718 if (refType == NULL)
1719 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1721 Module *pModule = refType->GetType().GetModule();
1723 return pModule->GetMDImport();
1728 //***********************************************************************************
1729 //***********************************************************************************
1730 //***********************************************************************************
1732 void * QCALLTYPE RuntimeMethodHandle::GetFunctionPointer(MethodDesc * pMethod)
1740 funcPtr = (void*)pMethod->GetMultiCallableAddrOfCode();
1747 FCIMPL1(LPCUTF8, RuntimeMethodHandle::GetUtf8Name, MethodDesc *pMethod) {
1753 LPCUTF8 szName = NULL;
1756 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1758 szName = pMethod->GetName();
1760 _ASSERTE(CheckPointer(szName, NULL_OK));
1766 FCIMPL2(FC_BOOL_RET, RuntimeMethodHandle::MatchesNameHash, MethodDesc * pMethod, ULONG hash)
1770 FC_RETURN_BOOL(pMethod->MightHaveName(hash));
1774 FCIMPL1(StringObject*, RuntimeMethodHandle::GetName, MethodDesc *pMethod) {
1781 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1783 STRINGREF refName = NULL;
1785 HELPER_METHOD_FRAME_BEGIN_RET_0();
1786 refName = StringObject::NewString(pMethod->GetName());
1787 HELPER_METHOD_FRAME_END();
1789 return (StringObject*)OBJECTREFToObject(refName);
1793 FCIMPL1(INT32, RuntimeMethodHandle::GetAttributes, MethodDesc *pMethod) {
1800 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1803 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
1804 retVal = (INT32)pMethod->GetAttrs();
1805 END_SO_INTOLERANT_CODE;
1810 FCIMPL1(INT32, RuntimeMethodHandle::GetImplAttributes, ReflectMethodObject *pMethodUNSAFE) {
1817 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1819 MethodDesc* pMethod = pMethodUNSAFE->GetMethod();
1820 INT32 attributes = 0;
1822 if (IsNilToken(pMethod->GetMemberDef()))
1825 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
1827 attributes = (INT32)pMethod->GetImplAttrs();
1829 END_SO_INTOLERANT_CODE;
1836 FCIMPL1(ReflectClassBaseObject*, RuntimeMethodHandle::GetDeclaringType, MethodDesc *pMethod) {
1839 PRECONDITION(CheckPointer(pMethod));
1844 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1846 MethodTable *pMT = pMethod->GetMethodTable();
1847 TypeHandle declType(pMT);
1850 HELPER_METHOD_FRAME_BEGIN_RET_0();
1852 // Load the TypeDesc for the array type. Note the returned type is approximate, i.e.
1853 // if shared between reference array types then we will get object[] back.
1854 DWORD rank = pMT->GetRank();
1855 TypeHandle elemType = pMT->GetApproxArrayElementTypeHandle();
1856 declType = ClassLoader::LoadArrayTypeThrowing(elemType, pMT->GetInternalCorElementType(), rank);
1857 HELPER_METHOD_FRAME_END();
1859 RETURN_CLASS_OBJECT(declType, NULL);
1863 FCIMPL1(INT32, RuntimeMethodHandle::GetSlot, MethodDesc *pMethod) {
1870 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1872 return (INT32)pMethod->GetSlot();
1876 FCIMPL3(Object *, SignatureNative::GetCustomModifiers, SignatureNative* pSignatureUNSAFE,
1877 INT32 parameter, CLR_BOOL fRequired)
1886 SIGNATURENATIVEREF pSig;
1890 gc.pSig = (SIGNATURENATIVEREF)pSignatureUNSAFE;
1893 HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
1896 BYTE callConv = *(BYTE*)gc.pSig->GetCorSig();
1897 SigTypeContext typeContext;
1898 gc.pSig->GetTypeContext(&typeContext);
1899 MetaSig sig(gc.pSig->GetCorSig(),
1900 gc.pSig->GetCorSigSize(),
1901 gc.pSig->GetModule(),
1903 (callConv & IMAGE_CEE_CS_CALLCONV_MASK) == IMAGE_CEE_CS_CALLCONV_FIELD ? MetaSig::sigField : MetaSig::sigMember);
1904 _ASSERTE(callConv == sig.GetCallingConventionInfo());
1906 SigPointer argument(NULL, 0);
1908 PRECONDITION(sig.GetCallingConvention() != IMAGE_CEE_CS_CALLCONV_FIELD || parameter == 1);
1912 argument = sig.GetReturnProps();
1916 for(INT32 i = 0; i < parameter; i++)
1919 argument = sig.GetArgProps();
1922 //if (parameter < 0 || parameter > (INT32)sig.NumFixedArgs())
1923 // FCThrowResVoid(kArgumentNullException, W("Arg_ArgumentOutOfRangeException"));
1925 SigPointer sp = argument;
1926 Module* pModule = sig.GetModule();
1928 CorElementType cmodType;
1930 CorElementType cmodTypeExpected = fRequired ? ELEMENT_TYPE_CMOD_REQD : ELEMENT_TYPE_CMOD_OPT;
1932 // Discover the number of required and optional custom modifiers.
1936 IfFailThrow(sp.GetByte(&data));
1937 cmodType = (CorElementType)data;
1939 if (cmodType == ELEMENT_TYPE_CMOD_REQD || cmodType == ELEMENT_TYPE_CMOD_OPT)
1941 if (cmodType == cmodTypeExpected)
1946 else if (cmodType != ELEMENT_TYPE_SENTINEL)
1951 IfFailThrow(sp.GetToken(NULL));
1954 // Reset sp and populate the arrays for the required and optional custom
1955 // modifiers now that we know how long they should be.
1958 MethodTable *pMT = MscorlibBinder::GetClass(CLASS__TYPE);
1959 TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pMT), ELEMENT_TYPE_SZARRAY);
1961 gc.retVal = (PTRARRAYREF) AllocateArrayEx(arrayHandle, &cMods, 1);
1966 IfFailThrow(sp.GetByte(&data));
1967 cmodType = (CorElementType)data;
1970 IfFailThrow(sp.GetToken(&token));
1972 if (cmodType == cmodTypeExpected)
1974 TypeHandle th = ClassLoader::LoadTypeDefOrRefOrSpecThrowing(pModule, token,
1976 ClassLoader::ThrowIfNotFound,
1977 ClassLoader::FailIfUninstDefOrRef);
1979 OBJECTREF refType = th.GetManagedClassObject();
1980 gc.retVal->SetAt(--cMods, refType);
1984 HELPER_METHOD_FRAME_END();
1986 return OBJECTREFToObject(gc.retVal);
1990 FCIMPL1(INT32, RuntimeMethodHandle::GetMethodDef, ReflectMethodObject *pMethodUNSAFE) {
1997 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
1999 MethodDesc* pMethod = pMethodUNSAFE->GetMethod();
2001 if (pMethod->HasMethodInstantiation())
2003 HELPER_METHOD_FRAME_BEGIN_RET_1(pMethodUNSAFE);
2005 pMethod = pMethod->StripMethodInstantiation();
2007 HELPER_METHOD_FRAME_END();
2010 INT32 tkMethodDef = (INT32)pMethod->GetMemberDef();
2011 _ASSERTE(TypeFromToken(tkMethodDef) == mdtMethodDef);
2013 if (IsNilToken(tkMethodDef) || TypeFromToken(tkMethodDef) != mdtMethodDef)
2014 return mdMethodDefNil;
2020 FCIMPL6(void, SignatureNative::GetSignature,
2021 SignatureNative* pSignatureNativeUNSAFE,
2022 PCCOR_SIGNATURE pCorSig, DWORD cCorSig,
2023 FieldDesc *pFieldDesc, ReflectMethodObject *pMethodUNSAFE, ReflectClassBaseObject *pDeclaringTypeUNSAFE) {
2026 PRECONDITION(pDeclaringTypeUNSAFE || pMethodUNSAFE->GetMethod()->IsDynamicMethod());
2027 PRECONDITION(CheckPointer(pCorSig, NULL_OK));
2028 PRECONDITION(CheckPointer(pMethodUNSAFE, NULL_OK));
2029 PRECONDITION(CheckPointer(pFieldDesc, NULL_OK));
2035 REFLECTCLASSBASEREF refDeclaringType;
2036 REFLECTMETHODREF refMethod;
2037 SIGNATURENATIVEREF pSig;
2040 gc.refDeclaringType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pDeclaringTypeUNSAFE);
2041 gc.refMethod = (REFLECTMETHODREF)ObjectToOBJECTREF(pMethodUNSAFE);
2042 gc.pSig = (SIGNATURENATIVEREF)pSignatureNativeUNSAFE;
2044 MethodDesc *pMethod;
2045 TypeHandle declType;
2047 if (gc.refDeclaringType == NULL)
2049 // for dynamic method, see precondition
2050 pMethod = gc.refMethod->GetMethod();
2051 declType = pMethod->GetMethodTable();
2055 pMethod = gc.refMethod != NULL ? gc.refMethod->GetMethod() : NULL;
2056 declType = gc.refDeclaringType->GetType();
2059 HELPER_METHOD_FRAME_BEGIN_PROTECT(gc);
2061 Module* pModule = declType.GetModule();
2065 pMethod->GetSig(&pCorSig, &cCorSig);
2066 if (pMethod->GetClassification() == mcInstantiated)
2068 LoaderAllocator *pLoaderAllocator = pMethod->GetLoaderAllocator();
2069 if (pLoaderAllocator->IsCollectible())
2070 gc.pSig->SetKeepAlive(pLoaderAllocator->GetExposedObject());
2073 else if (pFieldDesc)
2074 pFieldDesc->GetSig(&pCorSig, &cCorSig);
2076 gc.pSig->m_sig = pCorSig;
2077 gc.pSig->m_cSig = cCorSig;
2078 gc.pSig->m_pMethod = pMethod;
2080 REFLECTCLASSBASEREF refDeclType = (REFLECTCLASSBASEREF)declType.GetManagedClassObject();
2081 gc.pSig->SetDeclaringType(refDeclType);
2083 PREFIX_ASSUME(pCorSig!= NULL);
2084 BYTE callConv = *(BYTE*)pCorSig;
2085 SigTypeContext typeContext;
2087 SigTypeContext::InitTypeContext(
2088 pMethod, declType.GetClassOrArrayInstantiation(), pMethod->LoadMethodInstantiation(), &typeContext);
2090 SigTypeContext::InitTypeContext(declType, &typeContext);
2091 MetaSig msig(pCorSig, cCorSig, pModule, &typeContext,
2092 (callConv & IMAGE_CEE_CS_CALLCONV_MASK) == IMAGE_CEE_CS_CALLCONV_FIELD ? MetaSig::sigField : MetaSig::sigMember);
2094 if (callConv == IMAGE_CEE_CS_CALLCONV_FIELD)
2096 msig.NextArgNormalized();
2098 OBJECTREF refRetType = msig.GetLastTypeHandleThrowing().GetManagedClassObject();
2099 gc.pSig->SetReturnType(refRetType);
2103 gc.pSig->SetCallingConvention(msig.GetCallingConventionInfo());
2105 OBJECTREF refRetType = msig.GetRetTypeHandleThrowing().GetManagedClassObject();
2106 gc.pSig->SetReturnType(refRetType);
2108 INT32 nArgs = msig.NumFixedArgs();
2109 TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(g_pRuntimeTypeClass), ELEMENT_TYPE_SZARRAY);
2111 PTRARRAYREF ptrArrayarguments = (PTRARRAYREF) AllocateArrayEx(arrayHandle, &nArgs, 1);
2112 gc.pSig->SetArgumentArray(ptrArrayarguments);
2114 for (INT32 i = 0; i < nArgs; i++)
2118 OBJECTREF refArgType = msig.GetLastTypeHandleThrowing().GetManagedClassObject();
2119 gc.pSig->SetArgument(i, refArgType);
2122 _ASSERTE(gc.pSig->m_returnType != NULL);
2125 HELPER_METHOD_FRAME_END();
2129 FCIMPL2(FC_BOOL_RET, SignatureNative::CompareSig, SignatureNative* pLhsUNSAFE, SignatureNative* pRhsUNSAFE)
2137 SIGNATURENATIVEREF pLhs;
2138 SIGNATURENATIVEREF pRhs;
2141 gc.pLhs = (SIGNATURENATIVEREF)pLhsUNSAFE;
2142 gc.pRhs = (SIGNATURENATIVEREF)pRhsUNSAFE;
2144 HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
2146 ret = MetaSig::CompareMethodSigs(
2147 gc.pLhs->GetCorSig(), gc.pLhs->GetCorSigSize(), gc.pLhs->GetModule(), NULL,
2148 gc.pRhs->GetCorSig(), gc.pRhs->GetCorSigSize(), gc.pRhs->GetModule(), NULL);
2150 HELPER_METHOD_FRAME_END();
2151 FC_RETURN_BOOL(ret);
2155 void QCALLTYPE RuntimeMethodHandle::GetMethodInstantiation(MethodDesc * pMethod, QCall::ObjectHandleOnStack retTypes, BOOL fAsRuntimeTypeArray)
2160 Instantiation inst = pMethod->LoadMethodInstantiation();
2163 retTypes.Set(CopyRuntimeTypeHandles(NULL, inst.GetRawArgs(), inst.GetNumArgs(), fAsRuntimeTypeArray ? CLASS__CLASS : CLASS__TYPE));
2169 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::HasMethodInstantiation, MethodDesc * pMethod)
2173 FC_RETURN_BOOL(pMethod->HasMethodInstantiation());
2177 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsGenericMethodDefinition, MethodDesc * pMethod)
2181 FC_RETURN_BOOL(pMethod->IsGenericMethodDefinition());
2185 FCIMPL1(INT32, RuntimeMethodHandle::GetGenericParameterCount, MethodDesc * pMethod)
2189 return pMethod->GetNumGenericMethodArgs();
2193 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsDynamicMethod, MethodDesc * pMethod)
2197 FC_RETURN_BOOL(pMethod->IsNoMetadata());
2201 FCIMPL1(Object*, RuntimeMethodHandle::GetResolver, MethodDesc * pMethod)
2206 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2208 OBJECTREF resolver = NULL;
2209 if (pMethod->IsLCGMethod())
2211 resolver = pMethod->AsDynamicMethodDesc()->GetLCGMethodResolver()->GetManagedResolver();
2213 return OBJECTREFToObject(resolver);
2217 void QCALLTYPE RuntimeMethodHandle::Destroy(MethodDesc * pMethod)
2223 if (pMethod == NULL)
2224 COMPlusThrowArgumentNull(NULL, W("Arg_InvalidHandle"));
2226 DynamicMethodDesc* pDynamicMethodDesc = pMethod->AsDynamicMethodDesc();
2230 // Destroy should be called only if the managed part is gone.
2231 _ASSERTE(OBJECTREFToObject(pDynamicMethodDesc->GetLCGMethodResolver()->GetManagedResolver()) == NULL);
2233 // Fire Unload Dynamic Method Event here
2234 ETW::MethodLog::DynamicMethodDestroyed(pMethod);
2236 BEGIN_PIN_PROFILER(CORProfilerIsMonitoringDynamicFunctionUnloads());
2237 g_profControlBlock.pProfInterface->DynamicMethodUnloaded((FunctionID)pMethod);
2240 pDynamicMethodDesc->Destroy();
2245 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsTypicalMethodDefinition, ReflectMethodObject *pMethodUNSAFE)
2250 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2252 MethodDesc* pMethod = pMethodUNSAFE->GetMethod();
2254 FC_RETURN_BOOL(pMethod->IsTypicalMethodDefinition());
2258 void QCALLTYPE RuntimeMethodHandle::GetTypicalMethodDefinition(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod)
2266 _ASSERTE(((ReflectMethodObject *)(*refMethod.m_ppObject))->GetMethod() == pMethod);
2269 MethodDesc *pMethodTypical = pMethod->LoadTypicalMethodDefinition();
2270 if (pMethodTypical != pMethod)
2273 refMethod.Set(pMethodTypical->GetStubMethodInfo());
2280 void QCALLTYPE RuntimeMethodHandle::StripMethodInstantiation(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod)
2287 COMPlusThrowArgumentNull(NULL, W("Arg_InvalidHandle"));
2292 _ASSERTE(((ReflectMethodObject *)(*refMethod.m_ppObject))->GetMethod() == pMethod);
2295 MethodDesc *pMethodStripped = pMethod->StripMethodInstantiation();
2296 if (pMethodStripped != pMethod)
2299 refMethod.Set(pMethodStripped->GetStubMethodInfo());
2306 // In the VM there might be more than one MethodDescs for a "method"
2307 // examples are methods on generic types which may have additional instantiating stubs
2308 // and methods on value types which may have additional unboxing stubs.
2310 // For generic methods we always hand out an instantiating stub except for a generic method definition
2311 // For non-generic methods on generic types we need an instantiating stub if it's one of the following
2312 // - static method on a generic class
2313 // - static or instance method on a generic interface
2314 // - static or instance method on a generic value type
2315 // The Reflection policy is to always hand out instantiating stubs in these cases
2317 // For methods on non-generic value types we can use either the cannonical method or the unboxing stub
2318 // The Reflection policy is to always hand out unboxing stubs if the methods are virtual methods
2319 // The reason for this is that in the current implementation of the class loader, the v-table slots for
2320 // those methods point to unboxing stubs already. Note that this is just a implementation choice
2321 // that might change in the future. But we should always keep this Reflection policy an invariant.
2323 // For virtual methods on generic value types (intersection of the two cases), reflection will hand
2324 // out an unboxing instantiating stub
2326 // GetInstantiatingStub is called to:
2327 // 1. create an InstantiatedMethodDesc for a generic method when calling BindGenericArguments() on a generic
2328 // method. In this case instArray will not be null.
2329 // 2. create an InstantiatedMethodDesc for a method in a generic class. In this case instArray will be null.
2330 // 3. create an UnboxingStub for a method in a value type. In this case instArray will be null.
2331 // For case 2 and 3, an instantiating stub or unboxing stub might not be needed in which case the original
2332 // MethodDesc is returned.
2333 FCIMPL3(MethodDesc*, RuntimeMethodHandle::GetStubIfNeeded,
2334 MethodDesc *pMethod,
2335 ReflectClassBaseObject *pTypeUNSAFE,
2336 PtrArray* instArrayUNSAFE)
2343 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
2344 PTRARRAYREF instArray = (PTRARRAYREF)ObjectToOBJECTREF(instArrayUNSAFE);
2346 if (refType == NULL)
2347 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2349 TypeHandle instType = refType->GetType();
2350 MethodDesc *pNewMethod = pMethod;
2354 FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
2356 if (instType.IsNull())
2357 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2359 // Perf optimization: this logic is actually duplicated in FindOrCreateAssociatedMethodDescForReflection, but since it
2360 // is the more common case it's worth the duplicate check here to avoid the helper method frame
2361 if ( instArray == NULL &&
2362 ( pMethod->HasMethodInstantiation() ||
2363 ( !instType.IsValueType() &&
2364 ( !instType.HasInstantiation() || instType.IsGenericTypeDefinition() ) ) ) )
2369 HELPER_METHOD_FRAME_BEGIN_RET_2(refType, instArray);
2371 TypeHandle *inst = NULL;
2374 if (instArray != NULL)
2376 ntypars = instArray->GetNumComponents();
2378 size_t size = ntypars * sizeof(TypeHandle);
2379 if ((size / sizeof(TypeHandle)) != ntypars) // uint over/underflow
2380 COMPlusThrow(kArgumentException);
2381 inst = (TypeHandle*) _alloca(size);
2383 for (DWORD i = 0; i < ntypars; i++)
2385 REFLECTCLASSBASEREF instRef = (REFLECTCLASSBASEREF)instArray->GetAt(i);
2387 if (instRef == NULL)
2388 COMPlusThrowArgumentNull(W("inst"), W("ArgumentNull_ArrayElement"));
2390 inst[i] = instRef->GetType();
2394 pNewMethod = MethodDesc::FindOrCreateAssociatedMethodDescForReflection(pMethod, instType, Instantiation(inst, ntypars));
2396 HELPER_METHOD_FRAME_END();
2403 FCIMPL2(MethodDesc*, RuntimeMethodHandle::GetMethodFromCanonical, MethodDesc *pMethod, ReflectClassBaseObject *pTypeUNSAFE)
2407 PRECONDITION(CheckPointer(pMethod));
2411 REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
2413 TypeHandle instType = refType->GetType();
2414 MethodDesc* pMDescInCanonMT = instType.GetMethodTable()->GetParallelMethodDesc(pMethod);
2416 return pMDescInCanonMT;
2421 FCIMPL2(RuntimeMethodBody *, RuntimeMethodHandle::GetMethodBody, ReflectMethodObject *pMethodUNSAFE, ReflectClassBaseObject *pDeclaringTypeUNSAFE)
2431 RUNTIMEMETHODBODYREF MethodBodyObj;
2432 RUNTIMEEXCEPTIONHANDLINGCLAUSEREF EHClauseObj;
2433 RUNTIMELOCALVARIABLEINFOREF RuntimeLocalVariableInfoObj;
2435 BASEARRAYREF TempArray;
2436 REFLECTCLASSBASEREF declaringType;
2437 REFLECTMETHODREF refMethod;
2440 gc.MethodBodyObj = NULL;
2441 gc.EHClauseObj = NULL;
2442 gc.RuntimeLocalVariableInfoObj = NULL;
2444 gc.TempArray = NULL;
2445 gc.declaringType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pDeclaringTypeUNSAFE);
2446 gc.refMethod = (REFLECTMETHODREF)ObjectToOBJECTREF(pMethodUNSAFE);
2450 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2452 MethodDesc* pMethod = gc.refMethod->GetMethod();
2454 TypeHandle declaringType = gc.declaringType == NULL ? TypeHandle() : gc.declaringType->GetType();
2456 if (!pMethod->IsIL())
2459 HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
2461 MethodDesc *pMethodIL = pMethod;
2462 if (pMethod->IsWrapperStub())
2463 pMethodIL = pMethod->GetWrappedMethodDesc();
2465 COR_ILMETHOD* pILHeader = pMethodIL->GetILHeader();
2469 MethodTable * pExceptionHandlingClauseMT = MscorlibBinder::GetClass(CLASS__RUNTIME_EH_CLAUSE);
2470 TypeHandle thEHClauseArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pExceptionHandlingClauseMT), ELEMENT_TYPE_SZARRAY);
2472 MethodTable * pLocalVariableMT = MscorlibBinder::GetClass(CLASS__RUNTIME_LOCAL_VARIABLE_INFO);
2473 TypeHandle thLocalVariableArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pLocalVariableMT), ELEMENT_TYPE_SZARRAY);
2475 Module* pModule = pMethod->GetModule();
2476 COR_ILMETHOD_DECODER::DecoderStatus status;
2477 COR_ILMETHOD_DECODER header(pILHeader, pModule->GetMDImport(), &status);
2479 if (status != COR_ILMETHOD_DECODER::SUCCESS)
2481 if (status == COR_ILMETHOD_DECODER::VERIFICATION_ERROR)
2483 // Throw a verification HR
2484 COMPlusThrowHR(COR_E_VERIFICATION);
2488 COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
2492 gc.MethodBodyObj = (RUNTIMEMETHODBODYREF)AllocateObject(MscorlibBinder::GetClass(CLASS__RUNTIME_METHOD_BODY));
2494 gc.MethodBodyObj->_maxStackSize = header.GetMaxStack();
2495 gc.MethodBodyObj->_initLocals = !!(header.GetFlags() & CorILMethod_InitLocals);
2498 gc.MethodBodyObj->_localVarSigToken = header.GetLocalVarSigTok();
2500 gc.MethodBodyObj->_localVarSigToken = 0;
2502 // Allocate the array of IL and fill it in from the method header.
2503 BYTE* pIL = const_cast<BYTE*>(header.Code);
2504 COUNT_T cIL = header.GetCodeSize();
2505 gc.U1Array = (U1ARRAYREF) AllocatePrimitiveArray(ELEMENT_TYPE_U1, cIL);
2507 SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_IL, gc.U1Array, GetAppDomain());
2508 memcpyNoGCRefs(gc.MethodBodyObj->_IL->GetDataPtr(), pIL, cIL);
2510 // Allocate the array of exception clauses.
2511 INT32 cEh = (INT32)header.EHCount();
2512 const COR_ILMETHOD_SECT_EH* ehInfo = header.EH;
2513 gc.TempArray = (BASEARRAYREF) AllocateArrayEx(thEHClauseArray, &cEh, 1);
2515 SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_exceptionClauses, gc.TempArray, GetAppDomain());
2517 for (INT32 i = 0; i < cEh; i++)
2519 COR_ILMETHOD_SECT_EH_CLAUSE_FAT ehBuff;
2520 const COR_ILMETHOD_SECT_EH_CLAUSE_FAT* ehClause =
2521 (const COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)ehInfo->EHClause(i, &ehBuff);
2523 gc.EHClauseObj = (RUNTIMEEXCEPTIONHANDLINGCLAUSEREF) AllocateObject(pExceptionHandlingClauseMT);
2525 gc.EHClauseObj->_flags = ehClause->GetFlags();
2526 gc.EHClauseObj->_tryOffset = ehClause->GetTryOffset();
2527 gc.EHClauseObj->_tryLength = ehClause->GetTryLength();
2528 gc.EHClauseObj->_handlerOffset = ehClause->GetHandlerOffset();
2529 gc.EHClauseObj->_handlerLength = ehClause->GetHandlerLength();
2531 if ((ehClause->GetFlags() & COR_ILEXCEPTION_CLAUSE_FILTER) == 0)
2532 gc.EHClauseObj->_catchToken = ehClause->GetClassToken();
2534 gc.EHClauseObj->_filterOffset = ehClause->GetFilterOffset();
2536 gc.MethodBodyObj->_exceptionClauses->SetAt(i, (OBJECTREF) gc.EHClauseObj);
2537 SetObjectReference((OBJECTREF*)&(gc.EHClauseObj->_methodBody), (OBJECTREF)gc.MethodBodyObj, GetAppDomain());
2540 if (header.LocalVarSig != NULL)
2542 SigTypeContext sigTypeContext(pMethod, declaringType, pMethod->LoadMethodInstantiation());
2543 MetaSig metaSig(header.LocalVarSig,
2544 header.cbLocalVarSig,
2547 MetaSig::sigLocalVars);
2548 INT32 cLocals = metaSig.NumFixedArgs();
2549 gc.TempArray = (BASEARRAYREF) AllocateArrayEx(thLocalVariableArray, &cLocals, 1);
2550 SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_localVariables, gc.TempArray, GetAppDomain());
2552 for (INT32 i = 0; i < cLocals; i ++)
2554 gc.RuntimeLocalVariableInfoObj = (RUNTIMELOCALVARIABLEINFOREF)AllocateObject(pLocalVariableMT);
2556 gc.RuntimeLocalVariableInfoObj->_localIndex = i;
2560 CorElementType eType;
2561 IfFailThrow(metaSig.GetArgProps().PeekElemType(&eType));
2562 if (ELEMENT_TYPE_PINNED == eType)
2563 gc.RuntimeLocalVariableInfoObj->_isPinned = TRUE;
2565 TypeHandle tempType= metaSig.GetArgProps().GetTypeHandleThrowing(pModule, &sigTypeContext);
2566 OBJECTREF refLocalType = tempType.GetManagedClassObject();
2567 gc.RuntimeLocalVariableInfoObj->SetType(refLocalType);
2568 gc.MethodBodyObj->_localVariables->SetAt(i, (OBJECTREF) gc.RuntimeLocalVariableInfoObj);
2574 gc.TempArray = (BASEARRAYREF) AllocateArrayEx(thLocalVariableArray, &cLocals, 1);
2575 SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_localVariables, gc.TempArray, GetAppDomain());
2579 HELPER_METHOD_FRAME_END();
2581 return (RuntimeMethodBody*)OBJECTREFToObject(gc.MethodBodyObj);
2585 FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsConstructor, MethodDesc *pMethod)
2589 PRECONDITION(CheckPointer(pMethod));
2594 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
2595 ret = (BOOL)pMethod->IsClassConstructorOrCtor();
2596 END_SO_INTOLERANT_CODE;
2597 FC_RETURN_BOOL(ret);
2601 FCIMPL1(Object*, RuntimeMethodHandle::GetLoaderAllocator, MethodDesc *pMethod)
2608 OBJECTREF loaderAllocator = NULL;
2611 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2613 HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(loaderAllocator);
2615 LoaderAllocator *pLoaderAllocator = pMethod->GetLoaderAllocator();
2616 loaderAllocator = pLoaderAllocator->GetExposedObject();
2618 HELPER_METHOD_FRAME_END();
2620 return OBJECTREFToObject(loaderAllocator);
2624 //*********************************************************************************************
2625 //*********************************************************************************************
2626 //*********************************************************************************************
2628 FCIMPL1(StringObject*, RuntimeFieldHandle::GetName, ReflectFieldObject *pFieldUNSAFE) {
2634 REFLECTFIELDREF refField = (REFLECTFIELDREF)ObjectToOBJECTREF(pFieldUNSAFE);
2636 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2638 FieldDesc *pField = refField->GetField();
2640 STRINGREF refString = NULL;
2641 HELPER_METHOD_FRAME_BEGIN_RET_1(refField);
2643 refString = StringObject::NewString(pField->GetName());
2645 HELPER_METHOD_FRAME_END();
2646 return (StringObject*)OBJECTREFToObject(refString);
2650 FCIMPL1(LPCUTF8, RuntimeFieldHandle::GetUtf8Name, FieldDesc *pField) {
2653 PRECONDITION(CheckPointer(pField));
2657 LPCUTF8 szFieldName;
2659 if (FAILED(pField->GetName_NoThrow(&szFieldName)))
2661 FCThrow(kBadImageFormatException);
2667 FCIMPL2(FC_BOOL_RET, RuntimeFieldHandle::MatchesNameHash, FieldDesc * pField, ULONG hash)
2671 FC_RETURN_BOOL(pField->MightHaveName(hash));
2675 FCIMPL1(INT32, RuntimeFieldHandle::GetAttributes, FieldDesc *pField) {
2682 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2685 BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
2686 ret = (INT32)pField->GetAttributes();
2687 END_SO_INTOLERANT_CODE;
2692 FCIMPL1(ReflectClassBaseObject*, RuntimeFieldHandle::GetApproxDeclaringType, FieldDesc *pField) {
2699 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2701 TypeHandle th = TypeHandle(pField->GetApproxEnclosingMethodTable()); // <REVISIT_TODO> this needs to be checked - see bug 184355 </REVISIT_TODO>
2702 RETURN_CLASS_OBJECT(th, NULL);
2706 FCIMPL1(INT32, RuntimeFieldHandle::GetToken, ReflectFieldObject *pFieldUNSAFE) {
2712 REFLECTFIELDREF refField = (REFLECTFIELDREF)ObjectToOBJECTREF(pFieldUNSAFE);
2714 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2716 FieldDesc *pField = refField->GetField();
2718 INT32 tkFieldDef = (INT32)pField->GetMemberDef();
2719 _ASSERTE(!IsNilToken(tkFieldDef) || tkFieldDef == mdFieldDefNil);
2724 FCIMPL2(FieldDesc*, RuntimeFieldHandle::GetStaticFieldForGenericType, FieldDesc *pField, ReflectClassBaseObject *pDeclaringTypeUNSAFE)
2731 REFLECTCLASSBASEREF refDeclaringType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pDeclaringTypeUNSAFE);
2733 if ((refDeclaringType == NULL) || (pField == NULL))
2734 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2736 TypeHandle declaringType = refDeclaringType->GetType();
2739 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2740 if (declaringType.IsTypeDesc())
2741 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2742 MethodTable *pMT = declaringType.AsMethodTable();
2744 _ASSERTE(pField->IsStatic());
2745 if (pMT->HasGenericsStaticsInfo())
2746 pField = pMT->GetFieldDescByIndex(pField->GetApproxEnclosingMethodTable()->GetIndexForFieldDesc(pField));
2747 _ASSERTE(!pField->IsSharedByGenericInstantiations());
2748 _ASSERTE(pField->GetEnclosingMethodTable() == pMT);
2754 FCIMPL1(ReflectModuleBaseObject*, AssemblyHandle::GetManifestModule, AssemblyBaseObject* pAssemblyUNSAFE) {
2757 ASSEMBLYREF refAssembly = (ASSEMBLYREF)ObjectToOBJECTREF(pAssemblyUNSAFE);
2759 if (refAssembly == NULL)
2760 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2762 DomainAssembly *pAssembly = refAssembly->GetDomainAssembly();
2763 Assembly* currentAssembly = pAssembly->GetCurrentAssembly();
2765 if (currentAssembly == NULL)
2768 Module *pModule = currentAssembly->GetManifestModule();
2769 DomainFile * pDomainFile = pModule->FindDomainFile(GetAppDomain());
2774 HELPER_METHOD_FRAME_BEGIN_RET_1(refAssembly);
2775 orModule = (pDomainFile != NULL) ? pDomainFile->GetExposedModuleObjectIfExists() : NULL;
2776 if (orModule == NULL)
2777 orModule = pModule->GetExposedObject();
2779 OBJECTREF orModule = (pDomainFile != NULL) ? pDomainFile->GetExposedModuleObjectIfExists() : NULL;
2780 if (orModule != NULL)
2781 return (ReflectModuleBaseObject*)OBJECTREFToObject(orModule);
2783 HELPER_METHOD_FRAME_BEGIN_RET_1(refAssembly);
2784 orModule = pModule->GetExposedObject();
2787 HELPER_METHOD_FRAME_END();
2788 return (ReflectModuleBaseObject*)OBJECTREFToObject(orModule);
2793 FCIMPL1(INT32, AssemblyHandle::GetToken, AssemblyBaseObject* pAssemblyUNSAFE) {
2796 ASSEMBLYREF refAssembly = (ASSEMBLYREF)ObjectToOBJECTREF(pAssemblyUNSAFE);
2798 if (refAssembly == NULL)
2799 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2801 DomainAssembly *pAssembly = refAssembly->GetDomainAssembly();
2802 mdAssembly token = mdAssemblyNil;
2804 IMDInternalImport *mdImport = pAssembly->GetCurrentAssembly()->GetManifestImport();
2808 if (FAILED(mdImport->GetAssemblyFromScope(&token)))
2810 FCThrow(kBadImageFormatException);
2819 void QCALLTYPE ModuleHandle::GetPEKind(QCall::ModuleHandle pModule, DWORD* pdwPEKind, DWORD* pdwMachine)
2824 pModule->GetFile()->GetPEKindAndMachine(pdwPEKind, pdwMachine);
2828 FCIMPL1(INT32, ModuleHandle::GetMDStreamVersion, ReflectModuleBaseObject * pModuleUNSAFE)
2832 REFLECTMODULEBASEREF refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
2834 if (refModule == NULL)
2835 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2837 Module *pModule = refModule->GetModule();
2839 if (pModule->IsResource())
2842 return pModule->GetMDImport()->GetMetadataStreamVersion();
2846 void QCALLTYPE ModuleHandle::GetModuleType(QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retType)
2850 TypeHandle globalTypeHandle = TypeHandle();
2856 globalTypeHandle = TypeHandle(pModule->GetGlobalMethodTable());
2858 EX_SWALLOW_NONTRANSIENT;
2860 if (!globalTypeHandle.IsNull())
2863 retType.Set(globalTypeHandle.GetManagedClassObject());
2871 FCIMPL1(INT32, ModuleHandle::GetToken, ReflectModuleBaseObject * pModuleUNSAFE) {
2877 REFLECTMODULEBASEREF refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
2879 if (refModule == NULL)
2880 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
2882 Module *pModule = refModule->GetModule();
2884 if (pModule->IsResource())
2887 return pModule->GetMDImport()->GetModuleFromScope();
2891 FCIMPL1(IMDInternalImport*, ModuleHandle::GetMetadataImport, 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();
2909 BOOL QCALLTYPE ModuleHandle::ContainsPropertyMatchingHash(QCall::ModuleHandle pModule, INT32 tkProperty, ULONG hash)
2913 BOOL fContains = TRUE;
2917 fContains = pModule->MightContainMatchingProperty(tkProperty, hash);
2924 void QCALLTYPE ModuleHandle::ResolveType(QCall::ModuleHandle pModule, INT32 tkType, TypeHandle *typeArgs, INT32 typeArgsCount, TypeHandle *methodArgs, INT32 methodArgsCount, QCall::ObjectHandleOnStack retType)
2928 TypeHandle typeHandle;
2932 _ASSERTE(!IsNilToken(tkType));
2934 SigTypeContext typeContext(Instantiation(typeArgs, typeArgsCount), Instantiation(methodArgs, methodArgsCount));
2935 typeHandle = ClassLoader::LoadTypeDefOrRefOrSpecThrowing(pModule, tkType, &typeContext,
2936 ClassLoader::ThrowIfNotFound,
2937 ClassLoader::PermitUninstDefOrRef);
2940 retType.Set(typeHandle.GetManagedClassObject());
2947 MethodDesc *QCALLTYPE ModuleHandle::ResolveMethod(QCall::ModuleHandle pModule, INT32 tkMemberRef, TypeHandle *typeArgs, INT32 typeArgsCount, TypeHandle *methodArgs, INT32 methodArgsCount)
2951 MethodDesc* pMD = NULL;
2955 _ASSERTE(!IsNilToken(tkMemberRef));
2957 BOOL strictMetadataChecks = (TypeFromToken(tkMemberRef) == mdtMethodSpec);
2959 SigTypeContext typeContext(Instantiation(typeArgs, typeArgsCount), Instantiation(methodArgs, methodArgsCount));
2960 pMD = MemberLoader::GetMethodDescFromMemberDefOrRefOrSpec(pModule, tkMemberRef, &typeContext, strictMetadataChecks, FALSE);
2962 // This will get us the instantiating or unboxing stub if needed
2963 pMD = MethodDesc::FindOrCreateAssociatedMethodDescForReflection(pMD, pMD->GetMethodTable(), pMD->GetMethodInstantiation());
2970 void QCALLTYPE ModuleHandle::ResolveField(QCall::ModuleHandle pModule, INT32 tkMemberRef, TypeHandle *typeArgs, INT32 typeArgsCount, TypeHandle *methodArgs, INT32 methodArgsCount, QCall::ObjectHandleOnStack retField)
2974 FieldDesc* pField = NULL;
2978 _ASSERTE(!IsNilToken(tkMemberRef));
2980 SigTypeContext typeContext(Instantiation(typeArgs, typeArgsCount), Instantiation(methodArgs, methodArgsCount));
2981 pField = MemberLoader::GetFieldDescFromMemberDefOrRef(pModule, tkMemberRef, &typeContext, FALSE);
2983 retField.Set(pField->GetStubFieldInfo());
2990 void QCALLTYPE ModuleHandle::GetAssembly(QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retAssembly)
2994 DomainAssembly *pAssembly = NULL;
2997 pAssembly = pModule->GetDomainAssembly();
3000 retAssembly.Set(pAssembly->GetExposedAssemblyObject());
3006 FCIMPL5(ReflectMethodObject*, ModuleHandle::GetDynamicMethod, ReflectMethodObject *pMethodUNSAFE, ReflectModuleBaseObject *pModuleUNSAFE, StringObject *name, U1Array *sig, Object *resolver) {
3009 PRECONDITION(CheckPointer(name));
3010 PRECONDITION(CheckPointer(sig));
3014 DynamicMethodDesc *pNewMD = NULL;
3019 OBJECTREF resolverRef;
3020 OBJECTREF methodRef;
3021 REFLECTMETHODREF retMethod;
3022 REFLECTMODULEBASEREF refModule;
3024 gc.nameRef = (STRINGREF)name;
3025 gc.resolverRef = (OBJECTREF)resolver;
3026 gc.methodRef = ObjectToOBJECTREF(pMethodUNSAFE);
3027 gc.retMethod = NULL;
3028 gc.refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
3030 if (gc.refModule == NULL)
3031 FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
3033 Module *pModule = gc.refModule->GetModule();
3035 HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
3037 DomainFile *pDomainModule = pModule->GetDomainFile();
3039 U1ARRAYREF dataArray = (U1ARRAYREF)sig;
3040 DWORD sigSize = dataArray->GetNumComponents();
3041 NewHolder<BYTE> pSig(new BYTE[sigSize]);
3042 memcpy(pSig, dataArray->GetDataPtr(), sigSize);
3044 DWORD length = gc.nameRef->GetStringLength();
3045 NewArrayHolder<char> pName(new char[(length + 1) * 2]);
3047 length = WszWideCharToMultiByte(CP_UTF8, 0, gc.nameRef->GetBuffer(), length, pName, (length + 1) * 2 - sizeof(char), NULL, NULL);
3049 pName[length / sizeof(char)] = '\0';
3051 DynamicMethodTable *pMTForDynamicMethods = pDomainModule->GetDynamicMethodTable();
3052 pNewMD = pMTForDynamicMethods->GetDynamicMethod(pSig, sigSize, pName);
3053 _ASSERTE(pNewMD != NULL);
3054 // pNewMD now owns pSig and pName.
3055 pSig.SuppressRelease();
3056 pName.SuppressRelease();
3058 // create a handle to hold the resolver objectref
3059 OBJECTHANDLE resolverHandle = pDomainModule->GetAppDomain()->CreateLongWeakHandle(gc.resolverRef);
3060 pNewMD->GetLCGMethodResolver()->SetManagedResolver(resolverHandle);
3061 gc.retMethod = pNewMD->GetStubMethodInfo();
3062 gc.retMethod->SetKeepAlive(gc.resolverRef);
3064 LoaderAllocator *pLoaderAllocator = pModule->GetLoaderAllocator();
3066 if (pLoaderAllocator->IsCollectible())
3067 pLoaderAllocator->AddReference();
3069 HELPER_METHOD_FRAME_END();
3071 return (ReflectMethodObject*)OBJECTREFToObject(gc.retMethod);
3075 void QCALLTYPE RuntimeMethodHandle::GetCallerType(QCall::StackCrawlMarkHandle pStackMark, QCall::ObjectHandleOnStack retType)
3081 MethodTable *pMT = NULL;
3083 pMT = SystemDomain::GetCallersType(pStackMark);
3086 retType.Set(pMT->GetManagedClassObject());