diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-05-26 21:29:04 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-05-26 22:30:27 +0900 |
| commit | 54b45f6a1b4c14906c76da9f6a7ebb8f03cf90ea (patch) | |
| tree | bc2ebda20e2f865140b5e802c15792d7f7cd3f34 /src/backtrace.c | |
| parent | f269d1eb4009877765298242754b428a241f642b (diff) | |
| download | mruby-54b45f6a1b4c14906c76da9f6a7ebb8f03cf90ea.tar.gz mruby-54b45f6a1b4c14906c76da9f6a7ebb8f03cf90ea.zip | |
Use RData instead of String to represent backtrace.
Diffstat (limited to 'src/backtrace.c')
| -rw-r--r-- | src/backtrace.c | 34 |
1 files changed, 15 insertions, 19 deletions
diff --git a/src/backtrace.c b/src/backtrace.c index 17b4d0968..ea88aca9f 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -13,6 +13,7 @@ #include <mruby/debug.h> #include <mruby/error.h> #include <mruby/numeric.h> +#include <mruby/data.h> struct backtrace_location { int lineno; @@ -22,6 +23,8 @@ struct backtrace_location { typedef void (*each_backtrace_func)(mrb_state*, int i, struct backtrace_location*, void*); +static const mrb_data_type bt_type = { "Backtrace", mrb_free }; + static void each_backtrace(mrb_state *mrb, mrb_int ciidx, mrb_code *pc0, each_backtrace_func func, void *data) { @@ -102,14 +105,11 @@ print_packed_backtrace(mrb_state *mrb, mrb_value packed) struct backtrace_location *bt; mrb_int n, i; - if (!mrb_string_p(packed)) { - broken: + bt = (struct backtrace_location*)mrb_data_check_get_ptr(mrb, packed, &bt_type); + if (bt == NULL) { mrb_raise(mrb, E_RUNTIME_ERROR, "broken backtrace"); } - n = RSTRING_LEN(packed); - if (n%sizeof(struct backtrace_location) != 0) goto broken; - n /= sizeof(struct backtrace_location); - bt = (struct backtrace_location*)RSTRING_PTR(packed); + n = (mrb_int)RDATA(packed)->flags; fprintf(stream, "trace:\n"); for (i = 0; i < n; i++) { @@ -169,16 +169,17 @@ pack_backtrace_i(mrb_state *mrb, static mrb_value packed_backtrace(mrb_state *mrb) { - mrb_value backtrace; + struct RData *backtrace; mrb_int ciidx = mrb->c->ci - mrb->c->cibase; mrb_int len = (ciidx+1)*sizeof(struct backtrace_location); - char *ptr; + void *ptr; - backtrace = mrb_str_new(mrb, NULL, len); - ptr = RSTRING_PTR(backtrace); + ptr = mrb_malloc(mrb, len); memset(ptr, 0, len); + backtrace = mrb_data_object_alloc(mrb, NULL, ptr, &bt_type); + backtrace->flags = (unsigned int)ciidx+1; each_backtrace(mrb, ciidx, mrb->c->ci->pc, pack_backtrace_i, ptr); - return backtrace; + return mrb_obj_value(backtrace); } void @@ -195,21 +196,16 @@ mrb_keep_backtrace(mrb_state *mrb, mrb_value exc) mrb_value mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace) { - mrb_value str; struct backtrace_location *bt; mrb_int n, i; if (mrb_nil_p(backtrace)) return mrb_ary_new_capa(mrb, 0); if (mrb_array_p(backtrace)) return backtrace; - if (!mrb_string_p(backtrace)) { - broken: + bt = (struct backtrace_location*)mrb_data_check_get_ptr(mrb, backtrace, &bt_type); + if (bt == NULL) { mrb_raise(mrb, E_RUNTIME_ERROR, "broken backtrace"); } - str = backtrace; - n = RSTRING_LEN(str); - if (n%sizeof(struct backtrace_location) != 0) goto broken; - n /= sizeof(struct backtrace_location); - bt = (struct backtrace_location*)RSTRING_PTR(str); + n = (mrb_int)RDATA(backtrace)->flags; backtrace = mrb_ary_new_capa(mrb, n); for (i = 0; i < n; i++) { int ai = mrb_gc_arena_save(mrb); |
