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

Code before:
// 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)

    // 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 (refactor):
I wonder if this could come back to bite us in some way in the future due to introducing a block that can be in two try regions "at once" (in internal Jit modeling terms, not actual emitted code terms).

(One obvious way in which this is 'interesting' is that we'll need to be careful to not insert the virtual IP updates into the throw helper blocks themselves, since they'd be dynamically determined)

But it is what it is.

Code after:
// 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)

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