diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index 3e5f54cb2423f4..b93a07677c19d3 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -5740,9 +5740,11 @@ void CodeGen::genFnProlog() genZeroInitFrame(untrLclHi, untrLclLo, initReg, &initRegZeroed); -#ifndef TARGET_WASM // TODO-WASM: enable as needed. + // Save the generic context arg in the prolog so GetParamTypeArg can report it. genReportGenericContextArg(initReg, &initRegZeroed); +#ifndef TARGET_WASM // TODO-WASM: enable as needed. + #ifdef JIT32_GCENCODER // Initialize the LocalAllocSP slot if there is localloc in the function. if (m_compiler->lvaLocAllocSPvar != BAD_VAR_NUM) diff --git a/src/coreclr/jit/codegenwasm.cpp b/src/coreclr/jit/codegenwasm.cpp index 45b432c2a96537..2dc4f79bbeddf0 100644 --- a/src/coreclr/jit/codegenwasm.cpp +++ b/src/coreclr/jit/codegenwasm.cpp @@ -352,6 +352,37 @@ void CodeGen::genHomeRegisterParamsOutsideProlog() } } +//------------------------------------------------------------------------ +// genReportGenericContextArg: spill the generic context (or "this") into its +// GC-reportable frame slot in the prolog so the GC stack walk can locate it. +// initReg / pInitRegZeroed are unused on wasm. +// +void CodeGen::genReportGenericContextArg(regNumber initReg, bool* pInitRegZeroed) +{ + assert(m_compiler->compGeneratingProlog); + + const bool reportArg = m_compiler->lvaReportParamTypeArg(); + const bool reportThis = m_compiler->lvaKeepAliveAndReportThis(); + if (!reportArg && !reportThis) + { + return; + } + + const unsigned contextArg = reportArg ? m_compiler->info.compTypeCtxtArg : m_compiler->info.compThisArg; + noway_assert(contextArg != BAD_VAR_NUM); + + // The context arg is still in its incoming register at this point in the prolog. + const ABIPassingInformation& abiInfo = m_compiler->lvaGetParameterABIInfo(contextArg); + assert(abiInfo.HasExactlyOneRegisterSegment()); + const regNumber reg = abiInfo.Segment(0).GetRegister(); + + // [FP + lvaCachedGenericContextArgOffset()] = contextArg + emitter* emit = GetEmitter(); + emit->emitIns_I(INS_local_get, EA_PTRSIZE, GetFramePointerRegIndex()); + emit->emitIns_I(INS_local_get, EA_PTRSIZE, WasmRegToIndex(reg)); + emit->emitIns_I(ins_Store(TYP_I_IMPL), EA_PTRSIZE, m_compiler->lvaCachedGenericContextArgOffset()); +} + void CodeGen::genFnEpilog(BasicBlock* block) { #ifdef DEBUG