diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-05-23 23:41:12 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-05-23 23:50:42 +0900 |
| commit | 9644ad51b4a63d8db46d7918ec5e89a547236c56 (patch) | |
| tree | 12c3265c8c71d9b26ff544f2e0f0768bc64cf7c7 /src/error.c | |
| parent | d2458e66c26bac5e9db98c22dc6910cb45971b85 (diff) | |
| download | mruby-9644ad51b4a63d8db46d7918ec5e89a547236c56.tar.gz mruby-9644ad51b4a63d8db46d7918ec5e89a547236c56.zip | |
Simplify backtrace mechanism; fix #3633 #3634 #3644
Instead of preserving a backtrace in `mrb_state`, `mrb_exc_set`
keeps packed backtrace in an exception object. `#backtrace` unpacks
it to an array of strings.
Diffstat (limited to 'src/error.c')
| -rw-r--r-- | src/error.c | 44 |
1 files changed, 4 insertions, 40 deletions
diff --git a/src/error.c b/src/error.c index 5bb547afe..b71c718e2 100644 --- a/src/error.c +++ b/src/error.c @@ -163,8 +163,8 @@ exc_inspect(mrb_state *mrb, mrb_value exc) return str; } -void mrb_save_backtrace(mrb_state *mrb); -mrb_value mrb_restore_backtrace(mrb_state *mrb); +void mrb_keep_backtrace(mrb_state *mrb, mrb_value exc); +mrb_value mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace); static mrb_value exc_get_backtrace(mrb_state *mrb, mrb_value exc) @@ -175,17 +175,9 @@ exc_get_backtrace(mrb_state *mrb, mrb_value exc) attr_name = mrb_intern_lit(mrb, "backtrace"); backtrace = mrb_iv_get(mrb, exc, attr_name); if (!mrb_array_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); - } + backtrace = mrb_unpack_backtrace(mrb, backtrace); mrb_iv_set(mrb, exc, attr_name, backtrace); } - return backtrace; } @@ -224,7 +216,6 @@ exc_debug_info(mrb_state *mrb, struct RObject *exc) mrb_callinfo *ci = mrb->c->ci; mrb_code *pc = ci->pc; - mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "ciidx"), mrb_fixnum_value((mrb_int)(ci - mrb->c->cibase))); while (ci >= mrb->c->cibase) { mrb_code *err = ci->err; @@ -245,36 +236,9 @@ exc_debug_info(mrb_state *mrb, struct RObject *exc) } } -static mrb_bool -have_backtrace(mrb_state *mrb, struct RObject *exc) -{ - return !mrb_nil_p(mrb_obj_iv_get(mrb, exc, mrb_intern_lit(mrb, "backtrace"))); -} - 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; } @@ -282,7 +246,7 @@ mrb_exc_set(mrb_state *mrb, mrb_value exc) mrb->exc = mrb_obj_ptr(exc); if (!mrb->gc.out_of_memory) { exc_debug_info(mrb, mrb->exc); - mrb_save_backtrace(mrb); + mrb_keep_backtrace(mrb, exc); } } } |
