diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/codegen.c | 7 | ||||
| -rw-r--r-- | src/error.c | 56 |
2 files changed, 54 insertions, 9 deletions
diff --git a/src/codegen.c b/src/codegen.c index 6197da33e..6dcc747c3 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -2074,6 +2074,9 @@ scope_finish(codegen_scope *s, int idx) irep->syms = (mrb_sym *)codegen_realloc(s, s->syms, sizeof(mrb_sym)*s->slen); irep->slen = s->slen; } + if (s->filename) { + irep->filename = s->filename; + } irep->nlocals = s->nlocals; irep->nregs = s->nregs; @@ -2479,12 +2482,12 @@ codegen_start(mrb_state *mrb, parser_state *p) scope->filename = s; } if (setjmp(scope->jmp) != 0) { - if (scope->filename) mrb_free(mrb, scope->filename); + //if (scope->filename) mrb_free(mrb, scope->filename); return -1; } // prepare irep codegen(scope, p->tree, NOVAL); - if (scope->filename) mrb_free(mrb, scope->filename); + // if (scope->filename) mrb_free(mrb, scope->filename); mrb_pool_close(scope->mpool); return 0; } diff --git a/src/error.c b/src/error.c index 412a63d3e..444a088c9 100644 --- a/src/error.c +++ b/src/error.c @@ -13,6 +13,8 @@ #include "mruby/variable.h" #include "mruby/string.h" #include "mruby/class.h" +#include "mruby/proc.h" +#include "mruby/irep.h" #define warn_printf printf @@ -121,14 +123,32 @@ exc_message(mrb_state *mrb, mrb_value exc) static mrb_value exc_inspect(mrb_state *mrb, mrb_value exc) { - mrb_value str; - - str = mrb_str_new2(mrb, mrb_obj_classname(mrb, exc)); - exc = mrb_obj_as_string(mrb, exc); - - if (RSTRING_LEN(exc) > 0) { + mrb_value str, mesg, file, line; + + mesg = mrb_attr_get(mrb, exc, mrb_intern(mrb, "mesg")); + file = mrb_attr_get(mrb, exc, mrb_intern(mrb, "file")); + line = mrb_attr_get(mrb, exc, mrb_intern(mrb, "line")); + + if (!mrb_nil_p(file) && !mrb_nil_p(line)) { + str = file; + mrb_str_cat2(mrb, str, ":"); + mrb_str_append(mrb, str, line); mrb_str_cat2(mrb, str, ": "); - mrb_str_append(mrb, str, exc); + if (RSTRING_LEN(mesg) > 0) { + mrb_str_append(mrb, str, mesg); + mrb_str_cat2(mrb, str, " ("); + } + mrb_str_cat2(mrb, str, mrb_obj_classname(mrb, exc)); + if (RSTRING_LEN(mesg) > 0) { + mrb_str_cat2(mrb, str, ")"); + } + } + else { + str = mrb_str_new2(mrb, mrb_obj_classname(mrb, exc)); + if (RSTRING_LEN(mesg) > 0) { + mrb_str_cat2(mrb, str, ": "); + mrb_str_append(mrb, str, mesg); + } } return str; } @@ -160,10 +180,32 @@ exc_equal(mrb_state *mrb, mrb_value exc) return mrb_true_value(); } +static void +exc_debug_info(mrb_state *mrb, struct RObject *exc) +{ + mrb_callinfo *ci = mrb->ci; + mrb_code *pc = ci->pc; + + while (ci >= mrb->cibase) { + if (!pc && ci->pc) pc = ci->pc; + if (ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) { + mrb_irep *irep = ci->proc->body.irep; + + if (irep->lines && irep->iseq <= pc && pc < irep->iseq + irep->ilen) { + mrb_obj_iv_set(mrb, exc, mrb_intern(mrb, "file"), mrb_str_new_cstr(mrb, irep->filename)); + mrb_obj_iv_set(mrb, exc, mrb_intern(mrb, "line"), mrb_fixnum_value(irep->lines[pc - irep->iseq - 1])); + return; + } + } + ci--; + } +} + void mrb_exc_raise(mrb_state *mrb, mrb_value exc) { mrb->exc = (struct RObject*)mrb_object(exc); + exc_debug_info(mrb, mrb->exc); if (!mrb->jmp) { abort(); } |
