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

Code before:
//
// Arguments:
//    blk -- block that may eventually throw an exception
//    dsg [out] -- designator for which region controls throw block placement
//
// Return Value:
//    encoded region value to use in acd key formation
//
unsigned Compiler::bbThrowIndex(BasicBlock* blk, AcdKeyDesignator* dsg)
{
    const unsigned tryIndex = blk->bbTryIndex;
    const unsigned hndIndex = blk->bbHndIndex;
    const bool     inTry    = tryIndex > 0;
    const bool     inHnd    = hndIndex > 0;

    if (!inTry && !inHnd)
    {
        *dsg = AcdKeyDesignator::KD_NONE;
        return 0;
    }

    assert(inTry || inHnd);

#if defined(TARGET_WASM)
    // For WASM we want one throw helper per funclet
    // So we ignore any try region nesting.
    if (!inHnd)
    {
        *dsg = AcdKeyDesignator::KD_NONE;
        return 0;
    }
#else
    if (inTry && (!inHnd || (tryIndex < hndIndex)))
    {
        // The most enclosing region is a try body, use it
        assert(tryIndex <= 0x3FFFFFFF);
        *dsg = AcdKeyDesignator::KD_TRY;
        return tryIndex;
    }
#endif // !defined(TARGET_WASM)

    // The most enclosing region is a handler which will be a funclet
    // Now we have to figure out if blk is in the filter or handler
    assert(hndIndex <= 0x3FFFFFFF);
    assert(hndIndex >= 1);
    if (ehGetDsc(hndIndex - 1)->InFilterRegionBBRange(blk))
    {
        *dsg = AcdKeyDesignator::KD_FLT;
        return hndIndex | 0x80000000;
    }


Review comment (suggestion):
This would also be hardcoding the "one `catch` per funclet (with nested `try`s)" scheme, right? Otherwise we still need the nesting for proper resumption.

Apart from that, the comment could be improved to talk about "why" we want this.

Code after:

    return add;
}

//------------------------------------------------------------------------
// bbThrowIndex: find acd map key for a given block
//
// Arguments:
//    blk -- block that may eventually throw an exception
//    dsg [out] -- designator for which region controls throw block placement
//
// Return Value:
//    encoded region value to use in acd key formation
//
unsigned Compiler::bbThrowIndex(BasicBlock* blk, AcdKeyDesignator* dsg)
{
    const unsigned tryIndex = blk->bbTryIndex;
    const unsigned hndIndex = blk->bbHndIndex;
    const bool     inTry    = tryIndex > 0;
    const bool     inHnd    = hndIndex > 0;

    if (!inTry && !inHnd)
    {
        *dsg = AcdKeyDesignator::KD_NONE;
        return 0;
    }

    assert(inTry || inHnd);

#if defined(TARGET_WASM)
    // The current plan for Wasm: method regions or funclets with
    // trys will have a single Wasm try handle all
    // resumption from catches via virtual IPs.
    //
    // So we do not need to consider the nesting of the throw
    // in try regions, just in handlers.
    //
    if (!inHnd)
    {
        *dsg = AcdKeyDesignator::KD_NONE;
        return 0;
    }
#else
    if (inTry && (!inHnd || (tryIndex < hndIndex)))
    {
        // The most enclosing region is a try body, use it
        assert(tryIndex <= 0x3FFFFFFF);
        *dsg = AcdKeyDesignator::KD_TRY;
        return tryIndex;
    }
#endif // !defined(TARGET_WASM)