void mrb_exc_set(mrb_state *mrb, mrb_value exc) { if (!mrb->gc.out_of_memory && mrb->backtrace.n > 0) { mrb_value target_exc = mrb_nil_value(); int ai; ai = mrb_gc_arena_save(mrb); if ((mrb->exc && !have_backtrace(mrb, mrb->exc))) { target_exc = mrb_obj_value(mrb->exc); } else if (!mrb_nil_p(exc) && mrb->backtrace.exc) { target_exc = mrb_obj_value(mrb->backtrace.exc); mrb_gc_protect(mrb, target_exc); } if (!mrb_nil_p(target_exc)) { mrb_value backtrace; backtrace = mrb_restore_backtrace(mrb); set_backtrace(mrb, target_exc, backtrace); } mrb_gc_arena_restore(mrb, ai); } mrb->backtrace.n = 0; if (mrb_nil_p(exc)) { mrb->exc = 0; } else { if (!mrb_obj_is_kind_of(mrb, exc, mrb->eException_class)) mrb_raise(mrb, E_TYPE_ERROR, "exception object expected"); mrb->exc = mrb_obj_ptr(exc); } }
void mrb_exc_set(mrb_state *mrb, mrb_value exc) { if (!mrb->gc.out_of_memory && mrb->backtrace.n > 0) { mrb_value target_exc = mrb_nil_value(); if ((mrb->exc && !have_backtrace(mrb, mrb->exc))) { target_exc = mrb_obj_value(mrb->exc); } else if (!mrb_nil_p(exc) && mrb_obj_ptr(exc) == mrb->backtrace.exc) { target_exc = exc; } if (!mrb_nil_p(target_exc)) { mrb_value backtrace; backtrace = mrb_restore_backtrace(mrb); set_backtrace(mrb, target_exc, backtrace); } } mrb->backtrace.n = 0; if (mrb_nil_p(exc)) { mrb->exc = 0; } else { mrb->exc = mrb_obj_ptr(exc); } }
static mrb_value exc_get_backtrace(mrb_state *mrb, mrb_value exc) { mrb_sym attr_name; mrb_value backtrace; attr_name = mrb_intern_lit(mrb, "backtrace"); backtrace = mrb_iv_get(mrb, exc, attr_name); if (mrb_nil_p(backtrace)) { if (mrb_obj_ptr(exc) == mrb->backtrace.exc && mrb->backtrace.n > 0) { backtrace = mrb_restore_backtrace(mrb); mrb->backtrace.n = 0; mrb->backtrace.exc = 0; } else { backtrace = mrb_exc_backtrace(mrb, exc); } mrb_iv_set(mrb, exc, attr_name, backtrace); } return backtrace; }