diff --git a/src/CLR/Core/Execution.cpp b/src/CLR/Core/Execution.cpp index 0007730916..a52d135f2c 100644 --- a/src/CLR/Core/Execution.cpp +++ b/src/CLR/Core/Execution.cpp @@ -2032,7 +2032,8 @@ HRESULT CLR_RT_ExecutionEngine::InitializeLocals( CLR_RT_TypeSpec_Index genericTSIndex = {}; - if (methodDefInstance.genericType && methodDefInstance.genericType->data != 0) + if (methodDefInstance.genericType && NANOCLR_INDEX_IS_VALID(*methodDefInstance.genericType) && + methodDefInstance.genericType->data != CLR_EmptyToken) { // method is generic, it can only use class from method's class generic parameters genericInstance.InitializeFromIndex(*methodDefInstance.genericType); @@ -2093,7 +2094,8 @@ HRESULT CLR_RT_ExecutionEngine::InitializeLocals( // type-level generic parameter in a locals signature (e.g. 'T' inside a generic type) CLR_INT8 genericParamPosition = *sig++; - if (methodDefInstance.genericType && methodDefInstance.genericType->data != 0) + if (methodDefInstance.genericType && NANOCLR_INDEX_IS_VALID(*methodDefInstance.genericType) && + methodDefInstance.genericType->data != CLR_EmptyToken) { CLR_RT_TypeSpec_Instance typeSpec{}; typeSpec.InitializeFromIndex( diff --git a/src/CLR/Core/Interpreter.cpp b/src/CLR/Core/Interpreter.cpp index 59593f4155..9b2be3f137 100644 --- a/src/CLR/Core/Interpreter.cpp +++ b/src/CLR/Core/Interpreter.cpp @@ -2211,7 +2211,16 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg) NANOCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE); } - calleeInst.InitializeFromIndex(calleeReal); + if (calleeInst.genericType && NANOCLR_INDEX_IS_VALID(*calleeInst.genericType) && + calleeInst.genericType->data != CLR_EmptyToken) + { + // store the current generic context (if any) + calleeInst.InitializeFromIndex(calleeReal, *calleeInst.genericType); + } + else + { + calleeInst.InitializeFromIndex(calleeReal); + } } #if defined(NANOCLR_APPDOMAINS) diff --git a/src/CLR/Core/TypeSystem.cpp b/src/CLR/Core/TypeSystem.cpp index 54daaae60a..73e0601d67 100644 --- a/src/CLR/Core/TypeSystem.cpp +++ b/src/CLR/Core/TypeSystem.cpp @@ -1597,7 +1597,7 @@ bool CLR_RT_MethodDef_Instance::InitializeFromIndex( } // remember the TypeSpec so this is available when needed - this->genericType = &typeSpec; + genericType = &typeSpec; return true; } @@ -1695,9 +1695,8 @@ bool CLR_RT_MethodDef_Instance::ResolveToken( } } - // Pick the “winner” between methodOwnerTS or callerGeneric: - const CLR_RT_TypeSpec_Index *definitiveTypeSpec = useCaller ? callerGeneric : methodOwnerTS; - genericType = (CLR_RT_TypeSpec_Index *)definitiveTypeSpec; + // Pick the "winner" between methodOwnerTS or callerGeneric: + genericType = useCaller ? callerGeneric : methodOwnerTS; CLR_RT_Assembly *methodAssembly = g_CLR_RT_TypeSystem.m_assemblies[methodOwnerTS->Assembly() - 1]; @@ -6772,7 +6771,7 @@ HRESULT CLR_RT_TypeSystem::BuildMethodName( declTypeIdx.Set(md.Assembly(), declTypeInst.assembly->crossReferenceMethodDef[md.Method()].GetOwner()); - if (genericType != nullptr && genericType->data != 0xffffffff) + if (genericType != nullptr && NANOCLR_INDEX_IS_VALID(*genericType) && genericType->data != CLR_EmptyToken) { // parse TypeSpec to get its TypeDef CLR_RT_TypeSpec_Instance tsInst = {}; diff --git a/src/CLR/Diagnostics/Info.cpp b/src/CLR/Diagnostics/Info.cpp index 68b2a8a8ce..9bd7f44612 100644 --- a/src/CLR/Diagnostics/Info.cpp +++ b/src/CLR/Diagnostics/Info.cpp @@ -481,7 +481,8 @@ void CLR_RT_Assembly::DumpToken(CLR_UINT32 token, const CLR_RT_MethodDef_Instanc // use that, so ResizeArray prints as SimpleList::ResizeArray. // 2) Otherwise, fall back to xref.genericType (the raw MethodRef own owner). const CLR_RT_TypeSpec_Index *ownerTypeSpec; - if (methodDefInstance.genericType != nullptr && NANOCLR_INDEX_IS_VALID(*methodDefInstance.genericType)) + if (methodDefInstance.genericType != nullptr && NANOCLR_INDEX_IS_VALID(*methodDefInstance.genericType) && + methodDefInstance.genericType->data != CLR_EmptyToken) { ownerTypeSpec = methodDefInstance.genericType; }