@@ -1266,32 +1266,55 @@ bool CLR_RT_MethodDef_Instance::InitializeFromIndex(
12661266{
12671267 NATIVE_PROFILE_CLR_CORE ();
12681268
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) )
12721272 {
12731273 return false ;
12741274 }
1275- CLR_RT_Assembly *tsAsm = g_CLR_RT_TypeSystem.m_assemblies [tsAsmIdx - 1 ];
12761275
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);
12791281
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+ }
12821287
1283- // Compute the MethodDef_Index bound to the owner’s assembly
1288+ CLR_RT_TypeDef_Index ownerTypeIdx;
12841289 CLR_RT_MethodDef_Index mdRebound;
12851290
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 ();
12881311
12891312 if (!InitializeFromIndex (mdRebound))
12901313 {
12911314 return false ;
12921315 }
12931316
1294- // set the generic‐type context *before* we lose it
1317+ // remember the TypeSpec so this is available when needed
12951318 this ->genericType = &typeSpec;
12961319
12971320 return true ;
@@ -1401,7 +1424,7 @@ bool CLR_RT_MethodDef_Instance::ResolveToken(
14011424 return false ;
14021425 }
14031426
1404- Set (assemblyIndex - 1 , methodIndex.Method ());
1427+ Set (assemblyIndex, methodIndex.Method ());
14051428 assembly = g_CLR_RT_TypeSystem.m_assemblies [assemblyIndex - 1 ];
14061429 target = assembly->GetMethodDef (methodIndex.Method ());
14071430 }
@@ -3278,7 +3301,7 @@ HRESULT CLR_RT_Assembly::ResolveMethodRef()
32783301#endif
32793302 }
32803303
3281- CLR_UINT32 dummyAssemblyIndex = 0xffff ;
3304+ CLR_UINT32 dummyAssemblyIndex = 0xffffffff ;
32823305
32833306 if (typeSpecInstance.assembly ->FindMethodDef (
32843307 typeSpecInstance.target ,
@@ -4770,6 +4793,7 @@ bool CLR_RT_Assembly::FindGenericParamAtTypeSpec(
47704793 // element.Class was filled from the VAR position
47714794 typeDef = element.Class ;
47724795 dataType = element.DataType ;
4796+
47734797 return true ;
47744798}
47754799
@@ -5002,15 +5026,24 @@ bool CLR_RT_Assembly::FindMethodDef(
50025026
50035027 // switch to the assembly that declared this TypeSpec
50045028 CLR_RT_Assembly *declAssm = tsInstance.assembly ;
5005- const CLR_RECORD_TYPEDEF *td =
5006- (const CLR_RECORD_TYPEDEF *)declAssm->GetTable (TBL_TypeDef) + tsInstance.typeDefIndex ;
50075029
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))
50095040 {
50105041 assmIndex = declAssm->assemblyIndex ;
50115042 return true ;
50125043 }
50135044
5045+ try_typespec:
5046+
50145047 // parse the TypeSpec signature to get the *definition* token of the generic type:
50155048 CLR_RT_SignatureParser parser{};
50165049 parser.Initialize_TypeSpec (this , ts);
@@ -6233,18 +6266,41 @@ HRESULT CLR_RT_TypeSystem::BuildTypeName(const CLR_RT_TypeSpec_Index &typeIndex,
62336266
62346267 for (int i = 0 ; i < parser.GenParamCount ; i++)
62356268 {
6269+ // read the next element (should be either VAR, MVAR, or a concrete type)
62366270 parser.Advance (element);
62376271
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+
62416297 if (i + 1 < parser.GenParamCount )
62426298 {
62436299 NANOCLR_CHECK_HRESULT (QueueStringToBuffer (szBuffer, iBuffer, " ," ));
62446300 }
62456301 }
62466302
6247- CLR_SafeSprintf ( szBuffer, iBuffer, " >" );
6303+ NANOCLR_CHECK_HRESULT ( QueueStringToBuffer ( szBuffer, iBuffer, " >" ) );
62486304
62496305 NANOCLR_NOCLEANUP ();
62506306}
@@ -6320,69 +6376,66 @@ HRESULT CLR_RT_TypeSystem::BuildMethodName(
63206376 NATIVE_PROFILE_CLR_CORE ();
63216377 NANOCLR_HEADER ();
63226378
6379+ CLR_RT_TypeDef_Instance declTypeInst{};
6380+ CLR_RT_MethodDef_Instance tempMD{};
63236381 CLR_RT_MethodDef_Instance inst{};
6382+ CLR_RT_TypeDef_Index declTypeIdx;
6383+ CLR_RT_TypeDef_Instance instOwner{};
6384+ bool useGeneric = false ;
63246385
6325- if (genericType == nullptr )
6386+ // find out which type declares this method
6387+ if (!tempMD.InitializeFromIndex (md))
63266388 {
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);
63416390 }
6342- else
6343- {
6344- CLR_INDEX tsAsmIdx = genericType->Assembly ();
6345- CLR_RT_Assembly *genericTypeAssembly = g_CLR_RT_TypeSystem.m_assemblies [tsAsmIdx - 1 ];
63466391
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+ }
63576396
6358- BuildTypeName (typeDef, szBuffer, iBuffer );
6397+ declTypeIdx. Set (md. Assembly (), declTypeInst. assembly -> crossReferenceMethodDef [md. Method ()]. GetOwner () );
63596398
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 = {};
63616403
6362- for ( int i = 0 ; i < parser. GenParamCount ; i++ )
6404+ if (tsInst. InitializeFromIndex (*genericType) )
63636405 {
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 ())
63716407 {
6372- NANOCLR_CHECK_HRESULT ( QueueStringToBuffer (szBuffer, iBuffer, " , " )) ;
6408+ useGeneric = true ;
63736409 }
63746410 }
6411+ }
63756412
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))
63776425 {
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.
63806426 NANOCLR_SET_AND_LEAVE (CLR_E_WRONG_TYPE);
63816427 }
6428+ }
63826429
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);
63846433 }
63856434
6435+ NANOCLR_CHECK_HRESULT (BuildTypeName (instOwner, szBuffer, iBuffer));
6436+
6437+ CLR_SafeSprintf (szBuffer, iBuffer, " ::%s" , inst.assembly ->GetString (inst.target ->name ));
6438+
63866439 NANOCLR_NOCLEANUP ();
63876440}
63886441
0 commit comments