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