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

Code before:
            // Compute the actual dest/src of the slot being copied to pass to the helper.
            emit->emitIns_I(INS_local_get, attrDstAddr, WasmRegToIndex(dstReg));
            emit->emitIns_I(INS_I_const, attrDstAddr, dstOffset);
            emit->emitIns(INS_I_add);
            emit->emitIns_I(INS_local_get, attrSrcAddr, WasmRegToIndex(srcReg));
            emit->emitIns_I(INS_I_const, attrSrcAddr, srcOffset);
            emit->emitIns(INS_I_add);
            // TODO-WASM: Load the PEP value for the helper onto the stack here? Right now genEmitHelperCall does it.
            // Call the byref assign helper. On other targets this updates the dst/src regs but here it won't,
            //  so we have to do the local.get+i32.const+i32.add dance every time.
            genEmitHelperCall(CORINFO_HELP_ASSIGN_BYREF, 0, EA_PTRSIZE);
            gcPtrCount--;
        }
        ++i;
        srcOffset += TARGET_POINTER_SIZE;
        dstOffset += TARGET_POINTER_SIZE;
    }

    assert(gcPtrCount == 0);

    if (cpObjNode->IsVolatile())
    {
        // TODO-WASM: Memory barrier
    }

    WasmProduceReg(cpObjNode);
}

//------------------------------------------------------------------------
// 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);

    genConsumeOperands(blkOp);
    // Emit the value constant expected by the memory.fill opcode (zero)
    GetEmitter()->emitIns_I(INS_i32_const, EA_4BYTE, 0);
    // 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(INS_memory_fill, EA_8BYTE, LINEAR_MEMORY_INDEX);
}

BasicBlock* CodeGen::genCallFinally(BasicBlock* block)

Review comment (refactor):
```suggestion
    genUpdateLife(cpObjNode);
```
These nodes don't produce any values.

It would be better to move this call to the caller of this method so that it is called for call 'block' operations.

Code after:
            emit->emitIns_I(INS_local_get, attrSrcAddr, WasmRegToIndex(srcReg));
            emit->emitIns_I(INS_I_load, EA_PTRSIZE, srcOffset);
            emit->emitIns_I(INS_I_store, EA_PTRSIZE, dstOffset);
        }
        else
        {
            // Load the sp onto the stack for the helper call.
            // TODO-WASM: Implement a special calling convention for this helper that doesn't accept sp/pep.
            emit->emitIns_I(INS_local_get, EA_PTRSIZE, WasmRegToIndex(GetStackPointerReg()));
            // Compute the actual dest/src of the slot being copied to pass to the helper.
            emit->emitIns_I(INS_local_get, attrDstAddr, WasmRegToIndex(dstReg));
            emit->emitIns_I(INS_I_const, attrDstAddr, dstOffset);
            emit->emitIns(INS_I_add);
            emit->emitIns_I(INS_local_get, attrSrcAddr, WasmRegToIndex(srcReg));
            emit->emitIns_I(INS_I_const, attrSrcAddr, srcOffset);
            emit->emitIns(INS_I_add);
            // TODO-WASM: don't load PEP in genEmitHelperCall for write barriers.
            // TODO-WASM-CQ: add a version of CORINFO_HELP_ASSIGN_BYREF that returns the updated dest/src
            // pointers as a multi-value tuple and use it here.
            genEmitHelperCall(CORINFO_HELP_ASSIGN_BYREF, 0, EA_PTRSIZE);
            gcPtrCount--;
        }
        ++i;
        srcOffset += TARGET_POINTER_SIZE;
        dstOffset += TARGET_POINTER_SIZE;
    }

    assert(gcPtrCount == 0);

    if (cpObjNode->IsVolatile())
    {
        // TODO-WASM: Memory barrier
    }
}

//------------------------------------------------------------------------
// 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);

    genConsumeOperands(blkOp);
    // Emit the value constant expected by the memory.fill opcode (zero)