@@ -610,6 +610,8 @@ HRESULT CLR_RT_SignatureParser::Advance(Element &res)
610610 // sanity check
611611 if (dt == DATATYPE_CLASS || dt == DATATYPE_VALUETYPE)
612612 {
613+ res.DataType = dt;
614+
613615 // parse type
614616 goto parse_type;
615617 }
@@ -1258,6 +1260,43 @@ bool CLR_RT_MethodDef_Instance::InitializeFromIndex(const CLR_RT_MethodDef_Index
12581260 return false ;
12591261}
12601262
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+
12611300void CLR_RT_MethodDef_Instance::ClearInstance ()
12621301{
12631302 NATIVE_PROFILE_CLR_CORE ();
@@ -1344,16 +1383,26 @@ bool CLR_RT_MethodDef_Instance::ResolveToken(
13441383 const CLR_RT_TypeSpec_Index *definitiveTypeSpec = useCaller ? callerGeneric : methodOwnerTS;
13451384 genericType = (CLR_RT_TypeSpec_Index *)definitiveTypeSpec;
13461385
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 ;
13481391 CLR_RT_MethodDef_Index methodIndex;
13491392
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))
13511400 {
13521401 return false ;
13531402 }
13541403
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 ] ;
13571406 target = assembly->GetMethodDef (methodIndex.Method ());
13581407 }
13591408 else
@@ -1484,6 +1533,32 @@ bool CLR_RT_MethodDef_Instance::ResolveToken(
14841533 return false ;
14851534}
14861535
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+
14871562// ////////////////////////////
14881563
14891564bool CLR_RT_GenericParam_Instance::InitializeFromIndex (const CLR_RT_GenericParam_Index &index)
@@ -3203,8 +3278,15 @@ HRESULT CLR_RT_Assembly::ResolveMethodRef()
32033278#endif
32043279 }
32053280
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))
32083290 {
32093291 fGot = true ;
32103292
@@ -3376,6 +3458,27 @@ HRESULT CLR_RT_Assembly::ResolveTypeSpec()
33763458 CLR_Debug::Printf (" [%04X]\r\n " , i);
33773459 }
33783460#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+ }
33793482 }
33803483
33813484 NANOCLR_NOCLEANUP ();
@@ -4878,20 +4981,72 @@ bool CLR_RT_Assembly::FindMethodDef(
48784981 const char *methodName,
48794982 CLR_RT_Assembly *base,
48804983 CLR_SIG sig,
4881- CLR_RT_MethodDef_Index &index)
4984+ CLR_RT_MethodDef_Index &index,
4985+ CLR_UINT32 &assmIndex)
48824986{
48834987 NATIVE_PROFILE_CLR_CORE ();
48844988
48854989 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+ }
48874995
48884996 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+ }
48905024
4891- auto *td = (const CLR_RECORD_TYPEDEF *)base->GetTable (TBL_TypeDef);
4892- td += tsInstance.typeDefIndex ;
5025+ CLR_UINT32 genericDefToken = elem.Class .data ;
48935026
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 ;
48955050}
48965051
48975052bool CLR_RT_Assembly::FindTypeSpec (CLR_PMETADATA sig, CLR_RT_TypeSpec_Index &index)
@@ -6166,28 +6321,31 @@ HRESULT CLR_RT_TypeSystem::BuildMethodName(
61666321 NANOCLR_HEADER ();
61676322
61686323 CLR_RT_MethodDef_Instance inst{};
6169- CLR_RT_TypeDef_Instance instOwner{};
61706324
6171- if (inst. InitializeFromIndex (md) == false )
6325+ if (genericType == nullptr )
61726326 {
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+ }
61756331
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+ }
61806337
6181- if (genericType == nullptr )
6182- {
61836338 NANOCLR_CHECK_HRESULT (BuildTypeName (instOwner, szBuffer, iBuffer));
61846339
61856340 CLR_SafeSprintf (szBuffer, iBuffer, " ::%s" , inst.assembly ->GetString (inst.target ->name ));
61866341 }
61876342 else
61886343 {
6344+ CLR_INDEX tsAsmIdx = genericType->Assembly ();
6345+ CLR_RT_Assembly *genericTypeAssembly = g_CLR_RT_TypeSystem.m_assemblies [tsAsmIdx - 1 ];
6346+
61896347 CLR_RT_SignatureParser parser;
6190- parser.Initialize_TypeSpec (inst. assembly , inst. assembly ->GetTypeSpec (genericType->TypeSpec ()));
6348+ parser.Initialize_TypeSpec (genericTypeAssembly, genericTypeAssembly ->GetTypeSpec (genericType->TypeSpec ()));
61916349
61926350 CLR_RT_SignatureParser::Element element;
61936351
@@ -6215,7 +6373,14 @@ HRESULT CLR_RT_TypeSystem::BuildMethodName(
62156373 }
62166374 }
62176375
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 ));
62196384 }
62206385
62216386 NANOCLR_NOCLEANUP ();
0 commit comments