From f4b2ca47d136fbbf2e2b5510002dd3f198877831 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Tue, 4 Nov 2025 02:19:48 +0100 Subject: [PATCH 1/3] Fix generic argument access in filter funclets In funclets of generic methods, access to the generic argument may be needed. It doesn't work correctly, because the filter funclet has its own locals and various IR instructions that use that argument cannot access it. This change adds copying of that argument from the parent frame to the funclet frame at the same offset so that the access to it just works. --- src/coreclr/interpreter/compiler.cpp | 23 +++++++++++++++++++++++ src/coreclr/interpreter/compiler.h | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/coreclr/interpreter/compiler.cpp b/src/coreclr/interpreter/compiler.cpp index 81b40d5da6e114..19f6f9e21dfc92 100644 --- a/src/coreclr/interpreter/compiler.cpp +++ b/src/coreclr/interpreter/compiler.cpp @@ -5729,6 +5729,29 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo) { AddIns(INTOP_LOAD_EXCEPTION); m_pLastNewIns->SetDVar(m_pCBB->clauseVarIndex); + + // To allow filter clauses in generic methods to access the generic argument, + // we copy that argument variable from the parent frame to the filter's frame. + // The target variable offset is the same as the one in the parent frame. + if ((m_pCBB->clauseType == BBClauseFilter) && (m_paramArgIndex != -1)) + { + AddIns(INTOP_LOAD_FRAMEVAR); + PushInterpType(InterpTypeI, NULL); + m_pLastNewIns->SetDVar(m_pStackPointer[-1].var); + + m_pStackPointer--; + InterpVar *pParamArgVar = &m_pVars[m_paramArgIndex]; + int32_t opcode = GetLdindForType(pParamArgVar->interpType); + AddIns(opcode); + m_pLastNewIns->SetSVar(m_pStackPointer[0].var); + m_pLastNewIns->SetDVar(pParamArgVar->offset); + m_pLastNewIns->data[0] = pParamArgVar->offset; + if (pParamArgVar->interpType == InterpTypeVT) + { + int size = m_compHnd->getClassSize(pParamArgVar->clsHnd); + m_pLastNewIns->data[1] = size; + } + } } } diff --git a/src/coreclr/interpreter/compiler.h b/src/coreclr/interpreter/compiler.h index 120ffe465bd7a8..d44b65836bbab1 100644 --- a/src/coreclr/interpreter/compiler.h +++ b/src/coreclr/interpreter/compiler.h @@ -756,7 +756,7 @@ class InterpCompiler int32_t m_varsSize = 0; int32_t m_varsCapacity = 0; int32_t m_numILVars = 0; - int32_t m_paramArgIndex = 0; // Index of the type parameter argument in the m_pVars array. + int32_t m_paramArgIndex = -1; // Index of the type parameter argument in the m_pVars array. // For each catch or filter clause, we create a variable that holds the exception object. // This is the index of the first such variable. int32_t m_clauseVarsIndex = 0; From b2ac0fd634cce9a0b1e31e99290201563f76334c Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Tue, 4 Nov 2025 14:55:43 +0100 Subject: [PATCH 2/3] PR feedback --- src/coreclr/interpreter/compiler.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/coreclr/interpreter/compiler.cpp b/src/coreclr/interpreter/compiler.cpp index 19f6f9e21dfc92..9ab3be3f932d3b 100644 --- a/src/coreclr/interpreter/compiler.cpp +++ b/src/coreclr/interpreter/compiler.cpp @@ -5740,17 +5740,11 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo) m_pLastNewIns->SetDVar(m_pStackPointer[-1].var); m_pStackPointer--; - InterpVar *pParamArgVar = &m_pVars[m_paramArgIndex]; - int32_t opcode = GetLdindForType(pParamArgVar->interpType); + int32_t opcode = GetLdindForType(m_pVars[m_paramArgIndex].interpType); AddIns(opcode); m_pLastNewIns->SetSVar(m_pStackPointer[0].var); - m_pLastNewIns->SetDVar(pParamArgVar->offset); - m_pLastNewIns->data[0] = pParamArgVar->offset; - if (pParamArgVar->interpType == InterpTypeVT) - { - int size = m_compHnd->getClassSize(pParamArgVar->clsHnd); - m_pLastNewIns->data[1] = size; - } + m_pLastNewIns->SetDVar(m_pVars[m_paramArgIndex].offset); + m_pLastNewIns->data[0] = m_pVars[m_paramArgIndex].offset; } } } From ba7ed0504cfc053975289eb9512ac346d8f8a565 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Tue, 4 Nov 2025 23:49:30 +0100 Subject: [PATCH 3/3] Fix wrong DVar index --- src/coreclr/interpreter/compiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/interpreter/compiler.cpp b/src/coreclr/interpreter/compiler.cpp index 9ab3be3f932d3b..a248fca1a7df57 100644 --- a/src/coreclr/interpreter/compiler.cpp +++ b/src/coreclr/interpreter/compiler.cpp @@ -5743,7 +5743,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo) int32_t opcode = GetLdindForType(m_pVars[m_paramArgIndex].interpType); AddIns(opcode); m_pLastNewIns->SetSVar(m_pStackPointer[0].var); - m_pLastNewIns->SetDVar(m_pVars[m_paramArgIndex].offset); + m_pLastNewIns->SetDVar(m_paramArgIndex); m_pLastNewIns->data[0] = m_pVars[m_paramArgIndex].offset; } }