Skip to content

Commit 4391171

Browse files
committed
Fix handling VAR data type
- Now it's parsing it in the code instead of calling FindGenericParamAtTypeSpec(). - Remove declaration and implementation of FindGenericParamAtTypeSpec().
1 parent cfc6d81 commit 4391171

File tree

4 files changed

+88
-45
lines changed

4 files changed

+88
-45
lines changed

src/CLR/Core/Execution.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1971,10 +1971,26 @@ HRESULT CLR_RT_ExecutionEngine::InitializeLocals(
19711971

19721972
case DATATYPE_VAR:
19731973
{
1974+
// type-level generic parameter in a locals signature (e.g. 'T' inside a generic type)
19741975
CLR_INT8 genericParamPosition = *sig++;
19751976

1976-
methodDefInstance.assembly
1977-
->FindGenericParamAtTypeSpec(methodDefInstance, genericParamPosition, cls, dt);
1977+
// parse the locals-signature to extract that T
1978+
CLR_RT_SignatureParser parser;
1979+
parser.Initialize_MethodLocals(assembly, methodDef);
1980+
CLR_RT_SignatureParser::Element element;
1981+
1982+
// advance into the VAR entry
1983+
parser.Advance(element);
1984+
1985+
// walk forward to the Nth generic-parameter
1986+
for (int i = 0; i < genericParamPosition; i++)
1987+
{
1988+
parser.Advance(element);
1989+
}
1990+
1991+
// element.Class and element.DataType represent the T
1992+
cls = element.Class;
1993+
dt = element.DataType;
19781994

19791995
goto done;
19801996
}

src/CLR/Core/TypeSystem.cpp

Lines changed: 25 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -440,8 +440,6 @@ HRESULT CLR_RT_SignatureParser::Advance(Element &res)
440440

441441
NANOCLR_HEADER();
442442

443-
_ASSERTE(ParamCount > 0);
444-
445443
ParamCount--;
446444

447445
res.IsByRef = false;
@@ -988,13 +986,36 @@ bool CLR_RT_TypeDef_Instance::ResolveToken(
988986
case DATATYPE_VAR:
989987
{
990988
CLR_RT_TypeDef_Index typeDef;
991-
NanoCLRDataType dataType;
989+
CLR_RT_SignatureParser::Element genericElement;
990+
991+
CLR_RT_SignatureParser varParser;
992+
varParser.Initialize_TypeSpec(assm, ts);
992993

993-
caller->assembly->FindGenericParamAtTypeSpec(*caller, genericParamPosition, typeDef, dataType);
994+
// advance once to consume the GENERICINST or VAR entry
995+
varParser.Advance(genericElement);
994996

997+
// now walk forward genericParameterPosition steps to land on the actual
998+
// argument in the signature stream.
999+
for (CLR_INT8 i = 0; i <= genericParamPosition; i++)
1000+
{
1001+
if (FAILED(varParser.Advance(genericElement)))
1002+
{
1003+
return false;
1004+
}
1005+
}
1006+
1007+
// genericElement.Class now holds the TypeDef_Index of the T or U, etc.
1008+
typeDef = genericElement.Class;
1009+
1010+
// populate this instance from the resolved TypeDef
9951011
data = typeDef.data;
9961012
assembly = g_CLR_RT_TypeSystem.m_assemblies[typeDef.Assembly() - 1];
9971013
target = assembly->GetTypeDef(typeDef.Type());
1014+
1015+
#if defined(NANOCLR_INSTANCE_NAMES)
1016+
name = assembly->GetString(target->name);
1017+
#endif
1018+
return true;
9981019
}
9991020
break;
10001021

@@ -4455,36 +4476,6 @@ bool CLR_RT_Assembly::FindGenericParam(CLR_INDEX typeSpecIndex, CLR_RT_GenericPa
44554476
return false;
44564477
}
44574478

4458-
bool CLR_RT_Assembly::FindGenericParamAtTypeSpec(
4459-
CLR_RT_MethodDef_Instance md,
4460-
CLR_UINT32 genericParameterPosition,
4461-
CLR_RT_TypeDef_Index &index,
4462-
NanoCLRDataType &dataType)
4463-
{
4464-
NATIVE_PROFILE_CLR_CORE();
4465-
4466-
CLR_RT_SignatureParser parser;
4467-
parser.Initialize_TypeSpec(md.assembly, md.assembly->GetTypeSpec(md.genericType->TypeSpec()));
4468-
4469-
CLR_RT_SignatureParser::Element element;
4470-
4471-
// get type
4472-
parser.Advance(element);
4473-
4474-
for (uint32_t i = 0; i <= genericParameterPosition; i++)
4475-
{
4476-
if (FAILED(parser.Advance(element)))
4477-
{
4478-
return false;
4479-
}
4480-
}
4481-
4482-
index = element.Class;
4483-
dataType = element.DataType;
4484-
4485-
return true;
4486-
}
4487-
44884479
bool CLR_RT_Assembly::FindGenericParamAtMethodDef(
44894480
CLR_RT_MethodDef_Instance md,
44904481
CLR_UINT32 genericParameterPosition,

src/CLR/Debugger/Debugger.cpp

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//
1+
//
22
// Copyright (c) .NET Foundation and Contributors
33
// Portions Copyright (c) Microsoft Corporation. All rights reserved.
44
// 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)
28212821
// handle generic parameters
28222822
if (res.DataType == DATATYPE_VAR)
28232823
{
2824-
// Generic parameter in a generic TypeDef
2825-
md.assembly->FindGenericParamAtTypeSpec(md, res.GenericParamPosition, targetClass, targetDataType);
2824+
// type‐level generic parameter in a generic TypeDef: re‐parse the signature
2825+
CLR_RT_SignatureParser typeParser;
28262826

2827-
// isGenericInstance = true;
2827+
// for arguments, initialize over the method signature and skip the return slot
2828+
if (cmd->m_kind == CLR_DBG_Commands::Debugging_Value_GetStack::c_Argument)
2829+
{
2830+
typeParser.Initialize_MethodSignature(&md);
2831+
2832+
// skip the return value entry
2833+
iElement++;
2834+
2835+
// if there's an implicit 'this', adjust index
2836+
if (typeParser.Flags & PIMAGE_CEE_CS_CALLCONV_HASTHIS)
2837+
{
2838+
if (iElement == 0)
2839+
{
2840+
// requested the 'this' argument – invalid for a primitive
2841+
return false;
2842+
}
2843+
iElement--;
2844+
}
2845+
}
2846+
else
2847+
{
2848+
// for locals or eval‐stack, initialize over the locals signature
2849+
typeParser.Initialize_MethodLocals(md.assembly, md.target);
2850+
}
2851+
2852+
// advance to the requested argument/local
2853+
CLR_RT_SignatureParser::Element elem;
2854+
do
2855+
{
2856+
typeParser.Advance(elem);
2857+
} while (iElement-- > 0);
2858+
2859+
// now we've landed on a DATATYPE_VAR; walk to the Nth generic‐type parameter
2860+
typeParser.Advance(elem);
2861+
for (int i = 0; i < res.GenericParamPosition; i++)
2862+
{
2863+
parser.Advance(elem);
2864+
}
2865+
2866+
// this element.Class is the TypeDef_Index for 'T'
2867+
targetClass = elem.Class;
2868+
targetDataType = elem.DataType;
28282869
}
28292870
else if (res.DataType == DATATYPE_MVAR)
28302871
{

src/CLR/Include/nanoCLR_Runtime.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1423,11 +1423,6 @@ struct CLR_RT_Assembly : public CLR_RT_HeapBlock_Node // EVENT HEAP - NO RELOCAT
14231423

14241424
bool FindTypeSpec(const CLR_PMETADATA sig, CLR_RT_TypeSpec_Index &index);
14251425

1426-
bool FindGenericParamAtTypeSpec(
1427-
CLR_RT_MethodDef_Instance md,
1428-
CLR_UINT32 genericParameterPosition,
1429-
CLR_RT_TypeDef_Index &index,
1430-
NanoCLRDataType &dataType);
14311426
bool FindGenericParamAtMethodDef(
14321427
CLR_RT_MethodDef_Instance md,
14331428
CLR_UINT32 genericParameterPosition,

0 commit comments

Comments
 (0)