@@ -976,34 +976,23 @@ bool CLR_RT_TypeDef_Instance::ResolveToken(
976976 parser.Initialize_TypeSpec (assm, ts);
977977
978978 CLR_RT_SignatureParser::Element elem;
979-
980- // Skip any leading SZARRAY or BYREF
981- do
979+ if (FAILED (parser.Advance (elem)))
982980 {
983- if (FAILED (parser.Advance (elem)))
984- {
985- return false ;
986- }
987- } while (elem.DataType == DATATYPE_SZARRAY || elem.DataType == DATATYPE_BYREF);
981+ return false ;
982+ }
988983
989- // If this is a closed‐generic instantiation header, peel off the wrapper
990- if (elem.DataType == DATATYPE_GENERICINST)
984+ if (elem.DataType == DATATYPE_CLASS || elem.DataType == DATATYPE_VALUETYPE)
991985 {
992- // consume the CLASS/VALUETYPE marker
993- if (FAILED (parser.Advance (elem)))
994- {
995- return false ;
996- }
997- // consume the generic‐definition token itself
998- if (FAILED (parser.Advance (elem)))
999- {
1000- return false ;
1001- }
1002- // consume the count of generic arguments
1003- if (FAILED (parser.Advance (elem)))
1004- {
1005- return false ;
1006- }
986+ // If it's a class or value type, resolve the type
987+ data = elem.Class .data ;
988+ assembly = g_CLR_RT_TypeSystem.m_assemblies [elem.Class .Assembly () - 1 ];
989+ target = assembly->GetTypeDef (elem.Class .Type ());
990+
991+ #if defined(NANOCLR_INSTANCE_NAMES)
992+ name = assembly->GetString (target->name );
993+ #endif
994+
995+ return true ;
1007996 }
1008997
1009998 // walk forward until a VAR (type‐generic) or MVAR (method‐generic) is hit
@@ -1045,8 +1034,6 @@ bool CLR_RT_TypeDef_Instance::ResolveToken(
10451034 }
10461035 else
10471036 {
1048- // elem.DataType == DATATYPE_MVAR
1049-
10501037 // Use the *caller's* bound genericType (Stack<Int32>, etc.)
10511038 if (caller == nullptr || caller->genericType == nullptr )
10521039 {
@@ -1060,6 +1047,7 @@ bool CLR_RT_TypeDef_Instance::ResolveToken(
10601047 data = gp.classTypeDef .data ;
10611048 assembly = g_CLR_RT_TypeSystem.m_assemblies [gp.classTypeDef .Assembly () - 1 ];
10621049 target = assembly->GetTypeDef (gp.classTypeDef .Type ());
1050+
10631051 return true ;
10641052 }
10651053 }
@@ -1081,6 +1069,109 @@ bool CLR_RT_TypeDef_Instance::ResolveToken(
10811069 return false ;
10821070}
10831071
1072+ bool CLR_RT_TypeDef_Instance::ResolveNullableType (
1073+ CLR_UINT32 tk,
1074+ CLR_RT_Assembly *assm,
1075+ const CLR_RT_MethodDef_Instance *caller)
1076+ {
1077+ NATIVE_PROFILE_CLR_CORE ();
1078+
1079+ if (assm)
1080+ {
1081+ CLR_UINT32 index = CLR_DataFromTk (tk);
1082+
1083+ if (CLR_TypeFromTk (tk) != TBL_TypeSpec)
1084+ {
1085+ // not a TypeSpec, so return false
1086+ ClearInstance ();
1087+ return false ;
1088+ }
1089+
1090+ // Grab the raw signature for the IL token (e.g. !T[], List`1<T>, etc.)
1091+ const CLR_RECORD_TYPESPEC *ts = assm->GetTypeSpec (index);
1092+ CLR_RT_SignatureParser parser;
1093+ parser.Initialize_TypeSpec (assm, ts);
1094+
1095+ CLR_RT_SignatureParser::Element elem;
1096+ if (FAILED (parser.Advance (elem)))
1097+ {
1098+ return false ;
1099+ }
1100+
1101+ if (elem.DataType != DATATYPE_VALUETYPE)
1102+ {
1103+ // If it's not a value type, we can't resolve it as a nullable type
1104+ ClearInstance ();
1105+ return false ;
1106+ }
1107+
1108+ // move to the next element in the signature
1109+ if (FAILED (parser.Advance (elem)))
1110+ {
1111+ return false ;
1112+ }
1113+
1114+ // If it's a type‐generic slot (!T), resolve against the caller's closed generic
1115+ if (elem.DataType == DATATYPE_VAR)
1116+ {
1117+ int pos = elem.GenericParamPosition ;
1118+
1119+ // Use the *caller's* bound genericType (Stack<Int32>, etc.)
1120+ if (caller == nullptr || caller->genericType == nullptr )
1121+ {
1122+ return false ;
1123+ }
1124+
1125+ auto &tsi = *caller->genericType ;
1126+ CLR_UINT32 closedTsRow = tsi.TypeSpec ();
1127+
1128+ CLR_RT_TypeDef_Index realTypeDef;
1129+ NanoCLRDataType realDataType;
1130+
1131+ // Only call this once to map (e.g. !T→Int32)
1132+ caller->assembly ->FindGenericParamAtTypeSpec (closedTsRow, (CLR_UINT32)pos, realTypeDef, realDataType);
1133+
1134+ // populate this instance
1135+ data = realTypeDef.data ;
1136+ assembly = g_CLR_RT_TypeSystem.m_assemblies [realTypeDef.Assembly () - 1 ];
1137+ target = assembly->GetTypeDef (realTypeDef.Type ());
1138+
1139+ return true ;
1140+ }
1141+ else if (elem.DataType == DATATYPE_MVAR)
1142+ {
1143+ // Use the *caller's* bound genericType (Stack<Int32>, etc.)
1144+ if (caller == nullptr || caller->genericType == nullptr )
1145+ {
1146+ return false ;
1147+ }
1148+
1149+ CLR_RT_GenericParam_Index gpIdx;
1150+ caller->assembly ->FindGenericParamAtMethodDef (*caller, elem.GenericParamPosition , gpIdx);
1151+ auto &gp = caller->assembly ->crossReferenceGenericParam [gpIdx.GenericParam ()];
1152+
1153+ data = gp.classTypeDef .data ;
1154+ assembly = g_CLR_RT_TypeSystem.m_assemblies [gp.classTypeDef .Assembly () - 1 ];
1155+ target = assembly->GetTypeDef (gp.classTypeDef .Type ());
1156+
1157+ return true ;
1158+ }
1159+ else
1160+ {
1161+ // If it's a class or value type, resolve the type
1162+ data = elem.Class .data ;
1163+ assembly = g_CLR_RT_TypeSystem.m_assemblies [elem.Class .Assembly () - 1 ];
1164+ target = assembly->GetTypeDef (elem.Class .Type ());
1165+
1166+ return true ;
1167+ }
1168+ }
1169+
1170+ ClearInstance ();
1171+
1172+ return false ;
1173+ }
1174+
10841175// --//
10851176
10861177bool CLR_RT_TypeDef_Instance::SwitchToParent ()
@@ -4293,6 +4384,7 @@ static const TypeIndexLookup c_TypeIndexLookup[] = {
42934384 TIL (" System" , " Object" , Object),
42944385 TIL (" System" , " ValueType" , ValueType),
42954386 TIL (" System" , " Enum" , Enum),
4387+ TIL (" System" , " Nullable`1" , Nullable),
42964388
42974389 TIL (" System" , " AppDomainUnloadedException" , AppDomainUnloadedException),
42984390 TIL (" System" , " ArgumentNullException" , ArgumentNullException),
0 commit comments