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

Code before:
#endif // defined(DEBUG) && defined(TARGET_XARCH)

#else  // defined(TARGET_WASM)
    // TODO-WASM: proper local count, local declarations, and shadow stack maintenance
    assert(compiler->info.compLocalsCount >= compiler->info.compArgsCount);
    GetEmitter()->emitIns_I(INS_local_cnt, EA_8BYTE, compiler->info.compLocalsCount - compiler->info.compArgsCount);
    genWasmLocals();
    GetEmitter()->emitMarkPrologEnd();
#endif // !defined(TARGET_WASM)

    GetEmitter()->emitEndProlog();
}

#if defined(TARGET_WASM)

//------------------------------------------------------------------------
// genWasmLocals: generate wasm locals for all locals
//
// TODO-WASM: re-evaluate this, we may not want a 1:1 mapping of locals to wasm locals
// TODO-WASM: pre-declare all "register" locals
void CodeGen::genWasmLocals()
{
    for (unsigned i = 0; i < compiler->info.compLocalsCount - compiler->info.compArgsCount; i++)
    {
        LclVarDsc* varDsc = compiler->lvaGetDesc(i);
        assert(varDsc->lvIsParam);
        emitter::instWasmValueType type = GetEmitter()->genWasmTypeFromVarType(varDsc->TypeGet());
        GetEmitter()->emitIns_I_Ty(INS_local_decl, 1, type);
    }
}
#endif

#if !defined(TARGET_WASM)

//----------------------------------------------------------------------------------
// genEmitJumpTable: emit jump table and return its base offset
//
// Arguments:
//    treeNode     - the GT_JMPTABLE node
//    relativeAddr - if true, references are treated as 4-byte relative addresses,
//                   otherwise they are absolute pointers
//
// Return Value:
//    base offset to jump table
//
// Assumption:
//    The current basic block in process ends with a switch statement
//
unsigned CodeGen::genEmitJumpTable(GenTree* treeNode, bool relativeAddr)
{
    noway_assert(compiler->compCurBB->KindIs(BBJ_SWITCH));

Review comment (bug):
The loop index logic is incorrect. The loop variable 'i' ranges from 0 to (compLocalsCount - compArgsCount - 1), but lvaGetDesc(i) is being called with 'i'. This will always retrieve the first (compLocalsCount - compArgsCount) local variable descriptors, which are typically parameters. To iterate over non-parameter locals, the loop should use lvaGetDesc(i + compArgsCount) or start i at compArgsCount and iterate while i < compLocalsCount.
```suggestion
    for (unsigned i = compiler->info.compArgsCount; i < compiler->info.compLocalsCount; i++)
    {
        LclVarDsc* varDsc = compiler->lvaGetDesc(i);
        assert(!varDsc->lvIsParam);
```

Code after:
#endif // defined(DEBUG) && defined(TARGET_XARCH)

#else  // defined(TARGET_WASM)
    genWasmLocals();
    GetEmitter()->emitMarkPrologEnd();
#endif // !defined(TARGET_WASM)

    GetEmitter()->emitEndProlog();
}

#if !defined(TARGET_WASM)

//----------------------------------------------------------------------------------
// genEmitJumpTable: emit jump table and return its base offset
//
// Arguments:
//    treeNode     - the GT_JMPTABLE node
//    relativeAddr - if true, references are treated as 4-byte relative addresses,
//                   otherwise they are absolute pointers
//
// Return Value:
//    base offset to jump table
//
// Assumption:
//    The current basic block in process ends with a switch statement
//
unsigned CodeGen::genEmitJumpTable(GenTree* treeNode, bool relativeAddr)
{
    noway_assert(compiler->compCurBB->KindIs(BBJ_SWITCH));
    assert(treeNode->OperIs(GT_JMPTABLE));

    emitter*         emit       = GetEmitter();
    const unsigned   jumpCount  = compiler->compCurBB->GetSwitchTargets()->GetCaseCount();
    FlowEdge** const jumpTable  = compiler->compCurBB->GetSwitchTargets()->GetCases();
    const unsigned   jmpTabBase = emit->emitBBTableDataGenBeg(jumpCount, relativeAddr);

    JITDUMP("\n      J_M%03u_DS%02u LABEL   DWORD\n", compiler->compMethodID, jmpTabBase);

    for (unsigned i = 0; i < jumpCount; i++)
    {
        BasicBlock* target = jumpTable[i]->getDestinationBlock();
        noway_assert(target->HasFlag(BBF_HAS_LABEL));

        JITDUMP("            DD      L_M%03u_" FMT_BB "\n", compiler->compMethodID, target->bbNum);

        emit->emitDataGenData(i, target);
    };

    emit->emitDataGenEnd();
    return jmpTabBase;
}