Skip to content

Commit ae09a3a

Browse files
committed
Fix load and store field IL instructions for value types in stack
- Now dealing properly with value types for structs assigned from stack and not from heap. - Fixes in store and load field.
1 parent 927f73d commit ae09a3a

File tree

1 file changed

+62
-3
lines changed

1 file changed

+62
-3
lines changed

src/CLR/Core/Interpreter.cpp

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2568,8 +2568,41 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg)
25682568

25692569
CLR_RT_HeapBlock *obj = &evalPos[0];
25702570
NanoCLRDataType dt = obj->DataType();
2571+
2572+
// If it's a byref, it must be a struct instance on the stack/heap
2573+
bool instanceIsByRef =
2574+
(obj->DataType() == DATATYPE_BYREF) || (obj->DataType() == DATATYPE_ARRAY_BYREF);
25712575

2572-
NANOCLR_CHECK_HRESULT(CLR_RT_TypeDescriptor::ExtractObjectAndDataType(obj, dt));
2576+
if (instanceIsByRef)
2577+
{
2578+
// extra check for DATATYPE_DATETIME and DATATYPE_TIMESPAN (special cases)
2579+
if (obj->Dereference()->DataType() == DATATYPE_DATETIME ||
2580+
obj->Dereference()->DataType() == DATATYPE_TIMESPAN)
2581+
{
2582+
NANOCLR_CHECK_HRESULT(CLR_RT_TypeDescriptor::ExtractObjectAndDataType(obj, dt));
2583+
}
2584+
else
2585+
{
2586+
// we already have a pointer to the raw struct
2587+
dt = DATATYPE_VALUETYPE;
2588+
2589+
obj = obj->Dereference();
2590+
FAULT_ON_NULL(obj);
2591+
}
2592+
}
2593+
else
2594+
{
2595+
// ordinary object/array
2596+
FAULT_ON_NULL(obj);
2597+
NANOCLR_CHECK_HRESULT(CLR_RT_TypeDescriptor::ExtractObjectAndDataType(obj, dt));
2598+
}
2599+
2600+
//if ((dt == DATATYPE_OBJECT || dt == DATATYPE_BYREF) && obj->Dereference() == NULL)
2601+
//{
2602+
// NANOCLR_SET_AND_LEAVE(CLR_E_NULL_REFERENCE);
2603+
//}
2604+
2605+
//NANOCLR_CHECK_HRESULT(CLR_RT_TypeDescriptor::ExtractObjectAndDataType(obj, dt));
25732606

25742607
switch (dt)
25752608
{
@@ -2665,9 +2698,35 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg)
26652698
}
26662699

26672700
CLR_RT_HeapBlock *obj = &evalPos[1];
2668-
NanoCLRDataType dt = obj->DataType();
2701+
NanoCLRDataType dt;
26692702

2670-
NANOCLR_CHECK_HRESULT(CLR_RT_TypeDescriptor::ExtractObjectAndDataType(obj, dt));
2703+
// If it's a byref, it must be a struct instance on the stack/heap
2704+
bool instanceIsByRef =
2705+
(obj->DataType() == DATATYPE_BYREF) || (obj->DataType() == DATATYPE_ARRAY_BYREF);
2706+
2707+
if (instanceIsByRef)
2708+
{
2709+
// extra check for DATATYPE_DATETIME and DATATYPE_TIMESPAN (special cases)
2710+
if (obj->Dereference()->DataType() == DATATYPE_DATETIME ||
2711+
obj->Dereference()->DataType() == DATATYPE_TIMESPAN)
2712+
{
2713+
NANOCLR_CHECK_HRESULT(CLR_RT_TypeDescriptor::ExtractObjectAndDataType(obj, dt));
2714+
}
2715+
else
2716+
{
2717+
// we already have a pointer to the raw struct
2718+
dt = DATATYPE_VALUETYPE;
2719+
2720+
// follow the byref so obj really points at the struct
2721+
obj = obj->Dereference();
2722+
}
2723+
}
2724+
else
2725+
{
2726+
// ordinary object/array
2727+
FAULT_ON_NULL(obj);
2728+
NANOCLR_CHECK_HRESULT(CLR_RT_TypeDescriptor::ExtractObjectAndDataType(obj, dt));
2729+
}
26712730

26722731
switch (dt)
26732732
{

0 commit comments

Comments
 (0)