From a7c9a71684fccf8121f16803f8e3d758f0dea001 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 15 Oct 2013 12:49:41 +0900 Subject: better error position display --- src/backtrace.c | 13 ++++++++----- src/error.c | 12 +++++++----- src/vm.c | 9 ++++++++- 3 files changed, 23 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/backtrace.c b/src/backtrace.c index 4ad792a5e..54927ec00 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -77,18 +77,21 @@ mrb_output_backtrace(mrb_state *mrb, struct RObject *exc, output_stream_func fun if (MRB_PROC_CFUNC_P(ci->proc)) { continue; } - if(!MRB_PROC_CFUNC_P(ci->proc)) { + else { mrb_irep *irep = ci->proc->body.irep; mrb_code *pc; - if (i+1 <= ciidx) { - pc = mrb->c->cibase[i+1].pc; + if (mrb->c->cibase[i].err) { + pc = mrb->c->cibase[i].err; + } + else if (i+1 <= ciidx) { + pc = mrb->c->cibase[i+1].pc - 1; } else { pc = (mrb_code*)mrb_cptr(mrb_obj_iv_get(mrb, exc, mrb_intern2(mrb, "lastpc", 6))); } - filename = mrb_debug_get_filename(irep, pc - irep->iseq - 1); - line = mrb_debug_get_line(irep, pc - irep->iseq - 1); + filename = mrb_debug_get_filename(irep, pc - irep->iseq); + line = mrb_debug_get_line(irep, pc - irep->iseq); } if (line == -1) continue; if (ci->target_class == ci->proc->target_class) diff --git a/src/error.c b/src/error.c index 4ce2b4ade..10ba6170f 100644 --- a/src/error.c +++ b/src/error.c @@ -194,14 +194,16 @@ exc_debug_info(mrb_state *mrb, struct RObject *exc) mrb_code *pc = ci->pc; mrb_obj_iv_set(mrb, exc, mrb_intern2(mrb, "ciidx", 5), mrb_fixnum_value(ci - mrb->c->cibase)); - ci--; while (ci >= mrb->c->cibase) { - if (ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) { + mrb_code *err = ci->err; + + if (!err && pc) err = pc - 1; + if (err && ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) { mrb_irep *irep = ci->proc->body.irep; - int32_t const line = mrb_debug_get_line(irep, pc - irep->iseq - 1); - char const* file = mrb_debug_get_filename(irep, pc - irep->iseq - 1); - if(line != -1 && file) { + int32_t const line = mrb_debug_get_line(irep, err - irep->iseq); + char const* file = mrb_debug_get_filename(irep, err - irep->iseq); + if (line != -1 && file) { mrb_obj_iv_set(mrb, exc, mrb_intern2(mrb, "file", 4), mrb_str_new_cstr(mrb, file)); mrb_obj_iv_set(mrb, exc, mrb_intern2(mrb, "line", 4), mrb_fixnum_value(line)); return; diff --git a/src/vm.c b/src/vm.c index 534dfaa24..9b673cd0f 100644 --- a/src/vm.c +++ b/src/vm.c @@ -226,6 +226,8 @@ cipush(mrb_state *mrb) ci->eidx = eidx; ci->ridx = ridx; ci->env = 0; + ci->pc = 0; + return ci; } @@ -509,8 +511,9 @@ argnum_error(mrb_state *mrb, int num) mrb->exc = mrb_obj_ptr(exc); } +#define ERR_PC_HOOK(mrb, pc) mrb->c->ci->err = pc; #ifdef ENABLE_DEBUG -#define CODE_FETCH_HOOK(mrb, irep, pc, regs) if ((mrb)->code_fetch_hook) (mrb)->code_fetch_hook((mrb), (irep), (pc), (regs)); +#define CODE_FETCH_HOOK(mrb, irep, pc, regs) if ((mrb)->code_fetch_hook) (mrb)->code_fetch_hook((mrb), (irep), (pc), (regs)); #else #define CODE_FETCH_HOOK(mrb, irep, pc, regs) #endif @@ -593,6 +596,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) stack_init(mrb); } stack_extend(mrb, irep->nregs, irep->nregs); + mrb->c->ci->err = pc; mrb->c->ci->proc = proc; mrb->c->ci->nregs = irep->nregs + 1; regs = mrb->c->stack; @@ -684,6 +688,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) CASE(OP_GETCV) { /* A B R(A) := ivget(Sym(B)) */ + ERR_PC_HOOK(mrb, pc); regs[GETARG_A(i)] = mrb_vm_cv_get(mrb, syms[GETARG_Bx(i)]); NEXT; } @@ -696,6 +701,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) CASE(OP_GETCONST) { /* A B R(A) := constget(Sym(B)) */ + ERR_PC_HOOK(mrb, pc); regs[GETARG_A(i)] = mrb_vm_const_get(mrb, syms[GETARG_Bx(i)]); NEXT; } @@ -710,6 +716,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) /* A B C R(A) := R(C)::Sym(B) */ int a = GETARG_A(i); + ERR_PC_HOOK(mrb, pc); regs[a] = mrb_const_get(mrb, regs[a], syms[GETARG_Bx(i)]); NEXT; } -- cgit v1.2.3