Exemple #1
0
void TryFinallyStatement::toIR(IRState *irs)
{
    //printf("TryFinallyStatement::toIR()\n");

    Blockx *blx = irs->blx;

#if SEH
    nteh_declarvars(blx);
#endif

    block *tryblock = block_goto(blx, BCgoto, NULL);

    int previndex = blx->scope_index;
    tryblock->Blast_index = previndex;
    tryblock->Bscope_index = blx->next_index++;
    blx->scope_index = tryblock->Bscope_index;

    // Current scope index
    setScopeIndex(blx,tryblock,tryblock->Bscope_index);

    blx->tryblock = tryblock;
    block_goto(blx,BC_try,NULL);

    IRState bodyirs(irs, this);
    block *breakblock = block_calloc(blx);
    block *contblock = block_calloc(blx);

    if (body)
        body->toIR(&bodyirs);
    blx->tryblock = tryblock->Btry;     // back to previous tryblock

    setScopeIndex(blx,blx->curblock,previndex);
    blx->scope_index = previndex;

    block_goto(blx,BCgoto, breakblock);
    block *finallyblock = block_goto(blx,BCgoto,contblock);

    list_append(&tryblock->Bsucc,finallyblock);

    block_goto(blx,BC_finally,NULL);

    IRState finallyState(irs, this);
    breakblock = block_calloc(blx);
    contblock = block_calloc(blx);

    setScopeIndex(blx, blx->curblock, previndex);
    if (finalbody)
        finalbody->toIR(&finallyState);
    block_goto(blx, BCgoto, contblock);
    block_goto(blx, BCgoto, breakblock);

    block *retblock = blx->curblock;
    block_next(blx,BC_ret,NULL);

    list_append(&finallyblock->Bsucc, blx->curblock);
    list_append(&retblock->Bsucc, blx->curblock);
}
Exemple #2
0
    void visit(TryCatchStatement *s)
    {
        Blockx *blx = irs->blx;

#if SEH
        if (!global.params.is64bit)
            nteh_declarvars(blx);
#endif

        IRState mystate(irs, s);

        block *tryblock = block_goto(blx,BCgoto,NULL);

        int previndex = blx->scope_index;
        tryblock->Blast_index = previndex;
        blx->scope_index = tryblock->Bscope_index = blx->next_index++;

        // Set the current scope index
        setScopeIndex(blx,tryblock,tryblock->Bscope_index);

        // This is the catch variable
        tryblock->jcatchvar = symbol_genauto(type_fake(mTYvolatile | TYnptr));

        blx->tryblock = tryblock;
        block *breakblock = block_calloc(blx);
        block_goto(blx,BC_try,NULL);
        if (s->_body)
        {
            Statement_toIR(s->_body, &mystate);
        }
        blx->tryblock = tryblock->Btry;

        // break block goes here
        block_goto(blx, BCgoto, breakblock);

        setScopeIndex(blx,blx->curblock, previndex);
        blx->scope_index = previndex;

        // create new break block that follows all the catches
        breakblock = block_calloc(blx);

        blx->curblock->appendSucc(breakblock);
        block_next(blx,BCgoto,NULL);

        assert(s->catches);
        for (size_t i = 0 ; i < s->catches->dim; i++)
        {
            Catch *cs = (*s->catches)[i];
            if (cs->var)
                cs->var->csym = tryblock->jcatchvar;
            block *bcatch = blx->curblock;
            if (cs->type)
                bcatch->Bcatchtype = toSymbol(cs->type->toBasetype());
            tryblock->appendSucc(bcatch);
            block_goto(blx, BCjcatch, NULL);
            if (cs->handler != NULL)
            {
                IRState catchState(irs, s);

                /* Append to block:
                 *   *(sclosure + cs.offset) = cs;
                 */
                if (cs->var && cs->var->offset)
                {
                    tym_t tym = totym(cs->var->type);
                    elem *ex = el_var(irs->sclosure);
                    ex = el_bin(OPadd, TYnptr, ex, el_long(TYsize_t, cs->var->offset));
                    ex = el_una(OPind, tym, ex);
                    ex = el_bin(OPeq, tym, ex, el_var(toSymbol(cs->var)));
                    block_appendexp(catchState.blx->curblock, ex);
                }
                Statement_toIR(cs->handler, &catchState);
            }
            blx->curblock->appendSucc(breakblock);
            block_next(blx, BCgoto, NULL);
        }

        block_next(blx,(enum BC)blx->curblock->BC, breakblock);
    }
