@@ -1266,32 +1266,55 @@ bool CLR_RT_MethodDef_Instance::InitializeFromIndex(
1266
1266
{
1267
1267
NATIVE_PROFILE_CLR_CORE ();
1268
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 )
1269
+ CLR_RT_TypeSpec_Instance tsInst;
1270
+
1271
+ if (!tsInst. InitializeFromIndex (typeSpec) )
1272
1272
{
1273
1273
return false ;
1274
1274
}
1275
- CLR_RT_Assembly *tsAsm = g_CLR_RT_TypeSystem.m_assemblies [tsAsmIdx - 1 ];
1276
1275
1277
- int tsRow = (int )typeSpec.TypeSpec ();
1278
- const auto &xref = tsAsm->crossReferenceTypeSpec [tsRow];
1276
+ // parse the signature to get to the GENERICINST and then the definition token
1277
+ CLR_RT_Assembly *tsAsm = tsInst.assembly ;
1278
+ auto tsRec = tsAsm->GetTypeSpec (typeSpec.TypeSpec ());
1279
+ CLR_RT_SignatureParser parser;
1280
+ parser.Initialize_TypeSpec (tsAsm, tsRec);
1279
1281
1280
- // xref.ownerType is the open‐generic TypeDef_Index of Span`1, List`1, etc.
1281
- CLR_RT_TypeDef_Index ownerType = xref.ownerType ;
1282
+ CLR_RT_SignatureParser::Element elem;
1283
+ if (FAILED (parser.Advance (elem)))
1284
+ {
1285
+ return false ;
1286
+ }
1282
1287
1283
- // Compute the MethodDef_Index bound to the owner’s assembly
1288
+ CLR_RT_TypeDef_Index ownerTypeIdx;
1284
1289
CLR_RT_MethodDef_Index mdRebound;
1285
1290
1286
- // pack the new assembly index (ownerType.Assembly()) with the original row
1287
- mdRebound.data = (ownerType.Assembly () << 24 ) | md.Method ();
1291
+ if (elem.DataType == DATATYPE_VAR)
1292
+ {
1293
+ CLR_RT_TypeDef_Index realOwner;
1294
+ NanoCLRDataType dummyDT;
1295
+
1296
+ if (!tsAsm->FindGenericParamAtTypeSpec (typeSpec.TypeSpec (), elem.GenericParamPosition , realOwner, dummyDT))
1297
+ {
1298
+ return false ;
1299
+ }
1300
+
1301
+ ownerTypeIdx = realOwner;
1302
+ }
1303
+ else
1304
+ {
1305
+ // elem.Class.data now contains the TypeDef/TypeRef token for the generic definition
1306
+ ownerTypeIdx.data = elem.Class .data ;
1307
+ }
1308
+
1309
+ // rebind the method onto the *declaring* assembly of the generic
1310
+ mdRebound.data = (ownerTypeIdx.Assembly () << 24 ) | md.Method ();
1288
1311
1289
1312
if (!InitializeFromIndex (mdRebound))
1290
1313
{
1291
1314
return false ;
1292
1315
}
1293
1316
1294
- // set the generic‐type context *before* we lose it
1317
+ // remember the TypeSpec so this is available when needed
1295
1318
this ->genericType = &typeSpec;
1296
1319
1297
1320
return true ;
@@ -1401,7 +1424,7 @@ bool CLR_RT_MethodDef_Instance::ResolveToken(
1401
1424
return false ;
1402
1425
}
1403
1426
1404
- Set (assemblyIndex - 1 , methodIndex.Method ());
1427
+ Set (assemblyIndex, methodIndex.Method ());
1405
1428
assembly = g_CLR_RT_TypeSystem.m_assemblies [assemblyIndex - 1 ];
1406
1429
target = assembly->GetMethodDef (methodIndex.Method ());
1407
1430
}
@@ -3278,7 +3301,7 @@ HRESULT CLR_RT_Assembly::ResolveMethodRef()
3278
3301
#endif
3279
3302
}
3280
3303
3281
- CLR_UINT32 dummyAssemblyIndex = 0xffff ;
3304
+ CLR_UINT32 dummyAssemblyIndex = 0xffffffff ;
3282
3305
3283
3306
if (typeSpecInstance.assembly ->FindMethodDef (
3284
3307
typeSpecInstance.target ,
@@ -4770,6 +4793,7 @@ bool CLR_RT_Assembly::FindGenericParamAtTypeSpec(
4770
4793
// element.Class was filled from the VAR position
4771
4794
typeDef = element.Class ;
4772
4795
dataType = element.DataType ;
4796
+
4773
4797
return true ;
4774
4798
}
4775
4799
@@ -5002,15 +5026,24 @@ bool CLR_RT_Assembly::FindMethodDef(
5002
5026
5003
5027
// switch to the assembly that declared this TypeSpec
5004
5028
CLR_RT_Assembly *declAssm = tsInstance.assembly ;
5005
- const CLR_RECORD_TYPEDEF *td =
5006
- (const CLR_RECORD_TYPEDEF *)declAssm->GetTable (TBL_TypeDef) + tsInstance.typeDefIndex ;
5007
5029
5008
- if (declAssm->FindMethodDef (td, methodName, base, sig, index))
5030
+ CLR_INDEX typeDefIdx = tsInstance.typeDefIndex ;
5031
+
5032
+ // validate that it really is in-range
5033
+ if (typeDefIdx >= declAssm->tablesSize [TBL_TypeDef])
5034
+ {
5035
+ // doesn't seem to be, jump to TypeSpec parsing
5036
+ goto try_typespec;
5037
+ }
5038
+
5039
+ if (declAssm->FindMethodDef (declAssm->GetTypeDef (typeDefIdx), methodName, base, sig, index))
5009
5040
{
5010
5041
assmIndex = declAssm->assemblyIndex ;
5011
5042
return true ;
5012
5043
}
5013
5044
5045
+ try_typespec:
5046
+
5014
5047
// parse the TypeSpec signature to get the *definition* token of the generic type:
5015
5048
CLR_RT_SignatureParser parser{};
5016
5049
parser.Initialize_TypeSpec (this , ts);
@@ -6233,18 +6266,41 @@ HRESULT CLR_RT_TypeSystem::BuildTypeName(const CLR_RT_TypeSpec_Index &typeIndex,
6233
6266
6234
6267
for (int i = 0 ; i < parser.GenParamCount ; i++)
6235
6268
{
6269
+ // read the next element (should be either VAR, MVAR, or a concrete type)
6236
6270
parser.Advance (element);
6237
6271
6238
- #if defined(VIRTUAL_DEVICE)
6239
- NANOCLR_CHECK_HRESULT (QueueStringToBuffer (szBuffer, iBuffer, c_CLR_RT_DataTypeLookup[element.DataType ].m_name ));
6240
- #endif
6272
+ if (element.DataType == DATATYPE_VAR)
6273
+ {
6274
+ // resolve the !T against our *closed* typeIndex
6275
+ CLR_RT_TypeDef_Index realTd;
6276
+ NanoCLRDataType realDt;
6277
+
6278
+ // this will bind !T→System.Int32, etc.
6279
+ instance.assembly ->FindGenericParamAtTypeSpec (
6280
+ typeIndex.TypeSpec (), // closed instantiation row
6281
+ element.GenericParamPosition , // the !N slot
6282
+ realTd,
6283
+ realDt);
6284
+
6285
+ // now print the *actual* type name
6286
+ BuildTypeName (realTd, szBuffer, iBuffer);
6287
+ }
6288
+ else
6289
+ {
6290
+ // concrete type (e.g. a nested generic, a value type, another class...)
6291
+ CLR_RT_TypeDef_Index td;
6292
+ td.data = element.Class .data ;
6293
+
6294
+ BuildTypeName (td, szBuffer, iBuffer);
6295
+ }
6296
+
6241
6297
if (i + 1 < parser.GenParamCount )
6242
6298
{
6243
6299
NANOCLR_CHECK_HRESULT (QueueStringToBuffer (szBuffer, iBuffer, " ," ));
6244
6300
}
6245
6301
}
6246
6302
6247
- CLR_SafeSprintf ( szBuffer, iBuffer, " >" );
6303
+ NANOCLR_CHECK_HRESULT ( QueueStringToBuffer ( szBuffer, iBuffer, " >" ) );
6248
6304
6249
6305
NANOCLR_NOCLEANUP ();
6250
6306
}
@@ -6320,69 +6376,66 @@ HRESULT CLR_RT_TypeSystem::BuildMethodName(
6320
6376
NATIVE_PROFILE_CLR_CORE ();
6321
6377
NANOCLR_HEADER ();
6322
6378
6379
+ CLR_RT_TypeDef_Instance declTypeInst{};
6380
+ CLR_RT_MethodDef_Instance tempMD{};
6323
6381
CLR_RT_MethodDef_Instance inst{};
6382
+ CLR_RT_TypeDef_Index declTypeIdx;
6383
+ CLR_RT_TypeDef_Instance instOwner{};
6384
+ bool useGeneric = false ;
6324
6385
6325
- if (genericType == nullptr )
6386
+ // find out which type declares this method
6387
+ if (!tempMD.InitializeFromIndex (md))
6326
6388
{
6327
- if (inst.InitializeFromIndex (md) == false )
6328
- {
6329
- NANOCLR_SET_AND_LEAVE (CLR_E_WRONG_TYPE);
6330
- }
6331
-
6332
- CLR_RT_TypeDef_Instance instOwner{};
6333
- if (instOwner.InitializeFromMethod (inst) == false )
6334
- {
6335
- NANOCLR_SET_AND_LEAVE (CLR_E_WRONG_TYPE);
6336
- }
6337
-
6338
- NANOCLR_CHECK_HRESULT (BuildTypeName (instOwner, szBuffer, iBuffer));
6339
-
6340
- CLR_SafeSprintf (szBuffer, iBuffer, " ::%s" , inst.assembly ->GetString (inst.target ->name ));
6389
+ NANOCLR_SET_AND_LEAVE (CLR_E_WRONG_TYPE);
6341
6390
}
6342
- else
6343
- {
6344
- CLR_INDEX tsAsmIdx = genericType->Assembly ();
6345
- CLR_RT_Assembly *genericTypeAssembly = g_CLR_RT_TypeSystem.m_assemblies [tsAsmIdx - 1 ];
6346
6391
6347
- CLR_RT_SignatureParser parser;
6348
- parser.Initialize_TypeSpec (genericTypeAssembly, genericTypeAssembly->GetTypeSpec (genericType->TypeSpec ()));
6349
-
6350
- CLR_RT_SignatureParser::Element element;
6351
-
6352
- // get type
6353
- parser.Advance (element);
6354
-
6355
- CLR_RT_TypeDef_Index typeDef;
6356
- typeDef.data = element.Class .data ;
6392
+ if (!declTypeInst.InitializeFromMethod (tempMD))
6393
+ {
6394
+ NANOCLR_SET_AND_LEAVE (CLR_E_WRONG_TYPE);
6395
+ }
6357
6396
6358
- BuildTypeName (typeDef, szBuffer, iBuffer );
6397
+ declTypeIdx. Set (md. Assembly (), declTypeInst. assembly -> crossReferenceMethodDef [md. Method ()]. GetOwner () );
6359
6398
6360
- NANOCLR_CHECK_HRESULT (QueueStringToBuffer (szBuffer, iBuffer, " <" ));
6399
+ if (genericType != nullptr && genericType->data != 0xffffffff )
6400
+ {
6401
+ // parse TypeSpec to get its TypeDef
6402
+ CLR_RT_TypeSpec_Instance tsInst = {};
6361
6403
6362
- for ( int i = 0 ; i < parser. GenParamCount ; i++ )
6404
+ if (tsInst. InitializeFromIndex (*genericType) )
6363
6405
{
6364
- parser.Advance (element);
6365
-
6366
- #if defined(VIRTUAL_DEVICE)
6367
- NANOCLR_CHECK_HRESULT (
6368
- QueueStringToBuffer (szBuffer, iBuffer, c_CLR_RT_DataTypeLookup[element.DataType ].m_name ));
6369
- #endif
6370
- if (i + 1 < parser.GenParamCount )
6406
+ if (tsInst.typeDefIndex == declTypeIdx.Type ())
6371
6407
{
6372
- NANOCLR_CHECK_HRESULT ( QueueStringToBuffer (szBuffer, iBuffer, " , " )) ;
6408
+ useGeneric = true ;
6373
6409
}
6374
6410
}
6411
+ }
6375
6412
6376
- if (inst.InitializeFromIndex (md, *genericType) == false )
6413
+ if (!useGeneric)
6414
+ {
6415
+ // fallback: non generic method or a different type
6416
+ if (!inst.InitializeFromIndex (md))
6417
+ {
6418
+ NANOCLR_SET_AND_LEAVE (CLR_E_WRONG_TYPE);
6419
+ }
6420
+ }
6421
+ else
6422
+ {
6423
+ // method belong to a closed generic type, so bind it to the appropriate TypeSpec
6424
+ if (!inst.InitializeFromIndex (md, *genericType))
6377
6425
{
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
6426
NANOCLR_SET_AND_LEAVE (CLR_E_WRONG_TYPE);
6381
6427
}
6428
+ }
6382
6429
6383
- CLR_SafeSprintf (szBuffer, iBuffer, " >::%s" , genericTypeAssembly->GetString (inst.target ->name ));
6430
+ if (instOwner.InitializeFromMethod (inst) == false )
6431
+ {
6432
+ NANOCLR_SET_AND_LEAVE (CLR_E_WRONG_TYPE);
6384
6433
}
6385
6434
6435
+ NANOCLR_CHECK_HRESULT (BuildTypeName (instOwner, szBuffer, iBuffer));
6436
+
6437
+ CLR_SafeSprintf (szBuffer, iBuffer, " ::%s" , inst.assembly ->GetString (inst.target ->name ));
6438
+
6386
6439
NANOCLR_NOCLEANUP ();
6387
6440
}
6388
6441
0 commit comments