Skip to content

Commit 4854f6b

Browse files
authored
Fix load and store field IL instructions for value types in stack (nanoframework#3186)
***NO_CI***
1 parent 927f73d commit 4854f6b

File tree

1 file changed

+55
-3
lines changed

1 file changed

+55
-3
lines changed

src/CLR/Core/Interpreter.cpp

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2569,7 +2569,33 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg)
25692569
CLR_RT_HeapBlock *obj = &evalPos[0];
25702570
NanoCLRDataType dt = obj->DataType();
25712571

2572-
NANOCLR_CHECK_HRESULT(CLR_RT_TypeDescriptor::ExtractObjectAndDataType(obj, dt));
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);
2575+
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+
}
25732599

25742600
switch (dt)
25752601
{
@@ -2665,9 +2691,35 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg)
26652691
}
26662692

26672693
CLR_RT_HeapBlock *obj = &evalPos[1];
2668-
NanoCLRDataType dt = obj->DataType();
2694+
NanoCLRDataType dt;
26692695

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

26722724
switch (dt)
26732725
{

0 commit comments

Comments
 (0)