Ejemplo n.º 1
0
/* Searches for a handler of the specified category, relative to the given
 * starting frame, searching according to the chosen mode. */
static LocatedHandler search_for_handler_from(MVMThreadContext *tc, MVMFrame *f,
        MVMuint8 mode, MVMuint32 cat) {
    LocatedHandler lh;
    lh.frame = NULL;
    lh.handler = NULL;
    
    if (mode == MVM_EX_THROW_LEXOTIC) {
        while (f != NULL) {
            lh = search_for_handler_from(tc, f, MVM_EX_THROW_LEX, cat);
            if (lh.frame != NULL)
                return lh;
            f = f->caller;
        }
    }
    else {
        while (f != NULL) {
            MVMFrameHandler *h = search_frame_handlers(tc, f, cat);
            if (h != NULL) {
                lh.frame = f;
                lh.handler = h;
                return lh;
            }
            if (mode == MVM_EX_THROW_DYN) {
                f = f->caller;
            }
            else {
                MVMFrame *f_maybe = f->outer;
                while (f_maybe != NULL && !in_caller_chain(tc, f_maybe))
                    f_maybe = f_maybe->outer;
                f = f_maybe;
            }
        }
    }
    return lh;
}
Ejemplo n.º 2
0
/* Unwinds to a lexotic captured handler. */
void MVM_exception_gotolexotic(MVMThreadContext *tc, MVMFrameHandler *h, MVMFrame *f) {
    if (in_caller_chain(tc, f)) {
        LocatedHandler lh;
        lh.frame = f;
        lh.handler = h;
        run_handler(tc, lh, NULL);
    }
    else {
        MVM_exception_throw_adhoc(tc, "Too late to invoke lexotic return");
    }
}
Ejemplo n.º 3
0
/* Searches for a handler of the specified category, relative to the given
 * starting frame, searching according to the chosen mode. */
static LocatedHandler search_for_handler_from(MVMThreadContext *tc, MVMFrame *f,
        MVMuint8 mode, MVMuint32 cat, MVMObject *payload) {
    LocatedHandler lh;
    lh.frame = NULL;
    lh.handler = NULL;
    lh.jit_handler = NULL;
    lh.handler_out_of_dynamic_scope = 0;
    switch (mode) {
        case MVM_EX_THROW_LEX_CALLER:
            f = f->caller;
            while (f && f->static_info->body.is_thunk)
                f = f->caller;
            /* And now we've gone down a caller, it's just lexical... */
        case MVM_EX_THROW_LEX:
            while (f != NULL) {
                if (search_frame_handlers(tc, f, MVM_EX_THROW_LEX, cat, payload, &lh)) {
                    if (in_caller_chain(tc, f))
                        lh.frame = f;
                    else
                        lh.handler_out_of_dynamic_scope = 1;
                    return lh;
                }
                f = f->outer;
            }
            return lh;
        case MVM_EX_THROW_DYN:
            while (f != NULL) {
                if (search_frame_handlers(tc, f, mode, cat, payload, &lh)) {
                    lh.frame = f;
                    return lh;
                }
                f = f->caller;
            }
            return lh;
        case MVM_EX_THROW_LEXOTIC:
            while (f != NULL) {
                lh = search_for_handler_from(tc, f, MVM_EX_THROW_LEX, cat, payload);
                if (lh.frame != NULL)
                    return lh;
                f = f->caller;
            }
            return lh;
        default:
            MVM_panic(1, "Unhandled exception throw mode %d", (int)mode);
    }
}
Ejemplo n.º 4
0
/* Searches for a handler of the specified category, relative to the given
 * starting frame, searching according to the chosen mode. */
static LocatedHandler search_for_handler_from(MVMThreadContext *tc, MVMFrame *f,
        MVMuint8 mode, MVMuint32 cat, MVMObject *payload) {
    MVMuint32 skip_first_inlinee = 0;
    LocatedHandler lh;
    lh.frame = NULL;
    lh.handler = NULL;
    lh.jit_handler = NULL;
    lh.handler_out_of_dynamic_scope = 0;
    switch (mode) {
        case MVM_EX_THROW_LEX_CALLER:
            skip_first_inlinee = 1;
            /* fallthrough */
        case MVM_EX_THROW_LEX: {
            MVMint32 skip_all_inlinees = 0;
            while (f != NULL) {
                MVMFrame *outer_from_inlinee = NULL;
                if (search_frame_handlers_lex(tc, f, cat, payload, &lh, &skip_first_inlinee,
                            skip_all_inlinees, &outer_from_inlinee)) {
                    if (in_caller_chain(tc, f))
                        lh.frame = f;
                    else
                        lh.handler_out_of_dynamic_scope = 1;
                    return lh;
                }
                if (skip_first_inlinee) {
                    /* If this is still set, it means that the topmost frame
                     * had no inlines, so we didn't already reach a chain of
                     * outers to traverse. In this case, skip over any thunks
                     * and continue the search. */
                    skip_first_inlinee = 0;
                    f = f->caller;
                    while (f && f->static_info->body.is_thunk)
                        f = f->caller;
                }
                else {
                    f = outer_from_inlinee ? outer_from_inlinee : f->outer;
                    skip_all_inlinees = 1;
                }
            }
            return lh;
        }
        case MVM_EX_THROW_DYN:
            while (f != NULL) {
                if (search_frame_handlers_dyn(tc, f, cat, payload, &lh)) {
                    lh.frame = f;
                    return lh;
                }
                f = f->caller;
            }
            return lh;
        case MVM_EX_THROW_LEXOTIC:
            while (f != NULL) {
                lh = search_for_handler_from(tc, f, MVM_EX_THROW_LEX, cat, payload);
                if (lh.frame != NULL)
                    return lh;
                f = f->caller;
            }
            return lh;
        default:
            MVM_panic(1, "Unhandled exception throw mode %d", (int)mode);
    }
}