@@ -610,6 +610,8 @@ HRESULT CLR_RT_SignatureParser::Advance(Element &res)
610
610
// sanity check
611
611
if (dt == DATATYPE_CLASS || dt == DATATYPE_VALUETYPE)
612
612
{
613
+ res.DataType = dt;
614
+
613
615
// parse type
614
616
goto parse_type;
615
617
}
@@ -1258,6 +1260,43 @@ bool CLR_RT_MethodDef_Instance::InitializeFromIndex(const CLR_RT_MethodDef_Index
1258
1260
return false ;
1259
1261
}
1260
1262
1263
+ bool CLR_RT_MethodDef_Instance::InitializeFromIndex (
1264
+ const CLR_RT_MethodDef_Index &md,
1265
+ const CLR_RT_TypeSpec_Index &typeSpec)
1266
+ {
1267
+ NATIVE_PROFILE_CLR_CORE ();
1268
+
1269
+ // Look up the TypeSpec's cross‐reference to find the *open* generic definition and its assembly
1270
+ CLR_INDEX tsAsmIdx = typeSpec.Assembly ();
1271
+ if (tsAsmIdx == 0 || tsAsmIdx > (int )g_CLR_RT_TypeSystem.c_MaxAssemblies )
1272
+ {
1273
+ return false ;
1274
+ }
1275
+ CLR_RT_Assembly *tsAsm = g_CLR_RT_TypeSystem.m_assemblies [tsAsmIdx - 1 ];
1276
+
1277
+ int tsRow = (int )typeSpec.TypeSpec ();
1278
+ const auto &xref = tsAsm->crossReferenceTypeSpec [tsRow];
1279
+
1280
+ // xref.ownerType is the open‐generic TypeDef_Index of Span`1, List`1, etc.
1281
+ CLR_RT_TypeDef_Index ownerType = xref.ownerType ;
1282
+
1283
+ // Compute the MethodDef_Index bound to the owner’s assembly
1284
+ CLR_RT_MethodDef_Index mdRebound;
1285
+
1286
+ // pack the new assembly index (ownerType.Assembly()) with the original row
1287
+ mdRebound.data = (ownerType.Assembly () << 24 ) | md.Method ();
1288
+
1289
+ if (!InitializeFromIndex (mdRebound))
1290
+ {
1291
+ return false ;
1292
+ }
1293
+
1294
+ // set the generic‐type context *before* we lose it
1295
+ this ->genericType = &typeSpec;
1296
+
1297
+ return true ;
1298
+ }
1299
+
1261
1300
void CLR_RT_MethodDef_Instance::ClearInstance ()
1262
1301
{
1263
1302
NATIVE_PROFILE_CLR_CORE ();
@@ -1344,16 +1383,26 @@ bool CLR_RT_MethodDef_Instance::ResolveToken(
1344
1383
const CLR_RT_TypeSpec_Index *definitiveTypeSpec = useCaller ? callerGeneric : methodOwnerTS;
1345
1384
genericType = (CLR_RT_TypeSpec_Index *)definitiveTypeSpec;
1346
1385
1347
- const CLR_RECORD_TYPESPEC *ts = assm->GetTypeSpec (definitiveTypeSpec->TypeSpec ());
1386
+ CLR_INDEX tsAsmIdx = genericType->Assembly ();
1387
+ CLR_RT_Assembly *genericTypeAssembly = g_CLR_RT_TypeSystem.m_assemblies [tsAsmIdx - 1 ];
1388
+
1389
+ const CLR_RECORD_TYPESPEC *ts = genericTypeAssembly->GetTypeSpec (definitiveTypeSpec->TypeSpec ());
1390
+ CLR_UINT32 assemblyIndex = 0xFFFF ;
1348
1391
CLR_RT_MethodDef_Index methodIndex;
1349
1392
1350
- if (!assm->FindMethodDef (ts, assm->GetString (mr->name ), assm, mr->signature , methodIndex))
1393
+ if (!genericTypeAssembly->FindMethodDef (
1394
+ ts,
1395
+ genericTypeAssembly->GetString (mr->name ),
1396
+ genericTypeAssembly,
1397
+ mr->signature ,
1398
+ methodIndex,
1399
+ assemblyIndex))
1351
1400
{
1352
1401
return false ;
1353
1402
}
1354
1403
1355
- Set (assm-> assemblyIndex , methodIndex.Method ());
1356
- assembly = assm ;
1404
+ Set (assemblyIndex - 1 , methodIndex.Method ());
1405
+ assembly = g_CLR_RT_TypeSystem. m_assemblies [assemblyIndex - 1 ] ;
1357
1406
target = assembly->GetMethodDef (methodIndex.Method ());
1358
1407
}
1359
1408
else
@@ -1484,6 +1533,32 @@ bool CLR_RT_MethodDef_Instance::ResolveToken(
1484
1533
return false ;
1485
1534
}
1486
1535
1536
+ bool CLR_RT_MethodDef_Instance::GetDeclaringType (CLR_RT_TypeDef_Instance &declType) const
1537
+ {
1538
+ NATIVE_PROFILE_CLR_CORE ();
1539
+
1540
+ if (genericType && NANOCLR_INDEX_IS_VALID (*genericType))
1541
+ {
1542
+ // Look up the assembly that actually owns that TypeSpec
1543
+ auto tsAsm = g_CLR_RT_TypeSystem.m_assemblies [genericType->Assembly () - 1 ];
1544
+ auto tsRec = tsAsm->GetTypeSpec (genericType->TypeSpec ());
1545
+
1546
+ // Parse the signature so we can peel off [GENERICINST CLASS <type> <args>].
1547
+ CLR_RT_SignatureParser parser;
1548
+ parser.Initialize_TypeSpec (tsAsm, tsRec);
1549
+
1550
+ CLR_RT_SignatureParser::Element elem;
1551
+ parser.Advance (elem);
1552
+
1553
+ return declType.InitializeFromIndex (elem.Class );
1554
+ }
1555
+ else
1556
+ {
1557
+ // Normal (non‐generic or open‐generic)
1558
+ return declType.InitializeFromMethod (*this );
1559
+ }
1560
+ }
1561
+
1487
1562
// ////////////////////////////
1488
1563
1489
1564
bool CLR_RT_GenericParam_Instance::InitializeFromIndex (const CLR_RT_GenericParam_Index &index)
@@ -3203,8 +3278,15 @@ HRESULT CLR_RT_Assembly::ResolveMethodRef()
3203
3278
#endif
3204
3279
}
3205
3280
3206
- if (typeSpecInstance.assembly
3207
- ->FindMethodDef (typeSpecInstance.target , methodName, this , src->signature , dst->target ))
3281
+ CLR_UINT32 dummyAssemblyIndex = 0xffff ;
3282
+
3283
+ if (typeSpecInstance.assembly ->FindMethodDef (
3284
+ typeSpecInstance.target ,
3285
+ methodName,
3286
+ this ,
3287
+ src->signature ,
3288
+ dst->target ,
3289
+ dummyAssemblyIndex))
3208
3290
{
3209
3291
fGot = true ;
3210
3292
@@ -3376,6 +3458,27 @@ HRESULT CLR_RT_Assembly::ResolveTypeSpec()
3376
3458
CLR_Debug::Printf (" [%04X]\r\n " , i);
3377
3459
}
3378
3460
#endif
3461
+
3462
+ // parse the signature to find the defining type token
3463
+ CLR_RT_SignatureParser parser;
3464
+ parser.Initialize_TypeSpec (this , GetTypeSpec (i));
3465
+
3466
+ CLR_RT_SignatureParser::Element elem;
3467
+
3468
+ parser.Advance (elem);
3469
+
3470
+ if (elem.DataType == DATATYPE_VALUETYPE)
3471
+ {
3472
+ // now `elem.Class` is exactly the open Span`1 or List`1
3473
+ // store the open‐generic’s token
3474
+ dst->ownerType = elem.Class ;
3475
+ }
3476
+ else
3477
+ {
3478
+ // if the first element is not a generic instantiation, then it must be a type token
3479
+ // no open‐generic, so clear the token
3480
+ dst->ownerType .Clear ();
3481
+ }
3379
3482
}
3380
3483
3381
3484
NANOCLR_NOCLEANUP ();
@@ -4878,20 +4981,72 @@ bool CLR_RT_Assembly::FindMethodDef(
4878
4981
const char *methodName,
4879
4982
CLR_RT_Assembly *base,
4880
4983
CLR_SIG sig,
4881
- CLR_RT_MethodDef_Index &index)
4984
+ CLR_RT_MethodDef_Index &index,
4985
+ CLR_UINT32 &assmIndex)
4882
4986
{
4883
4987
NATIVE_PROFILE_CLR_CORE ();
4884
4988
4885
4989
CLR_RT_TypeSpec_Index tsIndex;
4886
- base->FindTypeSpec (base->GetSignature (ts->signature ), tsIndex);
4990
+ if (!base->FindTypeSpec (base->GetSignature (ts->signature ), tsIndex))
4991
+ {
4992
+ index.Clear ();
4993
+ return false ;
4994
+ }
4887
4995
4888
4996
CLR_RT_TypeSpec_Instance tsInstance;
4889
- tsInstance.InitializeFromIndex (tsIndex);
4997
+ if (!tsInstance.InitializeFromIndex (tsIndex))
4998
+ {
4999
+ index.Clear ();
5000
+ return false ;
5001
+ }
5002
+
5003
+ // switch to the assembly that declared this TypeSpec
5004
+ CLR_RT_Assembly *declAssm = tsInstance.assembly ;
5005
+ const CLR_RECORD_TYPEDEF *td =
5006
+ (const CLR_RECORD_TYPEDEF *)declAssm->GetTable (TBL_TypeDef) + tsInstance.typeDefIndex ;
5007
+
5008
+ if (declAssm->FindMethodDef (td, methodName, base, sig, index))
5009
+ {
5010
+ assmIndex = declAssm->assemblyIndex ;
5011
+ return true ;
5012
+ }
5013
+
5014
+ // parse the TypeSpec signature to get the *definition* token of the generic type:
5015
+ CLR_RT_SignatureParser parser{};
5016
+ parser.Initialize_TypeSpec (this , ts);
5017
+ CLR_RT_SignatureParser::Element elem{};
5018
+
5019
+ // advance to get the actual CLASS/VALUETYPE token for the generic definition.
5020
+ if (FAILED (parser.Advance (elem)))
5021
+ {
5022
+ return false ;
5023
+ }
4890
5024
4891
- auto *td = (const CLR_RECORD_TYPEDEF *)base->GetTable (TBL_TypeDef);
4892
- td += tsInstance.typeDefIndex ;
5025
+ CLR_UINT32 genericDefToken = elem.Class .data ;
4893
5026
4894
- return CLR_RT_Assembly::FindMethodDef (td, methodName, base, sig, index);
5027
+ CLR_RT_TypeDef_Index typeDef;
5028
+ typeDef.Clear ();
5029
+ typeDef.data = genericDefToken;
5030
+
5031
+ CLR_RT_TypeDef_Instance typeDefInstance;
5032
+ if (typeDefInstance.InitializeFromIndex (typeDef) == false )
5033
+ {
5034
+ return false ;
5035
+ }
5036
+
5037
+ while (NANOCLR_INDEX_IS_VALID (typeDefInstance))
5038
+ {
5039
+ if (typeDefInstance.assembly ->FindMethodDef (typeDefInstance.target , methodName, this , sig, index))
5040
+ {
5041
+ assmIndex = typeDefInstance.assembly ->assemblyIndex ;
5042
+
5043
+ return true ;
5044
+ }
5045
+
5046
+ typeDefInstance.SwitchToParent ();
5047
+ }
5048
+
5049
+ return false ;
4895
5050
}
4896
5051
4897
5052
bool CLR_RT_Assembly::FindTypeSpec (CLR_PMETADATA sig, CLR_RT_TypeSpec_Index &index)
@@ -6166,28 +6321,31 @@ HRESULT CLR_RT_TypeSystem::BuildMethodName(
6166
6321
NANOCLR_HEADER ();
6167
6322
6168
6323
CLR_RT_MethodDef_Instance inst{};
6169
- CLR_RT_TypeDef_Instance instOwner{};
6170
6324
6171
- if (inst. InitializeFromIndex (md) == false )
6325
+ if (genericType == nullptr )
6172
6326
{
6173
- NANOCLR_SET_AND_LEAVE (CLR_E_WRONG_TYPE);
6174
- }
6327
+ if (inst.InitializeFromIndex (md) == false )
6328
+ {
6329
+ NANOCLR_SET_AND_LEAVE (CLR_E_WRONG_TYPE);
6330
+ }
6175
6331
6176
- if (instOwner.InitializeFromMethod (inst) == false )
6177
- {
6178
- NANOCLR_SET_AND_LEAVE (CLR_E_WRONG_TYPE);
6179
- }
6332
+ CLR_RT_TypeDef_Instance instOwner{};
6333
+ if (instOwner.InitializeFromMethod (inst) == false )
6334
+ {
6335
+ NANOCLR_SET_AND_LEAVE (CLR_E_WRONG_TYPE);
6336
+ }
6180
6337
6181
- if (genericType == nullptr )
6182
- {
6183
6338
NANOCLR_CHECK_HRESULT (BuildTypeName (instOwner, szBuffer, iBuffer));
6184
6339
6185
6340
CLR_SafeSprintf (szBuffer, iBuffer, " ::%s" , inst.assembly ->GetString (inst.target ->name ));
6186
6341
}
6187
6342
else
6188
6343
{
6344
+ CLR_INDEX tsAsmIdx = genericType->Assembly ();
6345
+ CLR_RT_Assembly *genericTypeAssembly = g_CLR_RT_TypeSystem.m_assemblies [tsAsmIdx - 1 ];
6346
+
6189
6347
CLR_RT_SignatureParser parser;
6190
- parser.Initialize_TypeSpec (inst. assembly , inst. assembly ->GetTypeSpec (genericType->TypeSpec ()));
6348
+ parser.Initialize_TypeSpec (genericTypeAssembly, genericTypeAssembly ->GetTypeSpec (genericType->TypeSpec ()));
6191
6349
6192
6350
CLR_RT_SignatureParser::Element element;
6193
6351
@@ -6215,7 +6373,14 @@ HRESULT CLR_RT_TypeSystem::BuildMethodName(
6215
6373
}
6216
6374
}
6217
6375
6218
- CLR_SafeSprintf (szBuffer, iBuffer, " >::%s" , inst.assembly ->GetString (inst.target ->name ));
6376
+ if (inst.InitializeFromIndex (md, *genericType) == false )
6377
+ {
6378
+ // this is a MethodDef for a generic type, but the generic type is not bound to an assembly
6379
+ // so we cannot build the name of the method.
6380
+ NANOCLR_SET_AND_LEAVE (CLR_E_WRONG_TYPE);
6381
+ }
6382
+
6383
+ CLR_SafeSprintf (szBuffer, iBuffer, " >::%s" , genericTypeAssembly->GetString (inst.target ->name ));
6219
6384
}
6220
6385
6221
6386
NANOCLR_NOCLEANUP ();
0 commit comments