void mrb_objspace_each_objects(mrb_state *mrb, mrb_each_object_callback *callback, void *data) { mrb_bool iterating = mrb->gc.iterating; mrb->gc.iterating = TRUE; if (iterating) { gc_each_objects(mrb, &mrb->gc, callback, data); } else { struct mrb_jmpbuf *prev_jmp = mrb->jmp; struct mrb_jmpbuf c_jmp; MRB_TRY(&c_jmp) { mrb->jmp = &c_jmp; gc_each_objects(mrb, &mrb->gc, callback, data); mrb->jmp = prev_jmp; mrb->gc.iterating = iterating; } MRB_CATCH(&c_jmp) { mrb->gc.iterating = iterating; mrb->jmp = prev_jmp; MRB_THROW(prev_jmp); } MRB_END_EXC(&c_jmp); } }
MRB_API mrb_value mrb_rescue_exceptions(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_func_t rescue, mrb_value r_data, mrb_int len, struct RClass **classes) { struct mrb_jmpbuf *prev_jmp = mrb->jmp; struct mrb_jmpbuf c_jmp; mrb_value result; mrb_bool error_matched = FALSE; mrb_int i; MRB_TRY(&c_jmp) { mrb->jmp = &c_jmp; result = body(mrb, b_data); mrb->jmp = prev_jmp; } MRB_CATCH(&c_jmp) { mrb->jmp = prev_jmp; for (i = 0; i < len; ++i) { if (mrb_obj_is_kind_of(mrb, mrb_obj_value(mrb->exc), classes[i])) { error_matched = TRUE; break; } } if (!error_matched) { MRB_THROW(mrb->jmp); } mrb->exc = NULL; result = rescue(mrb, r_data); } MRB_END_EXC(&c_jmp); mrb_gc_protect(mrb, result); return result; }
void mrb_exc_raise(mrb_state *mrb, mrb_value exc) { mrb->m_exc = exc.object_ptr(); exc_debug_info(mrb, mrb->m_exc); if (!mrb->jmp) { mrb_p(mrb, exc); abort(); } MRB_THROW(mrb->jmp); }
MRB_API mrb_noreturn void mrb_exc_raise(mrb_state *mrb, mrb_value exc) { mrb->exc = mrb_obj_ptr(exc); if (!mrb->out_of_memory) { exc_debug_info(mrb, mrb->exc); } if (!mrb->jmp) { mrb_p(mrb, exc); abort(); } MRB_THROW(mrb->jmp); }
MRB_API mrb_noreturn void mrb_exc_raise(mrb_state *mrb, mrb_value exc) { mrb_exc_set(mrb, exc); if (!mrb->gc.out_of_memory) { exc_debug_info(mrb, mrb->exc); mrb_save_backtrace(mrb); } if (!mrb->jmp) { mrb_p(mrb, exc); abort(); } MRB_THROW(mrb->jmp); }
MRB_API mrb_value mrb_ensure(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_func_t ensure, mrb_value e_data) { struct mrb_jmpbuf *prev_jmp = mrb->jmp; struct mrb_jmpbuf c_jmp; mrb_value result; MRB_TRY(&c_jmp) { mrb->jmp = &c_jmp; result = body(mrb, b_data); mrb->jmp = prev_jmp; } MRB_CATCH(&c_jmp) { mrb->jmp = prev_jmp; ensure(mrb, e_data); MRB_THROW(mrb->jmp); /* rethrow catched exceptions */ } MRB_END_EXC(&c_jmp); ensure(mrb, e_data); mrb_gc_protect(mrb, result); return result; }
static void mrb_wslay_event_on_msg_recv_callback(wslay_event_context_ptr ctx, const struct wslay_event_on_msg_recv_arg *arg, void *user_data) { mrb_wslay_user_data *data = (mrb_wslay_user_data *) user_data; mrb_state *mrb = data->mrb; int ai = mrb_gc_arena_save(mrb); struct mrb_jmpbuf *prev_jmp = mrb->jmp; struct mrb_jmpbuf c_jmp; MRB_TRY(&c_jmp) { mrb->jmp = &c_jmp; mrb_value argv[4]; argv[0] = mrb_fixnum_value(arg->rsv); argv[1] = MRB_GET_OPCODE(mrb_fixnum_value(arg->opcode)); argv[2] = mrb_str_new(mrb, (const char *) arg->msg, arg->msg_length); argv[3] = MRB_GET_STATUSCODE(mrb_fixnum_value(arg->status_code)); mrb_value on_msg_recv_arg = mrb_obj_new(mrb, mrb_class_get_under(mrb, mrb_module_get_under(mrb, mrb_module_get(mrb, "Wslay"), "Event"), "OnMsgRecvArg"), NELEMS(argv), argv); mrb_assert(mrb_type(data->on_msg_recv_callback) == MRB_TT_PROC); mrb_yield(mrb, data->on_msg_recv_callback, on_msg_recv_arg); mrb_gc_arena_restore(mrb, ai); mrb->jmp = prev_jmp; } MRB_CATCH(&c_jmp) { mrb->jmp = prev_jmp; wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE); mrb_gc_arena_restore(mrb, ai); MRB_THROW(mrb->jmp); } MRB_END_EXC(&c_jmp); }