diff --git a/src/coreclr/interpreter/compiler.cpp b/src/coreclr/interpreter/compiler.cpp index 81b40d5da6e114..a248fca1a7df57 100644 --- a/src/coreclr/interpreter/compiler.cpp +++ b/src/coreclr/interpreter/compiler.cpp @@ -5729,6 +5729,23 @@ 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--; + int32_t opcode = GetLdindForType(m_pVars[m_paramArgIndex].interpType); + AddIns(opcode); + m_pLastNewIns->SetSVar(m_pStackPointer[0].var); + m_pLastNewIns->SetDVar(m_paramArgIndex); + m_pLastNewIns->data[0] = m_pVars[m_paramArgIndex].offset; + } } } 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;