Skip to content

Commit ae54fa9

Browse files
committed
Various fixes for generics
- Fix handling of generic types and instances in several locations. - Fix access to MethodSpec_Index. - Add missing handling of MethodSpec in ldtoken instruction. - Fix field iteration in NewGenericInstanceObject.
1 parent 22b35c6 commit ae54fa9

File tree

5 files changed

+35
-13
lines changed

5 files changed

+35
-13
lines changed

src/CLR/Core/CLR_RT_HeapBlock.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ HRESULT CLR_RT_HeapBlock::SetGenericInstanceObject(const CLR_RT_TypeSpec_Index &
351351

352352
m_data.genericInstance.genericType = genericType;
353353
m_data.genericInstance.ptr = nullptr;
354+
m_id.raw = CLR_RT_HEAPBLOCK_RAW_ID(DATATYPE_GENERICINST, 0, 1);
354355

355356
NANOCLR_NOCLEANUP();
356357
}

src/CLR/Core/Execution.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ HRESULT CLR_RT_ExecutionEngine::ExecutionEngine_Initialize()
9191
// CLR_RT_Thread* m_cctorThread;
9292
//
9393
#if !defined(NANOCLR_APPDOMAINS)
94-
m_globalLock = nullptr; // CLR_RT_HeapBlock* m_globalLock;
94+
m_globalLock = nullptr; // CLR_RT_HeapBlock* m_globalLock;
9595
m_outOfMemoryException = nullptr; // CLR_RT_HeapBlock* m_outOfMemoryException;
9696
#endif
9797

@@ -2262,27 +2262,31 @@ HRESULT CLR_RT_ExecutionEngine::NewGenericInstanceObject(
22622262
const CLR_RECORD_FIELDDEF *target = nullptr;
22632263
CLR_RT_Assembly *assm = nullptr;
22642264
CLR_RT_TypeDef_Instance instSub = instance;
2265+
CLR_RT_HeapBlock_GenericInstance *giHeader = nullptr;
2266+
CLR_RT_HeapBlock *fieldCursor = nullptr;
22652267

22662268
reference.SetObjectReference(nullptr);
22672269

22682270
int clsFields = instance.target->instanceFieldsCount;
22692271
int totFields = instance.CrossReference().totalFields + CLR_RT_HeapBlock::HB_Object_Fields_Offset;
22702272

2271-
CLR_RT_HeapBlock_GenericInstance *genericInst;
2273+
giHeader = (CLR_RT_HeapBlock_GenericInstance *)ExtractHeapBlocksForGenericInstance(0, genericInstance, totFields);
2274+
CHECK_ALLOCATION(giHeader);
22722275

2273-
genericInst =
2274-
(CLR_RT_HeapBlock_GenericInstance *)ExtractHeapBlocksForGenericInstance(0, genericInstance, totFields);
2275-
CHECK_ALLOCATION(genericInst);
2276+
reference.SetObjectReference(giHeader);
22762277

2277-
reference.SetObjectReference(genericInst);
2278+
// Associate the instance with its declaring type for reflection & casting utilities.
2279+
giHeader->SetObjectCls(instance);
22782280

22792281
//
22802282
// Initialize field types, from last to first.
22812283
//
22822284
// We do the decrement BEFORE the comparison because we want to stop short of the first field, the
22832285
// object descriptor (already initialized).
22842286
//
2285-
genericInst += totFields;
2287+
2288+
fieldCursor = reinterpret_cast<CLR_RT_HeapBlock *>(giHeader) + totFields;
2289+
22862290
while (--totFields > 0)
22872291
{
22882292
while (clsFields == 0)
@@ -2302,11 +2306,11 @@ HRESULT CLR_RT_ExecutionEngine::NewGenericInstanceObject(
23022306
target = assm->GetFieldDef(instSub.target->firstInstanceField + clsFields);
23032307
}
23042308

2305-
genericInst--;
2309+
fieldCursor--;
23062310
target--;
23072311
clsFields--;
23082312

2309-
NANOCLR_CHECK_HRESULT(InitializeReference(*genericInst, target, assm));
2313+
NANOCLR_CHECK_HRESULT(InitializeReference(*fieldCursor, target, assm));
23102314
}
23112315

23122316
if (instance.HasFinalizer())

src/CLR/Core/Interpreter.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2548,6 +2548,7 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg)
25482548
{
25492549
case DATATYPE_CLASS:
25502550
case DATATYPE_VALUETYPE:
2551+
case DATATYPE_GENERICINST:
25512552
evalPos[0].Assign(obj[fieldInst.CrossReference().offset]);
25522553
goto Execute_LoadAndPromote;
25532554
case DATATYPE_DATETIME:
@@ -2600,13 +2601,17 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg)
26002601
#if defined(NANOCLR_APPDOMAINS)
26012602
_ASSERTE(dt != DATATYPE_TRANSPARENT_PROXY);
26022603
#endif
2603-
if (dt == DATATYPE_CLASS || dt == DATATYPE_VALUETYPE)
2604+
if (dt == DATATYPE_CLASS || dt == DATATYPE_VALUETYPE || dt == DATATYPE_GENERICINST)
26042605
{
2606+
// This is a reference to the field.
2607+
// We need to make sure that the object is not a transparent proxy.
26052608
evalPos[0].SetReference(obj[fieldInst.CrossReference().offset]);
26062609
}
2607-
else if (dt == DATATYPE_DATETIME || dt == DATATYPE_TIMESPAN) // Special case.
2610+
// Special case.
2611+
else if (dt == DATATYPE_DATETIME || dt == DATATYPE_TIMESPAN)
26082612
{
2609-
NANOCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE); // NOT SUPPORTED.
2613+
// NOT SUPPORTED.
2614+
NANOCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
26102615
}
26112616
else
26122617
{
@@ -3212,6 +3217,17 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg)
32123217
}
32133218
break;
32143219

3220+
case TBL_MethodSpec:
3221+
{
3222+
CLR_RT_MethodDef_Instance method{};
3223+
if (!method.ResolveToken(arg, assm))
3224+
{
3225+
NANOCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
3226+
}
3227+
3228+
evalPos[0].SetReflection(method);
3229+
}
3230+
32153231
default:
32163232
NANOCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
32173233
break;

src/CLR/Include/nanoCLR_Runtime.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,7 @@ struct CLR_RT_MethodSpec_Index
712712

713713
CLR_INDEX Method() const
714714
{
715-
return (data & 0x7FFF);
715+
return (CLR_INDEX)data;
716716
}
717717
};
718718

src/CLR/Include/nanoCLR_Runtime__HeapBlock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,6 +1187,7 @@ struct CLR_RT_HeapBlock
11871187
{
11881188
m_id.raw = CLR_RT_HEAPBLOCK_RAW_ID(DATATYPE_GENERICINST, 0, 1);
11891189
m_data.genericInstance.genericType.data = genericType.data;
1190+
m_data.genericInstance.ptr = nullptr;
11901191
}
11911192

11921193
const CLR_RT_TypeSpec_Index &ObjectGenericType() const

0 commit comments

Comments
 (0)