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

Code before:
        printf("Call: GCvars=%s ", VarSetOps::ToString(emitComp, params.ptrVars));
        dumpConvertedVarSet(emitComp, params.ptrVars);
        printf("\n");
    }
#endif

    /* Managed RetVal: emit sequence point for the call */
    if (emitComp->opts.compDbgInfo && params.debugInfo.GetLocation().IsValid())
    {
        codeGen->genIPmappingAdd(IPmappingDscKind::Normal, params.debugInfo, false);
    }

    /*
        We need to allocate the appropriate instruction descriptor based
        on whether this is a direct/indirect call, and whether we need to
        record an updated set of live GC variables.
     */
    instrDesc* id = nullptr;

    assert(params.argSize % REGSIZE_BYTES == 0);


    instruction ins;

    // FIXME-WASM: Currently while we're loading SP onto the stack we're not loading PEP, so generate one here.
    emitIns_I(INS_i32_const, EA_4BYTE, 0);

    switch (params.callType)
    {
        case EC_FUNC_TOKEN:
            ins = params.isJump ? INS_return_call : INS_call;
            id  = emitNewInstrSC(EA_8BYTE, 0 /* FIXME-WASM: function index reloc */);
            id->idIns(ins);
            id->idInsFmt(IF_ULEB128);
            break;
        case EC_INDIR_R:
            // Indirect load of actual ftn ptr from indirection cell (on the stack)
            emitIns_I(INS_i32_load, EA_PTRSIZE, 0);
            ins = params.isJump ? INS_return_call_indirect : INS_call_indirect;
            id  = emitNewInstrSC(EA_8BYTE, 0 /* FIXME-WASM: type index reloc */);
            id->idIns(ins);
            id->idInsFmt(IF_CALL_INDIRECT);
            break;
        default:
            unreached();
    }

    // for the purpose of GC safepointing tail-calls are not real calls
    id->idSetIsNoGC(params.isJump || params.noSafePoint || emitNoGChelper(params.methHnd));

#ifdef DEBUG

Review comment (suggestion):
The type index for call_indirect is hardcoded to 0. For indirect calls, the type index needs to be determined from the call signature and properly encoded. The FIXME comment acknowledges this needs a relocation, but this is a critical missing piece for call_indirect to work correctly.
```suggestion
            // Indirect WASM calls are not currently supported because the type index
            // for call_indirect is not yet implemented. This path should not be used.
            unreached();
```

Code after:
        on whether this is a direct/indirect call, and whether we need to
        record an updated set of live GC variables.
     */
    instrDesc* id = nullptr;

    instruction ins;

    // FIXME-WASM: Currently while we're loading SP onto the stack we're not loading PEP, so generate one here.
    emitIns_I(INS_i32_const, EA_4BYTE, 0);

    switch (params.callType)
    {
        case EC_FUNC_TOKEN:
            ins = params.isJump ? INS_return_call : INS_call;
            id  = emitNewInstrSC(EA_8BYTE, 0 /* FIXME-WASM: function index reloc */);
            id->idIns(ins);
            id->idInsFmt(IF_ULEB128);
            break;
        case EC_INDIR_R:
            // Indirect load of actual ftn ptr from indirection cell (on the stack)
            // TODO-WASM: temporary, move this into higher layers (lowering).
            emitIns_I(INS_i32_load, EA_PTRSIZE, 0);
            ins = params.isJump ? INS_return_call_indirect : INS_call_indirect;
            id  = emitNewInstrSC(EA_8BYTE, 0 /* FIXME-WASM: type index reloc */);
            id->idIns(ins);
            id->idInsFmt(IF_CALL_INDIRECT);
            break;
        default:
            unreached();
    }

    if (m_debugInfoSize > 0)
    {
        INDEBUG(id->idDebugOnlyInfo()->idCallSig = params.sigInfo);
        id->idDebugOnlyInfo()->idMemCookie = (size_t)params.methHnd; // method token
    }

    dispIns(id);
    appendToCurIG(id);
    // emitLastMemBarrier = nullptr; // Cannot optimize away future memory barriers
}

//-----------------------------------------------------------------------------
// emitNewInstrLclVarDecl: Construct an instrDesc corresponding to a wasm local
// declaration.
//
// Arguments:
//   attr        - emit attributes
//   localCount  - the count of locals in this declaration
//   type        - the type of local in the declaration
//   lclOffset   - used to provide the starting index of this local