From e849c76beb5548287883d7b925bfc0195c29fda1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Sim=C3=B5es?= Date: Thu, 13 Nov 2025 15:17:03 +0000 Subject: [PATCH] Fix newobj handler for generic constructors - Now setting the correct context to allow NewObject to properly resolve all generic types. --- src/CLR/Core/Interpreter.cpp | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/CLR/Core/Interpreter.cpp b/src/CLR/Core/Interpreter.cpp index 8c7ebc38c4..89c02b84bb 100644 --- a/src/CLR/Core/Interpreter.cpp +++ b/src/CLR/Core/Interpreter.cpp @@ -2464,21 +2464,34 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg) } top->SetObjectReference(nullptr); - // Stack: ... ... -> ... - // ^ - // Top points here. + // For constructors on generic classes, we need to use the class's generic type + // from the calling context, not the method's generic type. + // The calleeInst.genericType might point to an open generic from the MethodRef, + // but we need the closed generic from the caller's context (stack->m_call.genericType). + const CLR_RT_TypeSpec_Index *genericTypeForContext = nullptr; + + // Prefer the caller's generic type if available and valid + if (stack->m_call.genericType != nullptr && NANOCLR_INDEX_IS_VALID(*stack->m_call.genericType)) + { + genericTypeForContext = stack->m_call.genericType; + } + // Fallback to the callee's generic type if caller's is not available + else if (calleeInst.genericType != nullptr && NANOCLR_INDEX_IS_VALID(*calleeInst.genericType)) + { + genericTypeForContext = calleeInst.genericType; + } - if (calleeInst.genericType == nullptr) + if (genericTypeForContext == nullptr) { NANOCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObject(top[0], cls)); } else { - CLR_RT_TypeSpec_Instance calleeInstGenericType; - calleeInstGenericType.InitializeFromIndex(*calleeInst.genericType); + CLR_RT_TypeSpec_Instance genericTypeInstance; + genericTypeInstance.InitializeFromIndex(*genericTypeForContext); NANOCLR_CHECK_HRESULT( - g_CLR_RT_ExecutionEngine.NewObject(top[0], cls, &calleeInstGenericType)); + g_CLR_RT_ExecutionEngine.NewObject(top[0], cls, &genericTypeInstance)); } //