diff options
| -rw-r--r-- | include/mruby/value.h | 87 | ||||
| -rw-r--r-- | include/mruby/variable.h | 1 | ||||
| -rw-r--r-- | src/kernel.c | 7 | ||||
| -rw-r--r-- | src/variable.c | 15 | ||||
| -rw-r--r-- | src/vm.c | 1 | ||||
| -rw-r--r-- | tools/mruby/mruby.c | 33 |
6 files changed, 97 insertions, 47 deletions
diff --git a/include/mruby/value.h b/include/mruby/value.h index 90c011a7e..ab56c9795 100644 --- a/include/mruby/value.h +++ b/include/mruby/value.h @@ -17,25 +17,26 @@ enum mrb_vtype { MRB_TT_SYMBOL, /* 4 */ MRB_TT_UNDEF, /* 5 */ MRB_TT_FLOAT, /* 6 */ - MRB_TT_MAIN, /* 7 */ - MRB_TT_OBJECT, /* 8 */ - MRB_TT_CLASS, /* 9 */ - MRB_TT_MODULE, /* 10 */ - MRB_TT_ICLASS, /* 11 */ - MRB_TT_SCLASS, /* 12 */ - MRB_TT_PROC, /* 13 */ - MRB_TT_ARRAY, /* 14 */ - MRB_TT_HASH, /* 15 */ - MRB_TT_STRING, /* 16 */ - MRB_TT_RANGE, /* 17 */ - MRB_TT_REGEX, /* 18 */ - MRB_TT_STRUCT, /* 19 */ - MRB_TT_EXCEPTION, /* 20 */ - MRB_TT_MATCH, /* 21 */ - MRB_TT_FILE, /* 22 */ - MRB_TT_ENV, /* 23 */ - MRB_TT_DATA, /* 24 */ - MRB_TT_MAXDEFINE /* 25 */ + MRB_TT_VOIDP, /* 7 */ + MRB_TT_MAIN, /* 8 */ + MRB_TT_OBJECT, /* 9 */ + MRB_TT_CLASS, /* 10 */ + MRB_TT_MODULE, /* 11 */ + MRB_TT_ICLASS, /* 12 */ + MRB_TT_SCLASS, /* 13 */ + MRB_TT_PROC, /* 14 */ + MRB_TT_ARRAY, /* 15 */ + MRB_TT_HASH, /* 16 */ + MRB_TT_STRING, /* 17 */ + MRB_TT_RANGE, /* 18 */ + MRB_TT_REGEX, /* 19 */ + MRB_TT_STRUCT, /* 20 */ + MRB_TT_EXCEPTION, /* 21 */ + MRB_TT_MATCH, /* 22 */ + MRB_TT_FILE, /* 23 */ + MRB_TT_ENV, /* 24 */ + MRB_TT_DATA, /* 25 */ + MRB_TT_MAXDEFINE /* 26 */ }; typedef struct mrb_value { @@ -78,24 +79,25 @@ enum mrb_vtype { MRB_TT_SYMBOL, /* 5 */ MRB_TT_UNDEF, /* 6 */ MRB_TT_FLOAT, /* 7 */ - MRB_TT_MAIN, /* 8 */ - MRB_TT_OBJECT, /* 9 */ - MRB_TT_CLASS, /* 10 */ - MRB_TT_MODULE, /* 11 */ - MRB_TT_ICLASS, /* 12 */ - MRB_TT_SCLASS, /* 13 */ - MRB_TT_PROC, /* 14 */ - MRB_TT_ARRAY, /* 15 */ - MRB_TT_HASH, /* 16 */ - MRB_TT_STRING, /* 17 */ - MRB_TT_RANGE, /* 18 */ - MRB_TT_REGEX, /* 19 */ - MRB_TT_STRUCT, /* 20 */ - MRB_TT_EXCEPTION, /* 21 */ - MRB_TT_MATCH, /* 22 */ - MRB_TT_FILE, /* 23 */ - MRB_TT_ENV, /* 24 */ - MRB_TT_DATA, /* 25 */ + MRB_TT_VOIDP, /* 8 */ + MRB_TT_MAIN, /* 9 */ + MRB_TT_OBJECT, /* 10 */ + MRB_TT_CLASS, /* 11 */ + MRB_TT_MODULE, /* 12 */ + MRB_TT_ICLASS, /* 13 */ + MRB_TT_SCLASS, /* 14 */ + MRB_TT_PROC, /* 15 */ + MRB_TT_ARRAY, /* 16 */ + MRB_TT_HASH, /* 17 */ + MRB_TT_STRING, /* 18 */ + MRB_TT_RANGE, /* 19 */ + MRB_TT_REGEX, /* 20 */ + MRB_TT_STRUCT, /* 21 */ + MRB_TT_EXCEPTION, /* 22 */ + MRB_TT_MATCH, /* 23 */ + MRB_TT_FILE, /* 24 */ + MRB_TT_ENV, /* 25 */ + MRB_TT_DATA, /* 26 */ MRB_TT_MAXDEFINE /* 27 */ }; @@ -149,6 +151,7 @@ mrb_float_value(mrb_float f) #define mrb_fixnum(o) (o).value.i #define mrb_symbol(o) (o).value.sym #define mrb_object(o) ((struct RBasic *) (o).value.p) +#define mrb_voidp(o) (o).value.p #define mrb_fixnum_p(o) (mrb_type(o) == MRB_TT_FIXNUM) #define mrb_float_p(o) (mrb_type(o) == MRB_TT_FLOAT) #define mrb_undef_p(o) (mrb_type(o) == MRB_TT_UNDEF) @@ -157,6 +160,7 @@ mrb_float_value(mrb_float f) #define mrb_array_p(o) (mrb_type(o) == MRB_TT_ARRAY) #define mrb_string_p(o) (mrb_type(o) == MRB_TT_STRING) #define mrb_hash_p(o) (mrb_type(o) == MRB_TT_HASH) +#define mrb_voidp_p(o) (mrb_type(o) == MRB_TT_VOIDP) #define mrb_test(o) (mrb_type(o) != MRB_TT_FALSE) #define MRB_OBJECT_HEADER \ @@ -229,6 +233,15 @@ mrb_obj_value(void *p) } static inline mrb_value +mrb_voidp_value(void *p) +{ + mrb_value v; + + MRB_SET_VALUE(v, MRB_TT_VOIDP, value.p, p); + return v; +} + +static inline mrb_value mrb_false_value(void) { mrb_value v; diff --git a/include/mruby/variable.h b/include/mruby/variable.h index 5126315c4..7189ef690 100644 --- a/include/mruby/variable.h +++ b/include/mruby/variable.h @@ -41,6 +41,7 @@ int mrb_const_defined(mrb_state*, mrb_value, mrb_sym); mrb_value mrb_obj_iv_get(mrb_state *mrb, struct RObject *obj, mrb_sym sym); void mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v); int mrb_obj_iv_defined(mrb_state *mrb, struct RObject *obj, mrb_sym sym); +void mrb_obj_iv_ifnone(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v); mrb_value mrb_iv_get(mrb_state *mrb, mrb_value obj, mrb_sym sym); void mrb_iv_set(mrb_state *mrb, mrb_value obj, mrb_sym sym, mrb_value v); int mrb_iv_defined(mrb_state*, mrb_value, mrb_sym); diff --git a/src/kernel.c b/src/kernel.c index 85eedc7ba..5e8a2f5aa 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -920,8 +920,9 @@ mrb_obj_public_methods(mrb_state *mrb, mrb_value self) mrb_value mrb_f_raise(mrb_state *mrb, mrb_value self) { - mrb_value a[2]; + mrb_value a[2], exc; int argc; + argc = mrb_get_args(mrb, "|oo", &a[0], &a[1]); switch (argc) { @@ -936,7 +937,9 @@ mrb_f_raise(mrb_state *mrb, mrb_value self) } /* fall through */ default: - mrb_exc_raise(mrb, mrb_make_exception(mrb, argc, a)); + exc = mrb_make_exception(mrb, argc, a); + mrb_obj_iv_set(mrb, mrb_obj_ptr(exc), mrb_intern(mrb, "lastpc"), mrb_voidp_value(mrb->ci->pc)); + mrb_exc_raise(mrb, exc); } return mrb_nil_value(); /* not reached */ } diff --git a/src/variable.c b/src/variable.c index 6907a8e2a..992663408 100644 --- a/src/variable.c +++ b/src/variable.c @@ -461,6 +461,21 @@ mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v) } void +mrb_obj_iv_ifnone(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v) +{ + iv_tbl *t = obj->iv; + + if (!t) { + t = obj->iv = iv_new(mrb); + } + else if (iv_get(mrb, t, sym, &v)) { + return; + } + mrb_write_barrier(mrb, (struct RBasic*)obj); + iv_put(mrb, t, sym, v); +} + +void mrb_iv_set(mrb_state *mrb, mrb_value obj, mrb_sym sym, mrb_value v) { if (obj_iv_p(obj)) { @@ -1151,6 +1151,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) int eidx; L_RAISE: + mrb_obj_iv_ifnone(mrb, mrb->exc, mrb_intern(mrb, "lastpc"), mrb_voidp_value(pc)); ci = mrb->ci; eidx = mrb->ci->eidx; if (ci == mrb->cibase) goto L_STOP; diff --git a/tools/mruby/mruby.c b/tools/mruby/mruby.c index d3ea924c7..99af7bc5d 100644 --- a/tools/mruby/mruby.c +++ b/tools/mruby/mruby.c @@ -188,8 +188,15 @@ showcallinfo(mrb_state *mrb) mrb_irep *irep = ci->proc->body.irep; if (irep->filename != NULL) filename = irep->filename; - if (irep->lines != NULL && i+1 <= ciidx) { - mrb_code *pc = mrb->cibase[i+1].pc; + if (irep->lines != NULL) { + mrb_code *pc; + + if (i+1 <= ciidx) { + pc = mrb->cibase[i+1].pc; + } + else { + pc = (mrb_code*)mrb_voidp(mrb_obj_iv_get(mrb, mrb->exc, mrb_intern(mrb, "lastpc"))); + } if (irep->iseq <= pc && pc < irep->iseq + irep->ilen) { line = irep->lines[pc - irep->iseq - 1]; } @@ -201,12 +208,22 @@ showcallinfo(mrb_state *mrb) sep = "#"; method = mrb_sym2name(mrb, ci->mid); - printf("\t[%d] %s:%d%s%s%s%s\n", - i, filename, line, - method ? ":in " : "", - method ? mrb_class_name(mrb, ci->proc->target_class) : "", - method ? sep : "", - method ? method : ""); + if (method) { + const char *cn = mrb_class_name(mrb, ci->proc->target_class); + + if (cn) { + printf("\t[%d] %s:%d:in %s%s%s\n", + i, filename, line, cn, sep, method); + } + else { + printf("\t[%d] %s:%d:in %s\n", + i, filename, line, method); + } + } + else { + printf("\t[%d] %s:%d\n", + i, filename, line); + } } } |
