Repository: dotnet/runtime
File: src/coreclr/jit/emit.h (C/C++)

Code before:
protected:
    unsigned _lvaVarNum : 15; // Usually the lvaVarNum
    unsigned _lvaExtra  : 15; // Usually the lvaOffset
    unsigned _lvaTag    : 2;  // tag field to support larger varnums
};

enum idAddrUnionTag
{
    iaut_ALIGNED_POINTER = 0x0,
    iaut_DATA_OFFSET     = 0x1,
    iaut_INST_COUNT      = 0x2,
    iaut_UNUSED_TAG      = 0x3,

    iaut_MASK  = 0x3,
    iaut_SHIFT = 2
};

enum EmitCallType
{
#ifdef TARGET_WASM
    // should generate: <push args>; <push cell-address>; i32.load 0 0; call_indirect <signature-type>
    EC_MANAGED_CELL, // call_indirect to a statically known managed method or helper (one level of indirection through
                     // cell to support interpretation)
    // should generate: <push args>; <push address-of-cell-address>; i32.load 0 0; i32.load 0 0; call_indirect
    // <signature-type>
    EC_MANAGED_PTR, // call_indirect to an unknown managed method or helper (two levels of indirection - ptr to
                    // arbitrary cell)
    // should generate: <push args>; call <func-index>
    EC_FUNCTION_INDEX, // call to a known wasm import or function from same module, no indirection
#else                  // TARGET_WASM
    EC_FUNC_TOKEN, //   Direct call to a helper/static/nonvirtual/global method (call/bl addr with IP-relative encoding)
#ifdef TARGET_XARCH
    EC_FUNC_TOKEN_INDIR, // Indirect call to a helper/static/nonvirtual/global method (call [addr]/call [rip+addr])
#endif
    EC_INDIR_R, // Indirect call via register (call/bl reg)
#ifdef TARGET_XARCH
    EC_INDIR_ARD, // Indirect call via an addressing mode (call [rax+rdx*8+disp])
#endif
#endif // TARGET_WASM

    EC_COUNT
};

struct EmitCallParams
{
    EmitCallType          callType = EC_COUNT;
    CORINFO_METHOD_HANDLE methHnd  = NO_METHOD_HANDLE;
#ifdef DEBUG
    // Used to report call sites to the EE
    CORINFO_SIG_INFO* sigInfo = nullptr;
#endif

Review comment (suggestion):
I don't think this should be an emitter concept. The design philosophy for the WASM emitter so far has been "one WASM instruction <=> one `emitIns_XYZ` method". It means handling this at the caller level.

Code after:
protected:
    unsigned _lvaVarNum : 15; // Usually the lvaVarNum
    unsigned _lvaExtra  : 15; // Usually the lvaOffset
    unsigned _lvaTag    : 2;  // tag field to support larger varnums
};

enum idAddrUnionTag
{
    iaut_ALIGNED_POINTER = 0x0,
    iaut_DATA_OFFSET     = 0x1,
    iaut_INST_COUNT      = 0x2,
    iaut_UNUSED_TAG      = 0x3,

    iaut_MASK  = 0x3,
    iaut_SHIFT = 2
};

enum EmitCallType
{
    EC_FUNC_TOKEN, //   Direct call to a helper/static/nonvirtual/global method (call/bl addr with IP-relative encoding)
#ifdef TARGET_XARCH
    EC_FUNC_TOKEN_INDIR, // Indirect call to a helper/static/nonvirtual/global method (call [addr]/call [rip+addr])
#endif
    EC_INDIR_R, // Indirect call via register (call/bl reg)
#ifdef TARGET_XARCH
    EC_INDIR_ARD, // Indirect call via an addressing mode (call [rax+rdx*8+disp])
#endif

    EC_COUNT
};

struct EmitCallParams
{
    EmitCallType          callType = EC_COUNT;
    CORINFO_METHOD_HANDLE methHnd  = NO_METHOD_HANDLE;
#ifdef DEBUG
    // Used to report call sites to the EE
    CORINFO_SIG_INFO* sigInfo = nullptr;
#endif
    void*    addr    = nullptr;
    ssize_t  argSize = 0;
    emitAttr retSize = EA_PTRSIZE;
    // For multi-reg args with GC returns in the second arg
    emitAttr  secondRetSize = EA_UNKNOWN;
    bool      hasAsyncRet   = false;
    BitVec    ptrVars       = BitVecOps::UninitVal();
    regMaskTP gcrefRegs     = RBM_NONE;
    regMaskTP byrefRegs     = RBM_NONE;
    DebugInfo debugInfo;
    regNumber ireg        = REG_NA;
    regNumber xreg        = REG_NA;