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

Code before:
//    tree - the node
//
void CodeGen::genCodeForStoreBlk(GenTreeBlk* blkOp)
{
    assert(blkOp->OperIs(GT_STORE_BLK));
    assert(!blkOp->gtBlkOpGcUnsafe);

    bool isCopyBlk = blkOp->OperIsCopyBlkOp();

    switch (blkOp->gtBlkOpKind)
    {
        case GenTreeBlk::BlkOpKindCpObjUnroll:
            assert(!blkOp->gtBlkOpGcUnsafe);
            genCodeForCpObj(blkOp->AsBlk());
            break;

        case GenTreeBlk::BlkOpKindLoop:
            assert(!isCopyBlk);
            genCodeForInitBlkLoop(blkOp);
            break;

        case GenTreeBlk::BlkOpKindNativeOpcode:
            genConsumeOperands(blkOp);
            // Emit the size constant expected by the memory.copy and memory.fill opcodes
            GetEmitter()->emitIns_I(INS_i32_const, EA_4BYTE, blkOp->Size());
            GetEmitter()->emitIns_I(isCopyBlk ? INS_memory_copy : INS_memory_fill, EA_8BYTE, /* memory index */ 0);
            break;

        default:
            unreached();
    }
}

void CodeGen::genCodeForCpObj(GenTreeBlk* cpObjNode)
{
    NYI_WASM("genCodeForCpObj");
}

//------------------------------------------------------------------------
// genCodeForInitBlkLoop - Generate code for an InitBlk using an inlined for-loop.
//    It's needed for cases when size is too big to unroll and we're not allowed
//    to use memset call due to atomicity requirements.
//
// Arguments:
//    initBlkNode - the GT_STORE_BLK node
//
void CodeGen::genCodeForInitBlkLoop(GenTreeBlk* blkOp)
{
    // TODO-WASM: In multi-threaded wasm we will need to generate a for loop that atomically zeroes one GC ref
    //  at a time. Right now we're single-threaded, so we can just use memory.fill.
    assert(!WASM_THREAD_SUPPORT);

Review comment (suggestion):
We should have a constant somewhere for `LINEAR_MEMORY_INDEX = 0`.

Code after:
//
// Arguments:
//    blkOp - the node
//
void CodeGen::genCodeForStoreBlk(GenTreeBlk* blkOp)
{
    assert(blkOp->OperIs(GT_STORE_BLK));

    bool isCopyBlk = blkOp->OperIsCopyBlkOp();

    switch (blkOp->gtBlkOpKind)
    {
        case GenTreeBlk::BlkOpKindCpObjUnroll:
            genCodeForCpObj(blkOp->AsBlk());
            break;

        case GenTreeBlk::BlkOpKindLoop:
            assert(!isCopyBlk);
            genCodeForInitBlkLoop(blkOp);
            break;

        case GenTreeBlk::BlkOpKindNativeOpcode:
            genConsumeOperands(blkOp);
            // Emit the size constant expected by the memory.copy and memory.fill opcodes
            GetEmitter()->emitIns_I(INS_i32_const, EA_4BYTE, blkOp->Size());
            GetEmitter()->emitIns_I(isCopyBlk ? INS_memory_copy : INS_memory_fill, EA_8BYTE, LINEAR_MEMORY_INDEX);
            break;

        default:
            unreached();
    }
}

void CodeGen::genCodeForCpObj(GenTreeBlk* cpObjNode)
{
    NYI_WASM("genCodeForCpObj");
}

//------------------------------------------------------------------------
// genCodeForInitBlkLoop - Generate code for an InitBlk using an inlined for-loop.
//    It's needed for cases when size is too big to unroll and we're not allowed
//    to use memset call due to atomicity requirements.
//
// Arguments:
//    blkOp - the GT_STORE_BLK node
//
void CodeGen::genCodeForInitBlkLoop(GenTreeBlk* blkOp)
{
    // TODO-WASM: In multi-threaded wasm we will need to generate a for loop that atomically zeroes one GC ref
    //  at a time. Right now we're single-threaded, so we can just use memory.fill.
    assert(!WASM_THREAD_SUPPORT);