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

Code before:
    // TODO-WASM: refactor once we have implemented other cases invoking throw helpers
    if (compiler->fgUseThrowHelperBlocks())
    {
        Compiler::AddCodeDsc* const add = compiler->fgFindExcptnTarget(SCK_NULL_CHECK, compiler->compCurBB);
        assert(add != nullptr);
        assert(add->acdUsed);
        GetEmitter()->emitIns_I(INS_I_const, EA_PTRSIZE, compiler->compMaxUncheckedOffsetForNullObject);
        GetEmitter()->emitIns(INS_I_le_u);
        inst_JMP(EJ_jmpif, add->acdDstBlk);
    }
    else
    {
        BasicBlock* const tgtBlk = genCreateTempLabel();
        GetEmitter()->emitIns(INS_block);
        GetEmitter()->emitIns_I(INS_I_const, EA_PTRSIZE, compiler->compMaxUncheckedOffsetForNullObject);
        GetEmitter()->emitIns(INS_I_gt_u);
        // tgtBlock is not on the model wasm control stack we set up earlier.
        // Since we have just emitted a `begin` that will end at this block, it will be at depth 0.
        // Indicate this via isTempLabel.
        inst_JMP(EJ_jmpif, tgtBlk, /* isTempLabel */ true);
        // TODO-WASM: codegen for the call
        // genEmitHelperCall(compiler->acdHelper(SCK_NULL_CHECK), 0, EA_UNKNOWN);
        // The helper won't return, and we may have things pended on the stack, so emit unreachable
        GetEmitter()->emitIns(INS_unreachable);
        GetEmitter()->emitIns(INS_end);
        genDefineTempLabel(tgtBlk);
    }
}

//------------------------------------------------------------------------
// genCodeForLclAddr: Generates the code for GT_LCL_ADDR.
//
// Arguments:
//    lclAddrNode - the node.
//
void CodeGen::genCodeForLclAddr(GenTreeLclFld* lclAddrNode)
{
    assert(lclAddrNode->OperIs(GT_LCL_ADDR));
    bool     FPBased;
    unsigned lclNum    = lclAddrNode->GetLclNum();
    unsigned lclOffset = lclAddrNode->GetLclOffs();

    GetEmitter()->emitIns_I(INS_local_get, EA_PTRSIZE, WasmRegToIndex(GetFramePointerReg()));
    if ((lclOffset != 0) || (compiler->lvaFrameAddress(lclNum, &FPBased) != 0))
    {
        GetEmitter()->emitIns_S(INS_I_const, EA_PTRSIZE, lclNum, lclOffset);
        GetEmitter()->emitIns(INS_I_add);
    }
    genProduceReg(lclAddrNode);
}


Review comment (refactor):
What if we do:
```wasm
<push comparison>
if
call <helper>
end
```
?

Seems it would be both smaller and simpler (no need for temp labels and such).

Code after:

    // TODO-WASM: refactor once we have implemented other cases invoking throw helpers
    if (compiler->fgUseThrowHelperBlocks())
    {
        Compiler::AddCodeDsc* const add = compiler->fgFindExcptnTarget(SCK_NULL_CHECK, compiler->compCurBB);

        if (add == nullptr)
        {
            NYI_WASM("Missing null check demand");
        }

        assert(add != nullptr);
        assert(add->acdUsed);
        GetEmitter()->emitIns_I(INS_I_const, EA_PTRSIZE, compiler->compMaxUncheckedOffsetForNullObject);
        GetEmitter()->emitIns(INS_I_le_u);
        inst_JMP(EJ_jmpif, add->acdDstBlk);
    }
    else
    {
        GetEmitter()->emitIns_I(INS_I_const, EA_PTRSIZE, compiler->compMaxUncheckedOffsetForNullObject);
        GetEmitter()->emitIns(INS_I_le_u);
        GetEmitter()->emitIns(INS_if);
        // TODO-WASM: codegen for the call instead of unreachable
        // genEmitHelperCall(compiler->acdHelper(SCK_NULL_CHECK), 0, EA_UNKNOWN);
        GetEmitter()->emitIns(INS_unreachable);
        GetEmitter()->emitIns(INS_end);
    }
}

//------------------------------------------------------------------------
// genCodeForLclAddr: Generates the code for GT_LCL_ADDR.
//
// Arguments:
//    lclAddrNode - the node.
//
void CodeGen::genCodeForLclAddr(GenTreeLclFld* lclAddrNode)
{
    assert(lclAddrNode->OperIs(GT_LCL_ADDR));
    bool     FPBased;
    unsigned lclNum    = lclAddrNode->GetLclNum();
    unsigned lclOffset = lclAddrNode->GetLclOffs();

    GetEmitter()->emitIns_I(INS_local_get, EA_PTRSIZE, WasmRegToIndex(GetFramePointerReg()));
    if ((lclOffset != 0) || (compiler->lvaFrameAddress(lclNum, &FPBased) != 0))
    {
        GetEmitter()->emitIns_S(INS_I_const, EA_PTRSIZE, lclNum, lclOffset);
        GetEmitter()->emitIns(INS_I_add);
    }
    genProduceReg(lclAddrNode);
}