From a26cd9db3a478abda80430ef8ff7a561bbcc5f98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Sim=C3=B5es?= Date: Tue, 24 Jun 2025 19:16:51 +0100 Subject: [PATCH] Fix loading token for TypeSpec - Parsing a typespec when dumping an ldtoken now outputs correct type. - Parsing a typespec when executing ldtoken IL now sets reflection with instanciated type. - Add parameter with caller to SetReflection from TypeSpec. - Fix calls. --- src/CLR/Core/CLR_RT_HeapBlock.cpp | 47 +++++++++++++++++--- src/CLR/Core/CLR_RT_HeapBlock_Array.cpp | 2 +- src/CLR/Core/Interpreter.cpp | 6 +-- src/CLR/Diagnostics/Info.cpp | 16 ++++--- src/CLR/Include/nanoCLR_Runtime__HeapBlock.h | 2 +- 5 files changed, 56 insertions(+), 17 deletions(-) diff --git a/src/CLR/Core/CLR_RT_HeapBlock.cpp b/src/CLR/Core/CLR_RT_HeapBlock.cpp index 3f340f7cec..6bcf07ab0a 100644 --- a/src/CLR/Core/CLR_RT_HeapBlock.cpp +++ b/src/CLR/Core/CLR_RT_HeapBlock.cpp @@ -232,17 +232,54 @@ HRESULT CLR_RT_HeapBlock::SetReflection(const CLR_RT_Assembly_Index &assm) NANOCLR_NOCLEANUP_NOLABEL(); } -HRESULT CLR_RT_HeapBlock::SetReflection(const CLR_RT_TypeSpec_Index &sig) +HRESULT CLR_RT_HeapBlock::SetReflection(const CLR_RT_TypeSpec_Instance &tsInst, const CLR_RT_TypeSpec_Index *caller) { NATIVE_PROFILE_CLR_CORE(); NANOCLR_HEADER(); - CLR_RT_TypeDescriptor desc{}; + m_id.raw = CLR_RT_HEAPBLOCK_RAW_ID(DATATYPE_REFLECTION, 0, 1); + m_data.reflection.kind = REFLECTION_TYPE; - NANOCLR_CHECK_HRESULT(desc.InitializeFromTypeSpec(sig)); + // start parsing the signature + CLR_RT_SignatureParser parser; + parser.Initialize_TypeSpec(tsInst.assembly, tsInst.target); - m_id.raw = CLR_RT_HEAPBLOCK_RAW_ID(DATATYPE_REFLECTION, 0, 1); - m_data.reflection = desc.m_reflex; + // read first element + CLR_RT_SignatureParser::Element elem; + if (FAILED(parser.Advance(elem))) + { + NANOCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE); + } + + if (elem.DataType == DATATYPE_VAR || elem.DataType == DATATYPE_MVAR) + { + int gpIndex = elem.GenericParamPosition; + + // if the caller's genericType is non‐null, ask the CLR to map !n→actual argument: + if (caller != nullptr && NANOCLR_INDEX_IS_VALID(*caller)) + { + CLR_RT_TypeDef_Index tdArg{}; + NanoCLRDataType dtArg; + + bool ok = g_CLR_RT_TypeSystem.m_assemblies[caller->Assembly() - 1] + ->FindGenericParamAtTypeSpec(caller->TypeSpec(), gpIndex, tdArg, dtArg); + if (ok) + { + m_data.reflection.data.type = tdArg; + m_data.reflection.levels = elem.Levels; + } + } + else + { + // TODO + _ASSERTE(false); + } + } + else + { + m_data.reflection.data.type = elem.Class; + m_data.reflection.levels = elem.Levels; + } NANOCLR_NOCLEANUP(); } diff --git a/src/CLR/Core/CLR_RT_HeapBlock_Array.cpp b/src/CLR/Core/CLR_RT_HeapBlock_Array.cpp index ff5dd4a5e7..b06f64431a 100644 --- a/src/CLR/Core/CLR_RT_HeapBlock_Array.cpp +++ b/src/CLR/Core/CLR_RT_HeapBlock_Array.cpp @@ -104,7 +104,7 @@ HRESULT CLR_RT_HeapBlock_Array::CreateInstance( } else if (def.ResolveToken(tk, assm)) { - NANOCLR_CHECK_HRESULT(ref.SetReflection(def)); + NANOCLR_CHECK_HRESULT(ref.SetReflection(def, caller->genericType)); } else { diff --git a/src/CLR/Core/Interpreter.cpp b/src/CLR/Core/Interpreter.cpp index 4a3f1cd371..ba41d2ff27 100644 --- a/src/CLR/Core/Interpreter.cpp +++ b/src/CLR/Core/Interpreter.cpp @@ -3210,13 +3210,13 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg) { case TBL_TypeSpec: { - CLR_RT_TypeSpec_Instance sig{}; - if (sig.ResolveToken(arg, assm) == false) + CLR_RT_TypeSpec_Instance tsInst{}; + if (tsInst.ResolveToken(arg, assm) == false) { NANOCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE); } - evalPos[0].SetReflection(sig); + evalPos[0].SetReflection(tsInst, stack->m_call.genericType); } break; diff --git a/src/CLR/Diagnostics/Info.cpp b/src/CLR/Diagnostics/Info.cpp index 194a6542d3..2a626dc5b0 100644 --- a/src/CLR/Diagnostics/Info.cpp +++ b/src/CLR/Diagnostics/Info.cpp @@ -531,7 +531,7 @@ void CLR_RT_Assembly::DumpToken(CLR_UINT32 token, const CLR_RT_TypeSpec_Index *g } CLR_RT_TypeSpec_Index tsIdx; - tsIdx.Set(ownerAsm, index); + tsIdx.Set(assemblyIndex, index); // bind to get the signature blob CLR_RT_TypeSpec_Instance tsInst{}; @@ -568,17 +568,19 @@ void CLR_RT_Assembly::DumpToken(CLR_UINT32 token, const CLR_RT_TypeSpec_Index *g { CLR_RT_TypeDef_Index tdArg{}; NanoCLRDataType dtArg; - - bool ok = - tsInst.assembly->FindGenericParamAtTypeSpec(genericType->TypeSpec(), gpIndex, tdArg, dtArg); + bool ok = g_CLR_RT_TypeSystem.m_assemblies[genericType->Assembly() - 1] + ->FindGenericParamAtTypeSpec(genericType->TypeSpec(), gpIndex, tdArg, dtArg); if (ok) { - // Print that bound argument (e.g. "I4" or full class name) - char bufArg[256]; + char bufArg[256]{}; char *pArg = bufArg; size_t cbArg = sizeof(bufArg); - g_CLR_RT_TypeSystem.BuildTypeName(tdArg, pArg, cbArg); + + g_CLR_RT_TypeSystem + .BuildTypeName(tdArg, pArg, cbArg, CLR_RT_TypeSystem::TYPENAME_FLAGS_FULL, elem.Levels); + CLR_Debug::Printf("%s", bufArg); + break; } } diff --git a/src/CLR/Include/nanoCLR_Runtime__HeapBlock.h b/src/CLR/Include/nanoCLR_Runtime__HeapBlock.h index 4205d6a99d..1498c409dc 100644 --- a/src/CLR/Include/nanoCLR_Runtime__HeapBlock.h +++ b/src/CLR/Include/nanoCLR_Runtime__HeapBlock.h @@ -1347,7 +1347,7 @@ struct CLR_RT_HeapBlock HRESULT SetReflection(const CLR_RT_ReflectionDef_Index &reflex); HRESULT SetReflection(const CLR_RT_Assembly_Index &assm); - HRESULT SetReflection(const CLR_RT_TypeSpec_Index &sig); + HRESULT SetReflection(const CLR_RT_TypeSpec_Instance &tsInst, const CLR_RT_TypeSpec_Index *caller); HRESULT SetReflection(const CLR_RT_TypeDef_Index &cls); HRESULT SetReflection(const CLR_RT_FieldDef_Index &fd); HRESULT SetReflection(const CLR_RT_MethodDef_Index &md);