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 assertion 'varDsc->lvIsParam' is incorrect. The loop iterates over local variables (i ranges from 0 to compLocalsCount - compArgsCount), and these are locals, not parameters. Parameters would be at indices >= compArgsCount. This should likely assert !varDsc->lvIsParam instead, or the loop index calculation is wrong.
```suggestion
        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;
}