diff options
| -rw-r--r-- | src/error.c | 9 | ||||
| -rw-r--r-- | src/gc.c | 5 |
2 files changed, 12 insertions, 2 deletions
diff --git a/src/error.c b/src/error.c index 14e4ab4d3..13032b136 100644 --- a/src/error.c +++ b/src/error.c @@ -255,17 +255,22 @@ 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_obj_ptr(exc) == mrb->backtrace.exc) { - target_exc = 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; @@ -695,8 +695,13 @@ obj_free(mrb_state *mrb, struct RBasic *obj) #endif case MRB_TT_OBJECT: + mrb_gc_free_iv(mrb, (struct RObject*)obj); + break; + case MRB_TT_EXCEPTION: mrb_gc_free_iv(mrb, (struct RObject*)obj); + if ((struct RObject*)obj == mrb->backtrace.exc) + mrb->backtrace.exc = 0; break; case MRB_TT_CLASS: |
