@@ -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