@@ -976,34 +976,23 @@ bool CLR_RT_TypeDef_Instance::ResolveToken(
976
976
parser.Initialize_TypeSpec (assm, ts);
977
977
978
978
CLR_RT_SignatureParser::Element elem;
979
-
980
- // Skip any leading SZARRAY or BYREF
981
- do
979
+ if (FAILED (parser.Advance (elem)))
982
980
{
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
+ }
988
983
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)
991
985
{
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 ;
1007
996
}
1008
997
1009
998
// walk forward until a VAR (type‐generic) or MVAR (method‐generic) is hit
@@ -1045,8 +1034,6 @@ bool CLR_RT_TypeDef_Instance::ResolveToken(
1045
1034
}
1046
1035
else
1047
1036
{
1048
- // elem.DataType == DATATYPE_MVAR
1049
-
1050
1037
// Use the *caller's* bound genericType (Stack<Int32>, etc.)
1051
1038
if (caller == nullptr || caller->genericType == nullptr )
1052
1039
{
@@ -1060,6 +1047,7 @@ bool CLR_RT_TypeDef_Instance::ResolveToken(
1060
1047
data = gp.classTypeDef .data ;
1061
1048
assembly = g_CLR_RT_TypeSystem.m_assemblies [gp.classTypeDef .Assembly () - 1 ];
1062
1049
target = assembly->GetTypeDef (gp.classTypeDef .Type ());
1050
+
1063
1051
return true ;
1064
1052
}
1065
1053
}
@@ -1081,6 +1069,109 @@ bool CLR_RT_TypeDef_Instance::ResolveToken(
1081
1069
return false ;
1082
1070
}
1083
1071
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
+
1084
1175
// --//
1085
1176
1086
1177
bool CLR_RT_TypeDef_Instance::SwitchToParent ()
@@ -4293,6 +4384,7 @@ static const TypeIndexLookup c_TypeIndexLookup[] = {
4293
4384
TIL (" System" , " Object" , Object),
4294
4385
TIL (" System" , " ValueType" , ValueType),
4295
4386
TIL (" System" , " Enum" , Enum),
4387
+ TIL (" System" , " Nullable`1" , Nullable),
4296
4388
4297
4389
TIL (" System" , " AppDomainUnloadedException" , AppDomainUnloadedException),
4298
4390
TIL (" System" , " ArgumentNullException" , ArgumentNullException),
0 commit comments