Ignore:
Timestamp:
Jul 9, 2020, 8:51:43 AM (4 years ago)
Author:
coas-nagasima
Message:

mrubyを2.1.1に更新

Location:
EcnlProtoTool/trunk/mruby-2.1.1
Files:
1 edited
1 moved

Legend:

Unmodified
Added
Removed
  • EcnlProtoTool/trunk/mruby-2.1.1/src/backtrace.c

    r331 r439  
    1717
    1818struct backtrace_location {
    19   int lineno;
     19  int32_t lineno;
     20  mrb_sym method_id;
    2021  const char *filename;
    21   mrb_sym method_id;
    2222};
    2323
    24 typedef void (*each_backtrace_func)(mrb_state*, int i, struct backtrace_location*, void*);
     24typedef void (*each_backtrace_func)(mrb_state*, const struct backtrace_location*, void*);
    2525
    2626static const mrb_data_type bt_type = { "Backtrace", mrb_free };
    2727
    28 static void
    29 each_backtrace(mrb_state *mrb, mrb_int ciidx, mrb_code *pc0, each_backtrace_func func, void *data)
    30 {
    31   int i, j;
     28mrb_value mrb_exc_inspect(mrb_state *mrb, mrb_value exc);
     29mrb_value mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace);
     30
     31static void
     32each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, const mrb_code *pc0, each_backtrace_func func, void *data)
     33{
     34  ptrdiff_t i;
    3235
    3336  if (ciidx >= mrb->c->ciend - mrb->c->cibase)
    3437    ciidx = 10; /* ciidx is broken... */
    3538
    36   for (i=ciidx, j=0; i >= 0; i--,j++) {
     39  for (i=ciidx; i >= 0; i--) {
    3740    struct backtrace_location loc;
    3841    mrb_callinfo *ci;
    3942    mrb_irep *irep;
    40     mrb_code *pc;
     43    const mrb_code *pc;
    4144
    4245    ci = &mrb->c->cibase[i];
     
    5255    }
    5356    else if (i+1 <= ciidx) {
    54       pc = mrb->c->cibase[i+1].pc - 1;
     57      if (!mrb->c->cibase[i + 1].pc) continue;
     58      pc = &mrb->c->cibase[i+1].pc[-1];
    5559    }
    5660    else {
    5761      pc = pc0;
    5862    }
    59     loc.filename = mrb_debug_get_filename(irep, (uint32_t)(pc - irep->iseq));
    60     loc.lineno = mrb_debug_get_line(irep, (uint32_t)(pc - irep->iseq));
    61 
     63
     64    loc.lineno = mrb_debug_get_line(mrb, irep, pc - irep->iseq);
    6265    if (loc.lineno == -1) continue;
    6366
     67    loc.filename = mrb_debug_get_filename(mrb, irep, pc - irep->iseq);
    6468    if (!loc.filename) {
    6569      loc.filename = "(unknown)";
     
    6771
    6872    loc.method_id = ci->mid;
    69     func(mrb, j, &loc, data);
     73    func(mrb, &loc, data);
    7074  }
    7175}
     
    7478
    7579static void
    76 print_backtrace(mrb_state *mrb, mrb_value backtrace)
    77 {
    78   int i, n;
     80print_backtrace(mrb_state *mrb, struct RObject *exc, mrb_value backtrace)
     81{
     82  mrb_int i;
     83  mrb_int n = RARRAY_LEN(backtrace);
     84  mrb_value *loc, mesg;
    7985  FILE *stream = stderr;
    8086
    81   if (!mrb_array_p(backtrace)) return;
    82   fprintf(stream, "trace:\n");
    83 
    84   n = RARRAY_LEN(backtrace);
    85   for (i=0; n--; i++) {
    86     mrb_value entry = RARRAY_PTR(backtrace)[n];
    87 
    88     if (mrb_string_p(entry)) {
    89       fprintf(stream, "\t[%d] %.*s\n", i, (int)RSTRING_LEN(entry), RSTRING_PTR(entry));
    90     }
    91   }
    92 }
    93 
    94 static void
    95 print_packed_backtrace(mrb_state *mrb, mrb_value packed)
    96 {
    97   FILE *stream = stderr;
    98   struct backtrace_location *bt;
    99   int n, i;
    100 
    101   bt = (struct backtrace_location*)mrb_data_check_get_ptr(mrb, packed, &bt_type);
    102   if (bt == NULL) {
    103     mrb_raise(mrb, E_RUNTIME_ERROR, "broken backtrace");
    104   }
    105   n = (mrb_int)RDATA(packed)->flags;
    106 
    107   fprintf(stream, "trace:\n");
    108   for (i = 0; n--; i++) {
    109     int ai = mrb_gc_arena_save(mrb);
    110     struct backtrace_location *entry = &bt[n];
    111     if (entry->filename == NULL) continue;
    112     fprintf(stream, "\t[%d] %s:%d", (int)i, entry->filename, entry->lineno);
    113     if (entry->method_id != 0) {
    114       const char *method_name;
    115 
    116       method_name = mrb_sym2name(mrb, entry->method_id);
    117       fprintf(stream, ":in %s", method_name);
    118       mrb_gc_arena_restore(mrb, ai);
    119     }
    120     fprintf(stream, "\n");
    121   }
     87  if (n != 0) {
     88    fprintf(stream, "trace (most recent call last):\n");
     89    for (i=n-1,loc=&RARRAY_PTR(backtrace)[i]; i>0; i--,loc--) {
     90      if (mrb_string_p(*loc)) {
     91        fprintf(stream, "\t[%d] %.*s\n",
     92                (int)i, (int)RSTRING_LEN(*loc), RSTRING_PTR(*loc));
     93      }
     94    }
     95    if (mrb_string_p(*loc)) {
     96      fprintf(stream, "%.*s: ", (int)RSTRING_LEN(*loc), RSTRING_PTR(*loc));
     97    }
     98  }
     99  mesg = mrb_exc_inspect(mrb, mrb_obj_value(exc));
     100  fprintf(stream, "%.*s\n", (int)RSTRING_LEN(mesg), RSTRING_PTR(mesg));
    122101}
    123102
     
    138117  backtrace = mrb_obj_iv_get(mrb, mrb->exc, mrb_intern_lit(mrb, "backtrace"));
    139118  if (mrb_nil_p(backtrace)) return;
    140   if (mrb_array_p(backtrace)) {
    141     print_backtrace(mrb, backtrace);
    142   }
    143   else {
    144     print_packed_backtrace(mrb, backtrace);
    145   }
     119  if (!mrb_array_p(backtrace)) backtrace = mrb_unpack_backtrace(mrb, backtrace);
     120  print_backtrace(mrb, mrb->exc, backtrace);
    146121}
    147122#else
     
    155130
    156131static void
     132count_backtrace_i(mrb_state *mrb,
     133                 const struct backtrace_location *loc,
     134                 void *data)
     135{
     136  int *lenp = (int*)data;
     137
     138  (*lenp)++;
     139}
     140
     141static void
    157142pack_backtrace_i(mrb_state *mrb,
    158                  int i,
    159                  struct backtrace_location *loc,
     143                 const struct backtrace_location *loc,
    160144                 void *data)
    161145{
    162   struct backtrace_location *entry = (struct backtrace_location*)data;
    163 
    164   entry[i] = *loc;
     146  struct backtrace_location **pptr = (struct backtrace_location**)data;
     147  struct backtrace_location *ptr = *pptr;
     148
     149  *ptr = *loc;
     150  *pptr = ptr+1;
    165151}
    166152
     
    170156  struct RData *backtrace;
    171157  ptrdiff_t ciidx = mrb->c->ci - mrb->c->cibase;
    172   mrb_int len = (ciidx+1)*sizeof(struct backtrace_location);
     158  int len = 0;
     159  int size;
    173160  void *ptr;
    174161
    175   ptr = mrb_malloc(mrb, len);
    176   memset(ptr, 0, len);
     162  each_backtrace(mrb, ciidx, mrb->c->ci->pc, count_backtrace_i, &len);
     163  size = len * sizeof(struct backtrace_location);
     164  ptr = mrb_malloc(mrb, size);
    177165  backtrace = mrb_data_object_alloc(mrb, NULL, ptr, &bt_type);
    178   backtrace->flags = (unsigned int)ciidx+1;
    179   each_backtrace(mrb, ciidx, mrb->c->ci->pc, pack_backtrace_i, ptr);
     166  backtrace->flags = (uint32_t)len;
     167  each_backtrace(mrb, ciidx, mrb->c->ci->pc, pack_backtrace_i, &ptr);
    180168  return mrb_obj_value(backtrace);
    181169}
     
    184172mrb_keep_backtrace(mrb_state *mrb, mrb_value exc)
    185173{
     174  mrb_sym sym = mrb_intern_lit(mrb, "backtrace");
    186175  mrb_value backtrace;
    187   int ai = mrb_gc_arena_save(mrb);
    188 
     176  int ai;
     177
     178  if (mrb_iv_defined(mrb, exc, sym)) return;
     179  ai = mrb_gc_arena_save(mrb);
    189180  backtrace = packed_backtrace(mrb);
    190   mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "backtrace"), backtrace);
     181  mrb_iv_set(mrb, exc, sym, backtrace);
    191182  mrb_gc_arena_restore(mrb, ai);
    192183}
     
    195186mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace)
    196187{
    197   struct backtrace_location *bt;
     188  const struct backtrace_location *bt;
    198189  mrb_int n, i;
    199 
    200   if (mrb_nil_p(backtrace)) return mrb_ary_new_capa(mrb, 0);
     190  int ai;
     191
     192  if (mrb_nil_p(backtrace)) {
     193  empty_backtrace:
     194    return mrb_ary_new_capa(mrb, 0);
     195  }
    201196  if (mrb_array_p(backtrace)) return backtrace;
    202197  bt = (struct backtrace_location*)mrb_data_check_get_ptr(mrb, backtrace, &bt_type);
    203   if (bt == NULL) {
    204     mrb_raise(mrb, E_RUNTIME_ERROR, "broken backtrace");
    205   }
     198  if (bt == NULL) goto empty_backtrace;
    206199  n = (mrb_int)RDATA(backtrace)->flags;
    207200  backtrace = mrb_ary_new_capa(mrb, n);
     201  ai = mrb_gc_arena_save(mrb);
    208202  for (i = 0; i < n; i++) {
    209     int ai = mrb_gc_arena_save(mrb);
    210     struct backtrace_location *entry = &bt[i];
     203    const struct backtrace_location *entry = &bt[i];
    211204    mrb_value btline;
    212205
    213     if (entry->filename == NULL) continue;
    214     btline = mrb_format(mrb, "%S:%S",
    215                               mrb_str_new_cstr(mrb, entry->filename),
    216                               mrb_fixnum_value(entry->lineno));
     206    btline = mrb_format(mrb, "%s:%d", entry->filename, (int)entry->lineno);
    217207    if (entry->method_id != 0) {
    218208      mrb_str_cat_lit(mrb, btline, ":in ");
    219       mrb_str_cat_cstr(mrb, btline, mrb_sym2name(mrb, entry->method_id));
     209      mrb_str_cat_cstr(mrb, btline, mrb_sym_name(mrb, entry->method_id));
    220210    }
    221211    mrb_ary_push(mrb, backtrace, btline);
Note: See TracChangeset for help on using the changeset viewer.