From ae09a3ac8cf88fef1b0c2634ac38ff42c4dbe949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Sim=C3=B5es?= Date: Mon, 23 Jun 2025 14:59:25 +0100 Subject: [PATCH 1/2] 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. --- src/CLR/Core/Interpreter.cpp | 65 ++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 3 deletions(-) diff --git a/src/CLR/Core/Interpreter.cpp b/src/CLR/Core/Interpreter.cpp index 4a3f1cd371..c242db647d 100644 --- a/src/CLR/Core/Interpreter.cpp +++ b/src/CLR/Core/Interpreter.cpp @@ -2568,8 +2568,41 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg) CLR_RT_HeapBlock *obj = &evalPos[0]; NanoCLRDataType dt = obj->DataType(); + + // If it's a byref, it must be a struct instance on the stack/heap + bool instanceIsByRef = + (obj->DataType() == DATATYPE_BYREF) || (obj->DataType() == DATATYPE_ARRAY_BYREF); - NANOCLR_CHECK_HRESULT(CLR_RT_TypeDescriptor::ExtractObjectAndDataType(obj, dt)); + if (instanceIsByRef) + { + // extra check for DATATYPE_DATETIME and DATATYPE_TIMESPAN (special cases) + if (obj->Dereference()->DataType() == DATATYPE_DATETIME || + obj->Dereference()->DataType() == DATATYPE_TIMESPAN) + { + NANOCLR_CHECK_HRESULT(CLR_RT_TypeDescriptor::ExtractObjectAndDataType(obj, dt)); + } + else + { + // we already have a pointer to the raw struct + dt = DATATYPE_VALUETYPE; + + obj = obj->Dereference(); + FAULT_ON_NULL(obj); + } + } + else + { + // ordinary object/array + FAULT_ON_NULL(obj); + NANOCLR_CHECK_HRESULT(CLR_RT_TypeDescriptor::ExtractObjectAndDataType(obj, dt)); + } + + //if ((dt == DATATYPE_OBJECT || dt == DATATYPE_BYREF) && obj->Dereference() == NULL) + //{ + // NANOCLR_SET_AND_LEAVE(CLR_E_NULL_REFERENCE); + //} + + //NANOCLR_CHECK_HRESULT(CLR_RT_TypeDescriptor::ExtractObjectAndDataType(obj, dt)); switch (dt) { @@ -2665,9 +2698,35 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg) } CLR_RT_HeapBlock *obj = &evalPos[1]; - NanoCLRDataType dt = obj->DataType(); + NanoCLRDataType dt; - NANOCLR_CHECK_HRESULT(CLR_RT_TypeDescriptor::ExtractObjectAndDataType(obj, dt)); + // If it's a byref, it must be a struct instance on the stack/heap + bool instanceIsByRef = + (obj->DataType() == DATATYPE_BYREF) || (obj->DataType() == DATATYPE_ARRAY_BYREF); + + if (instanceIsByRef) + { + // extra check for DATATYPE_DATETIME and DATATYPE_TIMESPAN (special cases) + if (obj->Dereference()->DataType() == DATATYPE_DATETIME || + obj->Dereference()->DataType() == DATATYPE_TIMESPAN) + { + NANOCLR_CHECK_HRESULT(CLR_RT_TypeDescriptor::ExtractObjectAndDataType(obj, dt)); + } + else + { + // we already have a pointer to the raw struct + dt = DATATYPE_VALUETYPE; + + // follow the byref so obj really points at the struct + obj = obj->Dereference(); + } + } + else + { + // ordinary object/array + FAULT_ON_NULL(obj); + NANOCLR_CHECK_HRESULT(CLR_RT_TypeDescriptor::ExtractObjectAndDataType(obj, dt)); + } switch (dt) { From 658a0c75b6831fe256341119d1e10488f01500fb Mon Sep 17 00:00:00 2001 From: nfbot Date: Mon, 23 Jun 2025 15:36:02 +0000 Subject: [PATCH 2/2] Code style fixes Automated fixes for code style. --- src/CLR/Core/Interpreter.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/CLR/Core/Interpreter.cpp b/src/CLR/Core/Interpreter.cpp index c242db647d..fed5ebaed5 100644 --- a/src/CLR/Core/Interpreter.cpp +++ b/src/CLR/Core/Interpreter.cpp @@ -2568,7 +2568,7 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg) CLR_RT_HeapBlock *obj = &evalPos[0]; NanoCLRDataType dt = obj->DataType(); - + // If it's a byref, it must be a struct instance on the stack/heap bool instanceIsByRef = (obj->DataType() == DATATYPE_BYREF) || (obj->DataType() == DATATYPE_ARRAY_BYREF); @@ -2597,12 +2597,12 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg) NANOCLR_CHECK_HRESULT(CLR_RT_TypeDescriptor::ExtractObjectAndDataType(obj, dt)); } - //if ((dt == DATATYPE_OBJECT || dt == DATATYPE_BYREF) && obj->Dereference() == NULL) + // if ((dt == DATATYPE_OBJECT || dt == DATATYPE_BYREF) && obj->Dereference() == NULL) //{ - // NANOCLR_SET_AND_LEAVE(CLR_E_NULL_REFERENCE); - //} + // NANOCLR_SET_AND_LEAVE(CLR_E_NULL_REFERENCE); + // } - //NANOCLR_CHECK_HRESULT(CLR_RT_TypeDescriptor::ExtractObjectAndDataType(obj, dt)); + // NANOCLR_CHECK_HRESULT(CLR_RT_TypeDescriptor::ExtractObjectAndDataType(obj, dt)); switch (dt) {