diff options
| author | take_cheeze <[email protected]> | 2013-08-26 22:51:53 +0900 |
|---|---|---|
| committer | take_cheeze <[email protected]> | 2013-09-02 00:48:06 +0900 |
| commit | d12b6ab2187528828977ba1ea8b6f6fc9f6e42f2 (patch) | |
| tree | 9d3bbe7d7c8d7beede1ce6841c56e35b7a9fe781 | |
| parent | d19d9bb047a8b63c79442d5713be9205cf74c60c (diff) | |
| download | mruby-d12b6ab2187528828977ba1ea8b6f6fc9f6e42f2.tar.gz mruby-d12b6ab2187528828977ba1ea8b6f6fc9f6e42f2.zip | |
add verbose_backtrace
| -rw-r--r-- | include/mruby.h | 1 | ||||
| -rw-r--r-- | src/backtrace.c | 34 | ||||
| -rw-r--r-- | src/class.c | 5 | ||||
| -rw-r--r-- | src/error.c | 2 | ||||
| -rw-r--r-- | test/t/exception.rb | 10 |
5 files changed, 44 insertions, 8 deletions
diff --git a/include/mruby.h b/include/mruby.h index 88546dd6d..0541bc709 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -323,6 +323,7 @@ void mrb_name_error(mrb_state *mrb, mrb_sym id, const char *fmt, ...); void mrb_warn(mrb_state *mrb, const char *fmt, ...); void mrb_bug(mrb_state *mrb, const char *fmt, ...); void mrb_print_backtrace(mrb_state *mrb); +void mrb_print_verbose_backtrace(mrb_state *mrb); void mrb_print_error(mrb_state *mrb); /* macros to get typical exception objects diff --git a/src/backtrace.c b/src/backtrace.c index 6092aaf86..cee2c9389 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -55,7 +55,7 @@ get_backtrace_i(mrb_state *mrb, void *stream, int level, const char *format, ... } static void -mrb_output_backtrace(mrb_state *mrb, struct RObject *exc, output_stream_func func, void *stream) +mrb_output_backtrace(mrb_state *mrb, struct RObject *exc, output_stream_func func, void *stream, mrb_bool verbose) { mrb_callinfo *ci; mrb_int ciidx; @@ -72,10 +72,10 @@ mrb_output_backtrace(mrb_state *mrb, struct RObject *exc, output_stream_func fun filename = "(unknown)"; line = -1; - if (MRB_PROC_CFUNC_P(ci->proc)) { + if (!verbose && MRB_PROC_CFUNC_P(ci->proc)) { continue; } - else { + if(!MRB_PROC_CFUNC_P(ci->proc)) { mrb_irep *irep = ci->proc->body.irep; if (irep->filename != NULL) filename = irep->filename; @@ -93,13 +93,16 @@ mrb_output_backtrace(mrb_state *mrb, struct RObject *exc, output_stream_func fun } } } - if (line == -1) continue; + if (!verbose && line == -1) continue; if (ci->target_class == ci->proc->target_class) sep = "."; else sep = "#"; method = mrb_sym2name(mrb, ci->mid); + if (verbose && !method && ci->proc->env) { + method = mrb_sym2name(mrb, ci->proc->env->mid); + } if (method) { const char *cn = mrb_class_name(mrb, ci->proc->target_class); @@ -126,7 +129,15 @@ void mrb_print_backtrace(mrb_state *mrb) { #ifdef ENABLE_STDIO - mrb_output_backtrace(mrb, mrb->exc, print_backtrace_i, (void*)stderr); + mrb_output_backtrace(mrb, mrb->exc, print_backtrace_i, (void*)stderr, 0); +#endif +} + +void +mrb_print_verbose_backtrace(mrb_state *mrb) +{ +#ifdef ENABLE_STDIO + mrb_output_backtrace(mrb, mrb->exc, print_backtrace_i, (void*)stderr, 1); #endif } @@ -136,7 +147,18 @@ mrb_get_backtrace(mrb_state *mrb, mrb_value self) mrb_value ary; ary = mrb_ary_new(mrb); - mrb_output_backtrace(mrb, mrb_obj_ptr(self), get_backtrace_i, (void*)mrb_ary_ptr(ary)); + mrb_output_backtrace(mrb, mrb_obj_ptr(self), get_backtrace_i, (void*)mrb_ary_ptr(ary), 0); + + return ary; +} + +mrb_value +mrb_get_verbose_backtrace(mrb_state *mrb, mrb_value self) +{ + mrb_value ary; + + ary = mrb_ary_new(mrb); + mrb_output_backtrace(mrb, mrb_obj_ptr(self), get_backtrace_i, (void*)mrb_ary_ptr(ary), 1); return ary; } diff --git a/src/class.c b/src/class.c index 1870b94ba..e04aa5ce8 100644 --- a/src/class.c +++ b/src/class.c @@ -55,7 +55,7 @@ mrb_name_class(mrb_state *mrb, struct RClass *c, mrb_sym name) mrb_obj_iv_set(mrb, (struct RObject*)c, mrb_intern2(mrb, "__classid__", 11), mrb_symbol_value(name)); } - + #define make_metaclass(mrb, c) prepare_singleton_class((mrb), (struct RBasic*)(c)) static void @@ -311,6 +311,7 @@ mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t f int ai = mrb_gc_arena_save(mrb); p = mrb_proc_new_cfunc(mrb, func); + p->target_class = c; mrb_define_method_raw(mrb, c, mid, p); mrb_gc_arena_restore(mrb, ai); } @@ -1065,7 +1066,7 @@ mrb_class_new_class(mrb_state *mrb, mrb_value cv) { mrb_value super; struct RClass *new_class; - + if (mrb_get_args(mrb, "|o", &super) == 0) { super = mrb_obj_value(mrb->object_class); } diff --git a/src/error.c b/src/error.c index 03f587a38..f7d41c2e2 100644 --- a/src/error.c +++ b/src/error.c @@ -436,6 +436,7 @@ mrb_sys_fail(mrb_state *mrb, const char *mesg) } mrb_value mrb_get_backtrace(mrb_state*, mrb_value); +mrb_value mrb_get_verbose_backtrace(mrb_state*, mrb_value); void mrb_init_exception(mrb_state *mrb) @@ -451,6 +452,7 @@ mrb_init_exception(mrb_state *mrb) mrb_define_method(mrb, e, "message", exc_message, MRB_ARGS_NONE()); mrb_define_method(mrb, e, "inspect", exc_inspect, MRB_ARGS_NONE()); mrb_define_method(mrb, e, "backtrace", mrb_get_backtrace, MRB_ARGS_NONE()); + mrb_define_method(mrb, e, "verbose_backtrace", mrb_get_verbose_backtrace, MRB_ARGS_NONE()); mrb->eStandardError_class = mrb_define_class(mrb, "StandardError", mrb->eException_class); /* 15.2.23 */ mrb_define_class(mrb, "RuntimeError", mrb->eStandardError_class); /* 15.2.28 */ diff --git a/test/t/exception.rb b/test/t/exception.rb index 4239cba8b..ef5b284a5 100644 --- a/test/t/exception.rb +++ b/test/t/exception.rb @@ -345,3 +345,13 @@ assert('Exception#backtrace') do true end + +assert('Exception#verbose_backtrace') do + begin + raise "get backtrace" + rescue => e + e.verbose_backtrace + end + + true +end |
