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

Code before:

    if (m_debugInfoSize > 0)
    {
        id->idDebugOnlyInfo()->lclOffset = lclOffset;
    }

    return id;
}

//-----------------------------------------------------------------------------------
// emitIns_I_Ty: Emit an instruction for a local variable declaration, encoding both
// a count (immediate) and a value type. This is specifically used for local variable
// declarations that require both the number of locals and their type to be encoded.
//
// Arguments:
//   ins      - instruction to emit
//   imm      - immediate value (local count)
//   valType  - value type of the local variable
//   offs     - local variable offset (= count of preceding locals) for debug info
void emitter::emitIns_I_Ty(instruction ins, unsigned int imm, WasmValueType valType, int offs)
{
    instrDesc* id  = emitNewInstrLclVarDecl(EA_8BYTE, imm, valType, offs);
    insFormat  fmt = emitInsFormat(ins);

    id->idIns(ins);
    id->idInsFmt(fmt);

    dispIns(id);
    appendToCurIG(id);
}

WasmValueType emitter::emitGetLclVarDeclType(const instrDesc* id)
{
    assert(id->idIsLclVarDecl());
    return static_cast<const instrDescLclVarDecl*>(id)->lclType;
}

unsigned int emitter::emitGetLclVarDeclCount(const instrDesc* id)
{
    assert(id->idIsLclVarDecl());
    return static_cast<const instrDescLclVarDecl*>(id)->lclCnt;
}

emitter::insFormat emitter::emitInsFormat(instruction ins)
{
    static_assert(IF_COUNT < 255);

    const static uint8_t insFormats[] = {
#define INST(id, nm, info, fmt, opcode) fmt,
#include "instrs.h"
    };

Review comment (suggestion):
Similar to the previous FIXME, this comment indicates incomplete implementation for type index relocation. Consider documenting the expected behavior or creating a tracking issue.

Code after:
    /*
        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;

    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