Skip to content

Commit ba275bd

Browse files
committed
Fix handling ldtoken with method generic param
- LDTOKEN code now can distinguish from Type (!T) and Method generic parameters (!!T). - Fix check in InitializeLocals for max generic parameters.
1 parent 8a1f072 commit ba275bd

File tree

2 files changed

+66
-13
lines changed

2 files changed

+66
-13
lines changed

src/CLR/Core/Execution.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1980,7 +1980,7 @@ HRESULT CLR_RT_ExecutionEngine::InitializeLocals(
19801980
CLR_RT_SignatureParser::Element element;
19811981

19821982
// ensure we don’t walk past the available generic parameters
1983-
const int maxParams = parser.GenParamCount;
1983+
const int maxParams = methodDefInstance.target->genericParamCount;
19841984
if (genericParamPosition < 0 || genericParamPosition > maxParams)
19851985
{
19861986
NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);

src/CLR/Core/Interpreter.cpp

Lines changed: 65 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3242,22 +3242,75 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg)
32423242

32433243
if (stack->m_call.genericType != nullptr)
32443244
{
3245-
// For a method in a generic type, caller->genericType points to the TypeSpec of the
3246-
// closed type
3247-
CLR_UINT32 closedTypeSpecRow = stack->m_call.genericType->TypeSpec();
3245+
CLR_UINT32 rawGenericParamRow = CLR_DataFromTk(arg);
32483246

3249-
CLR_RT_TypeDef_Index resolvedTypeDef;
3250-
NanoCLRDataType resolvedDataType;
3247+
CLR_RT_GenericParam_CrossReference gpCR =
3248+
stack->m_call.assembly->crossReferenceGenericParam[rawGenericParamRow];
32513249

3252-
CLR_UINT32 index = CLR_DataFromTk(arg);
3250+
if (gpCR.typeOrMethodDef == TBL_MethodDef)
3251+
{
3252+
// Method generic parameter (!!T)
32533253

3254-
assm->FindGenericParamAtTypeSpec(
3255-
closedTypeSpecRow,
3256-
index,
3257-
resolvedTypeDef,
3258-
resolvedDataType);
3254+
CLR_RT_MethodSpec_Index msIndex;
3255+
if (!assm->FindMethodSpecFromTypeSpec(
3256+
stack->m_call.genericType->TypeSpec(),
3257+
msIndex))
3258+
{
3259+
NANOCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
3260+
}
32593261

3260-
evalPos[0].SetReflection(resolvedTypeDef);
3262+
CLR_RT_MethodSpec_Instance ms;
3263+
if (ms.InitializeFromIndex(msIndex) == false)
3264+
{
3265+
NANOCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
3266+
}
3267+
3268+
auto &cross = param.CrossReference();
3269+
int genericParamPos = param.GenericParam();
3270+
3271+
CLR_RT_SignatureParser parser;
3272+
CLR_RT_SignatureParser::Element element;
3273+
parser.Initialize_MethodSignature(&ms);
3274+
3275+
for (int i = 0; i <= genericParamPos; i++)
3276+
{
3277+
NANOCLR_CHECK_HRESULT(parser.Advance(element));
3278+
}
3279+
3280+
evalPos[0].SetReflection(element.Class);
3281+
}
3282+
else
3283+
{
3284+
// type generic parameter (!T)
3285+
if (stack->m_call.genericType == nullptr)
3286+
{
3287+
// No closed‐generic context available: fall back to returning the
3288+
// declaring TYPE itself as the reflection result (rarely correct, but at least
3289+
// safe).
3290+
CLR_RT_TypeDef_Index fallbackTypeDef = gpCR.classTypeDef;
3291+
NANOCLR_CHECK_HRESULT(evalPos[0].SetReflection(fallbackTypeDef));
3292+
}
3293+
else
3294+
{
3295+
// closed TypeSpec
3296+
const CLR_RT_TypeSpec_Index *callerTypeSpec = stack->m_call.genericType;
3297+
CLR_RT_TypeDef_Index resolvedTypeDef;
3298+
NanoCLRDataType resolvedDataType;
3299+
3300+
HRESULT hr2 = stack->m_call.assembly->FindGenericParamAtTypeSpec(
3301+
callerTypeSpec->TypeSpec(),
3302+
(CLR_UINT32)gpCR.m_target.GenericParam(),
3303+
resolvedTypeDef,
3304+
resolvedDataType);
3305+
3306+
if (FAILED(hr2))
3307+
{
3308+
NANOCLR_SET_AND_LEAVE(hr2);
3309+
}
3310+
3311+
evalPos[0].SetReflection(resolvedTypeDef);
3312+
}
3313+
}
32613314
}
32623315
else
32633316
{

0 commit comments

Comments
 (0)