From d70ec580f7156f0564d8ad6a47734eae31936613 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Sim=C3=B5es?= Date: Wed, 12 Nov 2025 23:44:17 +0000 Subject: [PATCH 1/2] Fix box/unbox of generic types - Add checks for null objects and perform accordingly. --- src/CLR/Core/Interpreter.cpp | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/CLR/Core/Interpreter.cpp b/src/CLR/Core/Interpreter.cpp index a56339d1de..90d2ef8ef1 100644 --- a/src/CLR/Core/Interpreter.cpp +++ b/src/CLR/Core/Interpreter.cpp @@ -2905,7 +2905,28 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg) } else { - NANOCLR_CHECK_HRESULT(evalPos[0].PerformBoxing(typeInst)); + // Check if we're trying to box a null reference for a reference type + // For generic types, the value might already be null (DATATYPE_OBJECT with null reference) + if (evalPos[0].DataType() == DATATYPE_OBJECT) + { + CLR_RT_HeapBlock *ptr = evalPos[0].Dereference(); + if (ptr == nullptr) + { + // Already a null reference, no need to box + // Just ensure it stays as a null object reference + evalPos[0].SetObjectReference(nullptr); + } + else + { + // Non-null object reference, perform boxing + NANOCLR_CHECK_HRESULT(evalPos[0].PerformBoxing(typeInst)); + } + } + else + { + // Value type or other type, perform normal boxing + NANOCLR_CHECK_HRESULT(evalPos[0].PerformBoxing(typeInst)); + } } } else @@ -2947,6 +2968,17 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg) } else { + // Check if we're trying to unbox a null reference + if (evalPos[0].DataType() == DATATYPE_OBJECT) + { + CLR_RT_HeapBlock *ptr = evalPos[0].Dereference(); + if (ptr == nullptr) + { + // Attempting to unbox a null reference throws NullReferenceException + NANOCLR_SET_AND_LEAVE(CLR_E_NULL_REFERENCE); + } + } + NANOCLR_CHECK_HRESULT(evalPos[0].PerformUnboxing(typeInst)); } } From bc3d263406a6bb6418ba6dcc3e507a65af803e6d Mon Sep 17 00:00:00 2001 From: nfbot Date: Wed, 12 Nov 2025 23:49:34 +0000 Subject: [PATCH 2/2] Code style fixes Automated fixes for code style. --- src/CLR/Core/Interpreter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CLR/Core/Interpreter.cpp b/src/CLR/Core/Interpreter.cpp index 90d2ef8ef1..8c7ebc38c4 100644 --- a/src/CLR/Core/Interpreter.cpp +++ b/src/CLR/Core/Interpreter.cpp @@ -2978,7 +2978,7 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg) NANOCLR_SET_AND_LEAVE(CLR_E_NULL_REFERENCE); } } - + NANOCLR_CHECK_HRESULT(evalPos[0].PerformUnboxing(typeInst)); } }