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

Code before:
}

size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
{
    BYTE*       dst    = *dp;
    size_t      sz     = emitSizeOfInsDsc(id);
    instruction ins    = id->idIns();
    insFormat   insFmt = id->idInsFmt();
    unsigned    opcode = GetInsOpcode(ins);

    switch (insFmt)
    {
        case IF_NONE:
            break;
        case IF_OPCODE:
            dst += emitOutputByte(dst, opcode);
            break;
        case IF_BLOCK:
            dst += emitOutputByte(dst, opcode);
            dst += emitOutputByte(dst, 0x40 /* block type of void */);
            break;
        case IF_ULEB128:
        {
            dst += emitOutputByte(dst, opcode);
            cnsval_ssize_t constant = emitGetInsSC(id);
            dst += emitOutputULEB128(dst, constant);
            break;
        }
        case IF_SLEB128:
        {
            dst += emitOutputByte(dst, opcode);
            cnsval_ssize_t constant = emitGetInsSC(id);
            dst += emitOutputSLEB128(dst, constant);
            break;
        }
        case IF_F32:
        {
            dst += emitOutputByte(dst, opcode);
            // Reinterpret the bits as a double constant and then truncate it to f32,
            //  then finally copy the raw truncated f32 bits to the output.
            cnsval_ssize_t bits = emitGetInsSC(id);
            double         value;
            float          truncated;
            memcpy(&value, &bits, sizeof(double));
            truncated = (float)value;
            memcpy(dst + writeableOffset, &truncated, sizeof(float));
            dst += sizeof(float);
            break;
        }
        case IF_F64:
        {

Review comment (suggestion):
Passing a signed `cnsval_ssize_t` constant to `emitOutputULEB128()` which expects an unsigned `uint64_t` may result in unintended sign extension. For IF_ULEB128 encoding of unsigned values, the constant should be cast to an unsigned type or the function signature should be clarified to indicate that signed values are handled correctly.

Consider either:
1. Casting to `(uint64_t)constant` before passing to `emitOutputULEB128`, or
2. Ensuring the constant is actually unsigned at this point, or
3. Using a different instruction format for signed values
```suggestion
            dst += emitOutputULEB128(dst, static_cast<uint64_t>(constant));
```

Code after:
        }
        buffer[pos++] = b;
    }
    return pos;
}

size_t emitter::emitRawBytes(uint8_t* destination, const void* source, size_t count)
{
    memcpy(destination + writeableOffset, source, count);
    return count;
}

size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
{
    BYTE*       dst    = *dp;
    size_t      sz     = emitSizeOfInsDsc(id);
    instruction ins    = id->idIns();
    insFormat   insFmt = id->idInsFmt();
    unsigned    opcode = GetInsOpcode(ins);

    switch (insFmt)
    {
        case IF_OPCODE:
            dst += emitOutputByte(dst, opcode);
            break;
        case IF_BLOCK:
            dst += emitOutputByte(dst, opcode);
            dst += emitOutputByte(dst, 0x40 /* block type of void */);
            break;
        case IF_ULEB128:
        {
            dst += emitOutputByte(dst, opcode);
            cnsval_ssize_t constant = emitGetInsSC(id);
            dst += emitOutputULEB128(dst, (uint64_t)constant);
            break;
        }
        case IF_SLEB128:
        {
            dst += emitOutputByte(dst, opcode);
            cnsval_ssize_t constant = emitGetInsSC(id);
            dst += emitOutputSLEB128(dst, (int64_t)constant);
            break;
        }
        case IF_F32:
        {
            dst += emitOutputByte(dst, opcode);
            // Reinterpret the bits as a double constant and then truncate it to f32,
            //  then finally copy the raw truncated f32 bits to the output.
            cnsval_ssize_t bits = emitGetInsSC(id);
            double         value;
            float          truncated;