From 439117156f0bf87ffe5a6827cbfb32a88c63f24a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Sim=C3=B5es?= Date: Fri, 9 May 2025 16:50:44 +0100 Subject: [PATCH] Fix handling VAR data type - Now it's parsing it in the code instead of calling FindGenericParamAtTypeSpec(). - Remove declaration and implementation of FindGenericParamAtTypeSpec(). --- src/CLR/Core/Execution.cpp | 20 +++++++++-- src/CLR/Core/TypeSystem.cpp | 59 +++++++++++++------------------ src/CLR/Debugger/Debugger.cpp | 49 ++++++++++++++++++++++--- src/CLR/Include/nanoCLR_Runtime.h | 5 --- 4 files changed, 88 insertions(+), 45 deletions(-) diff --git a/src/CLR/Core/Execution.cpp b/src/CLR/Core/Execution.cpp index 27e5b86958..b6b8fa4ec4 100644 --- a/src/CLR/Core/Execution.cpp +++ b/src/CLR/Core/Execution.cpp @@ -1971,10 +1971,26 @@ HRESULT CLR_RT_ExecutionEngine::InitializeLocals( case DATATYPE_VAR: { + // type-level generic parameter in a locals signature (e.g. 'T' inside a generic type) CLR_INT8 genericParamPosition = *sig++; - methodDefInstance.assembly - ->FindGenericParamAtTypeSpec(methodDefInstance, genericParamPosition, cls, dt); + // parse the locals-signature to extract that T + CLR_RT_SignatureParser parser; + parser.Initialize_MethodLocals(assembly, methodDef); + CLR_RT_SignatureParser::Element element; + + // advance into the VAR entry + parser.Advance(element); + + // walk forward to the Nth generic-parameter + for (int i = 0; i < genericParamPosition; i++) + { + parser.Advance(element); + } + + // element.Class and element.DataType represent the T + cls = element.Class; + dt = element.DataType; goto done; } diff --git a/src/CLR/Core/TypeSystem.cpp b/src/CLR/Core/TypeSystem.cpp index 54cde956cd..9ec3dbdb82 100644 --- a/src/CLR/Core/TypeSystem.cpp +++ b/src/CLR/Core/TypeSystem.cpp @@ -440,8 +440,6 @@ HRESULT CLR_RT_SignatureParser::Advance(Element &res) NANOCLR_HEADER(); - _ASSERTE(ParamCount > 0); - ParamCount--; res.IsByRef = false; @@ -988,13 +986,36 @@ bool CLR_RT_TypeDef_Instance::ResolveToken( case DATATYPE_VAR: { CLR_RT_TypeDef_Index typeDef; - NanoCLRDataType dataType; + CLR_RT_SignatureParser::Element genericElement; + + CLR_RT_SignatureParser varParser; + varParser.Initialize_TypeSpec(assm, ts); - caller->assembly->FindGenericParamAtTypeSpec(*caller, genericParamPosition, typeDef, dataType); + // advance once to consume the GENERICINST or VAR entry + varParser.Advance(genericElement); + // now walk forward genericParameterPosition steps to land on the actual + // argument in the signature stream. + for (CLR_INT8 i = 0; i <= genericParamPosition; i++) + { + if (FAILED(varParser.Advance(genericElement))) + { + return false; + } + } + + // genericElement.Class now holds the TypeDef_Index of the T or U, etc. + typeDef = genericElement.Class; + + // populate this instance from the resolved TypeDef data = typeDef.data; assembly = g_CLR_RT_TypeSystem.m_assemblies[typeDef.Assembly() - 1]; target = assembly->GetTypeDef(typeDef.Type()); + +#if defined(NANOCLR_INSTANCE_NAMES) + name = assembly->GetString(target->name); +#endif + return true; } break; @@ -4455,36 +4476,6 @@ bool CLR_RT_Assembly::FindGenericParam(CLR_INDEX typeSpecIndex, CLR_RT_GenericPa return false; } -bool CLR_RT_Assembly::FindGenericParamAtTypeSpec( - CLR_RT_MethodDef_Instance md, - CLR_UINT32 genericParameterPosition, - CLR_RT_TypeDef_Index &index, - NanoCLRDataType &dataType) -{ - NATIVE_PROFILE_CLR_CORE(); - - CLR_RT_SignatureParser parser; - parser.Initialize_TypeSpec(md.assembly, md.assembly->GetTypeSpec(md.genericType->TypeSpec())); - - CLR_RT_SignatureParser::Element element; - - // get type - parser.Advance(element); - - for (uint32_t i = 0; i <= genericParameterPosition; i++) - { - if (FAILED(parser.Advance(element))) - { - return false; - } - } - - index = element.Class; - dataType = element.DataType; - - return true; -} - bool CLR_RT_Assembly::FindGenericParamAtMethodDef( CLR_RT_MethodDef_Instance md, CLR_UINT32 genericParameterPosition, diff --git a/src/CLR/Debugger/Debugger.cpp b/src/CLR/Debugger/Debugger.cpp index d4b902ea03..9265464b88 100644 --- a/src/CLR/Debugger/Debugger.cpp +++ b/src/CLR/Debugger/Debugger.cpp @@ -1,4 +1,4 @@ -// +// // Copyright (c) .NET Foundation and Contributors // Portions Copyright (c) Microsoft Corporation. All rights reserved. // See LICENSE file in the project root for full license information. @@ -2821,10 +2821,51 @@ bool CLR_DBG_Debugger::Debugging_Value_GetStack(WP_Message *msg) // handle generic parameters if (res.DataType == DATATYPE_VAR) { - // Generic parameter in a generic TypeDef - md.assembly->FindGenericParamAtTypeSpec(md, res.GenericParamPosition, targetClass, targetDataType); + // type‐level generic parameter in a generic TypeDef: re‐parse the signature + CLR_RT_SignatureParser typeParser; - // isGenericInstance = true; + // for arguments, initialize over the method signature and skip the return slot + if (cmd->m_kind == CLR_DBG_Commands::Debugging_Value_GetStack::c_Argument) + { + typeParser.Initialize_MethodSignature(&md); + + // skip the return value entry + iElement++; + + // if there's an implicit 'this', adjust index + if (typeParser.Flags & PIMAGE_CEE_CS_CALLCONV_HASTHIS) + { + if (iElement == 0) + { + // requested the 'this' argument – invalid for a primitive + return false; + } + iElement--; + } + } + else + { + // for locals or eval‐stack, initialize over the locals signature + typeParser.Initialize_MethodLocals(md.assembly, md.target); + } + + // advance to the requested argument/local + CLR_RT_SignatureParser::Element elem; + do + { + typeParser.Advance(elem); + } while (iElement-- > 0); + + // now we've landed on a DATATYPE_VAR; walk to the Nth generic‐type parameter + typeParser.Advance(elem); + for (int i = 0; i < res.GenericParamPosition; i++) + { + parser.Advance(elem); + } + + // this element.Class is the TypeDef_Index for 'T' + targetClass = elem.Class; + targetDataType = elem.DataType; } else if (res.DataType == DATATYPE_MVAR) { diff --git a/src/CLR/Include/nanoCLR_Runtime.h b/src/CLR/Include/nanoCLR_Runtime.h index 5134b73ed6..89a84c01d5 100644 --- a/src/CLR/Include/nanoCLR_Runtime.h +++ b/src/CLR/Include/nanoCLR_Runtime.h @@ -1423,11 +1423,6 @@ struct CLR_RT_Assembly : public CLR_RT_HeapBlock_Node // EVENT HEAP - NO RELOCAT bool FindTypeSpec(const CLR_PMETADATA sig, CLR_RT_TypeSpec_Index &index); - bool FindGenericParamAtTypeSpec( - CLR_RT_MethodDef_Instance md, - CLR_UINT32 genericParameterPosition, - CLR_RT_TypeDef_Index &index, - NanoCLRDataType &dataType); bool FindGenericParamAtMethodDef( CLR_RT_MethodDef_Instance md, CLR_UINT32 genericParameterPosition,