@@ -3242,22 +3242,75 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg)
3242
3242
3243
3243
if (stack->m_call .genericType != nullptr )
3244
3244
{
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);
3248
3246
3249
- CLR_RT_TypeDef_Index resolvedTypeDef;
3250
- NanoCLRDataType resolvedDataType ;
3247
+ CLR_RT_GenericParam_CrossReference gpCR =
3248
+ stack-> m_call . assembly -> crossReferenceGenericParam [rawGenericParamRow] ;
3251
3249
3252
- CLR_UINT32 index = CLR_DataFromTk (arg);
3250
+ if (gpCR.typeOrMethodDef == TBL_MethodDef)
3251
+ {
3252
+ // Method generic parameter (!!T)
3253
3253
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
+ }
3259
3261
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
+ }
3261
3314
}
3262
3315
else
3263
3316
{
0 commit comments