Exemple #3
0
    void visit(TryFinallyStatement *s)
    {
        //printf("TryFinallyStatement::toIR()\n");

        Blockx *blx = irs->blx;

#if SEH
        if (!global.params.is64bit)
            nteh_declarvars(blx);
#endif

        block *tryblock = block_goto(blx, BCgoto, NULL);

        int previndex = blx->scope_index;
        tryblock->Blast_index = previndex;
        tryblock->Bscope_index = blx->next_index++;
        blx->scope_index = tryblock->Bscope_index;

        // Current scope index
        setScopeIndex(blx,tryblock,tryblock->Bscope_index);

        blx->tryblock = tryblock;
        block_goto(blx,BC_try,NULL);

        IRState bodyirs(irs, s);
        block *breakblock = block_calloc(blx);
        block *contblock = block_calloc(blx);
        tryblock->appendSucc(contblock);
        contblock->BC = BC_finally;
        bodyirs.finallyBlock = contblock;

        if (s->_body)
            Statement_toIR(s->_body, &bodyirs);
        blx->tryblock = tryblock->Btry;     // back to previous tryblock

        setScopeIndex(blx,blx->curblock,previndex);
        blx->scope_index = previndex;

        block_goto(blx,BCgoto, breakblock);
        block *finallyblock = block_goto(blx,BCgoto,contblock);
        assert(finallyblock == contblock);

        block_goto(blx,BC_finally,NULL);

        IRState finallyState(irs, s);
        breakblock = block_calloc(blx);
        contblock = block_calloc(blx);

        setScopeIndex(blx, blx->curblock, previndex);
        if (s->finalbody)
            Statement_toIR(s->finalbody, &finallyState);
        block_goto(blx, BCgoto, contblock);
        block_goto(blx, BCgoto, breakblock);

        block *retblock = blx->curblock;
        block_next(blx,BC_ret,NULL);

        finallyblock->appendSucc(blx->curblock);
        retblock->appendSucc(blx->curblock);

        /* The BCfinally..BC_ret blocks form a function that gets called from stack unwinding.
         * The successors to BC_ret blocks are both the next outer BCfinally and the destination
         * after the unwinding is complete.
         */
        for (block *b = tryblock; b != finallyblock; b = b->Bnext)
        {
            block *btry = b->Btry;

            if (b->BC == BCgoto && b->numSucc() == 1)
            {
                block *bdest = b->nthSucc(0);
                if (btry && bdest->Btry != btry)
                {
                    //printf("test1 b %p b->Btry %p bdest %p bdest->Btry %p\n", b, btry, bdest, bdest->Btry);
                    block *bfinally = btry->nthSucc(1);
                    if (bfinally == finallyblock)
                        b->appendSucc(finallyblock);
                }
            }

            // If the goto exits a try block, then the finally block is also a successor
            if (b->BC == BCgoto && b->numSucc() == 2) // if goto exited a tryblock
            {
                block *bdest = b->nthSucc(0);

                // If the last finally block executed by the goto
                if (bdest->Btry == tryblock->Btry)
                    // The finally block will exit and return to the destination block
                    retblock->appendSucc(bdest);
            }

            if (b->BC == BC_ret && b->Btry == tryblock)
            {
                // b is nested inside this TryFinally, and so this finally will be called next
                b->appendSucc(finallyblock);
            }
        }
    }
Exemple #4
0
void TryCatchStatement::toIR(IRState *irs)
{
    Blockx *blx = irs->blx;

#if SEH
    nteh_declarvars(blx);
#endif

    IRState mystate(irs, this);

    block *tryblock = block_goto(blx,BCgoto,NULL);

    int previndex = blx->scope_index;
    tryblock->Blast_index = previndex;
    blx->scope_index = tryblock->Bscope_index = blx->next_index++;

    // Set the current scope index
    setScopeIndex(blx,tryblock,tryblock->Bscope_index);

    // This is the catch variable
    tryblock->jcatchvar = symbol_genauto(type_fake(mTYvolatile | TYnptr));

    blx->tryblock = tryblock;
    block *breakblock = block_calloc(blx);
    block_goto(blx,BC_try,NULL);
    if (body)
    {
        body->toIR(&mystate);
    }
    blx->tryblock = tryblock->Btry;

    // break block goes here
    block_goto(blx, BCgoto, breakblock);

    setScopeIndex(blx,blx->curblock, previndex);
    blx->scope_index = previndex;

    // create new break block that follows all the catches
    breakblock = block_calloc(blx);

    list_append(&blx->curblock->Bsucc, breakblock);
    block_next(blx,BCgoto,NULL);

    assert(catches);
    for (size_t i = 0 ; i < catches->dim; i++)
    {
        Catch *cs = catches->tdata()[i];
        if (cs->var)
            cs->var->csym = tryblock->jcatchvar;
        block *bcatch = blx->curblock;
        if (cs->type)
            bcatch->Bcatchtype = cs->type->toBasetype()->toSymbol();
        list_append(&tryblock->Bsucc,bcatch);
        block_goto(blx,BCjcatch,NULL);
        if (cs->handler != NULL)
        {
            IRState catchState(irs, this);
            cs->handler->toIR(&catchState);
        }
        list_append(&blx->curblock->Bsucc, breakblock);
        block_next(blx, BCgoto, NULL);
    }

    block_next(blx,(enum BC)blx->curblock->BC, breakblock);
}