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

Code before:
    genUpdateLife(tree);
}

//------------------------------------------------------------------------
// genCall: Produce code for a GT_CALL node
//
void CodeGen::genCall(GenTreeCall* call)
{
    if (call->NeedsNullCheck())
    {
        NYI_WASM("Insert nullchecks for calls that need it in lowering");
    }

    assert(!call->IsTailCall());

    genCallInstruction(call);
    genProduceReg(call);
}

//------------------------------------------------------------------------
// genCallInstruction - Generate instructions necessary to transfer control to the call.
//
// Arguments:
//    call - the GT_CALL node
//
void CodeGen::genCallInstruction(GenTreeCall* call)
{
    // Determine return value size(s).
    const ReturnTypeDesc* pRetTypeDesc = call->GetReturnTypeDesc();
    EmitCallParams        params;

    // unused values are of no interest to GC.
    if (!call->IsUnusedValue())
    {
        if (call->HasMultiRegRetVal())
        {
            NYI_WASM("multi-reg return values");
        }
        else
        {
            assert(!call->TypeIs(TYP_STRUCT));

            if (call->TypeIs(TYP_REF))
            {
                params.retSize = EA_GCREF;
            }
            else if (call->TypeIs(TYP_BYREF))
            {
                params.retSize = EA_BYREF;
            }
        }

Review comment (suggestion):
Arguments need to be consumed. Something like:
```
for (CallArg& arg : call->gtArgs.EarlyArgs())
{
    genConsumeReg(arg.GetEarlyNode());
}

for (CallArg& arg : call->gtArgs.LateArgs())
{
    genConsumeReg(arg.GetLateNode());
}
```

Code after:
    genUpdateLife(tree);
}

//------------------------------------------------------------------------
// genCall: Produce code for a GT_CALL node
//
void CodeGen::genCall(GenTreeCall* call)
{
    if (call->NeedsNullCheck())
    {
        NYI_WASM("Insert nullchecks for calls that need it in lowering");
    }

    assert(!call->IsTailCall());

    for (CallArg& arg : call->gtArgs.EarlyArgs())
    {
        genConsumeReg(arg.GetEarlyNode());
    }

    for (CallArg& arg : call->gtArgs.LateArgs())
    {
        genConsumeReg(arg.GetLateNode());
    }

    genCallInstruction(call);
    genProduceReg(call);
}

//------------------------------------------------------------------------
// genCallInstruction - Generate instructions necessary to transfer control to the call.
//
// Arguments:
//    call - the GT_CALL node
//
void CodeGen::genCallInstruction(GenTreeCall* call)
{
    EmitCallParams params;
    params.isJump      = call->IsFastTailCall();
    params.hasAsyncRet = call->IsAsync();

    // We need to propagate the debug information to the call instruction, so we can emit
    // an IL to native mapping record for the call, to support managed return value debugging.
    // We don't want tail call helper calls that were converted from normal calls to get a record,
    // so we skip this hash table lookup logic in that case.
    if (compiler->opts.compDbgInfo && compiler->genCallSite2DebugInfoMap != nullptr && !call->IsTailCall())
    {
        DebugInfo di;
        (void)compiler->genCallSite2DebugInfoMap->Lookup(call, &di);
        params.debugInfo = di;
    }