Repository: dotnet/runtime
File: src/coreclr/jit/codegenwasm.cpp (C++)

Code before:
        {
            indirectionCellArgKind = call->GetIndirectionCellArgKind();
        }

        if (indirectionCellArgKind != WellKnownArg::None)
        {
            assert(call->IsR2ROrVirtualStubRelativeIndir());

            params.callType = EC_INDIR_R;
            // params.ireg     = targetAddrReg;
            genEmitCallWithCurrentGC(params);
        }
        else
        {
            // Generate a direct call to a non-virtual user defined or helper method
            assert(call->IsHelperCall() || (call->gtCallType == CT_USER_FUNC));

            assert(call->gtEntryPoint.addr == NULL);

            if (call->IsHelperCall())
            {
                assert(!call->IsFastTailCall());
                CorInfoHelpFunc helperNum = m_compiler->eeGetHelperNum(params.methHnd);
                noway_assert(helperNum != CORINFO_HELP_UNDEF);
                genEmitHelperCall(helperNum, 0, EA_UNKNOWN);
                return;
            }
            else
            {
                // Direct call to a non-virtual user function.
                params.addr = call->gtDirectCallAddress;
            }

            params.callType = EC_FUNC_TOKEN;
            genEmitCallWithCurrentGC(params);
        }
    }
}

/*****************************************************************************
 *  Emit a call to a helper function.
 */
void CodeGen::genEmitHelperCall(unsigned helper, int argSize, emitAttr retSize, regNumber callTargetReg /*= REG_NA */)
{
    EmitCallParams params;

    CORINFO_CONST_LOOKUP helperFunction = m_compiler->compGetHelperFtn((CorInfoHelpFunc)helper);
    params.ireg                         = callTargetReg;

    if (helperFunction.accessType == IAT_VALUE)
    {

Review comment (bug):
The new helper-call path returns early via genEmitHelperCall(), which constructs its own EmitCallParams without carrying over params.debugInfo computed above. As a result, emitter::emitIns_Call won't emit the IL->native mapping record for helper calls in debug info builds, which can regress managed return value debugging/stepping. Consider either plumbing DebugInfo into genEmitHelperCall (and forwarding it to genEmitCallWithCurrentGC), or keeping the existing in-place helper emission but extending it to handle IAT_PVALUE as well.

Code after:
        {
            indirectionCellArgKind = call->GetIndirectionCellArgKind();
        }

        if (indirectionCellArgKind != WellKnownArg::None)
        {
            assert(call->IsR2ROrVirtualStubRelativeIndir());

            params.callType = EC_INDIR_R;
            // params.ireg     = targetAddrReg;
            genEmitCallWithCurrentGC(params);
        }
        else
        {
            // Generate a direct call to a non-virtual user defined or helper method
            assert(call->IsHelperCall() || (call->gtCallType == CT_USER_FUNC));

            assert(call->gtEntryPoint.addr == NULL);

            if (call->IsHelperCall())
            {
                assert(!call->IsFastTailCall());
                CorInfoHelpFunc helperNum = m_compiler->eeGetHelperNum(params.methHnd);
                noway_assert(helperNum != CORINFO_HELP_UNDEF);
                CORINFO_CONST_LOOKUP helperLookup = m_compiler->compGetHelperFtn(helperNum);
                assert(helperLookup.accessType == IAT_VALUE);
                params.addr = helperLookup.addr;
            }
            else
            {
                // Direct call to a non-virtual user function.
                params.addr = call->gtDirectCallAddress;
            }

            params.callType = EC_FUNC_TOKEN;
            genEmitCallWithCurrentGC(params);
        }
    }
}

/*****************************************************************************
 *  Emit a call to a helper function.
 */
void CodeGen::genEmitHelperCall(unsigned helper, int argSize, emitAttr retSize, regNumber callTargetReg /*= REG_NA */)
{
    EmitCallParams params;

    CORINFO_CONST_LOOKUP helperFunction = m_compiler->compGetHelperFtn((CorInfoHelpFunc)helper);
    params.ireg                         = callTargetReg;

    if (helperFunction.accessType == IAT_VALUE)