From ed1c27c7f4ef8006be26a5e27f9429ce96478679 Mon Sep 17 00:00:00 2001 From: Levi Broderick Date: Sun, 22 Nov 2020 15:31:10 -0800 Subject: [PATCH 1/5] Allow CreateInstanceForAnotherGenericParameter to take 2 args --- .../Generic/ArraySortHelper.CoreCLR.cs | 4 +- .../src/System/RuntimeHandles.cs | 52 +++++++++++++++- src/coreclr/src/vm/ecalllist.h | 2 +- src/coreclr/src/vm/reflectioninvocation.cpp | 62 ++++++++++--------- src/coreclr/src/vm/runtimehandles.h | 4 +- 5 files changed, 87 insertions(+), 37 deletions(-) diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.CoreCLR.cs index 5e7dd7ddc45342..da6adab43e2f2a 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.CoreCLR.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.CoreCLR.cs @@ -27,7 +27,7 @@ private static IArraySortHelper CreateArraySortHelper() if (typeof(IComparable).IsAssignableFrom(typeof(T))) { - defaultArraySortHelper = (IArraySortHelper)RuntimeTypeHandle.Allocate(typeof(GenericArraySortHelper).TypeHandle.Instantiate(new Type[] { typeof(T) })); + defaultArraySortHelper = (IArraySortHelper)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericArraySortHelper), (RuntimeType)typeof(T)); } else { @@ -62,7 +62,7 @@ private static IArraySortHelper CreateArraySortHelper() if (typeof(IComparable).IsAssignableFrom(typeof(TKey))) { - defaultArraySortHelper = (IArraySortHelper)RuntimeTypeHandle.Allocate(typeof(GenericArraySortHelper).TypeHandle.Instantiate(new Type[] { typeof(TKey), typeof(TValue) })); + defaultArraySortHelper = (IArraySortHelper)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericArraySortHelper), (RuntimeType)typeof(TKey), (RuntimeType)typeof(TValue)); } else { diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeHandles.cs index adc808e43de5af..4cdd5f69d39bc5 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -202,8 +202,49 @@ internal static bool HasElementType(RuntimeType type) [MethodImpl(MethodImplOptions.InternalCall)] internal static extern object Allocate(RuntimeType type); - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern object CreateInstanceForAnotherGenericParameter(RuntimeType type, RuntimeType genericParameter); + internal static object CreateInstanceForAnotherGenericParameter(RuntimeType type, RuntimeType genericParameter) + { + object? instantiatedObject = null; + + IntPtr typeHandle = genericParameter.GetTypeHandleInternal().Value; + _CreateInstanceForAnotherGenericParameter( + new QCallTypeHandle(ref type), + &typeHandle, + 1, + ObjectHandleOnStack.Create(ref instantiatedObject)); + + GC.KeepAlive(genericParameter); + return instantiatedObject!; + } + + internal static object CreateInstanceForAnotherGenericParameter(RuntimeType type, RuntimeType genericParameter1, RuntimeType genericParameter2) + { + object? instantiatedObject = null; + + IntPtr* pTypeHandles = stackalloc IntPtr[] + { + genericParameter1.GetTypeHandleInternal().Value, + genericParameter2.GetTypeHandleInternal().Value + }; + + _CreateInstanceForAnotherGenericParameter( + new QCallTypeHandle(ref type), + pTypeHandles, + 2, + ObjectHandleOnStack.Create(ref instantiatedObject)); + + GC.KeepAlive(genericParameter1); + GC.KeepAlive(genericParameter2); + + return instantiatedObject!; + } + + [DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)] + private static extern void _CreateInstanceForAnotherGenericParameter( + QCallTypeHandle baseType, + IntPtr* pTypeHandles, + int cTypeHandles, + ObjectHandleOnStack instantiatedObject); internal RuntimeType GetRuntimeType() { @@ -471,7 +512,12 @@ internal Type[] GetInstantiationPublic() internal RuntimeType Instantiate(Type[]? inst) { - // defensive copy to be sure array is not mutated from the outside during processing + // Defensive copy to ensure array is not mutated while during processing. + // Otherwise another thread could mutate the array after we've already + // fetched the underlying handles, resulting in our KeepAlive tracking + // the wrong values. + + inst = (Type[]?)inst?.Clone(); IntPtr[]? instHandles = CopyRuntimeTypeHandles(inst, out int instCount); fixed (IntPtr* pInst = instHandles) diff --git a/src/coreclr/src/vm/ecalllist.h b/src/coreclr/src/vm/ecalllist.h index 87389732f8d2e0..52e2dedec07ef5 100644 --- a/src/coreclr/src/vm/ecalllist.h +++ b/src/coreclr/src/vm/ecalllist.h @@ -190,7 +190,7 @@ FCFuncEnd() FCFuncStart(gCOMTypeHandleFuncs) FCFuncElement("CreateInstance", RuntimeTypeHandle::CreateInstance) - FCFuncElement("CreateInstanceForAnotherGenericParameter", RuntimeTypeHandle::CreateInstanceForGenericType) + QCFuncElement("_CreateInstanceForAnotherGenericParameter", RuntimeTypeHandle::CreateInstanceForGenericType) QCFuncElement("GetGCHandle", RuntimeTypeHandle::GetGCHandle) QCFuncElement("FreeGCHandle", RuntimeTypeHandle::FreeGCHandle) diff --git a/src/coreclr/src/vm/reflectioninvocation.cpp b/src/coreclr/src/vm/reflectioninvocation.cpp index e8bc4beb612186..a68c897ffb94d1 100644 --- a/src/coreclr/src/vm/reflectioninvocation.cpp +++ b/src/coreclr/src/vm/reflectioninvocation.cpp @@ -515,30 +515,28 @@ FCIMPL6(Object*, RuntimeTypeHandle::CreateInstance, ReflectClassBaseObject* refT } FCIMPLEND -FCIMPL2(Object*, RuntimeTypeHandle::CreateInstanceForGenericType, ReflectClassBaseObject* pTypeUNSAFE, ReflectClassBaseObject* pParameterTypeUNSAFE) { - FCALL_CONTRACT; - - struct _gc - { - OBJECTREF rv; - REFLECTCLASSBASEREF refType; - REFLECTCLASSBASEREF refParameterType; - } gc; - - gc.rv = NULL; - gc.refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE); - gc.refParameterType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pParameterTypeUNSAFE); +void QCALLTYPE RuntimeTypeHandle::CreateInstanceForGenericType( + QCall::TypeHandle pTypeHandle, + TypeHandle* pInstArray, + INT32 cInstArray, + QCall::ObjectHandleOnStack pInstantiatedObject +) +{ + CONTRACTL{ + QCALL_CHECK; + PRECONDITION(!pTypeHandle.AsTypeHandle().IsNull()); + PRECONDITION(cInstArray >= 0); + PRECONDITION(cInstArray == 0 || pInstArray != NULL); + } + CONTRACTL_END; - MethodDesc* pMeth; - TypeHandle genericType = gc.refType->GetType(); + TypeHandle genericType = pTypeHandle.AsTypeHandle(); - TypeHandle parameterHandle = gc.refParameterType->GetType(); + BEGIN_QCALL; _ASSERTE (genericType.HasInstantiation()); - HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc); - - TypeHandle instantiatedType = ((TypeHandle)genericType.GetCanonicalMethodTable()).Instantiate(Instantiation(¶meterHandle, 1)); + TypeHandle instantiatedType = ((TypeHandle)genericType.GetCanonicalMethodTable()).Instantiate(Instantiation(pInstArray, (DWORD)cInstArray)); // Get the type information associated with refThis MethodTable* pVMT = instantiatedType.GetMethodTable(); @@ -546,24 +544,30 @@ FCIMPL2(Object*, RuntimeTypeHandle::CreateInstanceForGenericType, ReflectClassBa _ASSERTE( !pVMT->IsAbstract() ||! instantiatedType.ContainsGenericVariables()); _ASSERTE(!pVMT->IsByRefLike() && pVMT->HasDefaultConstructor()); - pMeth = pVMT->GetDefaultConstructor(); - MethodDescCallSite ctor(pMeth); - // We've got the class, lets allocate it and call the constructor // Nullables don't take this path, if they do we need special logic to make an instance _ASSERTE(!Nullable::IsNullableType(instantiatedType)); - gc.rv = instantiatedType.GetMethodTable()->Allocate(); - ARG_SLOT arg = ObjToArgSlot(gc.rv); + { + GCX_COOP(); + + OBJECTREF newObj = instantiatedType.GetMethodTable()->Allocate(); + GCPROTECT_BEGIN(newObj); - // Call the method - TryCallMethod(&ctor, &arg, true); + MethodDesc* pMeth = pVMT->GetDefaultConstructor(); + MethodDescCallSite ctor(pMeth); - HELPER_METHOD_FRAME_END(); - return OBJECTREFToObject(gc.rv); + // Call the method + ARG_SLOT arg = ObjToArgSlot(newObj); + TryCallMethod(&ctor, &arg, true); + GCPROTECT_END(); + + pInstantiatedObject.Set(newObj); + } + + END_QCALL; } -FCIMPLEND NOINLINE FC_BOOL_RET IsInstanceOfTypeHelper(OBJECTREF obj, REFLECTCLASSBASEREF refType) { diff --git a/src/coreclr/src/vm/runtimehandles.h b/src/coreclr/src/vm/runtimehandles.h index 4063fd972237a3..2ef4c2904100fa 100644 --- a/src/coreclr/src/vm/runtimehandles.h +++ b/src/coreclr/src/vm/runtimehandles.h @@ -247,8 +247,8 @@ class RuntimeTypeHandle { static FCDECL1(MethodDesc *, GetFirstIntroducedMethod, ReflectClassBaseObject* pType); static FCDECL1(void, GetNextIntroducedMethod, MethodDesc **ppMethod); - static FCDECL2(Object*, CreateInstanceForGenericType, ReflectClassBaseObject* pType - , ReflectClassBaseObject* parameterType ); + static + void QCALLTYPE CreateInstanceForGenericType(QCall::TypeHandle pTypeHandle, TypeHandle *pInstArray, INT32 cInstArray, QCall::ObjectHandleOnStack pInstantiatedObject); static FCDECL1(IMDInternalImport*, GetMetadataImport, ReflectClassBaseObject * pModuleUNSAFE); From a0984d506ce9a4dcebae6dee92551d070e073134 Mon Sep 17 00:00:00 2001 From: Levi Broderick Date: Sun, 22 Nov 2020 18:16:28 -0800 Subject: [PATCH 2/5] PR feedback --- .../src/System/RuntimeHandles.cs | 12 +++--------- src/coreclr/src/vm/ecalllist.h | 2 +- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeHandles.cs index 4cdd5f69d39bc5..d4bf159d337878 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -207,7 +207,7 @@ internal static object CreateInstanceForAnotherGenericParameter(RuntimeType type object? instantiatedObject = null; IntPtr typeHandle = genericParameter.GetTypeHandleInternal().Value; - _CreateInstanceForAnotherGenericParameter( + CreateInstanceForAnotherGenericParameter( new QCallTypeHandle(ref type), &typeHandle, 1, @@ -227,7 +227,7 @@ internal static object CreateInstanceForAnotherGenericParameter(RuntimeType type genericParameter2.GetTypeHandleInternal().Value }; - _CreateInstanceForAnotherGenericParameter( + CreateInstanceForAnotherGenericParameter( new QCallTypeHandle(ref type), pTypeHandles, 2, @@ -240,7 +240,7 @@ internal static object CreateInstanceForAnotherGenericParameter(RuntimeType type } [DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)] - private static extern void _CreateInstanceForAnotherGenericParameter( + private static extern void CreateInstanceForAnotherGenericParameter( QCallTypeHandle baseType, IntPtr* pTypeHandles, int cTypeHandles, @@ -512,12 +512,6 @@ internal Type[] GetInstantiationPublic() internal RuntimeType Instantiate(Type[]? inst) { - // Defensive copy to ensure array is not mutated while during processing. - // Otherwise another thread could mutate the array after we've already - // fetched the underlying handles, resulting in our KeepAlive tracking - // the wrong values. - - inst = (Type[]?)inst?.Clone(); IntPtr[]? instHandles = CopyRuntimeTypeHandles(inst, out int instCount); fixed (IntPtr* pInst = instHandles) diff --git a/src/coreclr/src/vm/ecalllist.h b/src/coreclr/src/vm/ecalllist.h index 52e2dedec07ef5..7c793d3e40a348 100644 --- a/src/coreclr/src/vm/ecalllist.h +++ b/src/coreclr/src/vm/ecalllist.h @@ -190,7 +190,7 @@ FCFuncEnd() FCFuncStart(gCOMTypeHandleFuncs) FCFuncElement("CreateInstance", RuntimeTypeHandle::CreateInstance) - QCFuncElement("_CreateInstanceForAnotherGenericParameter", RuntimeTypeHandle::CreateInstanceForGenericType) + QCFuncElement("CreateInstanceForAnotherGenericParameter", RuntimeTypeHandle::CreateInstanceForGenericType) QCFuncElement("GetGCHandle", RuntimeTypeHandle::GetGCHandle) QCFuncElement("FreeGCHandle", RuntimeTypeHandle::FreeGCHandle) From 5a6682dce3d7538ab9b567da08d25901484bfe3f Mon Sep 17 00:00:00 2001 From: Levi Broderick Date: Sun, 22 Nov 2020 18:26:25 -0800 Subject: [PATCH 3/5] Fix possible GC holes in RuntimeHandles --- .../RuntimeHelpers.CoreCLR.cs | 3 +++ .../src/System/RuntimeHandles.cs | 23 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs index caaedd6199d628..95de9b788bfcb1 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs @@ -80,6 +80,9 @@ public static void PrepareMethod(RuntimeMethodHandle method) public static void PrepareMethod(RuntimeMethodHandle method, RuntimeTypeHandle[]? instantiation) { + // defensive copy of user-provided array, per CopyRuntimeTypeHandles contract + instantiation = (RuntimeTypeHandle[]?)instantiation?.Clone(); + unsafe { IntPtr[]? instantiationHandles = RuntimeTypeHandle.CopyRuntimeTypeHandles(instantiation, out int length); diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeHandles.cs index d4bf159d337878..30c9df8cefbdd5 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -162,6 +162,12 @@ internal static bool HasElementType(RuntimeType type) || (corElemType == CorElementType.ELEMENT_TYPE_BYREF); // IsByRef } + // ** WARNING ** + // Caller bears responsibility for ensuring that the provided Types remain + // GC-reachable while the unmanaged handles are being manipulated. The caller + // may need to make a defensive copy of the input array to ensure it's not + // mutated by another thread, and this defensive copy should be passed to + // a KeepAlive routine. internal static IntPtr[]? CopyRuntimeTypeHandles(RuntimeTypeHandle[]? inHandles, out int length) { if (inHandles == null || inHandles.Length == 0) @@ -179,6 +185,12 @@ internal static bool HasElementType(RuntimeType type) return outHandles; } + // ** WARNING ** + // Caller bears responsibility for ensuring that the provided Types remain + // GC-reachable while the unmanaged handles are being manipulated. The caller + // may need to make a defensive copy of the input array to ensure it's not + // mutated by another thread, and this defensive copy should be passed to + // a KeepAlive routine. internal static IntPtr[]? CopyRuntimeTypeHandles(Type[]? inHandles, out int length) { if (inHandles == null || inHandles.Length == 0) @@ -1239,6 +1251,10 @@ internal static RuntimeType ResolveTypeHandleInternal(RuntimeModule module, int throw new ArgumentOutOfRangeException(nameof(typeToken), SR.Format(SR.Argument_InvalidToken, typeToken, new ModuleHandle(module))); + // defensive copy of user-provided array, per CopyRuntimeTypeHandles contract + typeInstantiationContext = (RuntimeTypeHandle[]?)typeInstantiationContext?.Clone(); + methodInstantiationContext = (RuntimeTypeHandle[]?)methodInstantiationContext?.Clone(); + IntPtr[]? typeInstantiationContextHandles = RuntimeTypeHandle.CopyRuntimeTypeHandles(typeInstantiationContext, out int typeInstCount); IntPtr[]? methodInstantiationContextHandles = RuntimeTypeHandle.CopyRuntimeTypeHandles(methodInstantiationContext, out int methodInstCount); @@ -1272,6 +1288,9 @@ public RuntimeMethodHandle ResolveMethodHandle(int methodToken, RuntimeTypeHandl internal static IRuntimeMethodInfo ResolveMethodHandleInternal(RuntimeModule module, int methodToken, RuntimeTypeHandle[]? typeInstantiationContext, RuntimeTypeHandle[]? methodInstantiationContext) { + // defensive copy of user-provided array, per CopyRuntimeTypeHandles contract + typeInstantiationContext = (RuntimeTypeHandle[]?)typeInstantiationContext?.Clone(); + methodInstantiationContext = (RuntimeTypeHandle[]?)methodInstantiationContext?.Clone(); IntPtr[]? typeInstantiationContextHandles = RuntimeTypeHandle.CopyRuntimeTypeHandles(typeInstantiationContext, out int typeInstCount); IntPtr[]? methodInstantiationContextHandles = RuntimeTypeHandle.CopyRuntimeTypeHandles(methodInstantiationContext, out int methodInstCount); @@ -1317,6 +1336,10 @@ internal static IRuntimeFieldInfo ResolveFieldHandleInternal(RuntimeModule modul throw new ArgumentOutOfRangeException(nameof(fieldToken), SR.Format(SR.Argument_InvalidToken, fieldToken, new ModuleHandle(module))); + // defensive copy of user-provided array, per CopyRuntimeTypeHandles contract + typeInstantiationContext = (RuntimeTypeHandle[]?)typeInstantiationContext?.Clone(); + methodInstantiationContext = (RuntimeTypeHandle[]?)methodInstantiationContext?.Clone(); + // defensive copy to be sure array is not mutated from the outside during processing IntPtr[]? typeInstantiationContextHandles = RuntimeTypeHandle.CopyRuntimeTypeHandles(typeInstantiationContext, out int typeInstCount); IntPtr[]? methodInstantiationContextHandles = RuntimeTypeHandle.CopyRuntimeTypeHandles(methodInstantiationContext, out int methodInstCount); From 92c4cdcc036f561d556c9edd24ea86abe105cb2b Mon Sep 17 00:00:00 2001 From: Levi Broderick Date: Sun, 22 Nov 2020 20:28:33 -0800 Subject: [PATCH 4/5] PR feedback --- src/coreclr/src/vm/reflectioninvocation.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/coreclr/src/vm/reflectioninvocation.cpp b/src/coreclr/src/vm/reflectioninvocation.cpp index a68c897ffb94d1..95d82423e8b67d 100644 --- a/src/coreclr/src/vm/reflectioninvocation.cpp +++ b/src/coreclr/src/vm/reflectioninvocation.cpp @@ -554,13 +554,7 @@ void QCALLTYPE RuntimeTypeHandle::CreateInstanceForGenericType( OBJECTREF newObj = instantiatedType.GetMethodTable()->Allocate(); GCPROTECT_BEGIN(newObj); - - MethodDesc* pMeth = pVMT->GetDefaultConstructor(); - MethodDescCallSite ctor(pMeth); - - // Call the method - ARG_SLOT arg = ObjToArgSlot(newObj); - TryCallMethod(&ctor, &arg, true); + CallDefaultConstructor(newObj); GCPROTECT_END(); pInstantiatedObject.Set(newObj); From 8b975bc61dfe6767ae2caccbdf16ecc75a053901 Mon Sep 17 00:00:00 2001 From: Levi Broderick Date: Mon, 23 Nov 2020 12:07:40 -0800 Subject: [PATCH 5/5] PR feedback --- src/coreclr/src/vm/ecalllist.h | 2 +- src/coreclr/src/vm/reflectioninvocation.cpp | 2 +- src/coreclr/src/vm/runtimehandles.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/coreclr/src/vm/ecalllist.h b/src/coreclr/src/vm/ecalllist.h index 7c793d3e40a348..83374135b0a28c 100644 --- a/src/coreclr/src/vm/ecalllist.h +++ b/src/coreclr/src/vm/ecalllist.h @@ -190,7 +190,7 @@ FCFuncEnd() FCFuncStart(gCOMTypeHandleFuncs) FCFuncElement("CreateInstance", RuntimeTypeHandle::CreateInstance) - QCFuncElement("CreateInstanceForAnotherGenericParameter", RuntimeTypeHandle::CreateInstanceForGenericType) + QCFuncElement("CreateInstanceForAnotherGenericParameter", RuntimeTypeHandle::CreateInstanceForAnotherGenericParameter) QCFuncElement("GetGCHandle", RuntimeTypeHandle::GetGCHandle) QCFuncElement("FreeGCHandle", RuntimeTypeHandle::FreeGCHandle) diff --git a/src/coreclr/src/vm/reflectioninvocation.cpp b/src/coreclr/src/vm/reflectioninvocation.cpp index 95d82423e8b67d..22be44f4a2bcf3 100644 --- a/src/coreclr/src/vm/reflectioninvocation.cpp +++ b/src/coreclr/src/vm/reflectioninvocation.cpp @@ -515,7 +515,7 @@ FCIMPL6(Object*, RuntimeTypeHandle::CreateInstance, ReflectClassBaseObject* refT } FCIMPLEND -void QCALLTYPE RuntimeTypeHandle::CreateInstanceForGenericType( +void QCALLTYPE RuntimeTypeHandle::CreateInstanceForAnotherGenericParameter( QCall::TypeHandle pTypeHandle, TypeHandle* pInstArray, INT32 cInstArray, diff --git a/src/coreclr/src/vm/runtimehandles.h b/src/coreclr/src/vm/runtimehandles.h index 2ef4c2904100fa..4c5e9469da3cc4 100644 --- a/src/coreclr/src/vm/runtimehandles.h +++ b/src/coreclr/src/vm/runtimehandles.h @@ -248,7 +248,7 @@ class RuntimeTypeHandle { static FCDECL1(void, GetNextIntroducedMethod, MethodDesc **ppMethod); static - void QCALLTYPE CreateInstanceForGenericType(QCall::TypeHandle pTypeHandle, TypeHandle *pInstArray, INT32 cInstArray, QCall::ObjectHandleOnStack pInstantiatedObject); + void QCALLTYPE CreateInstanceForAnotherGenericParameter(QCall::TypeHandle pTypeHandle, TypeHandle *pInstArray, INT32 cInstArray, QCall::ObjectHandleOnStack pInstantiatedObject); static FCDECL1(IMDInternalImport*, GetMetadataImport, ReflectClassBaseObject * pModuleUNSAFE);