Skip to content

Commit 161fe48

Browse files
committed
Add static fields for generic types
- TypeSpec cross reference now stores instances of static fields and field defs. - Assembly now has GetGenericStaticField() and GetStaticFieldByFieldDef(). - TypeSpec instance now has a helper API IsClosedGenericType(). - Update handlers for stsfld, ldsfld and ldsflda to deal with static fields of closed generic types.
1 parent f187be0 commit 161fe48

File tree

3 files changed

+378
-10
lines changed

3 files changed

+378
-10
lines changed

src/CLR/Core/Interpreter.cpp

Lines changed: 66 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2728,13 +2728,33 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg)
27282728
{
27292729
FETCH_ARG_COMPRESSED_FIELDTOKEN(arg, ip);
27302730

2731-
CLR_RT_FieldDef_Instance field;
2731+
CLR_RT_FieldDef_Instance field{};
2732+
CLR_RT_HeapBlock *ptr = nullptr;
2733+
2734+
// resolve field token
27322735
if (field.ResolveToken(arg, assm, &stack->m_call) == false)
27332736
{
27342737
NANOCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
27352738
}
27362739

2737-
CLR_RT_HeapBlock *ptr = CLR_RT_ExecutionEngine::AccessStaticField(field);
2740+
if (field.genericType && NANOCLR_INDEX_IS_VALID(*field.genericType))
2741+
{
2742+
// access static field of a generic instance
2743+
CLR_RT_FieldDef_Index genericField{};
2744+
genericField.data = field.data;
2745+
2746+
// find the assembly where the generic type is instantiated
2747+
CLR_RT_Assembly *typeSpecAsm =
2748+
g_CLR_RT_TypeSystem.m_assemblies[field.genericType->Assembly() - 1];
2749+
2750+
// now access the generic static field
2751+
ptr = typeSpecAsm->GetGenericStaticField(*field.genericType, genericField);
2752+
}
2753+
else
2754+
{
2755+
// static field of a non-generic class
2756+
ptr = CLR_RT_ExecutionEngine::AccessStaticField(field);
2757+
}
27382758

27392759
if (ptr == nullptr)
27402760
{
@@ -2756,13 +2776,33 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg)
27562776
{
27572777
FETCH_ARG_COMPRESSED_FIELDTOKEN(arg, ip);
27582778

2759-
CLR_RT_FieldDef_Instance field;
2779+
CLR_RT_FieldDef_Instance field{};
2780+
CLR_RT_HeapBlock *ptr = nullptr;
2781+
2782+
// resolve field token
27602783
if (field.ResolveToken(arg, assm, &stack->m_call) == false)
27612784
{
27622785
NANOCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
27632786
}
27642787

2765-
CLR_RT_HeapBlock *ptr = CLR_RT_ExecutionEngine::AccessStaticField(field);
2788+
if (field.genericType && NANOCLR_INDEX_IS_VALID(*field.genericType))
2789+
{
2790+
// access static field of a generic instance
2791+
CLR_RT_FieldDef_Index genericField{};
2792+
genericField.data = field.data;
2793+
2794+
// find the assembly where the generic type is instantiated
2795+
CLR_RT_Assembly *typeSpecAsm =
2796+
g_CLR_RT_TypeSystem.m_assemblies[field.genericType->Assembly() - 1];
2797+
2798+
// now access the generic static field
2799+
ptr = typeSpecAsm->GetGenericStaticField(*field.genericType, genericField);
2800+
}
2801+
else
2802+
{
2803+
// static field of a non-generic class
2804+
ptr = CLR_RT_ExecutionEngine::AccessStaticField(field);
2805+
}
27662806

27672807
if (ptr == nullptr)
27682808
{
@@ -2783,13 +2823,33 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg)
27832823
{
27842824
FETCH_ARG_COMPRESSED_FIELDTOKEN(arg, ip);
27852825

2786-
CLR_RT_FieldDef_Instance field;
2826+
CLR_RT_FieldDef_Instance field{};
2827+
CLR_RT_HeapBlock *ptr = nullptr;
2828+
2829+
// resolve field token
27872830
if (field.ResolveToken(arg, assm, &stack->m_call) == false)
27882831
{
27892832
NANOCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
27902833
}
27912834

2792-
CLR_RT_HeapBlock *ptr = CLR_RT_ExecutionEngine::AccessStaticField(field);
2835+
if (field.genericType && NANOCLR_INDEX_IS_VALID(*field.genericType))
2836+
{
2837+
// access static field of a generic instance
2838+
CLR_RT_FieldDef_Index genericField{};
2839+
genericField.data = field.data;
2840+
2841+
// find the assembly where the generic type is instantiated
2842+
CLR_RT_Assembly *typeSpecAsm =
2843+
g_CLR_RT_TypeSystem.m_assemblies[field.genericType->Assembly() - 1];
2844+
2845+
// now access the generic static field
2846+
ptr = typeSpecAsm->GetGenericStaticField(*field.genericType, genericField);
2847+
}
2848+
else
2849+
{
2850+
// static field of a non-generic class
2851+
ptr = CLR_RT_ExecutionEngine::AccessStaticField(field);
2852+
}
27932853

27942854
if (ptr == nullptr)
27952855
{

0 commit comments

Comments
 (0)