Skip to content

Commit 38faac2

Browse files
authored
Fix loading token for TypeSpec (#3189)
1 parent 3625a85 commit 38faac2

File tree

5 files changed

+56
-17
lines changed

5 files changed

+56
-17
lines changed

src/CLR/Core/CLR_RT_HeapBlock.cpp

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -232,17 +232,54 @@ HRESULT CLR_RT_HeapBlock::SetReflection(const CLR_RT_Assembly_Index &assm)
232232
NANOCLR_NOCLEANUP_NOLABEL();
233233
}
234234

235-
HRESULT CLR_RT_HeapBlock::SetReflection(const CLR_RT_TypeSpec_Index &sig)
235+
HRESULT CLR_RT_HeapBlock::SetReflection(const CLR_RT_TypeSpec_Instance &tsInst, const CLR_RT_TypeSpec_Index *caller)
236236
{
237237
NATIVE_PROFILE_CLR_CORE();
238238
NANOCLR_HEADER();
239239

240-
CLR_RT_TypeDescriptor desc{};
240+
m_id.raw = CLR_RT_HEAPBLOCK_RAW_ID(DATATYPE_REFLECTION, 0, 1);
241+
m_data.reflection.kind = REFLECTION_TYPE;
241242

242-
NANOCLR_CHECK_HRESULT(desc.InitializeFromTypeSpec(sig));
243+
// start parsing the signature
244+
CLR_RT_SignatureParser parser;
245+
parser.Initialize_TypeSpec(tsInst.assembly, tsInst.target);
243246

244-
m_id.raw = CLR_RT_HEAPBLOCK_RAW_ID(DATATYPE_REFLECTION, 0, 1);
245-
m_data.reflection = desc.m_reflex;
247+
// read first element
248+
CLR_RT_SignatureParser::Element elem;
249+
if (FAILED(parser.Advance(elem)))
250+
{
251+
NANOCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
252+
}
253+
254+
if (elem.DataType == DATATYPE_VAR || elem.DataType == DATATYPE_MVAR)
255+
{
256+
int gpIndex = elem.GenericParamPosition;
257+
258+
// if the caller's genericType is non‐null, ask the CLR to map !n→actual argument:
259+
if (caller != nullptr && NANOCLR_INDEX_IS_VALID(*caller))
260+
{
261+
CLR_RT_TypeDef_Index tdArg{};
262+
NanoCLRDataType dtArg;
263+
264+
bool ok = g_CLR_RT_TypeSystem.m_assemblies[caller->Assembly() - 1]
265+
->FindGenericParamAtTypeSpec(caller->TypeSpec(), gpIndex, tdArg, dtArg);
266+
if (ok)
267+
{
268+
m_data.reflection.data.type = tdArg;
269+
m_data.reflection.levels = elem.Levels;
270+
}
271+
}
272+
else
273+
{
274+
// TODO
275+
_ASSERTE(false);
276+
}
277+
}
278+
else
279+
{
280+
m_data.reflection.data.type = elem.Class;
281+
m_data.reflection.levels = elem.Levels;
282+
}
246283

247284
NANOCLR_NOCLEANUP();
248285
}

src/CLR/Core/CLR_RT_HeapBlock_Array.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ HRESULT CLR_RT_HeapBlock_Array::CreateInstance(
104104
}
105105
else if (def.ResolveToken(tk, assm))
106106
{
107-
NANOCLR_CHECK_HRESULT(ref.SetReflection(def));
107+
NANOCLR_CHECK_HRESULT(ref.SetReflection(def, caller->genericType));
108108
}
109109
else
110110
{

src/CLR/Core/Interpreter.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3210,13 +3210,13 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg)
32103210
{
32113211
case TBL_TypeSpec:
32123212
{
3213-
CLR_RT_TypeSpec_Instance sig{};
3214-
if (sig.ResolveToken(arg, assm) == false)
3213+
CLR_RT_TypeSpec_Instance tsInst{};
3214+
if (tsInst.ResolveToken(arg, assm) == false)
32153215
{
32163216
NANOCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
32173217
}
32183218

3219-
evalPos[0].SetReflection(sig);
3219+
evalPos[0].SetReflection(tsInst, stack->m_call.genericType);
32203220
}
32213221
break;
32223222

src/CLR/Diagnostics/Info.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,7 @@ void CLR_RT_Assembly::DumpToken(CLR_UINT32 token, const CLR_RT_TypeSpec_Index *g
531531
}
532532

533533
CLR_RT_TypeSpec_Index tsIdx;
534-
tsIdx.Set(ownerAsm, index);
534+
tsIdx.Set(assemblyIndex, index);
535535

536536
// bind to get the signature blob
537537
CLR_RT_TypeSpec_Instance tsInst{};
@@ -568,17 +568,19 @@ void CLR_RT_Assembly::DumpToken(CLR_UINT32 token, const CLR_RT_TypeSpec_Index *g
568568
{
569569
CLR_RT_TypeDef_Index tdArg{};
570570
NanoCLRDataType dtArg;
571-
572-
bool ok =
573-
tsInst.assembly->FindGenericParamAtTypeSpec(genericType->TypeSpec(), gpIndex, tdArg, dtArg);
571+
bool ok = g_CLR_RT_TypeSystem.m_assemblies[genericType->Assembly() - 1]
572+
->FindGenericParamAtTypeSpec(genericType->TypeSpec(), gpIndex, tdArg, dtArg);
574573
if (ok)
575574
{
576-
// Print that bound argument (e.g. "I4" or full class name)
577-
char bufArg[256];
575+
char bufArg[256]{};
578576
char *pArg = bufArg;
579577
size_t cbArg = sizeof(bufArg);
580-
g_CLR_RT_TypeSystem.BuildTypeName(tdArg, pArg, cbArg);
578+
579+
g_CLR_RT_TypeSystem
580+
.BuildTypeName(tdArg, pArg, cbArg, CLR_RT_TypeSystem::TYPENAME_FLAGS_FULL, elem.Levels);
581+
581582
CLR_Debug::Printf("%s", bufArg);
583+
582584
break;
583585
}
584586
}

src/CLR/Include/nanoCLR_Runtime__HeapBlock.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1347,7 +1347,7 @@ struct CLR_RT_HeapBlock
13471347

13481348
HRESULT SetReflection(const CLR_RT_ReflectionDef_Index &reflex);
13491349
HRESULT SetReflection(const CLR_RT_Assembly_Index &assm);
1350-
HRESULT SetReflection(const CLR_RT_TypeSpec_Index &sig);
1350+
HRESULT SetReflection(const CLR_RT_TypeSpec_Instance &tsInst, const CLR_RT_TypeSpec_Index *caller);
13511351
HRESULT SetReflection(const CLR_RT_TypeDef_Index &cls);
13521352
HRESULT SetReflection(const CLR_RT_FieldDef_Index &fd);
13531353
HRESULT SetReflection(const CLR_RT_MethodDef_Index &md);

0 commit comments

Comments
 (0)