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
/* Throws the specified exception object, taking the category from it. If
 * the handler resumes, the resumption result will be put into resume_result.
 * Leaves the interpreter in a state where it will next run the instruction of
 * the handler. If there is no handler, it will panic and exit with a backtrace. */
void MVM_exception_throwobj(MVMThreadContext *tc, MVMuint8 mode, MVMObject *exObj, MVMRegister *resume_result) {
    LocatedHandler  lh;
    MVMException   *ex;
    
    if (IS_CONCRETE(exObj) && REPR(exObj)->ID == MVM_REPR_ID_MVMException)
        ex = (MVMException *)exObj;
    else
        MVM_exception_throw_adhoc(tc, "Can only throw an exception object");
    
    lh = search_for_handler_from(tc, tc->cur_frame, mode, ex->body.category);
    if (lh.frame == NULL)
        panic_unhandled_ex(tc, ex);
    run_handler(tc, lh, exObj);
}
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
/* Throws an exception by category, searching for a handler according to
 * the specified mode. If the handler resumes, the resumption result will
 * be put into resume_result. Leaves the interpreter in a state where it
 * will next run the instruction of the handler. If there is no handler,
 * it will panic and exit with a backtrace. */
void MVM_exception_throwcat(MVMThreadContext *tc, MVMuint8 mode, MVMuint32 cat, MVMRegister *resume_result) {
    LocatedHandler lh = search_for_handler_from(tc, tc->cur_frame, mode, cat);
    if (lh.frame == NULL)
        panic_unhandled_cat(tc, cat);
    run_handler(tc, lh, NULL);
}
Ejemplo n.º 5
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);
    }
}